Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-oran.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-29-100403-3660-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 * - Detect/indicate signs of application layer fragmentation?
41 * same eAxC in same symbol (same/different section ID?)
42 * - Not handling M-plane setting for "little endian byte order" as applied to
43 * IQ samples and beam weights does anyone use this?
44 * - for section extensions, check more constraints (which other extension types
45 * appear with them, order, repeated)
46 * - re-order items (decl and hf definitions) to match spec order?
47 * - track energy-saving status, and identify TRX or ASM commands as 'Sleep extension'
48 * - when tracking between C-plane and U-plane, indicated in C-plane any missing sectionIds/PRBs/REs
49 */
50
51/* Prototypes */
52void proto_register_oran(void);
53
54/* Initialize the protocol and registered fields */
55static int proto_oran;
56
57static int oran_tap = -1;
58
59static int hf_oran_du_port_id;
60static int hf_oran_bandsector_id;
61static int hf_oran_cc_id;
62static int hf_oran_ru_port_id;
63static int hf_oran_sequence_id;
64static int hf_oran_e_bit;
65static int hf_oran_subsequence_id;
66static int hf_oran_previous_frame;
67
68static int hf_oran_data_direction;
69static int hf_oran_payload_version;
70static int hf_oran_filter_index;
71static int hf_oran_frame_id;
72static int hf_oran_subframe_id;
73static int hf_oran_slot_id;
74static int hf_oran_slot_within_frame;
75static int hf_oran_start_symbol_id;
76static int hf_oran_numberOfSections;
77static int hf_oran_sectionType;
78
79static int hf_oran_udCompHdr;
80static int hf_oran_udCompHdrIqWidth;
81static int hf_oran_udCompHdrIqWidth_pref;
82static int hf_oran_udCompHdrMeth;
83static int hf_oran_udCompHdrMeth_pref;
84static int hf_oran_udCompLen;
85static int hf_oran_numberOfUEs;
86static int hf_oran_timeOffset;
87static int hf_oran_frameStructure_fft;
88static int hf_oran_frameStructure_subcarrier_spacing;
89static int hf_oran_cpLength;
90static int hf_oran_timing_header;
91static int hf_oran_section_id;
92static int hf_oran_rb;
93static int hf_oran_symInc;
94static int hf_oran_startPrbc;
95static int hf_oran_reMask_re1;
96static int hf_oran_reMask_re2;
97static int hf_oran_reMask_re3;
98static int hf_oran_reMask_re4;
99static int hf_oran_reMask_re5;
100static int hf_oran_reMask_re6;
101static int hf_oran_reMask_re7;
102static int hf_oran_reMask_re8;
103static int hf_oran_reMask_re9;
104static int hf_oran_reMask_re10;
105static int hf_oran_reMask_re11;
106static int hf_oran_reMask_re12;
107static int hf_oran_reMask;
108static int hf_oran_numPrbc;
109static int hf_oran_numSymbol;
110static int hf_oran_ef;
111static int hf_oran_beamId;
112
113static int hf_oran_sinrCompHdrIqWidth_pref;
114static int hf_oran_sinrCompHdrMeth_pref;
115
116static int hf_oran_ciCompHdr;
117static int hf_oran_ciCompHdrIqWidth;
118static int hf_oran_ciCompHdrMeth;
119static int hf_oran_ciCompOpt;
120
121static int hf_oran_extension;
122static int hf_oran_exttype;
123static int hf_oran_extlen;
124
125static int hf_oran_bfw_bundle;
126static int hf_oran_bfw_bundle_id;
127static int hf_oran_bfw;
128static int hf_oran_bfw_i;
129static int hf_oran_bfw_q;
130
131static int hf_oran_ueId;
132static int hf_oran_freqOffset;
133static int hf_oran_regularizationFactor;
134static int hf_oran_laaMsgType;
135static int hf_oran_laaMsgLen;
136static int hf_oran_lbtHandle;
137static int hf_oran_lbtDeferFactor;
138static int hf_oran_lbtBackoffCounter;
139static int hf_oran_lbtOffset;
140static int hf_oran_MCOT;
141static int hf_oran_lbtMode;
142static int hf_oran_sfnSfEnd;
143static int hf_oran_lbtPdschRes;
144static int hf_oran_sfStatus;
145static int hf_oran_initialPartialSF;
146static int hf_oran_lbtDrsRes;
147static int hf_oran_lbtBufErr;
148static int hf_oran_lbtTrafficClass;
149static int hf_oran_lbtCWConfig_H;
150static int hf_oran_lbtCWConfig_T;
151static int hf_oran_lbtCWR_Rst;
152
153static int hf_oran_reserved;
154static int hf_oran_reserved_1bit;
155static int hf_oran_reserved_2bits;
156static int hf_oran_reserved_3bits;
157static int hf_oran_reserved_4bits;
158static int hf_oran_reserved_last_4bits;
159static int hf_oran_reserved_last_5bits;
160static int hf_oran_reserved_6bits;
161static int hf_oran_reserved_last_6bits;
162static int hf_oran_reserved_7bits;
163static int hf_oran_reserved_last_7bits;
164static int hf_oran_reserved_8bits;
165static int hf_oran_reserved_16bits;
166static int hf_oran_reserved_15bits;
167static int hf_oran_reserved_bit1;
168static int hf_oran_reserved_bit2;
169static int hf_oran_reserved_bit4;
170static int hf_oran_reserved_bit5;
171static int hf_oran_reserved_bits123;
172static int hf_oran_reserved_bits456;
173
174static int hf_oran_bundle_offset;
175static int hf_oran_cont_ind;
176
177static int hf_oran_bfwCompHdr;
178static int hf_oran_bfwCompHdr_iqWidth;
179static int hf_oran_bfwCompHdr_compMeth;
180static int hf_oran_symbolId;
181static int hf_oran_startPrbu;
182static int hf_oran_numPrbu;
183
184static int hf_oran_udCompParam;
185static int hf_oran_sReSMask;
186static int hf_oran_sReSMask_re12;
187static int hf_oran_sReSMask_re11;
188static int hf_oran_sReSMask_re10;
189static int hf_oran_sReSMask_re9;
190static int hf_oran_sReSMask_re8;
191static int hf_oran_sReSMask_re7;
192static int hf_oran_sReSMask_re6;
193static int hf_oran_sReSMask_re5;
194static int hf_oran_sReSMask_re4;
195static int hf_oran_sReSMask_re3;
196static int hf_oran_sReSMask_re2;
197static int hf_oran_sReSMask_re1;
198
199static int hf_oran_sReSMask1;
200static int hf_oran_sReSMask2;
201static int hf_oran_sReSMask1_2_re12;
202static int hf_oran_sReSMask1_2_re11;
203static int hf_oran_sReSMask1_2_re10;
204static int hf_oran_sReSMask1_2_re9;
205
206static int hf_oran_bfwCompParam;
207
208static int hf_oran_iSample;
209static int hf_oran_qSample;
210
211static int hf_oran_ciCompParam;
212
213static int hf_oran_blockScaler;
214static int hf_oran_compBitWidth;
215static int hf_oran_compShift;
216
217static int hf_oran_active_beamspace_coefficient_n1;
218static int hf_oran_active_beamspace_coefficient_n2;
219static int hf_oran_active_beamspace_coefficient_n3;
220static int hf_oran_active_beamspace_coefficient_n4;
221static int hf_oran_active_beamspace_coefficient_n5;
222static int hf_oran_active_beamspace_coefficient_n6;
223static int hf_oran_active_beamspace_coefficient_n7;
224static int hf_oran_active_beamspace_coefficient_n8;
225static int hf_oran_activeBeamspaceCoefficientMask;
226static int hf_oran_activeBeamspaceCoefficientMask_bits_set;
227
228static int hf_oran_se6_repetition;
229
230static int hf_oran_rbgSize;
231static int hf_oran_rbgMask;
232static int hf_oran_noncontig_priority;
233
234static int hf_oran_symbol_mask;
235static int hf_oran_symbol_mask_s13;
236static int hf_oran_symbol_mask_s12;
237static int hf_oran_symbol_mask_s11;
238static int hf_oran_symbol_mask_s10;
239static int hf_oran_symbol_mask_s9;
240static int hf_oran_symbol_mask_s8;
241static int hf_oran_symbol_mask_s7;
242static int hf_oran_symbol_mask_s6;
243static int hf_oran_symbol_mask_s5;
244static int hf_oran_symbol_mask_s4;
245static int hf_oran_symbol_mask_s3;
246static int hf_oran_symbol_mask_s2;
247static int hf_oran_symbol_mask_s1;
248static int hf_oran_symbol_mask_s0;
249
250static int hf_oran_exponent;
251static int hf_oran_iq_user_data;
252
253static int hf_oran_disable_bfws;
254static int hf_oran_rad;
255static int hf_oran_num_bund_prbs;
256static int hf_oran_beam_id;
257static int hf_oran_num_weights_per_bundle;
258
259static int hf_oran_ack_nack_req_id;
260
261static int hf_oran_frequency_range;
262static int hf_oran_off_start_prb;
263static int hf_oran_num_prb;
264
265static int hf_oran_samples_prb;
266static int hf_oran_ciSample;
267static int hf_oran_ciIsample;
268static int hf_oran_ciQsample;
269
270static int hf_oran_beamGroupType;
271static int hf_oran_numPortc;
272
273static int hf_oran_csf;
274static int hf_oran_modcompscaler;
275
276static int hf_oran_modcomp_param_set;
277static int hf_oran_mc_scale_re_mask_re1;
278static int hf_oran_mc_scale_re_mask_re2;
279static int hf_oran_mc_scale_re_mask_re3;
280static int hf_oran_mc_scale_re_mask_re4;
281static int hf_oran_mc_scale_re_mask_re5;
282static int hf_oran_mc_scale_re_mask_re6;
283static int hf_oran_mc_scale_re_mask_re7;
284static int hf_oran_mc_scale_re_mask_re8;
285static int hf_oran_mc_scale_re_mask_re9;
286static int hf_oran_mc_scale_re_mask_re10;
287static int hf_oran_mc_scale_re_mask_re11;
288static int hf_oran_mc_scale_re_mask_re12;
289static int hf_oran_mc_scale_re_mask_re1_even;
290static int hf_oran_mc_scale_re_mask_re2_even;
291static int hf_oran_mc_scale_re_mask_re3_even;
292static int hf_oran_mc_scale_re_mask_re4_even;
293static int hf_oran_mc_scale_re_mask_re5_even;
294static int hf_oran_mc_scale_re_mask_re6_even;
295static int hf_oran_mc_scale_re_mask_re7_even;
296static int hf_oran_mc_scale_re_mask_re8_even;
297static int hf_oran_mc_scale_re_mask_re9_even;
298static int hf_oran_mc_scale_re_mask_re10_even;
299static int hf_oran_mc_scale_re_mask_re11_even;
300static int hf_oran_mc_scale_re_mask_re12_even;
301
302static int hf_oran_mc_scale_re_mask;
303static int hf_oran_mc_scale_re_mask_even;
304
305static int hf_oran_mc_scale_offset;
306
307static int hf_oran_eAxC_mask;
308static int hf_oran_technology;
309static int hf_oran_nullLayerInd;
310
311static int hf_oran_se19_repetition;
312static int hf_oran_portReMask;
313static int hf_oran_portSymbolMask;
314
315static int hf_oran_ext19_port;
316
317static int hf_oran_prb_allocation;
318static int hf_oran_nextSymbolId;
319static int hf_oran_nextStartPrbc;
320
321static int hf_oran_puncPattern;
322static int hf_oran_numPuncPatterns;
323static int hf_oran_symbolMask_ext20;
324static int hf_oran_startPuncPrb;
325static int hf_oran_numPuncPrb;
326static int hf_oran_puncReMask;
327static int hf_oran_multiSDScope;
328static int hf_oran_RbgIncl;
329
330static int hf_oran_ci_prb_group_size;
331static int hf_oran_prg_size_st5;
332static int hf_oran_prg_size_st6;
333
334static int hf_oran_num_ueid;
335
336static int hf_oran_antMask;
337
338static int hf_oran_transmissionWindowOffset;
339static int hf_oran_transmissionWindowSize;
340static int hf_oran_toT;
341
342static int hf_oran_bfaCompHdr;
343static int hf_oran_bfAzPtWidth;
344static int hf_oran_bfZePtWidth;
345static int hf_oran_bfAz3ddWidth;
346static int hf_oran_bfZe3ddWidth;
347static int hf_oran_bfAzPt;
348static int hf_oran_bfZePt;
349static int hf_oran_bfAz3dd;
350static int hf_oran_bfZe3dd;
351static int hf_oran_bfAzSl;
352static int hf_oran_bfZeSl;
353
354static int hf_oran_cmd_scope;
355static int hf_oran_number_of_st4_cmds;
356
357static int hf_oran_st4_cmd_header;
358static int hf_oran_st4_cmd_type;
359static int hf_oran_st4_cmd_len;
360static int hf_oran_st4_cmd_num_slots;
361static int hf_oran_st4_cmd_ack_nack_req_id;
362
363static int hf_oran_st4_cmd;
364
365static int hf_oran_sleepmode_trx;
366static int hf_oran_sleepmode_asm;
367static int hf_oran_log2maskbits;
368static int hf_oran_num_slots_ext;
369static int hf_oran_antMask_trx_control;
370
371static int hf_oran_ready;
372static int hf_oran_number_of_acks;
373static int hf_oran_number_of_nacks;
374static int hf_oran_ackid;
375static int hf_oran_nackid;
376
377static int hf_oran_acknack_request_frame;
378static int hf_oran_acknack_request_time;
379static int hf_oran_acknack_request_type;
380static int hf_oran_acknack_response_frame;
381static int hf_oran_acknack_response_time;
382
383static int hf_oran_disable_tdbfns;
384static int hf_oran_td_beam_group;
385static int hf_oran_disable_tdbfws;
386static int hf_oran_td_beam_num;
387
388static int hf_oran_dir_pattern;
389static int hf_oran_guard_pattern;
390
391static int hf_oran_ecpri_pcid;
392static int hf_oran_ecpri_rtcid;
393static int hf_oran_ecpri_seqid;
394
395static int hf_oran_num_sym_prb_pattern;
396static int hf_oran_prb_mode;
397static int hf_oran_sym_prb_pattern;
398static int hf_oran_sym_mask;
399static int hf_oran_num_mc_scale_offset;
400static int hf_oran_prb_pattern;
401static int hf_oran_prb_blk_offset;
402static int hf_oran_prb_blk_size;
403
404static int hf_oran_codebook_index;
405static int hf_oran_layerid;
406static int hf_oran_numlayers;
407static int hf_oran_txscheme;
408static int hf_oran_crs_remask;
409static int hf_oran_crs_shift;
410static int hf_oran_crs_symnum;
411static int hf_oran_beamid_ap1;
412static int hf_oran_beamid_ap2;
413static int hf_oran_beamid_ap3;
414
415static int hf_oran_port_list_index;
416static int hf_oran_alpn_per_sym;
417static int hf_oran_ant_dmrs_snr;
418static int hf_oran_user_group_size;
419static int hf_oran_user_group_id;
420static int hf_oran_entry_type;
421static int hf_oran_dmrs_port_number;
422static int hf_oran_ueid_reset;
423
424static int hf_oran_dmrs_symbol_mask;
425static int hf_oran_dmrs_symbol_mask_s13;
426static int hf_oran_dmrs_symbol_mask_s12;
427static int hf_oran_dmrs_symbol_mask_s11;
428static int hf_oran_dmrs_symbol_mask_s10;
429static int hf_oran_dmrs_symbol_mask_s9;
430static int hf_oran_dmrs_symbol_mask_s8;
431static int hf_oran_dmrs_symbol_mask_s7;
432static int hf_oran_dmrs_symbol_mask_s6;
433static int hf_oran_dmrs_symbol_mask_s5;
434static int hf_oran_dmrs_symbol_mask_s4;
435static int hf_oran_dmrs_symbol_mask_s3;
436static int hf_oran_dmrs_symbol_mask_s2;
437static int hf_oran_dmrs_symbol_mask_s1;
438static int hf_oran_dmrs_symbol_mask_s0;
439
440static int hf_oran_scrambling;
441static int hf_oran_nscid;
442static int hf_oran_dtype;
443static int hf_oran_cmd_without_data;
444static int hf_oran_lambda;
445static int hf_oran_first_prb;
446static int hf_oran_last_prb;
447static int hf_oran_low_papr_type;
448static int hf_oran_hopping_mode;
449
450static int hf_oran_tx_win_for_on_air_symbol_l;
451static int hf_oran_tx_win_for_on_air_symbol_r;
452
453static int hf_oran_num_fo_fb;
454static int hf_oran_freq_offset_fb;
455
456static int hf_oran_num_ue_sinr_rpt;
457static int hf_oran_num_sinr_per_prb;
458static int hf_oran_num_sinr_per_prb_right;
459
460static int hf_oran_sinr_value;
461
462static int hf_oran_measurement_report;
463static int hf_oran_mf;
464static int hf_oran_meas_data_size;
465static int hf_oran_meas_type_id;
466static int hf_oran_ipn_power;
467static int hf_oran_ue_tae;
468static int hf_oran_ue_layer_power;
469static int hf_oran_num_elements;
470static int hf_oran_ant_dmrs_snr_val;
471static int hf_oran_ue_freq_offset;
472
473static int hf_oran_measurement_command;
474
475static int hf_oran_beam_type;
476static int hf_oran_meas_cmd_size;
477
478static int hf_oran_symbol_reordering_layer;
479static int hf_oran_dmrs_entry;
480
481static int hf_oran_c_section_common;
482static int hf_oran_c_section;
483static int hf_oran_u_section;
484
485static int hf_oran_u_section_ul_symbol_time;
486static int hf_oran_u_section_ul_symbol_frames;
487static int hf_oran_u_section_ul_symbol_first_frame;
488static int hf_oran_u_section_ul_symbol_last_frame;
489
490static int hf_oran_cd_scg_size;
491static int hf_oran_cd_scg_phase_step;
492
493static int hf_oran_sinr_prb;
494static int hf_oran_oru_control_sinr_slot_mask_id;
495static int hf_oran_pos_meas;
496
497static int hf_oran_ue_radial_speed;
498static int hf_oran_ue_az_aoa;
499static int hf_oran_ue_ze_aoa;
500static int hf_oran_ue_pos_toa_offset;
501
502static int hf_oran_num_rep_ue;
503static int hf_oran_rep_ueid;
504static int hf_oran_is_last_rep;
505static int hf_oran_rep_index;
506static int hf_oran_num_reps;
507
508static int hf_oran_mcs_table;
509static int hf_oran_mcs_index;
510
511static int hf_oran_num_meas_req;
512static int hf_oran_num_of_ue_ant_ports;
513static int hf_oran_ue_rank;
514static int hf_oran_codebook_subset;
515static int hf_oran_full_pwr_mode;
516static int hf_oran_full_pwr_mode_2_tpmi_group;
517
518static int hf_oran_num_cand_ranks;
519static int hf_oran_ue_pref_rank;
520static int hf_oran_ue_tpmi_rank_y;
521static int hf_oran_ue_tpmi_rank_y_sinr_lx;
522static int hf_oran_ue_layer_pre_eq_sinr;
523
524
525/* Computed fields */
526static int hf_oran_c_eAxC_ID;
527static int hf_oran_refa;
528
529static int hf_oran_bfws_frame_defined;
530static int hf_oran_bfws_symbols_since_defined;
531
532static int hf_oran_corresponding_cplane_frame;
533static int hf_oran_corresponding_cplane_frame_time_delta;
534static int hf_oran_corresponding_uplane_frame;
535static int hf_oran_corresponding_uplane_frames_total;
536
537
538/* Convenient fields for filtering, mostly shown as hidden */
539static int hf_oran_cplane;
540static int hf_oran_uplane;
541static int hf_oran_bf; /* to match frames that configure beamforming in any way */
542static int hf_oran_zero_prb;
543static int hf_oran_nonzero_prb;
544static int hf_oran_bundle_weights_all_zero;
545
546static int hf_oran_ul_cplane_ud_comp_hdr_frame;
547
548/* For reassembly */
549static int hf_oran_fragments;
550static int hf_oran_fragment;
551static int hf_oran_fragment_overlap;
552static int hf_oran_fragment_overlap_conflict;
553static int hf_oran_fragment_multiple_tails;
554static int hf_oran_fragment_too_long_fragment;
555static int hf_oran_fragment_error;
556static int hf_oran_fragment_count;
557static int hf_oran_reassembled_in;
558static int hf_oran_reassembled_length;
559static int hf_oran_reassembled_data;
560
561static int hf_oran_payload;
562
563
564/* Subtrees */
565static int ett_oran;
566static int ett_oran_ecpri_rtcid;
567static int ett_oran_ecpri_pcid;
568static int ett_oran_ecpri_seqid;
569static int ett_oran_section;
570static int ett_oran_section_type;
571static int ett_oran_u_timing;
572static int ett_oran_u_section;
573static int ett_oran_u_prb;
574static int ett_oran_iq;
575static int ett_oran_bfw_bundle;
576static int ett_oran_bfw;
577static int ett_oran_frequency_range;
578static int ett_oran_prb_cisamples;
579static int ett_oran_cisample;
580static int ett_oran_udcomphdr;
581static int ett_oran_udcompparam;
582static int ett_oran_cicomphdr;
583static int ett_oran_cicompparam;
584static int ett_oran_bfwcomphdr;
585static int ett_oran_bfwcompparam;
586static int ett_oran_ext19_port;
587static int ett_oran_prb_allocation;
588static int ett_oran_punc_pattern;
589static int ett_oran_bfacomphdr;
590static int ett_oran_modcomp_param_set;
591static int ett_oran_st4_cmd_header;
592static int ett_oran_st4_cmd;
593static int ett_oran_sym_prb_pattern;
594static int ett_oran_measurement_report;
595static int ett_oran_measurement_command;
596static int ett_oran_sresmask;
597static int ett_oran_c_section_common;
598static int ett_oran_c_section;
599static int ett_oran_remask;
600static int ett_oran_mc_scale_remask;
601static int ett_oran_symbol_reordering_layer;
602static int ett_oran_dmrs_entry;
603static int ett_oran_dmrs_symbol_mask;
604static int ett_oran_symbol_mask;
605static int ett_oran_active_beamspace_coefficient_mask;
606static int ett_oran_sinr_prb;
607
608static int ett_oran_fragment;
609static int ett_oran_fragments;
610
611/* Reassembly table. */
612static reassembly_table oran_reassembly_table;
613
614static void *oran_key(const packet_info *pinfo _U___attribute__((unused)), const uint32_t id _U___attribute__((unused)), const void *data)
615{
616 return (void *)data;
617}
618
619static void oran_free_key(void *ptr _U___attribute__((unused)))
620{
621}
622
623static reassembly_table_functions oran_reassembly_table_functions =
624{
625 g_direct_hash,
626 g_direct_equal,
627 oran_key,
628 oran_key,
629 oran_free_key,
630 oran_free_key
631};
632
633static const fragment_items oran_frag_items = {
634 &ett_oran_fragment,
635 &ett_oran_fragments,
636 &hf_oran_fragments,
637 &hf_oran_fragment,
638 &hf_oran_fragment_overlap,
639 &hf_oran_fragment_overlap_conflict,
640 &hf_oran_fragment_multiple_tails,
641 &hf_oran_fragment_too_long_fragment,
642 &hf_oran_fragment_error,
643 &hf_oran_fragment_count,
644 &hf_oran_reassembled_in,
645 &hf_oran_reassembled_length,
646 &hf_oran_reassembled_data,
647 "O-RAN FH CUS fragments"
648};
649
650
651
652/* Don't want all extensions to open and close together. Use [extType-1] entry */
653static int ett_oran_c_section_extension[HIGHEST_EXTTYPE32];
654
655/* Expert info */
656static expert_field ei_oran_unsupported_bfw_compression_method;
657static expert_field ei_oran_invalid_sample_bit_width;
658static expert_field ei_oran_reserved_numBundPrb;
659static expert_field ei_oran_extlen_wrong;
660static expert_field ei_oran_invalid_eaxc_bit_width;
661static expert_field ei_oran_extlen_zero;
662static expert_field ei_oran_rbg_size_reserved;
663static expert_field ei_oran_frame_length;
664static expert_field ei_oran_numprbc_ext21_zero;
665static expert_field ei_oran_ci_prb_group_size_reserved;
666static expert_field ei_oran_st8_nackid;
667static expert_field ei_oran_st4_no_cmds;
668static expert_field ei_oran_st4_zero_len_cmd;
669static expert_field ei_oran_st4_wrong_len_cmd;
670static expert_field ei_oran_st4_unknown_cmd;
671static expert_field ei_oran_mcot_out_of_range;
672static expert_field ei_oran_se10_unknown_beamgrouptype;
673static expert_field ei_oran_se10_not_allowed;
674static expert_field ei_oran_start_symbol_id_not_zero;
675static expert_field ei_oran_trx_control_cmd_scope;
676static expert_field ei_oran_unhandled_se;
677static expert_field ei_oran_bad_symbolmask;
678static expert_field ei_oran_numslots_not_zero;
679static expert_field ei_oran_version_unsupported;
680static expert_field ei_oran_laa_msg_type_unsupported;
681static expert_field ei_oran_se_on_unsupported_st;
682static expert_field ei_oran_cplane_unexpected_sequence_number_ul;
683static expert_field ei_oran_cplane_unexpected_sequence_number_dl;
684static expert_field ei_oran_uplane_unexpected_sequence_number_ul;
685static expert_field ei_oran_uplane_unexpected_sequence_number_dl;
686static expert_field ei_oran_acknack_no_request;
687static expert_field ei_oran_udpcomphdr_should_be_zero;
688static expert_field ei_oran_radio_fragmentation_c_plane;
689static expert_field ei_oran_lastRbdid_out_of_range;
690static expert_field ei_oran_rbgMask_beyond_last_rbdid;
691static expert_field ei_oran_unexpected_measTypeId;
692static expert_field ei_oran_unsupported_compression_method;
693static expert_field ei_oran_ud_comp_len_wrong_size;
694static expert_field ei_oran_sresmask2_not_zero_with_rb;
695static expert_field ei_oran_st6_rb_shall_be_0;
696static expert_field ei_oran_st9_not_ul;
697static expert_field ei_oran_st10_numsymbol_not_14;
698static expert_field ei_oran_st10_startsymbolid_not_0;
699static expert_field ei_oran_st10_not_ul;
700static expert_field ei_oran_se24_nothing_to_inherit;
701static expert_field ei_oran_num_sinr_per_prb_unknown;
702static expert_field ei_oran_start_symbol_id_bits_ignored;
703static expert_field ei_oran_user_group_id_reserved_value;
704static expert_field ei_oran_port_list_index_zero;
705static expert_field ei_oran_ul_uplane_symbol_too_long;
706static expert_field ei_oran_reserved_not_zero;
707static expert_field ei_oran_too_many_symbols;
708static expert_field ei_oran_se30_not_ul;
709static expert_field ei_oran_se30_unknown_ueid;
710static expert_field ei_oran_beamid_bfws_not_found;
711static expert_field ei_oran_syminc_set_for_uplane;
712static expert_field ei_oran_cplane_entry_not_found;
713
714
715/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
716#define ECPRI_MT_IQ_DATA0 0
717#define ECPRI_MT_RT_CTRL_DATA2 2
718
719
720/* Preference settings - try to set reasonable defaults */
721static unsigned pref_du_port_id_bits = 4;
722static unsigned pref_bandsector_id_bits = 4;
723static unsigned pref_cc_id_bits = 4;
724static unsigned pref_ru_port_id_bits = 4;
725
726/* TODO: ideally should be per-flow */
727static unsigned pref_sample_bit_width_uplink = 14;
728static unsigned pref_sample_bit_width_downlink = 14;
729static unsigned pref_sample_bit_width_sinr = 14;
730
731/* TODO: these ideally should be per-flow too */
732static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
733static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
734
735static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
736
737
738/* Is udCompHeader present (both directions) */
739static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
740static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
741
742/* Are we ignoring UL C-Plane udCompHdr? */
743static bool_Bool pref_override_ul_compression = false0;
744
745static unsigned pref_data_plane_section_total_rbs = 273;
746static unsigned pref_num_bf_antennas = 32;
747static bool_Bool pref_showIQSampleValues = true1;
748
749/* Based upon m-plane param, so will be system-wide */
750static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
751static bool_Bool udcomplen_heuristic_result_set = false0;
752static bool_Bool udcomplen_heuristic_result = false0;
753
754/* st6-4byte-alignment-required */
755static bool_Bool st6_4byte_alignment = false0;
756
757/* Requested, allows I/Q to be stored as integers.. */
758static bool_Bool show_unscaled_values = false0;
759
760/* Initialized off. Timing is in microseconds. */
761static unsigned us_allowed_for_ul_in_symbol = 0;
762
763/* Reassemble U-Plane (at Radio Transport layer) */
764static bool_Bool do_radio_transport_layer_reassembly = true1;
765
766/* Link U-plane back to C-plane using sectionIds */
767static bool_Bool link_planes_together = true1;
768
769static const enum_val_t dl_compression_options[] = {
770 { "COMP_NONE", "No Compression", COMP_NONE0 },
771 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
772 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
773 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
774 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
775 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
776 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
777 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
778 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
779 { NULL((void*)0), NULL((void*)0), 0 }
780};
781
782/* No Modulation compression in UL.. */
783static const enum_val_t ul_compression_options[] = {
784 { "COMP_NONE", "No Compression", COMP_NONE0 },
785 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
786 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
787 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
788 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
789 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
790 { NULL((void*)0), NULL((void*)0), 0 }
791};
792
793static const enum_val_t udcomplen_support_options[] = {
794 { "NOT_SUPPORTED", "Not Supported", 0 },
795 { "SUPPORTED", "Supported", 1 },
796 { "HEURISTIC", "Attempt Heuristic", 2 },
797 { NULL((void*)0), NULL((void*)0), 0 }
798};
799
800static const enum_val_t udcomphdr_present_options[] = {
801 { "NOT_PRESENT", "Not Present", 0 },
802 { "PRESENT", "Present", 1 },
803 { "HEURISTIC", "Attempt Heuristic", 2 },
804 { NULL((void*)0), NULL((void*)0), 0 }
805};
806
807
808
809static const value_string e_bit[] = {
810 { 0, "More fragments follow" },
811 { 1, "Last fragment" },
812 { 0, NULL((void*)0)}
813};
814
815#define DIR_UPLINK0 0
816#define DIR_DOWNLINK1 1
817
818
819static const value_string data_direction_vals[] = {
820 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
821 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
822 { 0, NULL((void*)0)}
823};
824
825static const value_string rb_vals[] = {
826 { 0, "Every RB used" },
827 { 1, "Every other RB used" },
828 { 0, NULL((void*)0)}
829};
830
831static const value_string sym_inc_vals[] = {
832 { 0, "Use the current symbol number" },
833 { 1, "Increment the current symbol number" },
834 { 0, NULL((void*)0)}
835};
836
837static const value_string lbtMode_vals[] = {
838 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
839 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
840 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
841 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
842 { 0, NULL((void*)0)}
843};
844
845static const value_string ue_rank_vals[] = {
846 { 1, "1" },
847 { 2, "2" },
848 { 3, "3" },
849 { 4, "4" },
850 { 0, NULL((void*)0)}
851};
852
853static const value_string num_of_ue_ant_ports_vals[] = {
854 { 2, "2" },
855 { 4, "4" },
856 { 0, NULL((void*)0)}
857};
858
859static const value_string codebook_subset_vals[] = {
860 { 0, "nonCoherent" },
861 { 1, "partialAndNonCoherent" },
862 { 2, "fullyAndPartialAndNonCoherent" },
863 { 3, "reserved" },
864 { 0, NULL((void*)0)}
865};
866
867
868static const range_string filter_indices[] = {
869 {0, 0, "standard channel filter"},
870 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
871 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
872 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
873 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
874 {5, 5, "UL filter for PRACH preamble formats"},
875 {8, 8, "UL filter NPUSCH"},
876 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
877 {9, 15, "Reserved"},
878 {0, 0, NULL((void*)0)}
879};
880
881/* 7.3.1-1 */
882static const range_string section_types[] = {
883 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
884 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
885 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
886 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
887 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
888 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
889 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
890 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
891 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
892 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
893 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
894 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
895 { 12, 255, "Reserved for future use" },
896 { 0, 0, NULL((void*)0)} };
897
898static const range_string section_types_short[] = {
899 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
900 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
901 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
902 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
903 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
904 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
905 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
906 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
907 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
908 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
909 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
910 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
911 { 12, 255, "Reserved for future use" },
912 { 0, 0, NULL((void*)0) }
913};
914
915static const range_string ud_comp_header_width[] = {
916 {0, 0, "I and Q are each 16 bits wide"},
917 {1, 15, "Bit width of I and Q"},
918 {0, 0, NULL((void*)0)} };
919
920/* Table 8.3.3.13-3 */
921static const range_string ud_comp_header_meth[] = {
922 {COMP_NONE0, COMP_NONE0, "No compression" },
923 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
924 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
925 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
926 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
927 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
928 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
929 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
930 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
931 {9, 15, "Reserved"},
932 {0, 0, NULL((void*)0)}
933};
934
935/* Table 7.5.2.13-2 */
936static const range_string frame_structure_fft[] = {
937 {0, 0, "Reserved (no FFT/iFFT processing)"},
938 {1, 3, "Reserved"},
939 {4, 4, "FFT size 16"},
940 {5, 5, "FFT size 32"},
941 {6, 6, "FFT size 64"},
942 {7, 7, "FFT size 128"},
943 {8, 8, "FFT size 256"},
944 {9, 9, "FFT size 512"},
945 {10, 10, "FFT size 1024"},
946 {11, 11, "FFT size 2048"},
947 {12, 12, "FFT size 4096"},
948 {13, 13, "FFT size 1536"},
949 {14, 14, "FFT size 3072"},
950 {15, 15, "Reserved"},
951 {0, 0, NULL((void*)0)}
952};
953
954/* Table 7.5.2.13-3 */
955static const range_string subcarrier_spacings[] = {
956 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
957 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
958 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
959 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
960 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
961 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
962 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
963 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
964 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
965 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
966 { 0, 0, NULL((void*)0) }
967};
968
969/* Table 7.5.3.14-1 laaMsgType definition */
970static const range_string laaMsgTypes[] = {
971 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
972 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
973 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
974 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
975 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
976 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
977 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
978 {7, 15, "reserved for future methods"},
979 {0, 0, NULL((void*)0)}
980};
981
982/* 7.7.26.3 */
983static const range_string freq_offset_fb_values[] = {
984 {0, 0, "no frequency offset"},
985 {8000, 8000, "value not provided"},
986 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
987 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
988 {0x0, 0xffff, "reserved"},
989 {0, 0, NULL((void*)0)}
990};
991
992/* 7.5.3.78 */
993static const range_string ue_tmpi_rank_sinr_vals[] = {
994 {0, 0, "0 dB SINR"},
995 {0x0001, 0x07ff, "positive SINR"},
996 {0xf800, 0xffff, "-ve SINR"},
997 {0x8000, 0x8000, "invalid measurement result"},
998 {0x0, 0xffff, "reserved"},
999 {0, 0, NULL((void*)0)}
1000};
1001
1002
1003
1004/* Table 7.5.2.19-1 */
1005static const value_string num_sinr_per_prb_vals[] = {
1006 { 0, "1" },
1007 { 1, "2" },
1008 { 2, "3" },
1009 { 3, "4" },
1010 { 4, "6" },
1011 { 5, "12" },
1012 { 6, "1 SINR value per section for DFT-s-OFDM" },
1013 { 7, "reserved" },
1014 { 0, NULL((void*)0)}
1015};
1016
1017static const value_string meas_type_id_vals[] = {
1018 { 1, "UE Timing Advance Error" },
1019 { 2, "UE Layer power" },
1020 { 3, "UE frequency offset" },
1021 { 4, "Interference plus Noise for allocated PRBs" },
1022 { 5, "Interference plus Noise for unallocated PRBs" },
1023 { 6, "DMRS-SNR per antenna" },
1024 { 7, "UE positioning measurement report" },
1025 { 8, "UE radial speed measurement report" },
1026 { 9, "UE post-equalization MU inteference measurement" },
1027 { 10, "UE TPMI and rank recommendation measurement" },
1028 { 11, "UE layer pre-equalization SINR report" },
1029 { 0, NULL((void*)0)}
1030};
1031
1032static const value_string beam_type_vals[] = {
1033 { 0, "List of beamId values" },
1034 { 1, "Range of beamId values" },
1035 { 0, NULL((void*)0)}
1036};
1037
1038/* 7.7.24.3 */
1039static const value_string entry_type_vals[] = {
1040 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
1041 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
1042 { 2, "related parameters if have transform precoding disabled " },
1043 { 3, "related parameters if have transform precoding enabled " },
1044 { 0, NULL((void*)0)}
1045};
1046
1047/* Table 7.7.29.3-1 */
1048static const range_string cd_scg_size_vals[] = {
1049 { 0, 0, "1 subcarrier" },
1050 { 1, 1, "1 RB x N subcarriers" },
1051 { 2, 2, "2 RB x N subcarriers" },
1052 { 3, 3, "4 RB x N subcarriers" },
1053 { 4, 4, "8 RB x N subcarriers" },
1054 { 5, 5, "16 RB x N subcarriers" },
1055 { 6, 6, "32 RB x N subcarriers" },
1056 { 7, 15, "reserved"},
1057 { 0, 0, NULL((void*)0)}
1058};
1059
1060
1061/* Table 7.6.1-1 */
1062static const value_string exttype_vals[] = {
1063 {0, "Reserved"},
1064 {1, "Beamforming weights"},
1065 {2, "Beamforming attributes"},
1066 {3, "DL Precoding configuration parameters and indications"},
1067 {4, "Modulation compr. params"},
1068 {5, "Modulation compression additional scaling parameters"},
1069 {6, "Non-contiguous PRB allocation"},
1070 {7, "Multiple-eAxC designation"},
1071 {8, "Regularization factor"},
1072 {9, "Dynamic Spectrum Sharing parameters"},
1073 {10, "Multiple ports grouping"},
1074 {11, "Flexible BF weights"},
1075 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1076 {13, "PRB Allocation with Frequency Hopping"},
1077 {14, "Nulling-layer Info. for ueId-based beamforming"},
1078 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1079 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1080 {17, "Section description for indication of user port group"},
1081 {18, "Section description for Uplink Transmission Management"},
1082 {19, "Compact beamforming information for multiple port"},
1083 {20, "Puncturing extension"},
1084 {21, "Variable PRB group size for channel information"},
1085 {22, "ACK/NACK request"},
1086 {23, "Multiple symbol modulation compression parameters"},
1087 {24, "PUSCH DMRS configuration"},
1088 {25, "Symbol reordering for DMRS-BF"},
1089 {26, "Frequency offset feedback"},
1090 {27, "O-DU controlled dimensionality reduction"},
1091 {28, "O-DU controlled frequency resolution for SINR reporting"},
1092 {29, "Cyclic delay adjustment"},
1093 {30, "PUSCH repetition indication"},
1094 {31, "MCS Information"},
1095 {32, "Rank and TPMI measurement request"},
1096 {0, NULL((void*)0)}
1097};
1098static 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) }
;
1099
1100
1101/**************************************************************************************/
1102/* Keep track for each Section Extension, which section types are allowed to carry it */
1103typedef struct {
1104 bool_Bool ST0;
1105 bool_Bool ST1;
1106 bool_Bool ST3;
1107 bool_Bool ST5;
1108 bool_Bool ST6;
1109 bool_Bool ST10;
1110 bool_Bool ST11;
1111} AllowedCTs_t;
1112
1113
1114static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE32] = {
1115 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1116 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1117 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1118 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1119 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1120 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1121 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1122 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1123 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1124 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1125 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1126 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1127 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1128 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1129 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1130 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1131 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1132 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1133 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1134 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1135 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1136 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1137 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1138 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1139 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1140 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1141 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1142 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1143 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1144 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1145 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1146 { false0, true1, true1, true1, false0, false0, false0}, // SE 31 (1,3,5)
1147 { false0, false0, false0, true1, false0, false0, false0}, // SE 32 (5)
1148};
1149
1150static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1151{
1152 if (se==0 || se>HIGHEST_EXTTYPE32) {
1153 /* Don't know about new SE, so don't complain.. */
1154 return true1;
1155 }
1156
1157 switch (st) {
1158 case 0:
1159 return ext_cts[se-1].ST0;
1160 case 1:
1161 return ext_cts[se-1].ST1;
1162 case 3:
1163 return ext_cts[se-1].ST3;
1164 case 5:
1165 return ext_cts[se-1].ST5;
1166 case 6:
1167 return ext_cts[se-1].ST6;
1168 case 10:
1169 return ext_cts[se-1].ST10;
1170 case 11:
1171 return ext_cts[se-1].ST11;
1172 default:
1173 /* New/unknown section type that includes 'ef'.. assume ok */
1174 return true1;
1175 }
1176}
1177
1178/************************************************************************************/
1179
1180/* Table 7.7.1.2-2 */
1181static const value_string bfw_comp_headers_iq_width[] = {
1182 {0, "I and Q are 16 bits wide"},
1183 {1, "I and Q are 1 bit wide"},
1184 {2, "I and Q are 2 bits wide"},
1185 {3, "I and Q are 3 bits wide"},
1186 {4, "I and Q are 4 bits wide"},
1187 {5, "I and Q are 5 bits wide"},
1188 {6, "I and Q are 6 bits wide"},
1189 {7, "I and Q are 7 bits wide"},
1190 {8, "I and Q are 8 bits wide"},
1191 {9, "I and Q are 9 bits wide"},
1192 {10, "I and Q are 10 bits wide"},
1193 {11, "I and Q are 11 bits wide"},
1194 {12, "I and Q are 12 bits wide"},
1195 {13, "I and Q are 13 bits wide"},
1196 {14, "I and Q are 14 bits wide"},
1197 {15, "I and Q are 15 bits wide"},
1198 {0, NULL((void*)0)}
1199};
1200
1201/* Table 7.7.1.2-3 */
1202static const value_string bfw_comp_headers_comp_meth[] = {
1203 {COMP_NONE0, "no compression"},
1204 {COMP_BLOCK_FP1, "block floating point"},
1205 {COMP_BLOCK_SCALE2, "block scaling"},
1206 {COMP_U_LAW3, "u-law"},
1207 {4, "beamspace compression type I"},
1208 {5, "beamspace compression type II"},
1209 {0, NULL((void*)0)}
1210};
1211
1212/* 7.7.6.2 rbgSize (resource block group size) */
1213static const value_string rbg_size_vals[] = {
1214 {0, "reserved"},
1215 {1, "1"},
1216 {2, "2"},
1217 {3, "3"},
1218 {4, "4"},
1219 {5, "6"},
1220 {6, "8"},
1221 {7, "16"},
1222 {0, NULL((void*)0)}
1223};
1224
1225/* 7.7.6.5 */
1226static const value_string priority_vals[] = {
1227 {0, "0"},
1228 {1, "+1"},
1229 {2, "-2 (reserved, should not be used)"},
1230 {3, "-1"},
1231 {0, NULL((void*)0)}
1232};
1233
1234/* 7.7.10.2 beamGroupType */
1235static const value_string beam_group_type_vals[] = {
1236 {0x0, "common beam"},
1237 {0x1, "beam matrix indication"},
1238 {0x2, "beam vector listing"},
1239 {0x3, "beamId/ueId listing with associated port-list index"},
1240 {0, NULL((void*)0)}
1241};
1242
1243/* 7.7.9.2 technology (interface name) */
1244static const value_string interface_name_vals[] = {
1245 {0x0, "LTE"},
1246 {0x1, "NR"},
1247 {0, NULL((void*)0)}
1248};
1249
1250/* 7.7.18.4 toT (type of transmission) */
1251static const value_string type_of_transmission_vals[] = {
1252 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1253 {0x1, "uniformly distributed over the transmission window"},
1254 {0x2, "Reserved"},
1255 {0x3, "Reserved"},
1256 {0, NULL((void*)0)}
1257};
1258
1259/* 7.7.2.2 (width of bfa parameters) */
1260static const value_string bfa_bw_vals[] = {
1261 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1262 {1, "2-bit bitwidth"},
1263 {2, "3-bit bitwidth"},
1264 {3, "4-bit bitwidth"},
1265 {4, "5-bit bitwidth"},
1266 {5, "6-bit bitwidth"},
1267 {6, "7-bit bitwidth"},
1268 {7, "8-bit bitwidth"},
1269 {0, NULL((void*)0)}
1270};
1271
1272/* 7.7.2.7 & 7.7.2.8 */
1273static const value_string sidelobe_suppression_vals[] = {
1274 {0, "10 dB"},
1275 {1, "15 dB"},
1276 {2, "20 dB"},
1277 {3, "25 dB"},
1278 {4, "30 dB"},
1279 {5, "35 dB"},
1280 {6, "40 dB"},
1281 {7, ">= 45 dB"},
1282 {0, NULL((void*)0)}
1283};
1284
1285static const value_string lbtTrafficClass_vals[] = {
1286 {1, "Priority 1"},
1287 {2, "Priority 2"},
1288 {3, "Priority 3"},
1289 {4, "Priority 4"},
1290 {0, NULL((void*)0)}
1291};
1292
1293/* 7.5.3.22 */
1294static const value_string lbtPdschRes_vals[] = {
1295 {0, "not sensing – indicates that the O-RU is transmitting data"},
1296 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1297 {2, "success – indicates that the channel was successfully acquired"},
1298 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1299 {0, NULL((void*)0)}
1300};
1301
1302/* Table 7.5.2.15-3 */
1303static const value_string ci_comp_opt_vals[] = {
1304 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1305 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1306 {0, NULL((void*)0)}
1307};
1308
1309/* 7.5.2.17 */
1310static const range_string cmd_scope_vals[] = {
1311 {0, 0, "ARRAY-COMMAND"},
1312 {1, 1, "CARRIER-COMMAND"},
1313 {2, 2, "O-RU-COMMAND"},
1314 {3, 15, "reserved"},
1315 {0, 0, NULL((void*)0)}
1316};
1317
1318/* N.B., table in 7.5.3.38 is truncated.. */
1319static const range_string st4_cmd_type_vals[] = {
1320 {0, 0, "reserved for future command types"},
1321 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1322 {2, 2, "TDD_CONFIG_PATTERN"},
1323 {3, 3, "TRX_CONTROL"},
1324 {4, 4, "ASM"},
1325 {5, 5, "TRX_CONTROL_BIDIR"},
1326 {6, 255, "reserved for future command types"},
1327 {0, 0, NULL((void*)0)}
1328};
1329
1330/* Table 7.5.3.51-1 */
1331static const value_string log2maskbits_vals[] = {
1332 {0, "reserved"},
1333 {1, "min antMask size is 16 bits.."},
1334 {2, "min antMask size is 16 bits.."},
1335 {3, "min antMask size is 16 bits.."},
1336 {4, "16 bits"},
1337 {5, "32 bits"},
1338 {6, "64 bits"},
1339 {7, "128 bits"},
1340 {8, "256 bits"},
1341 {9, "512 bits"},
1342 {10, "1024 bits"},
1343 {11, "2048 bits"},
1344 {12, "4096 bits"},
1345 {13, "8192 bits"},
1346 {14, "16384 bits"},
1347 {15, "reserved"},
1348 {0, NULL((void*)0)}
1349};
1350
1351/* Table 16.1-1 Sleep modes */
1352static const value_string sleep_mode_trx_vals[] = {
1353 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1354 { 1, "TRXC-mode1-wake-up-duration (L)"},
1355 { 2, "TRXC-mode2-wake-up-duration (M)"},
1356 { 3, "TRXC-mode3-wake-up-duration (N)"},
1357 { 0, NULL((void*)0)}
1358};
1359
1360static const value_string sleep_mode_asm_vals[] = {
1361 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1362 { 1, "ASM-mode1-wake-up-duration (L)"},
1363 { 2, "ASM-mode2-wake-up-duration (M)"},
1364 { 3, "ASM-mode3-wake-up-duration (N)"},
1365 { 0, NULL((void*)0)}
1366};
1367
1368/* 7.7.21.3.1 */
1369static const value_string prg_size_st5_vals[] = {
1370 { 0, "reserved"},
1371 { 1, "Precoding resource block group size as WIDEBAND"},
1372 { 2, "Precoding resource block group size 2"},
1373 { 3, "Precoding resource block group size 4"},
1374 { 0, NULL((void*)0)}
1375};
1376
1377/* 7.7.21.3.2 */
1378static const value_string prg_size_st6_vals[] = {
1379 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1380 { 1, "Precoding resource block group size as WIDEBAND"},
1381 { 2, "Precoding resource block group size 2"},
1382 { 3, "Precoding resource block group size 4"},
1383 { 0, NULL((void*)0)}
1384};
1385
1386/* 7.7.24.4 */
1387static const value_string alpn_per_sym_vals[] = {
1388 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1389 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1390 { 0, NULL((void*)0)}
1391};
1392
1393/* 7.7.24.5 */
1394static const value_string ant_dmrs_snr_vals[] = {
1395 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1396 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1397 { 0, NULL((void*)0)}
1398};
1399
1400/* 7.7.24.14 */
1401static const value_string dtype_vals[] = {
1402 { 0, "assume DMRS configuration type 1"},
1403 { 1, "assume DMRS configuration type 2"},
1404 { 0, NULL((void*)0)}
1405};
1406
1407/* 7.7.24.17 */
1408static const value_string papr_type_vals[] = {
1409 { 0, "sequence generator type 1 for short sequence lengths"},
1410 { 1, "sequence generator type 1 for long sequence lengths"},
1411 { 2, "sequence generator type 2 for short sequence lengths"},
1412 { 3, "sequence generator type 2 for long sequence lengths"},
1413 { 0, NULL((void*)0)}
1414};
1415
1416/* 7.7.24.18 */
1417static const value_string hopping_mode_vals[] = {
1418 { 0, "neither group, nor sequence hopping is enabled"},
1419 { 1, "group hopping is enabled and sequence hopping is disabled"},
1420 { 2, "sequence hopping is enabled and group hopping is disabled"},
1421 { 3, "reserved"},
1422 { 0, NULL((void*)0)}
1423};
1424
1425/* Table 7.7.31.2-1 */
1426static const value_string mcs_table_vals[] = {
1427 { 0, "MCS index table 1 for PDSCH and PUSCH without transform precoding" },
1428 { 1, "MCS index table 2 for PDSCH and PUSCH without transform precoding" },
1429 { 2, "MCS index table 3 for PDSCH and PUSCH without transform precoding" },
1430 { 3, "MCS index table 4 for PDSCH" },
1431 { 4, "MCS index table for PUSCH with transform precoding and 64QAM" },
1432 { 5, "MCS index table 2 for PUSCH with transform precoding and 64QAM" },
1433 { 0, NULL((void*)0)}
1434};
1435
1436/* 7.7.32.9 */
1437static const value_string full_pwr_mode_vals[] = {
1438 { 0, "not configured"},
1439 { 1, "full power mode 0"},
1440 { 2, "full power mode 1"},
1441 { 3, "full power mode 2"},
1442 { 0, NULL((void*)0)}
1443};
1444
1445
1446static const true_false_string tfs_sfStatus =
1447{
1448 "subframe was transmitted",
1449 "subframe was dropped"
1450};
1451
1452static const true_false_string tfs_lbtBufErr =
1453{
1454 "buffer overflow – data received at O-RU is larger than the available buffer size",
1455 "reserved"
1456};
1457
1458static const true_false_string tfs_partial_full_sf = {
1459 "partial SF",
1460 "full SF"
1461};
1462
1463static const true_false_string disable_tdbfns_tfs = {
1464 "beam numbers excluded",
1465 "beam numbers included"
1466};
1467
1468static const true_false_string continuity_indication_tfs = {
1469 "continuity between current and next bundle",
1470 "discontinuity between current and next bundle"
1471};
1472
1473static const true_false_string prb_mode_tfs = {
1474 "PRB-BLOCK mode",
1475 "PRB-MASK mode"
1476};
1477
1478static const true_false_string symbol_direction_tfs = {
1479 "DL symbol",
1480 "UL symbol"
1481};
1482
1483static const true_false_string symbol_guard_tfs = {
1484 "guard symbol",
1485 "non-guard symbol"
1486};
1487
1488static const true_false_string beam_numbers_included_tfs = {
1489 "time-domain beam numbers excluded in this command",
1490 "time-domain beam numbers included in this command"
1491};
1492
1493static const true_false_string measurement_flag_tfs = {
1494 "at least one additional measurement report or command after the current one",
1495 "no additional measurement report or command"
1496};
1497
1498static const true_false_string repetition_se6_tfs = {
1499 "repeated highest priority data section in the C-Plane message",
1500 "no repetition"
1501};
1502
1503static const true_false_string repetition_se19_tfs = {
1504 "per port information not present in the extension",
1505 "per port info present in the extension"
1506};
1507
1508static const true_false_string tfs_report_no_report_pos_meas =
1509{
1510 "Report MEAS_UE_POS for UE",
1511 "Do not report UE_POS for UE"
1512};
1513
1514
1515/* Forward declaration */
1516static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1517 unsigned comp_meth,
1518 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1519
1520
1521static const true_false_string ready_tfs = {
1522 "message is a \"ready\" message",
1523 "message is a ACK message"
1524};
1525
1526static const true_false_string multi_sd_scope_tfs = {
1527 "Puncturing pattern applies to current and following sections",
1528 "Puncturing pattern applies to current section"
1529};
1530
1531static const true_false_string tfs_ueid_reset = {
1532 "cannot assume same UE as in preceding slot",
1533 "can assume same UE as in preceding slot"
1534};
1535
1536
1537/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1538typedef struct {
1539 /* Ext 6 config */
1540 bool_Bool ext6_set;
1541 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1542
1543 uint8_t ext6_num_bits_set;
1544 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1545 /* TODO: store an f value for each bit position? */
1546
1547 /* Ext 12 config */
1548 bool_Bool ext12_set;
1549 unsigned ext12_num_pairs;
1550#define MAX_BFW_EXT12_PAIRS128 128
1551 struct {
1552 uint8_t off_start_prb;
1553 uint8_t num_prb;
1554 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1555
1556 /* Ext 13 config */
1557 bool_Bool ext13_set;
1558 unsigned ext13_num_start_prbs;
1559#define MAX_BFW_EXT13_ALLOCATIONS128 128
1560 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1561 /* TODO: store nextSymbolId here too? */
1562
1563 /* Ext 21 config */
1564 bool_Bool ext21_set;
1565 uint8_t ext21_ci_prb_group_size;
1566
1567 /* Results/settings (after calling ext11_work_out_bundles()) */
1568 uint32_t num_bundles;
1569#define MAX_BFW_BUNDLES512 512
1570 struct {
1571 uint32_t start; /* first prb of bundle */
1572 uint32_t end; /* last prb of bundle*/
1573 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1574 } bundles[MAX_BFW_BUNDLES512];
1575} ext11_settings_t;
1576
1577
1578/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1579/* Won't be called with numBundPrb=0 */
1580static void ext11_work_out_bundles(unsigned startPrbc,
1581 unsigned numPrbc,
1582 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1583 ext11_settings_t *settings)
1584{
1585 /* Allocation configured by ext 6 */
1586 if (settings->ext6_set) {
1587 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1588
1589 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1590 rbg size. i.e. each bundle gets the correct number of PRBs until
1591 all rbg entries are consumed... */
1592
1593 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1594
1595 if (bundles_per_entry == 0) {
1596 bundles_per_entry = 1;
1597 }
1598
1599 /* Ext6 behaviour may also be affected by ext 21 */
1600 if (settings->ext21_set) {
1601 /* N.B., have already checked that numPrbc is not 0 */
1602
1603 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1604 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1605
1606 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1607 }
1608
1609 unsigned bundles_set = 0;
1610 bool_Bool reached_orphan = false0;
1611 /* For each bit set in ext6 rbg mask.. */
1612 for (unsigned n=0;
1613 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1614 n++) {
1615
1616 /* Watch out for array bound */
1617 if (n >= 28) {
1618 break;
1619 }
1620
1621 /* For each bundle... */
1622
1623 /* TODO: Work out where first PRB is */
1624 /* May not be the start of an rbg block... */
1625 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1626
1627 /* For each bundle within identified rbgSize block */
1628 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1629
1630 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1631
1632 /* Start already beyond end, so doesn't count. */
1633 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1634 settings->num_bundles = bundles_set;
1635 return;
1636 }
1637
1638 /* Bundle consists of numBundPrb bundles */
1639 /* TODO: may involve PRBs from >1 rbg blocks.. */
1640 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1641 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1642 /* Extends beyond end, so counts but is an orphan bundle */
1643 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1644 settings->bundles[bundles_set].is_orphan = true1;
1645 reached_orphan = true1;
1646 }
1647
1648 /* Get out if have reached array bound */
1649 if (++bundles_set == MAX_BFW_BUNDLES512) {
1650 return;
1651 }
1652 }
1653 }
1654 settings->num_bundles = bundles_set;
1655 }
1656
1657 /* Allocation configured by ext 12 */
1658 else if (settings->ext12_set) {
1659 /* First, allocate normally from startPrbc, numPrbc */
1660 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1661
1662 /* Don't overflow settings->bundles[] ! */
1663 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1664
1665 for (uint32_t n=0; n < settings->num_bundles; n++) {
1666 settings->bundles[n].start = startPrbc + n*numBundPrb;
1667 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1668 /* Does it go beyond the end? */
1669 if (settings->bundles[n].end > startPrbc+numPrbc) {
1670 settings->bundles[n].end = startPrbc+numPrbc;
1671 settings->bundles[n].is_orphan = true1;
1672 }
1673 }
1674 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1675 return;
1676 }
1677
1678 unsigned prb_offset = startPrbc + numPrbc;
1679
1680 /* Loop over pairs, adding bundles for each */
1681 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1682 prb_offset += settings->ext12_pairs[p].off_start_prb;
1683 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1684
1685 for (uint32_t n=0; n < pair_bundles; n++) {
1686 unsigned idx = settings->num_bundles;
1687
1688 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1689 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1690 /* Does it go beyond the end? */
1691 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1692 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1693 settings->bundles[idx].is_orphan = true1;
1694 }
1695 /* Range check / return */
1696 settings->num_bundles++;
1697 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1698 return;
1699 }
1700 }
1701
1702 prb_offset += settings->ext12_pairs[p].num_prb;
1703 }
1704 }
1705
1706 /* Allocation configured by ext 13 */
1707 else if (settings->ext13_set) {
1708 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1709 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1710
1711 /* Don't overflow settings->bundles[] ! */
1712 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1713
1714 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1715 unsigned alloc_start = alloc * alloc_size;
1716 for (uint32_t n=0; n < alloc_size; n++) {
1717 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1718 /* ERROR */
1719 return;
1720 }
1721 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1722 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1723 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1724 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1725 settings->bundles[alloc_start+n].is_orphan = true1;
1726 }
1727 }
1728 }
1729 }
1730
1731 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1732 else {
1733 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1734
1735 /* Don't overflow settings->bundles[] */
1736 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1737
1738 /* For each bundle.. */
1739 for (uint32_t n=0; n < settings->num_bundles; n++) {
1740 /* Allocate start and end */
1741 settings->bundles[n].start = startPrbc + n*numBundPrb;
1742 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1743 /* If would go beyond end of PRBs, limit and identify as orphan */
1744 if (settings->bundles[n].end > startPrbc+numPrbc) {
1745 settings->bundles[n].end = startPrbc+numPrbc;
1746 settings->bundles[n].is_orphan = true1;
1747 }
1748 }
1749 }
1750}
1751
1752
1753/* Modulation Compression configuration */
1754typedef struct {
1755 /* Application of each entry is filtered by RE.
1756 * TODO: should also be filtered by PRB + symbol... */
1757 uint16_t mod_compr_re_mask;
1758
1759 /* Settings to apply */
1760 bool_Bool mod_compr_csf;
1761 float mod_compr_scaler;
1762} mod_compr_config_t;
1763
1764/* Multiple configs with a section */
1765typedef struct {
1766 uint16_t section_id;
1767 uint32_t num_configs;
1768
1769 #define MAX_MOD_COMPR_CONFIGS12 12
1770 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1771} section_mod_compr_config_t;
1772
1773/* Flow has separate configs for each section */
1774typedef struct {
1775 uint16_t num_sections;
1776
1777 /* Separate config for each section */
1778 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1779} mod_compr_params_t;
1780
1781
1782typedef struct {
1783 uint32_t frame_number;
1784 nstime_t frame_time;
1785
1786 /* Timing to match */
1787 uint8_t frame;
1788 uint8_t subframe;
1789 uint8_t slot;
1790 uint8_t startSymbol;
1791
1792 bool_Bool in_use;
1793 uint16_t startPrb;
1794 uint16_t numPrb;
1795 uint16_t numSymbols;
1796 uint16_t beamIds[273];
1797} section_details_t;
1798
1799typedef struct {
1800 uint16_t sectionId;
1801 /* For the same sectionId, can have 2 currently active entries.. */
1802 section_details_t details[2];
1803} expected_section_data_t;
1804
1805
1806/*******************************************************/
1807/* Overall state of a flow (eAxC/plane) */
1808typedef struct {
1809 /* State for sequence analysis [each direction] */
1810 bool_Bool last_frame_seen[2];
1811 uint32_t last_frame[2];
1812 uint8_t next_expected_sequence_number[2];
1813
1814 /* expected frames. sectionId -> expected_section_data_t* */
1815 wmem_tree_t *expected_sections[2]; /* [direction] */
1816
1817 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1818 Note that this assumes that the same ackNackId will not be reused within a state,
1819 which may well not be valid */
1820 wmem_tree_t *ack_nack_requests;
1821
1822 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1823 Note that this appears in the common section header parts of ST1, ST3, ST5,
1824 so can still be over-written per sectionId in the U-Plane */
1825 unsigned ul_ud_comp_hdr_frame;
1826 bool_Bool ul_ud_comp_hdr_set;
1827 unsigned ul_ud_comp_hdr_bit_width;
1828 int ul_ud_comp_hdr_compression;
1829
1830 bool_Bool udcomphdrDownlink_heuristic_result_set;
1831 bool_Bool udcomphdrDownlink_heuristic_result;
1832 bool_Bool udcomphdrUplink_heuristic_result_set;
1833 bool_Bool udcomphdrUplink_heuristic_result;
1834
1835 /* Modulation compression params */
1836 mod_compr_params_t mod_comp_params;
1837} flow_state_t;
1838
1839static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1840 unsigned sectionId)
1841{
1842 if (flow == NULL((void*)0)) {
1843 return NULL((void*)0);
1844 }
1845
1846 /* Look for this section among existing entries */
1847 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1848 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1849 return &flow->mod_comp_params.sections[s];
1850 }
1851 }
1852
1853 /* Not found, so try to add a new one */
1854 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1855 /* Can't allocate one! */
1856 return NULL((void*)0);
1857 }
1858 else {
1859 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1860 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1861 }
1862}
1863
1864static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1865 unsigned sectionId)
1866{
1867 if (flow == NULL((void*)0)) {
1868 return NULL((void*)0);
1869 }
1870
1871 /* Look for this section among existing entries */
1872 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1873 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1874 return &flow->mod_comp_params.sections[s];
1875 }
1876 }
1877
1878 /* Not found */
1879 return NULL((void*)0);
1880}
1881
1882
1883
1884typedef struct {
1885 uint32_t request_frame_number;
1886 nstime_t request_frame_time;
1887 enum {
1888 SE22,
1889 ST4Cmd1,
1890 ST4Cmd2,
1891 ST4Cmd3,
1892 ST4Cmd4
1893 } requestType;
1894
1895 uint32_t response_frame_number;
1896 nstime_t response_frame_time;
1897} ack_nack_request_t;
1898
1899static const value_string acknack_type_vals[] = {
1900 { SE22, "SE 22" },
1901 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1902 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1903 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1904 { ST4Cmd4, "ST4 (ASM)" },
1905 { 0, NULL((void*)0)}
1906};
1907
1908#define ORAN_C_PLANE0 0
1909#define ORAN_U_PLANE1 1
1910
1911/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1912static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1913{
1914 uint16_t eth_bits = 0;
1915 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1916 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1917 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1918 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1919 if (!opposite_dir) {
1920 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1921 }
1922 else {
1923 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1924 }
1925 }
1926 return eaxc_id | (plane << 16) | (eth_bits << 17);
1927}
1928
1929
1930/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1931static wmem_tree_t *flow_states_table;
1932
1933typedef struct {
1934 uint32_t frame_number;
1935 uint16_t sectionId;
1936 uint32_t gap_in_usecs;
1937 uint8_t symbol;
1938 uint16_t startPrbu;
1939 uint16_t numPrbu;
1940} corresponding_uplane_frame;
1941
1942/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1943static wmem_tree_t *flow_results_table;
1944
1945typedef struct {
1946 /* Sequence analysis */
1947 bool_Bool unexpected_seq_number;
1948 uint8_t expected_sequence_number;
1949 uint32_t previous_frame;
1950
1951 /* sectionId -> expected_section_data_t* */
1952 /* Frame only covers one direction */
1953 wmem_tree_t *expected_sections;
1954
1955 /* List of u-plane frames (corresponding_uplane_frame*) corresponding to a c-plane frame */
1956 wmem_list_t *u_plane_frames;
1957} flow_result_t;
1958
1959
1960/* Uplink timing */
1961/* For a given symbol, track first to last UL frame to find out first-last time */
1962/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1963/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1964static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1965{
1966 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1967}
1968
1969typedef struct {
1970 uint32_t first_frame;
1971 nstime_t first_frame_time;
1972 uint32_t frames_seen_in_symbol;
1973 uint32_t last_frame_in_symbol;
1974} ul_timing_for_slot;
1975
1976/* Set during first pass. timing_key -> ul_timing_for_slot* */
1977static wmem_tree_t *ul_symbol_timing;
1978
1979
1980/* Tracking lifetimes of DL beamIds */
1981typedef struct {
1982 uint32_t frame_defined;
1983 uint32_t symbol_when_defined;
1984} bfw_definition;
1985
1986/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1987static wmem_tree_t *dl_beam_ids_defined;
1988/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1989static wmem_tree_t *dl_beam_ids_results;
1990
1991
1992static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1993 ack_nack_request_t *response);
1994
1995
1996
1997
1998static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1999 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
2000
2001 /* Write the given formatted text to:
2002 - the info column (if pinfo != NULL)
2003 - 1 or 2 other labels (optional)
2004 */
2005static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2006 packet_info *pinfo, const char *format, ...)
2007{
2008#define MAX_INFO_BUFFER256 256
2009 char info_buffer[MAX_INFO_BUFFER256];
2010 va_list ap;
2011
2012 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
2013 return;
2014 }
2015
2016 va_start(ap, format)__builtin_va_start(ap, format);
2017 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
2018 va_end(ap)__builtin_va_end(ap);
2019
2020 /* Add to indicated places */
2021 if (pinfo != NULL((void*)0)) {
2022 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2023 }
2024 if (ti1 != NULL((void*)0)) {
2025 proto_item_append_text(ti1, "%s", info_buffer);
2026 }
2027 if (ti2 != NULL((void*)0)) {
2028 proto_item_append_text(ti2, "%s", info_buffer);
2029 }
2030}
2031
2032/* Add section labels (type + PRB range) for C-Plane, U-Plane */
2033static void
2034write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
2035 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
2036{
2037 switch (num_prbx) {
2038 case 0:
2039 /* None -> all */
2040 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
2041 break;
2042 case 1:
2043 /* Single PRB */
2044 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
2045 break;
2046 default:
2047 /* Range */
2048 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
2049 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
2050 }
2051}
2052
2053static void
2054write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
2055 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
2056 uint32_t num_trx)
2057{
2058 switch (num_prbx) {
2059 case 0:
2060 /* TODO: ?? */
2061 break;
2062 case 1:
2063 /* Single PRB */
2064 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2065 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
2066 section_id, ueId, start_prbx, num_trx);
2067 break;
2068 default:
2069 /* Range */
2070 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2071 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
2072 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
2073 }
2074}
2075
2076/* Add a reserved field, and warn if value isn't 0 */
2077/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
2078static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
2079{
2080 uint32_t reserved;
2081 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
2082 if (reserved != 0) {
2083 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
2084 "reserved field saw value of 0x%x", reserved);
2085 }
2086}
2087
2088/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2089static void
2090addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2091{
2092 /* Subtree */
2093 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2094 tvb, *offset, 2, ENC_NA0x00000000);
2095 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2096
2097 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2098 int id_offset = *offset;
2099
2100 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2101 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2102 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2103 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2104 *eAxC = 0;
2105 *offset += 2;
2106 return;
2107 }
2108
2109 unsigned bit_offset = *offset * 8;
2110
2111 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2112 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2113
2114 /* DU Port ID */
2115 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);
2116 bit_offset += pref_du_port_id_bits;
2117 /* BandSector ID */
2118 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2119 bit_offset += pref_bandsector_id_bits;
2120 /* CC ID */
2121 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2122 bit_offset += pref_cc_id_bits;
2123 /* RU Port ID */
2124 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);
2125 *offset += 2;
2126
2127 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2128 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2129 char id[16];
2130 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2131 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2132 proto_item_set_generated(pi);
2133
2134 tap_info->eaxc = *eAxC;
2135 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2136 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2137 tap_info->eaxc_cc_id = (uint16_t)ccId;
2138 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2139}
2140
2141/* Uniquely identify the U-plane stream that may need to be reassembled */
2142static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2143 uint8_t frameid, uint8_t subframeid,
2144 uint8_t slotid, uint8_t symbolid)
2145{
2146 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2147 and hope for no collisions */
2148 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2149 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2150}
2151
2152/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2153/* Return out info that may be used for sequence number analysis and reassembly */
2154static int
2155addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2156 uint32_t *subseqid, uint32_t *e)
2157{
2158 /* Subtree */
2159 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2160 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2161
2162 /* Sequence ID (8 bits) */
2163 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2164 offset += 1;
2165
2166 /* Show link back to previous sequence ID, if set */
2167 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2168 if (result) {
2169 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2170 proto_item_set_generated(prev_ti);
2171 }
2172
2173 /* E bit */
2174 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2175 /* Subsequence ID (7 bits) */
2176 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2177 offset += 1;
2178
2179 /* radio-transport fragmentation not allowed for C-Plane messages */
2180 if (plane == ORAN_C_PLANE0) {
2181 if (*e !=1 || *subseqid != 0) {
2182 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2183 }
2184 }
2185
2186 /* Summary */
2187 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2188 return offset;
2189}
2190
2191static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2192{
2193 uint64_t temp_val;
2194
2195 static int * const symbol_mask_flags[] = {
2196 &hf_oran_symbol_mask_s13,
2197 &hf_oran_symbol_mask_s12,
2198 &hf_oran_symbol_mask_s11,
2199 &hf_oran_symbol_mask_s10,
2200 &hf_oran_symbol_mask_s9,
2201 &hf_oran_symbol_mask_s8,
2202 &hf_oran_symbol_mask_s7,
2203 &hf_oran_symbol_mask_s6,
2204 &hf_oran_symbol_mask_s5,
2205 &hf_oran_symbol_mask_s4,
2206 &hf_oran_symbol_mask_s3,
2207 &hf_oran_symbol_mask_s2,
2208 &hf_oran_symbol_mask_s1,
2209 &hf_oran_symbol_mask_s0,
2210 NULL((void*)0)
2211 };
2212
2213 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2214 hf_oran_symbol_mask,
2215 ett_oran_symbol_mask, symbol_mask_flags,
2216 ENC_BIG_ENDIAN0x00000000, &temp_val);
2217 /* Set out parameters */
2218 if (symbol_mask) {
2219 *symbol_mask = (uint32_t)temp_val;
2220 }
2221 if (ti) {
2222 *ti = temp_ti;
2223 }
2224 return offset+2;
2225}
2226
2227/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2228static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2229 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2230{
2231 /* Subtree */
2232 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2233 tvb, offset, 1, "",
2234 "bfwCompHdr");
2235 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2236
2237 /* Width and method */
2238 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2239 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2240 /* Special case: 0 -> 16 */
2241 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2242 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2243 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2244 offset++;
2245
2246 /* Summary */
2247 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2248 *iq_width,
2249 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2250
2251 return offset;
2252}
2253
2254/* Return offset */
2255/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2256 each BFW is actually for.. */
2257static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2258{
2259 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2260 /* K is the number of elements in uncompressed beamforming weight vector.
2261 * Calculated from parameters describing tx-array or tx-array */
2262 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2263
2264 static uint16_t trx_enabled[1024];
2265
2266 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2267 static int * const mask_bits[] = {
2268 &hf_oran_active_beamspace_coefficient_n1,
2269 &hf_oran_active_beamspace_coefficient_n2,
2270 &hf_oran_active_beamspace_coefficient_n3,
2271 &hf_oran_active_beamspace_coefficient_n4,
2272 &hf_oran_active_beamspace_coefficient_n5,
2273 &hf_oran_active_beamspace_coefficient_n6,
2274 &hf_oran_active_beamspace_coefficient_n7,
2275 &hf_oran_active_beamspace_coefficient_n8,
2276 NULL((void*)0)
2277 };
2278
2279 *num_trx_entries = 0;
2280 uint64_t val;
2281 for (unsigned n=0; n < k_octets; n++) {
2282 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2283 hf_oran_activeBeamspaceCoefficientMask,
2284 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2285 ENC_BIG_ENDIAN0x00000000, &val);
2286 offset++;
2287 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2288 for (unsigned b=0; b < 8; b++) {
2289 if ((1 << b) & (unsigned)val) {
2290 if (((n*8)+b) < pref_num_bf_antennas) {
2291 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2292 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2293 }
2294 }
2295 }
2296 }
2297 }
2298 /* Set pointer to static array */
2299 *trx_entries = trx_enabled;
2300
2301 /* Show how many bits set */
2302 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2303 offset-k_octets, k_octets, *num_trx_entries);
2304 proto_item_set_generated(ti);
2305
2306 return offset;
2307}
2308
2309static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2310{
2311 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2312 tap_info->beams[tap_info->num_beams++] = beam_id;
2313 }
2314}
2315
2316
2317/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2318 * Depends upon passed-in bfwCompMeth (field may be empty) */
2319static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2320 proto_item *meth_ti, uint32_t *bfw_comp_method,
2321 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2322{
2323 if (*bfw_comp_method == COMP_NONE0) {
2324 /* Absent! */
2325 *num_trx_entries = 0;
2326 *supported = true1;
2327 return offset;
2328 }
2329
2330 /* Subtree */
2331 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2332 tvb, offset, 1, "",
2333 "bfwCompParam");
2334 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2335
2336 proto_item_append_text(bfwcompparam_ti,
2337 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2338
2339 *num_trx_entries = 0;
2340 *supported = false0;
2341 switch (*bfw_comp_method) {
2342 case COMP_BLOCK_FP1: /* block floating point */
2343 /* 4 reserved bits + exponent */
2344 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2345 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2346 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2347 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2348 *supported = true1;
2349 offset++;
2350 break;
2351 case COMP_BLOCK_SCALE2: /* block scaling */
2352 /* Separate into integer and fractional bits? */
2353 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2354 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2355 offset++;
2356 break;
2357 case COMP_U_LAW3: /* u-law */
2358 /* compBitWidth, compShift */
2359 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2360 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2361 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2362 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2363 offset++;
2364 break;
2365 case 4: /* beamspace I (BLOCK SCALING) */
2366 /* activeBeamspaceCoefficientMask */
2367 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2368 *bfw_comp_method = COMP_BLOCK_SCALE2;
2369 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2370 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2371 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2372 offset++;
2373 break;
2374 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2375 /* activeBeamspaceCoefficientMask */
2376 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2377 /* reserved (4 bits) + exponent (4 bits) */
2378 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2379 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2380 offset += 1;
2381 *bfw_comp_method = COMP_BLOCK_FP1;
2382 *supported = true1;
2383 break;
2384
2385 default:
2386 /* Not handled */
2387 break;
2388 }
2389
2390 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2391
2392 /* Can't go on if compression scheme not supported */
2393 if (!(*supported) && meth_ti) {
2394 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2395 "BFW Compression method %u (%s) not decompressed by dissector",
2396 *bfw_comp_method,
2397 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2398 }
2399 return offset;
2400}
2401
2402
2403/* Special case for uncompressed value with given iq_width */
2404static float uncompressed_to_float(uint32_t bits, uint32_t iq_width)
2405{
2406 if (iq_width == 0 || iq_width > 16) {
2407 /* Not valid */
2408 return 0.0;
2409 }
2410
2411 uint16_t mask = (1U << (iq_width-1)) - 1;
2412 int16_t i16 = (bits < mask) ? (bits & mask) : (bits - (1<<iq_width));
2413
2414 if (show_unscaled_values) {
2415 return (float)i16;
2416 }
2417 return ((float)i16) / (mask);
2418}
2419
2420/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2421static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2422 uint32_t exponent,
2423 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2424 section_mod_compr_config_t *m_c_p, uint8_t re)
2425{
2426 switch (comp_method) {
2427 case COMP_NONE0: /* no compression */
2428 return uncompressed_to_float(bits, iq_width);
2429
2430 case COMP_BLOCK_FP1: /* block floating point */
2431 case BFP_AND_SELECTIVE_RE5:
2432 {
2433 /* A.1.3 Block Floating Point Decompression Algorithm */
2434 int32_t cPRB = bits;
2435 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2436
2437 /* Check last bit, in case we need to flip to -ve */
2438 if (cPRB >= (1<<(iq_width-1))) {
2439 cPRB -= (1<<iq_width);
2440 }
2441
2442 /* Unscale (8.1.3.1) */
2443 cPRB *= scaler;
2444 if (show_unscaled_values) {
2445 return (float)cPRB;
2446 }
2447
2448 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2449 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 */
2450
2451 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2452 return ret;
2453 }
2454
2455 case COMP_BLOCK_SCALE2:
2456 case COMP_U_LAW3:
2457 /* Not supported! But will be reported as expert info outside of this function! */
2458 return 0.0;
2459
2460 case COMP_MODULATION4:
2461 case MOD_COMPR_AND_SELECTIVE_RE6:
2462 {
2463 /* Described in A.5 (with pseudo code) */
2464 /* N.B., Applies to downlink data only - is not used for BFW */
2465
2466 /* Defaults if not overridden. TODO: what should these be? */
2467 bool_Bool csf = false0;
2468 float mcScaler = (float)(1 << 11);
2469
2470 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2471 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2472 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2473 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2474 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2475 /* Return first (should be only) found */
2476 csf = m_c_p->configs[c].mod_compr_csf;
2477 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2478 break;
2479 }
2480 }
2481 }
2482
2483 int32_t cPRB = bits;
2484
2485 /* 2) Map iqSample to iqSampleFx */
2486 /* Check last bit, in case we need to flip to -ve */
2487 if (cPRB >= (1<<(iq_width-1))) {
2488 cPRB -= (1<<iq_width);
2489 }
2490 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2491
2492
2493 /* 3) or 4) (b) - add unshifted value if csf set */
2494 float csf_to_add = 0.0;
2495 if (csf) {
2496 /* Unshift the constellation point */
2497 csf_to_add = (float)1.0 / (1 << (iq_width));
2498 }
2499 iqSampleFx += csf_to_add;
2500
2501 /* 3) or 4) (c) - unscaling */
2502 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2503 return iqSampleScaled;
2504 }
2505
2506 default:
2507 /* Not supported! But will be reported as expert info outside of this function! */
2508 return 0.0;
2509 }
2510}
2511
2512/* Out-of-range value used for special case */
2513#define ORPHAN_BUNDLE_NUMBER999 999
2514
2515/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2516static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2517 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2518 section_mod_compr_config_t *mod_compr_params,
2519 uint32_t num_weights_per_bundle,
2520 uint8_t iq_width,
2521 unsigned bundle_number,
2522 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2523 uint32_t symbol_count,
2524 section_details_t *section_details,
2525 oran_tap_info *tap_info)
2526{
2527 /* Set bundle name */
2528 char bundle_name[32];
2529 if (!is_orphan) {
2530 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2531 }
2532 else {
2533 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2534 }
2535
2536 /* Create Bundle root */
2537 proto_item *bundle_ti;
2538 if (first_prb != last_prb) {
2539 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2540 tvb, offset, 0, "",
2541 "%s: (PRBs %3u-%3u)",
2542 bundle_name,
2543 first_prb, last_prb);
2544 }
2545 else {
2546 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2547 tvb, offset, 0, "",
2548 "%s: (PRB %3u)",
2549 bundle_name,
2550 first_prb);
2551 }
2552 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2553
2554 /* Generated bundle id */
2555 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2556 bundle_number);
2557 proto_item_set_generated(bundleid_ti);
2558 proto_item_set_hidden(bundleid_ti);
2559
2560 /* bfwCompParam */
2561 bool_Bool compression_method_supported = false0;
2562 unsigned exponent = 0;
2563 unsigned num_trx_entries = 0;
2564 uint16_t *trx_entries;
2565 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2566 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2567 &num_trx_entries, &trx_entries);
2568
2569 /* Create Bundle subtree */
2570 int bit_offset = offset*8;
2571 int bfw_offset;
2572
2573 /* contInd */
2574 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2575 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2576 /* beamId */
2577 uint32_t beam_id;
2578 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2579 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2580 bit_offset += 16;
2581 add_beam_id_to_tap(tap_info, beam_id);
2582
2583 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2584 if (section_details) {
2585 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2586 if (prb < 273) {
2587 section_details->beamIds[prb] = beam_id;
2588 }
2589 }
2590 }
2591 }
2592
2593 /* On first pass, record that beamId was defined here */
2594 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2595 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2596 definition->frame_defined = pinfo->num;
2597 definition->symbol_when_defined = symbol_count;
2598 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2599 }
2600
2601
2602 /* Number of weights per bundle (from preference) */
2603 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2604 num_weights_per_bundle);
2605 proto_item_set_generated(wpb_ti);
2606
2607 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2608 if (num_trx_entries != 0) {
2609 num_weights_per_bundle = num_trx_entries;
2610 }
2611
2612 bool_Bool non_zero_weights_seen = false0;
2613 int bit_offset_before_weights = bit_offset;
2614 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2615
2616 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2617
2618 /* Create subtree */
2619 bfw_offset = bit_offset / 8;
2620 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2621 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2622 tvb, bfw_offset, bfw_extent,
2623 "", "TRX %3u: (", trx_index);
2624 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2625
2626 /* I */
2627 /* Get bits, and convert to float. */
2628 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2629 if (bits) {
2630 non_zero_weights_seen = true1;
2631 }
2632 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2633 exponent, mod_compr_params, 0 /* RE */);
2634 /* Add to tree. */
2635 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);
2636 bit_offset += iq_width;
2637 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2638
2639 /* Q */
2640 /* Get bits, and convert to float. */
2641 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2642 if (bits) {
2643 non_zero_weights_seen = true1;
2644 }
2645
2646 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2647 exponent, mod_compr_params, 0 /* RE */);
2648 /* Add to tree. */
2649 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);
2650 bit_offset += iq_width;
2651 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2652 }
2653
2654 if (!non_zero_weights_seen) {
2655 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2656 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2657 }
2658
2659 /* Set extent of bundle */
2660 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2661
2662 return (bit_offset+7)/8;
2663}
2664
2665/* Return new bit offset. in/out will always be byte-aligned.. */
2666static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2667 unsigned comp_meth, uint8_t *exponent)
2668{
2669 if (comp_meth == COMP_NONE0) {
2670 /* Nothing in frame so don't even create subtree */
2671 return bit_offset;
2672 }
2673
2674 /* Subtree */
2675 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2676 tvb, bit_offset/8, 1, "",
2677 "ciCompParam");
2678 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2679 uint32_t ci_exponent;
2680
2681 /* Contents differ by compression method */
2682 switch (comp_meth) {
2683 case COMP_BLOCK_FP1:
2684 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2685 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2686 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2687 *exponent = ci_exponent;
2688 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2689 bit_offset += 8; /* one byte */
2690 break;
2691 case COMP_BLOCK_SCALE2:
2692 /* Separate into integer (1) and fractional (7) bits? */
2693 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2694 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2695 bit_offset += 8;
2696 break;
2697 case COMP_U_LAW3:
2698 /* compBitWidth, compShift (4 bits each) */
2699 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2700 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2701 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2702 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2703 bit_offset += 8;
2704 break;
2705
2706 default:
2707 /* reserved, ? bytes of zeros.. */
2708 break;
2709 }
2710
2711 return bit_offset;
2712}
2713
2714/* frameStructure (7.5.2.13) */
2715static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2716 uint32_t subframeId, uint32_t slotId)
2717{
2718 uint32_t scs;
2719 /* FFT Size (4 bits) */
2720 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2721 /* Subcarrier spacing (SCS) */
2722 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2723
2724 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2725 uint32_t slots_per_subframe = 1;
2726 if (scs <= 4) {
2727 slots_per_subframe = 1 << scs;
2728 }
2729 if (scs <= 4 || scs >= 12) {
2730 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2731 (slots_per_subframe*subframeId) + slotId);
2732 proto_item_set_generated(ti);
2733 }
2734 return offset + 1;
2735}
2736
2737static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2738 unsigned iq_width, bool_Bool *p_csf)
2739{
2740 proto_item *csf_ti;
2741 uint64_t csf;
2742 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2743 if (csf) {
2744 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2745 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2746 if (iq_width >=1 && iq_width <= 5) {
2747 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2748 }
2749 }
2750
2751 /* Set out parameter */
2752 if (p_csf != NULL((void*)0)) {
2753 *p_csf = (csf!=0);
2754 }
2755 return bit_offset+1;
2756}
2757
2758
2759/* Section 7.
2760 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2761static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2762 flow_state_t* state,
2763 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2764 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2765 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2766 unsigned num_sinr_per_prb)
2767{
2768 unsigned offset = 0;
2769 proto_tree *c_section_tree = NULL((void*)0);
2770 proto_item *sectionHeading = NULL((void*)0);
2771
2772 /* Section subtree */
2773 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2774 tvb, offset, 0, "", "Section");
2775 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2776
2777 uint32_t sectionId = 0;
2778
2779 uint32_t startPrbc=0, startPrbu=0;
2780 uint32_t numPrbc=0, numPrbu=0;
2781 uint32_t ueId = 0;
2782 proto_item *ueId_ti = NULL((void*)0);
2783 uint32_t section_beamId = 0;
2784 proto_item *section_beamId_ti = NULL((void*)0);
2785 bool_Bool section_beamId_ignored = false0;
2786
2787 proto_item *numsymbol_ti = NULL((void*)0);
2788 bool_Bool numsymbol_ignored = false0;
2789
2790 proto_item *numprbc_ti = NULL((void*)0);
2791
2792 /* Config affecting ext11 bundles (initially unset) */
2793 ext11_settings_t ext11_settings;
2794 memset(&ext11_settings, 0, sizeof(ext11_settings));
2795
2796 /* Section Type 10 needs to keep track of PRB range that should be reported
2797 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2798 /* All PRBs start as false */
2799#define MAX_PRBS273 273
2800 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2801 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2802
2803 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2804#define MAX_UEIDS16 16
2805 uint32_t ueids[MAX_UEIDS16];
2806 uint32_t number_of_ueids = 0;
2807
2808
2809 bool_Bool extension_flag = false0;
2810
2811 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2812 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2813 (sectionType != SEC_C_SLOT_CONTROL)) {
2814
2815 /* sectionID */
2816 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2817 if (sectionId == 4095) {
2818 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2819 }
2820 offset++;
2821
2822 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2823 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2824 }
2825
2826 /* rb */
2827 uint32_t rb;
2828 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2829 /* symInc (1 bit) */
2830 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2831 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2832 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2833 unsigned int sym_inc;
2834 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2835 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2836 /* "0 shall be used" */
2837 proto_item_append_text(sym_inc_ti, " (should be 0)");
2838 }
2839 }
2840 else {
2841 /* reserved (1 bit) */
2842 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2843 }
2844
2845 /* startPrbx and numPrbx */
2846 if (sectionType == SEC_C_SINR_REPORTING) {
2847 /* startPrbu (10 bits) */
2848 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2849 offset += 2;
2850
2851 /* numPrbu */
2852 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2853 if (numPrbu == 0) {
2854 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2855 numPrbu = pref_data_plane_section_total_rbs;
2856 }
2857 offset += 1;
2858 }
2859 else {
2860 /* startPrbc (10 bits) */
2861 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2862 offset += 2;
2863
2864 /* numPrbc */
2865 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2866 if (numPrbc == 0) {
2867 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2868 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2869 numPrbc = MAX_PRBS273;
2870 }
2871 offset += 1;
2872 }
2873
2874 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2875 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2876 if (n < MAX_PRBS273) {
2877 prbs_for_st10_type5[n] = true1;
2878 }
2879 }
2880
2881 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2882 static int * const remask_flags[] = {
2883 &hf_oran_reMask_re1,
2884 &hf_oran_reMask_re2,
2885 &hf_oran_reMask_re3,
2886 &hf_oran_reMask_re4,
2887 &hf_oran_reMask_re5,
2888 &hf_oran_reMask_re6,
2889 &hf_oran_reMask_re7,
2890 &hf_oran_reMask_re8,
2891 &hf_oran_reMask_re9,
2892 &hf_oran_reMask_re10,
2893 &hf_oran_reMask_re11,
2894 &hf_oran_reMask_re12,
2895 NULL((void*)0)
2896 };
2897
2898 /* reMask */
2899 uint64_t remask;
2900 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2901 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2902 offset++;
2903 /* numSymbol */
2904 uint32_t numSymbol;
2905 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2906 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2907 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2908 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2909 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2910 }
2911 if ((startSymbolId + numSymbol) > 14) {
2912 /* Warn if startSymbol + numSymbol would be > 14 */
2913 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2914 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2915 startSymbolId, numSymbol);
2916 }
2917 offset++;
2918
2919 /* [ef] (extension flag) */
2920 switch (sectionType) {
2921 case SEC_C_UNUSED_RB: /* Section Type 0 */
2922 case SEC_C_NORMAL: /* Section Type 1 */
2923 case SEC_C_PRACH: /* Section Type 3 */
2924 case SEC_C_UE_SCHED: /* Section Type 5 */
2925 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2926 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2927 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2928 break;
2929 default:
2930 /* Other section types don't support extensions */
2931 break;
2932 }
2933
2934 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2935 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2936
2937 if (numPrbc == 0) {
2938 /* Special case for all PRBs */
2939 numPrbc = pref_data_plane_section_total_rbs;
2940 startPrbc = 0; /* may already be 0... */
2941 }
2942 }
2943 else {
2944 /* Section Type 9 */
2945 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2946 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2947 }
2948
2949 /* Section type specific fields (after 'numSymbol') */
2950 switch (sectionType) {
2951 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2952 /* reserved (15 bits) */
2953 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2954 offset += 2;
2955 break;
2956
2957 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2958 /* beamId */
2959 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2960 offset += 2;
2961
2962 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2963 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2964 break;
2965
2966 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2967 {
2968 /* beamId */
2969 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2970 offset += 2;
2971
2972 /* freqOffset */
2973 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2974 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);
2975 freqOffset |= 0xff000000; /* Must sign-extend */
2976 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2977 offset += 3;
2978
2979 /* reserved (8 bits) */
2980 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2981 offset += 1;
2982
2983 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2984 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2985 break;
2986 }
2987
2988 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2989 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2990 /* ueId */
2991 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2992 offset += 2;
2993 if (ueId == 0x7fff) {
2994 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2995 }
2996 else {
2997 ueids[number_of_ueids++] = ueId;
2998 }
2999
3000 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
3001 break;
3002
3003 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
3004 {
3005 /* Hidden filter for bf (DMFS-BF) */
3006 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3007 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3008
3009 unsigned bit_offset = offset*8;
3010
3011 /* sinr iqWidth */
3012 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
3013 proto_item_append_text(iq_width_item, " (from preferences)");
3014 proto_item_set_generated(iq_width_item);
3015
3016 /* sinr compMethod */
3017 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
3018 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
3019 proto_item_set_generated(sinr_comp_meth_item);
3020
3021 /* Add SINR entries for each PRB */
3022 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
3023 /* Create a subtree for each PRB */
3024 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
3025 tvb, offset, 0, "", "PRB %3u (", prb);
3026 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
3027
3028 /* Each prb starts byte-aligned */
3029 bit_offset = ((bit_offset+7)/8) * 8;
3030
3031 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
3032
3033 /* sinrCompParam (udCompParam format, may be empty) */
3034 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
3035 uint16_t sReSMask;
3036 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
3037 pref_iqCompressionSINR, &exponent, &sReSMask,
3038 true1) * 8; /* last param is for_sinr */
3039
3040 /* sinrValues for this PRB. */
3041 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
3042 for (unsigned n=0; n < num_sinr_per_prb; n++) {
3043 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
3044
3045 /* Using SINR compression settings from preferences */
3046 float value = decompress_value(sinr_bits,
3047 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
3048 exponent,
3049 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
3050 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
3051 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
3052 bit_offset/8, sample_len_in_bytes, value);
3053 proto_item_append_text(prb_ti, " %8f", value);
3054
3055 /* Show here which subcarriers share which values (they all divide 12..) */
3056 if (num_sinr_per_prb == 12) {
3057 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
3058 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
3059 }
3060 else {
3061 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
3062 startPrbu+((prb-startPrbu)*(rb+1)),
3063 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
3064 }
3065 bit_offset += pref_sample_bit_width_sinr;
3066 }
3067
3068 /* 1-byte alignment per PRB (7.2.11) */
3069 offset = (bit_offset+7)/8;
3070 bit_offset = offset*8;
3071
3072 proto_item_append_text(prb_ti, ")");
3073 proto_item_set_end(prb_ti, tvb, offset);
3074 }
3075 break;
3076 }
3077 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
3078 /* Reserved (15 bits) */
3079 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
3080 offset += 2;
3081 break;
3082
3083 default:
3084 break;
3085 }
3086 }
3087 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
3088 /* ef */
3089 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3090 /* ueId */
3091 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
3092 offset += 2;
3093 /* regularizationFactor */
3094 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3095 offset += 2;
3096 /* reserved (4 bits) */
3097 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3098 /* rb ("Value=0 shall be set") */
3099 uint32_t rb;
3100 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3101 if (rb != 0) {
3102 proto_item_append_text(rb_ti, " (should be set to 0)");
3103 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3104 }
3105 /* symInc */
3106 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3107 /* startPrbc */
3108 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3109 offset += 2;
3110 /* numPrbc */
3111 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3112 offset += 1;
3113
3114 /* Hidden filter for bf */
3115 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3116 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3117
3118 /* ciIsample,ciQsample pairs */
3119 unsigned m;
3120 unsigned prb;
3121 uint32_t bit_offset = offset*8;
3122
3123 /* Antenna count from preference */
3124 unsigned num_trx = pref_num_bf_antennas;
3125
3126 write_channel_section_info(sectionHeading, pinfo,
3127 sectionId, ueId, startPrbc, numPrbc, num_trx);
3128
3129 bool_Bool first_prb = true1;
3130 uint8_t exponent = 0;
3131 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3132
3133 /* PRB subtree */
3134 unsigned prb_start_offset = bit_offset;
3135 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3136 tvb, bit_offset/8, 0,
3137 "", "PRB=%u", prb);
3138 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3139
3140 /* There may be a ciCompParam here.. */
3141 if (first_prb || ci_comp_opt==1) {
3142 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3143 }
3144 first_prb = false0;
3145
3146 /* Antennas */
3147 for (m=0; m < num_trx; m++) {
3148
3149 unsigned sample_offset = bit_offset / 8;
3150 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3151
3152 /* Create subtree for antenna */
3153 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3154 tvb, sample_offset, sample_extent,
3155 "", "TRX=%2u: ", m);
3156 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3157
3158 /* I */
3159 /* Get bits, and convert to float. */
3160 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3161 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3162
3163 /* Add to tree. */
3164 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);
3165 bit_offset += ci_iq_width;
3166 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3167
3168 /* Q */
3169 /* Get bits, and convert to float. */
3170 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3171 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3172
3173 /* Add to tree. */
3174 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);
3175 bit_offset += ci_iq_width;
3176 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3177 }
3178 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3179 }
3180
3181 /* Pad out by 1 or 4 bytes, according to preference */
3182 if (!st6_4byte_alignment) {
3183 offset = (bit_offset + 7) / 8;
3184 }
3185 else {
3186 int mode = bit_offset % 32;
3187 if (mode != 0) {
3188 offset = (bit_offset + (32-mode))/8;
3189 }
3190 else {
3191 offset = bit_offset/8;
3192 }
3193 }
3194 proto_item_set_end(c_section_tree, tvb, offset);
3195 }
3196
3197
3198 expected_section_data_t *data_section = NULL((void*)0);
3199 unsigned index_to_use = 0;
3200
3201 /* On first pass, allocate a section entry to use */
3202 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3203
3204 /* Look for existing entry for sectionId to overwrite first. */
3205 uint8_t direction = !tap_info->uplink;
3206 data_section = wmem_tree_lookup32(state->expected_sections[direction],
3207 sectionId);
3208 if (data_section == NULL((void*)0)) {
3209 /* None, so create */
3210 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)))
;
3211 wmem_tree_insert32(state->expected_sections[direction],
3212 sectionId,
3213 data_section);
3214 }
3215
3216 /* If 2nd entry not in use, use that one */
3217 if (!data_section->details[1].in_use) {
3218 index_to_use = 1;
3219 }
3220 else {
3221 /* Both in use, so replace the older of the 2 entries */
3222 if (data_section->details[1].frame_number < data_section->details[0].frame_number) {
3223 index_to_use = 1;
3224 }
3225 }
3226
3227 if (data_section) {
3228 section_details_t *details = &data_section->details[index_to_use];
3229
3230 details->in_use = true1;
3231 details->frame = frameId;
3232 details->subframe = subframeId;
3233 details->slot = slotId;
3234 details->startSymbol = startSymbolId;
3235
3236 details->frame_number = pinfo->num;
3237 details->frame_time = pinfo->abs_ts;
3238 data_section->sectionId = sectionId;
3239 details->startPrb = startPrbc;
3240 details->numPrb = numPrbc;
3241 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3242 if (prb < 273) {
3243 details->beamIds[prb] = section_beamId;
3244 }
3245 }
3246 }
3247 }
3248
3249 bool_Bool seen_se10 = false0;
3250 uint32_t numPortc = 0;
3251 proto_item *bf_ti = NULL((void*)0);
3252
3253 /* Section extension commands */
3254 while (extension_flag) {
3255 int extension_start_offset = offset;
3256
3257 /* Prefetch extType so can use specific extension type ett */
3258 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3259 uint32_t exttype_ett_index = exttype;
3260 if (exttype == 0 || exttype > HIGHEST_EXTTYPE32) {
3261 /* Just use first one if out of range */
3262 exttype_ett_index = 1;
3263 }
3264
3265 /* Create subtree for each extension (with summary) */
3266 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3267 tvb, offset, 0, "", "Extension");
3268 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3269
3270 /* ef (i.e. another extension after this one?) */
3271 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3272
3273 /* extType */
3274 proto_item *exttype_ti;
3275 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3276 offset++;
3277 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3278
3279 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3280
3281 /* Don't tap if out of range. */
3282 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE32) {
3283 tap_info->extensions[exttype] = true1;
3284 }
3285
3286 /* Is this SE allowed for this section type? */
3287 if (!se_allowed_in_st(exttype, sectionType)) {
3288 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3289 "SE %u (%s) should not appear in ST %u (%s)!",
3290 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3291 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3292 }
3293
3294
3295 /* extLen (number of 32-bit words) */
3296 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3297 uint32_t extlen;
3298 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3299 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3300 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3301 offset += extlen_len;
3302 if (extlen == 0) {
3303 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3304 /* Break out to avoid infinitely looping! */
3305 break;
3306 }
3307
3308 bool_Bool ext_unhandled = false0;
3309
3310 switch (exttype) {
3311
3312 case 1: /* SE 1: Beamforming Weights */
3313 {
3314 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3315 proto_item *comp_meth_ti = NULL((void*)0);
3316
3317 /* Hidden filter for bf */
3318 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3319 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3320
3321 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3322 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3323 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3324
3325 /* bfwCompParam */
3326 uint32_t exponent = 0;
3327 bool_Bool compression_method_supported = false0;
3328 unsigned num_trx = 0;
3329 uint16_t *trx; /* ptr to array */
3330 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3331 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3332 &num_trx, &trx);
3333
3334 /* Can't show details of unsupported compression method */
3335 if (!compression_method_supported) {
3336 break;
3337 }
3338
3339 /* We know:
3340 - iq_width (above)
3341 - numBfWeights (taken from preference)
3342 - remaining bytes in extension
3343 We can therefore derive TRX (number of antennas).
3344 */
3345
3346 bool_Bool using_array = false0;
3347
3348 /* I & Q samples
3349 May know how many entries from activeBeamspaceCoefficientMask. */
3350 if (num_trx == 0) {
3351 /* Don't know how many there will be, so just fill available bytes... */
3352 unsigned weights_bytes = (extlen*4)-3;
3353 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3354 num_trx = num_weights_pairs;
3355 }
3356 else {
3357 using_array = true1;
3358 num_trx = pref_num_bf_antennas;
3359 }
3360
3361 int bit_offset = offset*8;
3362
3363 for (unsigned n=0; n < num_trx; n++) {
3364 /* Create antenna subtree */
3365 int bfw_offset = bit_offset / 8;
3366
3367 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3368
3369 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3370 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3371 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3372
3373 /* I value */
3374 /* Get bits, and convert to float. */
3375 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3376 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3377 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3378 /* Add to tree. */
3379 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3380 (bfwcomphdr_iq_width+7)/8, value);
3381 bit_offset += bfwcomphdr_iq_width;
3382 proto_item_append_text(bfw_ti, "I=%f ", value);
3383
3384 /* Leave a gap between I and Q values */
3385 proto_item_append_text(bfw_ti, " ");
3386
3387 /* Q value */
3388 /* Get bits, and convert to float. */
3389 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3390 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3391 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3392 /* Add to tree. */
3393 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3394 (bfwcomphdr_iq_width+7)/8, value);
3395 bit_offset += bfwcomphdr_iq_width;
3396 proto_item_append_text(bfw_ti, "Q=%f", value);
3397
3398 proto_item_append_text(bfw_ti, ")");
3399 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3400 }
3401 /* Need to round to next byte */
3402 offset = (bit_offset+7)/8;
3403
3404 break;
3405 }
3406
3407 case 2: /* SE 2: Beamforming attributes */
3408 {
3409 /* Hidden filter for bf */
3410 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3411 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3412
3413 /* bfaCompHdr (get widths of fields to follow) */
3414 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3415 /* subtree */
3416 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3417 tvb, offset, 2, "", "bfaCompHdr");
3418 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3419
3420 /* reserved (2 bits) */
3421 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3422 /* bfAzPtWidth (3 bits) */
3423 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3424 /* bfZePtWidth (3 bits) */
3425 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3426 offset += 1;
3427
3428 /* reserved (2 bits) */
3429 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3430 /* bfAz3ddWidth (3 bits) */
3431 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3432 /* bfZe3ddWidth (3 bits) */
3433 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3434 offset += 1;
3435
3436 unsigned bit_offset = offset*8;
3437
3438 /* bfAzPt */
3439 if (bfAzPtWidth > 0) {
3440 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3441 bit_offset += (bfAzPtWidth+1);
3442 }
3443 /* bfZePt */
3444 if (bfZePtWidth > 0) {
3445 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3446 bit_offset += (bfZePtWidth+1);
3447 }
3448 /* bfAz3dd */
3449 if (bfAz3ddWidth > 0) {
3450 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3451 bit_offset += (bfAz3ddWidth+1);
3452 }
3453 /* bfZe3dd */
3454 if (bfZe3ddWidth > 0) {
3455 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3456 bit_offset += (bfZe3ddWidth+1);
3457 }
3458
3459 /* Pad to next byte (unless last 2 fields already fit in this one) */
3460 if ((bit_offset % 8) > 2) {
3461 offset = (bit_offset+7) / 8;
3462 }
3463 else {
3464 offset = bit_offset / 8;
3465 }
3466
3467 /* bfAzSl (3 bits) */
3468 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3469 /* bfZeSl (3 bits) */
3470 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3471 offset += 1;
3472 break;
3473 }
3474
3475 case 3: /* SE 3: DL precoding parameters */
3476 {
3477 /* codebookindex (8 bits) */
3478 /* "This parameter is not used and shall be set to zero." */
3479 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3480 offset += 1;
3481 /* layerid */
3482 uint32_t layerid;
3483 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3484 /* numLayers */
3485 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3486 offset += 1;
3487
3488 /* Stop here for non-first data layer */
3489 if (layerid != 0 && layerid != 0xf) {
3490 break;
3491 }
3492
3493 /* First data layer case */
3494 /* txScheme */
3495 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3496 /* crsReMask */
3497 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3498 offset += 2;
3499
3500 /* crsShift (1 bit) */
3501 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3502 /* reserved (3 bits) */
3503 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3504 /* crsSymNum (4 bits) */
3505 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3506 offset += 1;
3507 /* reserved (8 bits) */
3508 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3509 offset += 1;
3510
3511 /* reserved (1 bit) */
3512 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3513 /* beamIdAP1 (15 bits) */
3514 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3515 offset += 2;
3516 /* reserved (1 bit) */
3517 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3518 /* beamIdAP2 (15 bits) */
3519 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3520 offset += 2;
3521 /* reserved (1 bit) */
3522 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3523 /* beamIdAP3 (15 bits) */
3524 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3525 offset += 2;
3526 break;
3527 }
3528
3529 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3530 {
3531 /* csf */
3532 bool_Bool csf;
3533 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3534
3535 /* modCompScaler */
3536 uint32_t modCompScaler;
3537 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3538 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3539 offset += 2;
3540
3541 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3542 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3543 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3544 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3545 proto_item_append_text(ti, " (%f)", value);
3546
3547 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3548
3549 /* Store these params in this flow's state */
3550 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3551 unsigned i = sect_config->num_configs;
3552 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3553 sect_config->configs[i].mod_compr_csf = csf;
3554 sect_config->configs[i].mod_compr_scaler = value;
3555 sect_config->num_configs++;
3556 }
3557 break;
3558 }
3559
3560 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3561 {
3562 /* Applies only to section types 1,3 and 5 */
3563 /* N.B. there may be multiple instances of this SE in the same frame */
3564
3565 /* There may be one or 2 entries, depending upon extlen */
3566 int sets = 1, reserved_bits = 0;
3567 switch (extlen) {
3568 case 2:
3569 sets = 1;
3570 reserved_bits = 20;
3571 break;
3572 case 3:
3573 sets = 2;
3574 reserved_bits = 24;
3575 break;
3576 case 4:
3577 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3578 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3579 sets = 3;
3580 reserved_bits = 28;
3581 }
3582 else {
3583 sets = 4;
3584 reserved_bits = 0;
3585 }
3586 break;
3587
3588 default:
3589 /* Malformed error!!! */
3590 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3591 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3592 extlen);
3593 break;
3594 }
3595
3596 unsigned bit_offset = offset*8;
3597 /* Dissect each set */
3598 for (int n=0; n < sets; n++) {
3599 /* Subtree for each set */
3600 unsigned set_start_offset = bit_offset/8;
3601 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3602 tvb, set_start_offset, 0, "");
3603 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3604
3605 uint64_t mcScaleReMask, mcScaleOffset;
3606 bool_Bool csf;
3607
3608 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3609 static int * const remask_flags[] = {
3610 &hf_oran_mc_scale_re_mask_re1,
3611 &hf_oran_mc_scale_re_mask_re2,
3612 &hf_oran_mc_scale_re_mask_re3,
3613 &hf_oran_mc_scale_re_mask_re4,
3614 &hf_oran_mc_scale_re_mask_re5,
3615 &hf_oran_mc_scale_re_mask_re6,
3616 &hf_oran_mc_scale_re_mask_re7,
3617 &hf_oran_mc_scale_re_mask_re8,
3618 &hf_oran_mc_scale_re_mask_re9,
3619 &hf_oran_mc_scale_re_mask_re10,
3620 &hf_oran_mc_scale_re_mask_re11,
3621 &hf_oran_mc_scale_re_mask_re12,
3622 NULL((void*)0)
3623 };
3624 /* Same as above, but offset by 4 bits */
3625 static int * const remask_flags_even[] = {
3626 &hf_oran_mc_scale_re_mask_re1_even,
3627 &hf_oran_mc_scale_re_mask_re2_even,
3628 &hf_oran_mc_scale_re_mask_re3_even,
3629 &hf_oran_mc_scale_re_mask_re4_even,
3630 &hf_oran_mc_scale_re_mask_re5_even,
3631 &hf_oran_mc_scale_re_mask_re6_even,
3632 &hf_oran_mc_scale_re_mask_re7_even,
3633 &hf_oran_mc_scale_re_mask_re8_even,
3634 &hf_oran_mc_scale_re_mask_re9_even,
3635 &hf_oran_mc_scale_re_mask_re10_even,
3636 &hf_oran_mc_scale_re_mask_re11_even,
3637 &hf_oran_mc_scale_re_mask_re12_even,
3638 NULL((void*)0)
3639 };
3640
3641 /* RE Mask (12 bits) */
3642 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3643 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3644 ett_oran_mc_scale_remask,
3645 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3646 bit_offset += 12;
3647
3648 /* csf (1 bit) */
3649 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3650 /* mcScaleOffset (15 bits) */
3651 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3652 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3653 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3654 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3655 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3656 bit_offset += 15;
3657
3658 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3659
3660 /* Record this config */
3661 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3662 unsigned i = sect_config->num_configs;
3663 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3664 sect_config->configs[i].mod_compr_csf = csf;
3665 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3666 sect_config->num_configs++;
3667 }
3668
3669 /* Summary */
3670 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3671 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3672 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3673 }
3674
3675 proto_item_append_text(extension_ti, " (%u sets)", sets);
3676
3677 /* Reserved (variable-length) */
3678 if (reserved_bits) {
3679 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3680 bit_offset += reserved_bits;
3681 }
3682
3683 offset = bit_offset/8;
3684 break;
3685 }
3686
3687 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3688 {
3689 /* numSymbol not used in this case */
3690 if (numsymbol_ti && !numsymbol_ignored) {
3691 proto_item_append_text(numsymbol_ti, " (ignored)");
3692 numsymbol_ignored = true1;
3693 }
3694
3695 /* Will update ext6 recorded info */
3696 ext11_settings.ext6_set = true1;
3697
3698 /* repetition */
3699 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3700 /* rbgSize (PRBs per bit set in rbgMask) */
3701 uint32_t rbgSize;
3702 proto_item *rbg_size_ti;
3703 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3704 if (rbgSize == 0) {
3705 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3706 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3707 }
3708 /* rbgMask (28 bits) */
3709 uint32_t rbgMask;
3710 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3711 if (rbgSize == 0) {
3712 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3713 }
3714
3715 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3716 offset += 4;
3717 /* priority */
3718 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3719 /* symbolMask */
3720 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3721
3722 /* Look up rbg_size enum -> value */
3723 switch (rbgSize) {
3724 case 0:
3725 /* N.B. reserved, but covered above with expert info (would remain 0) */
3726 break;
3727 case 1:
3728 ext11_settings.ext6_rbg_size = 1; break;
3729 case 2:
3730 ext11_settings.ext6_rbg_size = 2; break;
3731 case 3:
3732 ext11_settings.ext6_rbg_size = 3; break;
3733 case 4:
3734 ext11_settings.ext6_rbg_size = 4; break;
3735 case 5:
3736 ext11_settings.ext6_rbg_size = 6; break;
3737 case 6:
3738 ext11_settings.ext6_rbg_size = 8; break;
3739 case 7:
3740 ext11_settings.ext6_rbg_size = 16; break;
3741 /* N.B., encoded in 3 bits, so no other values are possible */
3742 }
3743
3744 /* Set to looked-up value */
3745 rbgSize = ext11_settings.ext6_rbg_size;
3746
3747 uint32_t lastRbgid = 0;
3748 if (rbgSize != 0) {
3749 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3750 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3751 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3752 if (lastRbgid > 27) {
3753 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3754 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3755 rbgSize, startPrbc, numPrbc);
3756 break;
3757 }
3758 }
3759
3760 /* Record (and count) which bits are set in rbgMask */
3761 bool_Bool first_seen = false0;
3762 unsigned first_seen_pos=0, last_seen_pos=0;
3763 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3764 if ((rbgMask >> n) & 0x01) {
3765 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3766 if (!first_seen) {
3767 first_seen = true1;
3768 first_seen_pos = n;
3769 }
3770 last_seen_pos = n;
3771 }
3772 }
3773
3774 /* Show how many bits were set in rbgMask */
3775 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3776 /* Also, that is the range of bits */
3777 if (first_seen) {
3778 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3779
3780 /* Complain if last set bit is beyond lastRbgid */
3781 if (last_seen_pos > lastRbgid) {
3782 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3783 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3784 rbgMask, last_seen_pos, lastRbgid);
3785 }
3786 }
3787
3788 /* Also update prbs_for_st10_type5[] */
3789 if (sectionType == 10 && rbgSize != 0) {
3790 /* Unset all entries */
3791 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3792
3793 /* Work out which PRB first bit corresponds to */
3794 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3795
3796 /* Add PRBs corresponding to each bit set */
3797 for (unsigned n=0; n < 28 ; n++) {
3798 if ((rbgMask >> n) & 0x01) {
3799 /* Lazy way to clip any values that lie outside of range for section */
3800 for (unsigned p=0; p < rbgSize; p++) {
3801 unsigned start = firstPrbStart + (n*rbgSize);
3802 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3803 prbs_for_st10_type5[start+p] = true1;
3804 }
3805 }
3806 }
3807 }
3808 }
3809
3810 break;
3811 }
3812
3813 case 7: /* SE 7: eAxC mask */
3814 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3815 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3816 offset += 2;
3817 break;
3818
3819 case 8: /* SE 8: Regularization factor */
3820 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3821 offset += 2;
3822 break;
3823
3824 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3825 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3826 offset += 1;
3827 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3828 offset += 1;
3829 break;
3830
3831 case 10: /* SE 10: Group configuration of multiple ports */
3832 {
3833 seen_se10 = true1;
3834
3835 /* beamGroupType */
3836 uint32_t beam_group_type = 0;
3837 proto_item *bgt_ti;
3838 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3839 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3840 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3841
3842 /* numPortc */
3843 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3844 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3845 offset++;
3846
3847 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3848 unsigned n;
3849
3850 switch (beam_group_type) {
3851 case 0x0: /* common beam */
3852 case 0x1: /* beam matrix indication */
3853 /* Reserved byte */
3854 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3855 offset++;
3856
3857 /* Explain how entries are allocated */
3858 if (beam_group_type == 0x0) {
3859 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3860 }
3861 else {
3862 /* 'numPortc' consecutive BeamIds from section header */
3863 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3864 }
3865
3866 if (sectionType == 5) {
3867 /* These types are not allowed */
3868 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3869 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3870 }
3871 break;
3872
3873 case 0x2: /* beam vector listing */
3874 {
3875 proto_item_append_text(extension_ti, " [ ");
3876
3877 /* Beam listing vector case */
3878 /* Work out how many port beam entries there is room for */
3879 /* Using numPortC as visible in issue 18116 */
3880 for (n=0; n < numPortc; n++) {
3881 /* 1 reserved bit */
3882 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3883
3884 /* port beam ID (or UEID) (15 bits) */
3885 uint32_t id;
3886 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3887 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3888 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3889 offset += 2;
3890
3891 if (id != 0x7fff) {
3892 if (number_of_ueids < MAX_UEIDS16) {
3893 ueids[number_of_ueids++] = id;
3894 }
3895 }
3896
3897 proto_item_append_text(extension_ti, "%u ", id);
3898 }
3899
3900 proto_item_append_text(extension_ti, "]");
3901 break;
3902 }
3903 case 0x3: /* beamId/ueId listing with associated port-list index */
3904 {
3905 proto_item_append_text(extension_ti, " [ ");
3906
3907 if (numPortc > 0) {
3908 /* first portListIndex is outside loop */
3909 uint32_t port_list_index;
3910 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3911 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3912 if (port_list_index == 0) {
3913 /* Value 0 is reserved */
3914 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3915 }
3916 offset += 1;
3917
3918 for (n=0; n < numPortc-1; n++) {
3919 /* 1 reserved bit */
3920 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3921
3922 /* port beam ID (or UEID) */
3923 uint32_t id;
3924 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3925 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3926 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3927 offset += 2;
3928
3929 if (id != 0x7fff) {
3930 if (number_of_ueids < MAX_UEIDS16) {
3931 ueids[number_of_ueids++] = id;
3932 }
3933 }
3934
3935 /* subsequent portListIndex */
3936 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3937 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3938 if (port_list_index == 0) {
3939 /* Value 0 is reserved */
3940 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3941 }
3942 offset += 1;
3943
3944 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3945 }
3946 }
3947
3948 proto_item_append_text(extension_ti, "]");
3949 break;
3950 }
3951
3952
3953 default:
3954 /* Warning for unsupported/reserved value */
3955 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3956 break;
3957 }
3958 break;
3959 }
3960
3961 case 11: /* SE 11: Flexible Weights Extension Type */
3962 {
3963 /* Hidden filter for bf */
3964 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3965 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3966
3967 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3968 if (section_beamId_ti && !section_beamId_ignored) {
3969 proto_item_append_text(section_beamId_ti, " (ignored)");
3970 section_beamId_ignored = true1;
3971 }
3972
3973 bool_Bool disableBFWs;
3974 uint32_t numBundPrb;
3975 bool_Bool rad;
3976
3977 /* disableBFWs */
3978 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3979 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3980 if (disableBFWs) {
3981 proto_item_append_text(extension_ti, " (disableBFWs)");
3982 }
3983
3984 /* RAD */
3985 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3986 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3987 /* bundleOffset (6 bits) */
3988 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3989 offset, 1, ENC_BIG_ENDIAN0x00000000);
3990 offset++;
3991
3992 /* numBundPrb (number of prbs in each bundle) */
3993 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3994 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3995 offset++;
3996 /* value zero is reserved.. */
3997 if (numBundPrb == 0) {
3998 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3999 }
4000
4001 uint32_t num_bundles;
4002 bool_Bool orphaned_prbs = false0;
4003
4004 /* N.B. glibly assuming that Mu=1 */
4005 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
4006
4007 if (!disableBFWs) {
4008 /********************************************/
4009 /* Table 7.7.1.1-1 */
4010 /********************************************/
4011
4012 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4013 proto_item *comp_meth_ti = NULL((void*)0);
4014
4015 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
4016 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4017 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4018
4019 /* Work out number of bundles, but take care not to divide by zero. */
4020 if (numBundPrb == 0) {
4021 break;
4022 }
4023
4024 /* Work out bundles! */
4025 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4026 num_bundles = ext11_settings.num_bundles;
4027
4028 /* Add (complete) bundles */
4029 for (unsigned b=0; b < num_bundles; b++) {
4030 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
4031 comp_meth_ti, bfwcomphdr_comp_meth,
4032 NULL((void*)0) /* no ModCompr */,
4033 (ext11_settings.ext21_set) ?
4034 numPrbc :
4035 pref_num_bf_antennas,
4036 bfwcomphdr_iq_width,
4037 b, /* bundle number */
4038 ext11_settings.bundles[b].start,
4039 ext11_settings.bundles[b].end,
4040 ext11_settings.bundles[b].is_orphan,
4041 symbol_count,
4042 (link_planes_together && data_section) ? &data_section->details[index_to_use] : NULL((void*)0),
4043 tap_info);
4044 if (!offset) {
4045 break;
4046 }
4047 }
4048 if (num_bundles > 0) {
4049 /* Set flag from last bundle entry */
4050 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
4051 }
4052 }
4053 else {
4054 /********************************************/
4055 /* Table 7.7.1.1-2 */
4056 /* No weights in this case */
4057 /********************************************/
4058
4059 /* Work out number of bundles, but take care not to divide by zero. */
4060 if (numBundPrb == 0) {
4061 break;
4062 }
4063
4064 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4065 num_bundles = ext11_settings.num_bundles;
4066
4067 for (unsigned n=0; n < num_bundles; n++) {
4068 /* contInd */
4069 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
4070 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4071 /* beamId */
4072 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
4073 uint32_t beam_id;
4074 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
4075 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
4076 if (!ext11_settings.bundles[n].is_orphan) {
4077 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
4078 ext11_settings.bundles[n].start,
4079 ext11_settings.bundles[n].end,
4080 n);
4081 }
4082 else {
4083 orphaned_prbs = true1;
4084 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
4085 ext11_settings.bundles[n].start,
4086 ext11_settings.bundles[n].end);
4087 }
4088 offset += 2;
4089
4090 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4091 if (data_section) {
4092 /* Set beamId only for range of PRBs */
4093 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4094 if (prb < 273) {
4095 data_section->details[index_to_use].beamIds[prb] = beam_id;
4096 }
4097 }
4098 }
4099 }
4100
4101 /* Look for where BFWs were sent for this beamId */
4102 bfw_definition *definition;
4103
4104 wmem_tree_key_t key[3];
4105 key[0].length = 1;
4106 key[0].key = &pinfo->num;
4107 key[1].length = 1;
4108 key[1].key = &beam_id;
4109 key[2].length = 0;
4110 key[2].key = NULL((void*)0);
4111
4112 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4113 /* Look up current result */
4114 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4115 if (definition != NULL((void*)0)) {
4116 /* Add to results table for this frame */
4117 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4118 }
4119 }
4120 else {
4121 /* Look up from result table */
4122 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4123 }
4124
4125 /* Show link back to frame where/when beamId was defined */
4126 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4127 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4128 proto_item_set_generated(defined_ti);
4129 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4130 symbol_count - definition->symbol_when_defined);
4131 proto_item_set_generated(since_ti);
4132 }
4133 else {
4134 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4135 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4136 }
4137 }
4138
4139 }
4140
4141 /* Add summary to extension root */
4142 if (orphaned_prbs) {
4143 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4144 }
4145 else {
4146 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4147 }
4148 }
4149
4150 break;
4151
4152 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4153 {
4154 /* numSymbol not used in this case */
4155 if (numsymbol_ti && !numsymbol_ignored) {
4156 proto_item_append_text(numsymbol_ti, " (ignored)");
4157 numsymbol_ignored = true1;
4158 }
4159
4160 ext11_settings.ext12_set = true1;
4161
4162 /* priority */
4163 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4164
4165 /* symbolMask */
4166 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4167
4168 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4169 should be populated with 0s. */
4170 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4171 uint8_t prb_index;
4172
4173 /* This is for ST10/ST11. First pair starts after frames signalled there */
4174 uint16_t st10_st11_offset = startPrbc + numPrbc;
4175
4176 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4177 {
4178 /* Create a subtree for each pair */
4179 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4180 tvb, offset, 2, "");
4181 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4182
4183 /* offStartPrb */
4184 uint32_t off_start_prb;
4185 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4186 offset++;
4187
4188 /* numPrb */
4189 uint32_t num_prb;
4190 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4191 offset++;
4192
4193 extlen_remaining_bytes -= 2;
4194
4195 /* Last pair may be 0,0 if not used. Check for this */
4196 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4197 proto_item_append_text(pair_ti, " (not used)");
4198 }
4199 /* Add summary to pair root item, and configure details in ext11_settings */
4200 else {
4201 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4202 prb_index, off_start_prb, num_prb);
4203 proto_item_append_text(extension_ti, "[%u : %u]",
4204 off_start_prb, num_prb);
4205 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4206 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4207 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4208 }
4209
4210 /* Also update PRBs to be covered for ST10 type 5 */
4211 /* Original range from section is added to.. */
4212 /* TODO: I don't think this is quite right.. */
4213 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4214 if (prb < MAX_PRBS273) {
4215 prbs_for_st10_type5[prb] = true1;
4216 }
4217 }
4218
4219 /* Any next pair will begin after this one */
4220 st10_st11_offset += (off_start_prb + num_prb);
4221 }
4222 }
4223 break;
4224 }
4225
4226 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4227 {
4228 /* Will update settings for ext11 */
4229 ext11_settings.ext13_set = true1;
4230
4231 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4232 uint8_t allocation_index;
4233
4234 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4235
4236 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4237 {
4238 /* Subtree for allocation */
4239 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4240 tvb, offset, 2, "");
4241 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4242
4243 /* Reserved (2 bits) */
4244 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4245
4246 /* nextSymbolId (4 bits) */
4247 uint32_t next_symbol_id;
4248 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4249
4250 /* nextStartPrbc (10 bits) */
4251 uint32_t next_start_prbc;
4252 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4253 offset += 2;
4254
4255 /* Add summary to allocation root item */
4256 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4257 allocation_index, next_symbol_id, next_start_prbc);
4258
4259 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4260 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4261 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4262 }
4263 else {
4264 /* Add entry for configuring ext11. don't store out of range */
4265 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4266 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4267 }
4268 }
4269 prev_next_symbol_id = next_symbol_id;
4270 prev_next_start_prbc = next_start_prbc;
4271
4272 extlen_remaining_bytes -= 2;
4273 }
4274 break;
4275 }
4276
4277 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4278 /* Hidden filter for bf (DMRS BF) */
4279 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4280 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4281
4282 if (!seen_se10) {
4283 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4284 offset += 1;
4285 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4286 offset += 1;
4287 }
4288 else {
4289 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4290 for (unsigned port=0; port < numPortc+1; port++) {
4291 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4292 offset += 1;
4293 }
4294 }
4295 break;
4296
4297 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4298 {
4299 /* frameStructure */
4300 offset = dissect_frame_structure(extension_tree, tvb, offset,
4301 subframeId, slotId);
4302 /* freqOffset */
4303 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4304 offset += 3;
4305 /* cpLength */
4306 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4307 if (sectionType != 0 && sectionType != 3) {
4308 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4309 }
4310 offset += 2;
4311 break;
4312 }
4313
4314 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4315 {
4316 /* Just filling available bytes with antMask entries.
4317 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4318 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4319 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4320 for (unsigned n=0; n < num_ant_masks; n++) {
4321 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4322 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4323 offset += 8;
4324 }
4325 break;
4326 }
4327
4328 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4329 {
4330 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4331 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4332 uint32_t ueid_index = 1;
4333
4334 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4335 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4336 /* numUeId (Number of UE Ids per user) */
4337 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4338 /* TODO: show ueids[ueid_index] here too? */
4339 proto_item_append_text(ti, " (user #%u)", ueid_index);
4340 }
4341 break;
4342 }
4343
4344 case 18: /* SE 18: Uplink transmission management */
4345 /* transmissionWindowOffset */
4346 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4347 offset += 2;
4348 /* reserved (2 bits) */
4349 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4350 /* transmissionWindowSize (14 bits) */
4351 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4352 offset += 2;
4353
4354 /* reserved (6 bits) */
4355 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4356 /* toT (2 bits) */
4357 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4358 offset += 1;
4359 break;
4360
4361 case 19: /* SE 19: Compact beamforming information for multiple port */
4362 {
4363 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4364 if (section_beamId_ti && !section_beamId_ignored) {
4365 proto_item_append_text(section_beamId_ti, " (ignored)");
4366 section_beamId_ignored = true1;
4367 }
4368
4369 /* numSymbol not used in this case */
4370 if (numsymbol_ti && !numsymbol_ignored) {
4371 proto_item_append_text(numsymbol_ti, " (ignored)");
4372 numsymbol_ignored = true1;
4373 }
4374
4375 /* disableBFWs */
4376 bool_Bool disableBFWs;
4377 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4378 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4379 if (disableBFWs) {
4380 proto_item_append_text(extension_ti, " (disableBFWs)");
4381 }
4382 /* repetition (1 bit) */
4383 uint64_t repetition;
4384 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4385 /* numPortc (6 bits) */
4386 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4387 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4388 offset++;
4389
4390 /* priority (2 bits) */
4391 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4392 /* symbolMask (14 bits) */
4393 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4394
4395 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4396 proto_item *comp_meth_ti = NULL((void*)0);
4397
4398 if (!repetition) {
4399
4400 if (!disableBFWs) {
4401 /* bfwCompHdr */
4402 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4403 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4404 }
4405
4406 /* Add entries for each port */
4407 for (unsigned port=0; port < numPortc; port++) {
4408
4409 /* Create subtree for port entry*/
4410 int port_start_offset = offset;
4411 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4412 tvb, offset, 0,
4413 "", "Port %u: ", port);
4414 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4415
4416 /* Reserved (4 bits) */
4417 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4418 /* portReMask (12 bits) */
4419 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4420 offset += 2;
4421
4422 /* Reserved (2 bits) */
4423 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4424 /* portSymbolMask (14 bits) */
4425 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4426 offset += 2;
4427
4428 /* Reserved (1 bit) */
4429 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4430 /* beamID (15 bits) */
4431 uint16_t beamId;
4432 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4433 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4434 offset += 2;
4435
4436 /* No weights present */
4437 if (!disableBFWs) {
4438 /*******************************************************************/
4439 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4440 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4441 /*******************************************************************/
4442
4443 /* bfwCompParam */
4444 bool_Bool compression_method_supported = false0;
4445 uint32_t exponent = 0;
4446 unsigned num_trx_entries = 0;
4447 uint16_t *trx;
4448 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4449 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4450 &num_trx_entries, &trx);
4451
4452 int bit_offset = offset*8;
4453 int bfw_offset;
4454
4455 /* Add weights for each TRX */
4456 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4457 for (unsigned b=0; b < trx_to_add; b++) {
4458
4459 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4460
4461 /* Create BFW subtree */
4462 bfw_offset = bit_offset / 8;
4463 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4464 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4465 tvb, bfw_offset, bfw_extent,
4466 "", "TRX %u: (", trx_index);
4467 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4468
4469 /* I */
4470 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4471 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4472 /* Add to tree. */
4473 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4474 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4475 bit_offset += bfwcomphdr_iq_width;
4476 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4477
4478 /* Q */
4479 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4480 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4481 /* Add to tree. */
4482 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4483 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4484 bit_offset += bfwcomphdr_iq_width;
4485 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4486 }
4487
4488 offset = (bit_offset+7)/8;
4489 }
4490 else {
4491 /* No weights... */
4492 }
4493
4494 /* Set length of this port entry */
4495 proto_item_set_len(port_ti, offset-port_start_offset);
4496 }
4497 }
4498 break;
4499 }
4500
4501 case 20: /* SE 20: Puncturing extension */
4502 {
4503 /* numPuncPatterns */
4504 uint32_t numPuncPatterns;
4505 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4506 offset += 1;
4507
4508 /* Add each puncturing pattern */
4509 for (uint32_t n=0; n < numPuncPatterns; n++) {
4510 unsigned pattern_start_offset = offset;
4511
4512 /* Subtree for this puncturing pattern */
4513 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4514 tvb, offset, 0,
4515 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4516 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4517
4518 /* SymbolMask (14 bits) */
4519 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4520 offset += 1;
4521
4522 uint32_t startPuncPrb, numPuncPrb;
4523
4524 /* startPuncPrb (10 bits) */
4525 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4526 offset += 2;
4527 /* numPuncPrb (8 bits) */
4528 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4529 offset += 1;
4530
4531 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4532
4533 /* Make a hole in range of PRBs to report */
4534 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4535 if (p < MAX_PRBS273) {
4536 prbs_for_st10_type5[p] = false0;
4537 }
4538 }
4539
4540 /* puncReMask (12 bits) */
4541 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4542 offset += 1;
4543 /* rb (1 bit) */
4544 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4545 /* reserved (1 bit) */
4546 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4547 /* multiSDScope (1 bit) */
4548 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4549 /* rbgIncl (1 bit) */
4550 bool_Bool rbgIncl;
4551 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4552 offset += 1;
4553
4554 if (rbgIncl) {
4555 /* reserved (1 bit) */
4556 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4557 /* rbgSize(3 bits) */
4558 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4559 /* rbgMask (28 bits) */
4560 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4561 offset += 4;
4562
4563 proto_item_append_text(rb_ti, " (ignored)");
4564 }
4565
4566 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4567 }
4568
4569 break;
4570 }
4571 case 21: /* SE 21: Variable PRB group size for channel information */
4572 {
4573 /* ciPrbGroupSize */
4574 uint32_t ci_prb_group_size;
4575 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);
4576 offset += 1;
4577
4578 switch (ci_prb_group_size) {
4579 case 0:
4580 case 1:
4581 case 255:
4582 /* Reserved value */
4583 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4584 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4585 ci_prb_group_size);
4586 break;
4587 default:
4588 /* This value affects how SE 11 is interpreted */
4589 ext11_settings.ext21_set = true1;
4590 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4591
4592 if (numPrbc == 0) {
4593 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4594 }
4595 break;
4596 }
4597
4598 /* reserved (6 bits) */
4599 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4600
4601 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4602 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4603 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4604 }
4605 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4606 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4607 }
4608 offset += 1;
4609 break;
4610 }
4611
4612 case 22: /* SE 22: ACK/NACK request */
4613 {
4614 uint32_t ack_nack_req_id;
4615 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4616 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4617 offset += 2;
4618
4619 if (state) {
4620 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4621 /* Add this request into conversation state on first pass */
4622 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)))
;
4623 request_details->request_frame_number = pinfo->num;
4624 request_details->request_frame_time = pinfo->abs_ts;
4625 request_details->requestType = SE22;
4626 /* Insert into flow's tree */
4627 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4628 }
4629 else {
4630 /* Try to link forward to ST8 response */
4631 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4632 ack_nack_req_id);
4633 if (response) {
4634 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4635 }
4636 }
4637 }
4638 break;
4639 }
4640
4641 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4642 {
4643 /* Green common header */
4644
4645 /* numSymPrbPattern (4 bits) */
4646 uint32_t num_sym_prb_pattern;
4647 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4648 /* reserved (3 bits) */
4649 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4650 /* prbMode (1 bit) */
4651 bool_Bool prb_mode;
4652 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4653 offset += 1;
4654
4655 /* reserved (8 bits) */
4656 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4657 offset += 1;
4658
4659 /* Dissect each SymPrbPattern */
4660 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4661
4662 /* Subtree */
4663 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4664 tvb, offset, 1, "",
4665 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4666 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4667
4668
4669 /* Orange part */
4670
4671 /* Reserved (2 bits) */
4672 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4673 /* symMask (14 bits) */
4674 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4675 offset += 2;
4676 /* numMcScaleOffset (4 bits) */
4677 uint32_t numMcScaleOffset;
4678 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4679
4680 if (!prb_mode) { /* PRB-MASK */
4681 /* prbPattern (4 bits) */
4682 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4683 offset += 1;
4684 /* reserved (8 bits) */
4685 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4686 offset += 1;
4687 /* reserved (4 bits) */
4688 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4689 }
4690 else { /* PRB-BLOCK */
4691 /* prbBlkOffset (8 bits) */
4692 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_offset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4693 offset += 1;
4694 /* prbBlkSize (8 bits) */
4695 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_size, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4696 offset += 1;
4697 }
4698
4699 for (unsigned c=0; c < numMcScaleOffset; c++) {
4700 if (c > 0) {
4701 /* reserved (4 bits) */
4702 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4703 }
4704
4705 static int * const remask_flags_even[] = {
4706 &hf_oran_mc_scale_re_mask_re1_even,
4707 &hf_oran_mc_scale_re_mask_re2_even,
4708 &hf_oran_mc_scale_re_mask_re3_even,
4709 &hf_oran_mc_scale_re_mask_re4_even,
4710 &hf_oran_mc_scale_re_mask_re5_even,
4711 &hf_oran_mc_scale_re_mask_re6_even,
4712 &hf_oran_mc_scale_re_mask_re7_even,
4713 &hf_oran_mc_scale_re_mask_re8_even,
4714 &hf_oran_mc_scale_re_mask_re9_even,
4715 &hf_oran_mc_scale_re_mask_re10_even,
4716 &hf_oran_mc_scale_re_mask_re11_even,
4717 &hf_oran_mc_scale_re_mask_re12_even,
4718 NULL((void*)0)
4719 };
4720
4721 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4722 uint64_t mcScaleReMask, mcScaleOffset;
4723 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4724 hf_oran_mc_scale_re_mask_even,
4725 ett_oran_mc_scale_remask,
4726 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4727 offset += 2;
4728
4729 /* csf (1 bit) */
4730 bool_Bool csf;
4731 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4732 /* mcScaleOffset (15 bits) */
4733 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);
4734 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4735 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4736 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4737 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4738
4739 offset += 2;
4740
4741 /* Record this config. */
4742 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4743 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4744
4745 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4746 unsigned i = sect_config->num_configs;
4747 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4748 sect_config->configs[i].mod_compr_csf = csf;
4749 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4750 sect_config->num_configs++;
4751 }
4752 }
4753
4754 proto_item_set_end(pattern_ti, tvb, offset);
4755 }
4756 break;
4757 }
4758
4759 case 24: /* SE 24: PUSCH DMRS configuration */
4760 {
4761 /* Hidden filter for bf (DMRS BF) */
4762 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4763 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4764
4765 /* alpnPerSym (1 bit) */
4766 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4767 /* antDmrsSnr (1 bit) */
4768 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4769 /* reserved (1 bit) */
4770 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4771 /* userGroupSize (5 bits) */
4772 uint32_t user_group_size;
4773 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);
4774 if (user_group_size == 0) {
4775 proto_item_append_text(ugs_ti, " (not used)");
4776 }
4777 else if (user_group_size > 12) {
4778 proto_item_append_text(ugs_ti, " (reserved)");
4779 }
4780 offset += 1;
4781 /* userGroupId (8 bits)*/
4782 uint32_t user_group_id;
4783 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);
4784 if (user_group_id == 0) {
4785 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4786 }
4787 if (user_group_id == 255) {
4788 /* Value 255 is reserved */
4789 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4790 }
4791 offset += 1;
4792
4793 bool_Bool seen_value_to_inherit = false0;
4794 bool_Bool inherited_config_has_transform_precoding = false0;
4795 int dmrs_configs_seen = 0;
4796
4797 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4798 uint32_t ueid_index = 0;
4799 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4800 dmrs_configs_seen++;
4801
4802 /* Subtree */
4803 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4804 tvb, offset, 0, "",
4805 "Entry");
4806 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4807
4808 /* entryType (3 bits) */
4809 uint32_t entry_type;
4810 proto_item *entry_type_ti;
4811 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4812 if (entry_type > 3) {
4813 proto_item_append_text(entry_type_ti, " (reserved)");
4814 }
4815
4816 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4817 unsigned int dmrs_port_number;
4818 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);
4819 if (dmrs_port_number > 11) {
4820 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4821 }
4822 offset += 1;
4823
4824 /* What follows depends upon entryType */
4825 switch (entry_type) {
4826 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4827 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4828 /* No further fields for these */
4829 /* Error here if no previous values to inherit!! */
4830 if (!seen_value_to_inherit) {
4831 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4832 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4833
4834 }
4835 /* TODO: would be useful to repeat whole inherited config here? */
4836 break;
4837
4838 case 2: /* transform precoding disabled */
4839 case 3: /* transform precoding enabled */
4840 {
4841 /* Type 2/3 are very similar.. */
4842
4843 /* ueIdReset (1 bit) */
4844 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4845 /* posMeas (1 bit) */
4846 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4847
4848 /* dmrsSymbolMask (14 bits) */
4849 static int * const dmrs_symbol_mask_flags[] = {
4850 &hf_oran_dmrs_symbol_mask_s13,
4851 &hf_oran_dmrs_symbol_mask_s12,
4852 &hf_oran_dmrs_symbol_mask_s11,
4853 &hf_oran_dmrs_symbol_mask_s10,
4854 &hf_oran_dmrs_symbol_mask_s9,
4855 &hf_oran_dmrs_symbol_mask_s8,
4856 &hf_oran_dmrs_symbol_mask_s7,
4857 &hf_oran_dmrs_symbol_mask_s6,
4858 &hf_oran_dmrs_symbol_mask_s5,
4859 &hf_oran_dmrs_symbol_mask_s4,
4860 &hf_oran_dmrs_symbol_mask_s3,
4861 &hf_oran_dmrs_symbol_mask_s2,
4862 &hf_oran_dmrs_symbol_mask_s1,
4863 &hf_oran_dmrs_symbol_mask_s0,
4864 NULL((void*)0)
4865 };
4866 proto_tree_add_bitmask(entry_tree, tvb, offset,
4867 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4868 offset += 2;
4869
4870 /* scrambling */
4871 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4872 offset += 2;
4873
4874 /* nscid (1 bit) */
4875 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4876
4877 /* These 5 bits differ depending upon entry type */
4878 if (entry_type == 2) { /* type 2 */
4879 /* dType (1 bit) */
4880 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4881 /* cdmWithoutData (2 bits) */
4882 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4883 /* lambda (2 bits) */
4884 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4885 }
4886 else { /* type 3 */
4887 /* reserved (1 bit) */
4888 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4889 /* lowPaprType (2 bits) */
4890 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4891 /* hoppingMode (2 bits) */
4892 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4893 }
4894
4895 /* firstPrb (9 bits) */
4896 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4897 offset += 1;
4898 /* lastPrb (9 bits) */
4899 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4900 offset += 2;
4901 /* Reserved (16 bits) */
4902 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4903 offset += 2;
4904
4905 /* Could now see entry types 0 or 1 - they have these values to inherit */
4906 seen_value_to_inherit = true1;
4907 inherited_config_has_transform_precoding = (entry_type == 3);
4908 break;
4909 }
4910
4911 default:
4912 /* reserved - expert info */
4913 break;
4914 }
4915
4916 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4917 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4918 proto_item_set_end(entry_ti, tvb, offset);
4919
4920 if (entry_type <= 1) {
4921 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4922 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4923 }
4924 }
4925
4926 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4927 break;
4928 }
4929
4930 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4931 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4932 where each layer could be one or apply to all layers. */
4933 {
4934 /* TODO: should only appear in one section of a message - check? */
4935 unsigned layer = 0;
4936 proto_item *layer_ti;
4937 while (offset+7 <= (extension_start_offset + extlen*4)) {
4938 /* Layer subtree */
4939 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4940 tvb, offset, 7, "",
4941 "Layer");
4942 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4943
4944 /* All 14 symbols for a layer (or all layers) */
4945 for (unsigned s=0; s < 14; s++) {
4946 proto_item *sym_ti;
4947 /* txWinForOnAirSymbol */
4948 unsigned int tx_win_for_on_air_symbol;
4949 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4950 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4951 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4952 if (tx_win_for_on_air_symbol == 0x0F) {
4953 /* Ordering not affected */
4954 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4955 }
4956 else {
4957 proto_item_append_text(sym_ti, " (sym %u)", s);
4958 }
4959 if (s % 2) {
4960 offset += 1;
4961 }
4962 }
4963
4964 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4965 proto_item_append_text(extension_ti, " (layer %u)", layer);
4966 }
4967 /* Set layer subtree label */
4968 if (layer == 1) {
4969 proto_item_append_text(layer_ti, " (all)");
4970 proto_item_append_text(extension_ti, " (all)");
4971 }
4972 if (layer == 0) {
4973 /* TODO: are no layers valid? What does it mean? */
4974 proto_item_append_text(extension_ti, " (none)");
4975 }
4976 break;
4977 }
4978
4979 case 26: /* SE 26: Frequency offset feedback */
4980 /* Reserved (8 bits) */
4981 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4982 offset += 1;
4983 /* Reserved (1 bit) */
4984 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4985 /* numFoFb (7 bits) */
4986 unsigned num_fo_fb;
4987 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4988 offset += 1;
4989
4990 /* Add each freqOffsetFb value */
4991 for (unsigned n=0; n < num_fo_fb; n++) {
4992 unsigned freq_offset_fb;
4993 /* freqOffsetFb (16 bits) */
4994 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4995 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4996 /* Show if maps onto a -ve number */
4997 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4998 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4999 }
5000 proto_item_append_text(offset_ti, " [#%u]", n+1);
5001 offset += 2;
5002 }
5003 break;
5004
5005 case 27: /* SE 27: O-DU controlled dimensionality reduction */
5006 {
5007 /* Hidden filter for bf (DMRS BF) */
5008 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5009 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5010
5011 /* beamType (2 bits) */
5012 unsigned beam_type;
5013 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
5014 /* reserved (6 bits) */
5015 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5016 offset += 1;
5017
5018 /* numElements */
5019 unsigned num_elements;
5020 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);
5021 if (num_elements == 0) {
5022 num_elements = 256;
5023 proto_item_append_text(num_elements_ti, " (256");
5024 }
5025
5026 offset += 1;
5027
5028 /* beamId value(s) */
5029 switch (beam_type) {
5030 case 0:
5031 for (unsigned n=0; n < num_elements; n++) {
5032 /* reserved (1 bit) + beamId */
5033 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5034 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5035 offset += 2;
5036 }
5037 break;
5038 case 1:
5039 /* reserved (1 bit) + beamId */
5040 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5041 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5042 offset += 2;
5043 break;
5044 default:
5045 /* Unknown type... */
5046 break;
5047 }
5048 break;
5049 }
5050
5051 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
5052 {
5053 /* reserved (3 bits) */
5054 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5055 /* numUeSinrRpt (5 bits) */
5056 uint32_t num_ue_sinr_rpt;
5057 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
5058 offset += 1;
5059
5060 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
5061 /* reserved (1 bit) */
5062 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
5063 tvb, offset, 1);
5064
5065 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
5066 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
5067 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5068 if (n % 2) {
5069 offset += 1;
5070 }
5071 }
5072
5073 /* May need to skip beyond half-used byte */
5074 if (num_ue_sinr_rpt % 2) {
5075 offset += 1;
5076 }
5077 break;
5078 }
5079
5080 case 29: /* SE 29: Cyclic delay adjustment */
5081 /* reserved (4 bits) */
5082 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5083 /* cdScgSize (4 bits) */
5084 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5085 offset += 1;
5086
5087 /* cdScgPhaseStep */
5088 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5089 offset += 1;
5090 break;
5091
5092 case 30: /* SE 30: PUSCH repetition indication */
5093 {
5094 /* Only valid for UL */
5095 if (!tap_info->uplink) {
5096 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5097 }
5098
5099 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5100
5101 /* reserved (4 bits) */
5102 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5103 /* numRepUe (4 bits) */
5104 uint8_t num_rep_ue;
5105 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5106 offset ++;
5107 /* reserved (8 bits) */
5108 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5109 offset += 1;
5110
5111 if (num_rep_ue == 1) {
5112 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5113 /* reserved (1 bit) */
5114 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5115 /* isLastRep (1 bit). Value meaningless here? */
5116 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
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_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5126 /* TODO: should numReps be 0 here? */
5127 offset += 1;
5128
5129 /* reserved (2 bits) */
5130 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5131 offset += 2;
5132
5133 }
5134 else {
5135 /* SE10 present */
5136 bool_Bool is_last_rep = false0;
5137 /* TODO: should is_last_rep (also) cause loop exit? */
5138 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5139 /* reserved (1 bit) */
5140 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5141 /* isLastRep (1 bit) */
5142 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5143 /* repIndex (6 bits) */
5144 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5145 offset += 1;
5146
5147 /* reserved (2 bits) */
5148 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5149 /* numReps (6 bits) */
5150 uint8_t num_reps;
5151 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);
5152 /* TODO: values 33-63 are reserved */
5153 if (num_reps > 32) {
5154 proto_item_append_text(num_reps_ti, " (reserved)");
5155 }
5156 offset += 1;
5157
5158 for (uint8_t rep=0; rep < num_reps; rep++) {
5159 /* reserved (1 bit) */
5160 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5161 /* repUeId (15 bits) */
5162 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5163 uint16_t ueid;
5164 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5165
5166 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5167 bool_Bool matched = false0;
5168 for (unsigned u=0; u < number_of_ueids; u++) {
5169 if (ueid == ueids[u])
5170 matched = true1;
5171 }
5172 if (!matched) {
5173 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5174 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5175 }
5176 offset += 2;
5177 }
5178 }
5179 }
5180 break;
5181 }
5182 case 31: /* SE 31: MCS Information */
5183 {
5184 /* TODO: show ueid (from ST5 or SE10) as generated field? Maybe add a subtree for each entry? */
5185 for (uint32_t u=0; u < number_of_ueids; u++) {
5186 /* reserved (4 bits) */
5187 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5188 /* mcsTable (4 bits) */
5189 proto_tree_add_item(extension_tree, hf_oran_mcs_table, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5190 offset += 1;
5191
5192 /* reserved (2 bits) */
5193 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5194 /* mcsIndex (6 bits) */
5195 proto_tree_add_item(extension_tree, hf_oran_mcs_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5196 }
5197 break;
5198 }
5199
5200 case 32: /* SE 32: Rank and TPMI measurement request */
5201 {
5202 /* reserved (3 bits) */
5203 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5204 /* numMeasReq (5 bits) */
5205 uint8_t num_meas_req;
5206 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_meas_req, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_meas_req);
5207 offset += 1;
5208
5209 /* reserved (8 bits) */
5210 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5211 offset += 1;
5212
5213 /* Show each measurement request */
5214 for (unsigned r=0; r < num_meas_req; r++) {
5215 /* Reserved (1 bit) */
5216 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5217 /* ueId (14 bits) */
5218 proto_tree_add_item(extension_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5219 offset += 2;
5220
5221 /* numOfUeAntPorts (4 bits) */
5222 proto_tree_add_item(extension_tree, hf_oran_num_of_ue_ant_ports, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5223 /* ueRank (4 bits) */
5224 proto_tree_add_item(extension_tree, hf_oran_ue_rank, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5225 offset += 1;
5226
5227 /* codebookSubset (2 bits) */
5228 proto_tree_add_item(extension_tree, hf_oran_codebook_subset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5229 /* TODO: tpmiIndex (6 bits) */
5230 offset += 1;
5231
5232 /* fullPwrMode (2 bits) */
5233 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5234 /* fullPwrMode2TmpiGroup (14 bits) */
5235 /* TODO: add as a bitset */
5236 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode_2_tpmi_group, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5237 offset += 2;
5238
5239 /* reserved (2 bytes) */
5240 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5241 offset += 2;
5242 }
5243 break;
5244 }
5245
5246 default:
5247 /* Other/unexpected extension types */
5248 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5249 "SE %u (%s) not supported by dissector",
5250 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5251 ext_unhandled = true1;
5252 break;
5253 }
5254
5255 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5256 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5257 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5258 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5259 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5260 extlen*4, offset-extension_start_offset);
5261 }
5262
5263 /* Move offset to beyond signalled length of extension */
5264 offset = extension_start_offset + (extlen*4);
5265
5266 /* Set length of extension header. */
5267 proto_item_set_len(extension_ti, extlen*4);
5268 }
5269 /* End of section extension handling */
5270
5271 /* Tap section beamId if not overwritten by SEs */
5272 if (!section_beamId_ignored && section_beamId != 0) {
5273 add_beam_id_to_tap(tap_info, section_beamId);
5274 }
5275
5276
5277 /* RRM measurement reports have measurement reports *after* extensions */
5278 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5279 {
5280 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5281 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5282 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5283
5284 bool_Bool mf;
5285 do {
5286 /* Measurement report subtree */
5287 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5288 tvb, offset, 1, "", "Measurement Report");
5289 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5290 unsigned report_start_offset = offset;
5291
5292 /* measurement flag (i.e., more reports after this one) (1 bit) */
5293 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5294
5295 /* measTypeId (7 bits) */
5296 uint32_t meas_type_id;
5297 proto_item *meas_type_id_ti;
5298 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);
5299 offset += 1;
5300
5301 /* Common to all measurement types */
5302 unsigned num_elements = 0;
5303 if (meas_type_id == 6) {
5304 /* numElements */
5305 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5306 }
5307 else {
5308 /* All other meas ids have a reserved byte */
5309 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5310 }
5311 offset += 1;
5312
5313 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5314 unsigned meas_data_size;
5315 proto_item *meas_data_size_ti;
5316 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);
5317 meas_data_size *= 4;
5318 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5319 offset += 2;
5320
5321 /* Summary for measurement report root */
5322 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5323 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5324 /* And section header */
5325 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5326 /* And Info column */
5327 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5328
5329 /* Handle specific message type fields */
5330 switch (meas_type_id) {
5331 case 1:
5332 {
5333 /* ueTae */
5334 unsigned ue_tae;
5335 proto_item *ue_tae_ti;
5336 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5337 /* Show if maps onto a -ve number */
5338 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5339 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5340 }
5341 offset += 2;
5342
5343 /* Reserved (16 bits) */
5344 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5345 offset += 2;
5346 break;
5347 }
5348 case 2:
5349 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5350 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5351 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5352 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5353 unsigned ue_layer_power;
5354 proto_item *ue_layer_power_ti;
5355 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);
5356 /* Show if maps onto a -ve number */
5357 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5358 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5359 }
5360 offset += 2;
5361 }
5362 /* padding out to 4 bytes */
5363 break;
5364 case 3:
5365 {
5366 /* ueFreqOffset */
5367 unsigned ue_freq_offset;
5368 proto_item *ue_freq_offset_ti;
5369 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);
5370 /* Show if maps onto a -ve number */
5371 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5372 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5373 }
5374 offset += 2;
5375
5376 /* Reserved (16 bits) */
5377 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5378 offset += 2;
5379 break;
5380 }
5381 case 4:
5382 case 5:
5383 /* reserved (2 bits) */
5384 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5385 /* symbolMask (14 bits) */
5386 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5387
5388 /* 2 bytes for each PRB ipnPower */
5389 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5390 /* Skip if should not be reported */
5391 if (!prbs_for_st10_type5[prb]) {
5392 continue;
5393 }
5394 unsigned ipn_power;
5395 proto_item *ipn_power_ti;
5396 /* ipnPower (2 bytes) */
5397 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5398 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5399 /* Show if maps onto a -ve number */
5400 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5401 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5402 }
5403 offset += 2;
5404 }
5405 /* padding out to 4 bytes */
5406 break;
5407 case 6:
5408 /* antDmrsSnrVal entries */
5409 for (unsigned n=0; n < num_elements; n++) {
5410 unsigned snr_value;
5411 proto_item *snr_value_ti;
5412 /* antDmrsSnrVal (2 bytes) */
5413 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);
5414 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5415 /* Show if maps onto a -ve number */
5416 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5417 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5418 }
5419 offset += 2;
5420 }
5421 break;
5422 case 7:
5423 {
5424 /* UE positioning measurement report */
5425 float start_value;
5426
5427 /* ueAzAoa (16 bits) */
5428 uint32_t ue_az_aoa;
5429 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);
5430 if (ue_az_aoa <= 0xE0F) {
5431 if (ue_az_aoa >= 0x0708) {
5432 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5433 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5434 }
5435 else {
5436 start_value = 180 + (ue_az_aoa * (float)0.1);
5437 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5438 }
5439 }
5440 else if (ue_az_aoa == 0xffff) {
5441 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5442 }
5443 else {
5444 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5445 }
5446 offset += 2;
5447
5448 /* Reserved (16 bits) */
5449 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5450 offset += 2;
5451
5452 /* ueZeAoa (16 bits) */
5453 uint32_t ue_ze_aoa;
5454 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);
5455 if (ue_ze_aoa <= 0x707) {
5456 start_value = ue_ze_aoa * (float)0.1;
5457 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5458 }
5459 else if (ue_az_aoa == 0xffff) {
5460 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5461 }
5462 else {
5463 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5464 }
5465 offset += 2;
5466
5467 /* Reserved (16 bits) */
5468 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5469 offset += 2;
5470
5471 /* uePosToaOffset (16 bits) */
5472 uint32_t ue_pos_toa_offset;
5473 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);
5474 if (ue_pos_toa_offset == 0) {
5475 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5476 }
5477 else if (ue_pos_toa_offset <= 0x7fff) {
5478 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5479 }
5480 else if (ue_pos_toa_offset == 0x8000) {
5481 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5482 }
5483 else {
5484 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5485 }
5486 offset += 2;
5487
5488 /* Reserved (16 bits) */
5489 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5490 offset += 2;
5491 break;
5492 }
5493 case 8:
5494 {
5495 /* UE radial speed measurement report */
5496
5497 /* ueRadialSpeed (16 bits) */
5498 uint32_t radial_speed;
5499 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);
5500 if (radial_speed <= 10000) {
5501 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5502 }
5503 else if (radial_speed == 0x8000) {
5504 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5505 }
5506 else {
5507 proto_item_append_text(radial_speed_ti, " (reserved value)");
5508 }
5509 offset += 2;
5510
5511 /* Reserved (16 bits) */
5512 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5513 offset += 2;
5514 break;
5515 }
5516 case 9:
5517 {
5518 /* TODO: UE post-equalization MU interference measurement */
5519
5520 /* reserved (16 bits) */
5521 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5522 offset += 2;
5523
5524 /* TODO: muInterferenceLevel (all layers * all PRB blocks) */
5525 break;
5526 }
5527 case 10:
5528 {
5529 /* UE TPMI and rank recommendation measurement */
5530
5531 /* numCandRanks (4 bits - only 1-4 valid) */
5532 uint8_t num_cand_ranks;
5533 proto_tree_add_item_ret_uint8(mr_tree, hf_oran_num_cand_ranks, tvb, offset, 1, ENC_NA0x00000000, &num_cand_ranks);
5534 if (num_cand_ranks > 4) {
5535 num_cand_ranks = 4;
5536 }
5537 if (num_cand_ranks < 1) {
5538 num_cand_ranks = 1;
5539 }
5540
5541 /* uePrefRank (4 bits) */
5542 add_reserved_field(mr_tree, hf_oran_ue_pref_rank, tvb, offset, 1);
5543 offset += 1;
5544
5545 for (uint8_t cand_rank=1; cand_rank <= num_cand_ranks; cand_rank++) {
5546 /* ueTpmiRankY (1 byte) */
5547 proto_item *rank_y_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y,
5548 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5549 proto_item_append_text(rank_y_ti, " (rank %u)", cand_rank);
5550
5551 offset += 1;
5552
5553 for (uint8_t sinr = 1; sinr <= cand_rank; sinr++) {
5554 /* ueTpmiRankYSinrLX (2 bytes) */
5555 proto_item *rank_y_sinr_x_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y_sinr_lx,
5556 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5557 proto_item_append_text(rank_y_sinr_x_ti, " (rank %u, sinr %u)", cand_rank, sinr);
5558 offset += 2;
5559 }
5560 }
5561 break;
5562 }
5563 case 11:
5564 {
5565 /* UE layer pre-equalization SINR report */
5566 /* TODO: how to know how many layers? Just fill up available data? */
5567 unsigned num_layers = (meas_data_size-1) * 4;
5568 for (unsigned layer=0; layer < num_layers; layer++) {
5569 /* ueLayerPreEqSinr (2 bytes each) */
5570 proto_item *pre_eq_sinr_ti = proto_tree_add_item(mr_tree, hf_oran_ue_layer_pre_eq_sinr,
5571 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5572 proto_item_append_text(pre_eq_sinr_ti, " (layer %u)", layer);
5573 offset += 2;
5574 }
5575 break;
5576 }
5577
5578 default:
5579 /* Anything else is not expected */
5580 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5581 "measTypeId %u (%s) not supported - only 1-6 are expected",
5582 meas_type_id,
5583 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5584 break;
5585
5586 }
5587
5588 /* Pad out to next 4 bytes */
5589 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5590
5591 /* TODO: verify dissected size of report vs meas_data_size? */
5592
5593 /* End of measurement report tree */
5594 proto_item_set_end(mr_ti, tvb, offset);
5595 } while (mf);
5596 }
5597
5598 /* Request for RRM Measurements has measurement commands after extensions */
5599 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5600 {
5601 bool_Bool mf = true1;
5602 do {
5603 /* Measurement command subtree */
5604 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5605 tvb, offset, 8, "", "Measurement Command");
5606 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5607
5608 /* mf (1 bit). 1st measurement command is always preset */
5609 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5610
5611 /* measTypeId (7 bits) */
5612 uint32_t meas_type_id;
5613 proto_item *meas_type_id_ti;
5614 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);
5615 offset += 1;
5616
5617 proto_item *meas_command_ti;
5618 uint32_t meas_command_size;
5619
5620 switch (meas_type_id) {
5621 case 5: /* command for IpN for unallocated PRBs */
5622 /* reserved (1 byte) */
5623 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5624 offset += 1;
5625 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5626 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);
5627 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5628 offset += 2;
5629 /* reserved (2 bits) */
5630 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5631 /* symbolMask (14 bits) */
5632 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5633 /* reserved (16 bits) */
5634 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5635 offset += 2;
5636 break;
5637
5638 default:
5639 /* Anything else is not expected */
5640 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5641 "measTypeId %u (%s) not supported - only 5 is expected",
5642 meas_type_id,
5643 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5644 break;
5645 }
5646 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5647
5648 } while (mf);
5649 }
5650
5651 /* Set extent of overall section */
5652 proto_item_set_len(sectionHeading, offset);
5653
5654 return offset;
5655}
5656
5657/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5658/* bit_width and comp_meth are out params */
5659static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5660 bool_Bool cplane, bool_Bool ignore,
5661 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5662 oran_tap_info *tap_info)
5663{
5664 /* Subtree */
5665 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5666 tvb, offset, 1, "",
5667 "udCompHdr");
5668 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5669
5670 /* udIqWidth */
5671 uint32_t hdr_iq_width;
5672 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5673 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5674 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5675
5676 /* udCompMeth */
5677 uint32_t ud_comp_meth;
5678 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5679 if (comp_meth) {
5680 *comp_meth = ud_comp_meth;
5681 }
5682
5683 /* Populate tap header with compression settings */
5684 if (!ignore) {
5685 tap_info->compression_methods |= (1 << ud_comp_meth);
5686 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))
;
5687 /* Summary */
5688 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5689 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5690 }
5691 else {
5692 proto_item_append_text(udcomphdr_ti, " (ignored)");
5693 if (hdr_iq_width || ud_comp_meth) {
5694 if (cplane) {
5695 /* Only ignore DL for cplane */
5696 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5697 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5698 tvb_get_uint8(tvb, offset));
5699 }
5700 else {
5701 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5702 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5703 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5704 tvb_get_uint8(tvb, offset));
5705 */
5706 }
5707
5708 }
5709 }
5710 return offset+1;
5711}
5712
5713/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5714/* bit_width and comp_meth are out params */
5715static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5716 unsigned comp_meth,
5717 uint32_t *exponent, uint16_t *sReSMask,
5718 bool_Bool for_sinr)
5719{
5720 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5721 /* sinrCompParam only present when bfp is used */
5722 return offset;
5723 }
5724
5725 if (comp_meth == COMP_NONE0 ||
5726 comp_meth == COMP_MODULATION4 ||
5727 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5728
5729 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5730 return offset;
5731 }
5732
5733 /* Subtree */
5734 unsigned start_offset = offset;
5735 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5736 tvb, offset, 1, "",
5737 (for_sinr) ? "sinrCompParam" : "udCompParam");
5738 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5739
5740 /* Show comp_meth as a generated field */
5741 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5742 proto_item_set_generated(meth_ti);
5743
5744 uint32_t param_exponent;
5745 uint64_t param_sresmask;
5746
5747 static int * const sres_mask_flags[] = {
5748 &hf_oran_sReSMask_re12,
5749 &hf_oran_sReSMask_re11,
5750 &hf_oran_sReSMask_re10,
5751 &hf_oran_sReSMask_re9,
5752 &hf_oran_sReSMask_re8,
5753 &hf_oran_sReSMask_re7,
5754 &hf_oran_sReSMask_re6,
5755 &hf_oran_sReSMask_re5,
5756 &hf_oran_sReSMask_re4,
5757 &hf_oran_sReSMask_re3,
5758 &hf_oran_sReSMask_re2,
5759 &hf_oran_sReSMask_re1,
5760 NULL((void*)0)
5761 };
5762
5763 switch (comp_meth) {
5764 case COMP_BLOCK_FP1: /* 1 */
5765 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5766 /* reserved (4 bits) */
5767 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5768 /* exponent (4 bits) */
5769 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5770 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5771 *exponent = param_exponent;
5772 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5773 offset += 1;
5774 break;
5775
5776 case COMP_BLOCK_SCALE2: /* 2 */
5777 /* Separate into integer and fractional bits? */
5778 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5779 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5780 offset++;
5781 break;
5782
5783 case COMP_U_LAW3: /* 3 */
5784 /* compBitWidth, compShift */
5785 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5786 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5787 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5788 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5789 offset += 1;
5790 break;
5791
5792 case BFP_AND_SELECTIVE_RE5: /* 5 */
5793 {
5794 /* sReSMask (exponent in middle!) */
5795 proto_item *sresmask_ti;
5796 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5797 hf_oran_sReSMask,
5798 ett_oran_sresmask,
5799 sres_mask_flags,
5800 ENC_NA0x00000000,
5801 &param_sresmask);
5802
5803 /* Get rid of exponent-shaped gap */
5804 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5805 unsigned res = 0;
5806 for (unsigned n=0; n < 12; n++) {
5807 if ((param_sresmask >> n) & 0x1) {
5808 res++;
5809 }
5810 }
5811 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5812
5813 /* exponent */
5814 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5815 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5816 *sReSMask = (uint16_t)param_sresmask;
5817 *exponent = param_exponent;
5818
5819 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5820 offset += 2;
5821 break;
5822 }
5823
5824 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5825 {
5826 /* sReSMask (exponent in middle!) */
5827 proto_item *sresmask_ti;
5828
5829 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5830 hf_oran_sReSMask,
5831 ett_oran_sresmask,
5832 sres_mask_flags,
5833 ENC_NA0x00000000,
5834 &param_sresmask);
5835
5836 /* Get rid of reserved-shaped gap */
5837 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5838 unsigned res = 0;
5839 for (unsigned n=0; n < 12; n++) {
5840 if ((param_sresmask >> n) & 0x1) {
5841 res++;
5842 }
5843 }
5844 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5845
5846 /* reserved (4 bits) */
5847 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5848 *sReSMask = (uint16_t)param_sresmask;
5849
5850 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5851 offset += 2;
5852 break;
5853 }
5854
5855 default:
5856 /* reserved (set to all zeros), but how many bytes?? */
5857 break;
5858 }
5859
5860 proto_item_set_len(udcompparam_ti, offset-start_offset);
5861 return offset;
5862}
5863
5864
5865/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5866/* bit_width and comp_meth are out params */
5867static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5868 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5869{
5870 /* Subtree */
5871 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5872 tvb, offset, 1, "",
5873 "ciCompHdr");
5874 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5875
5876 /* ciIqWidth */
5877 uint32_t hdr_iq_width;
5878 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5879 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5880 if (bit_width) {
5881 *bit_width = hdr_iq_width;
5882 }
5883 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5884
5885 /* ciCompMeth */
5886 uint32_t ci_comp_meth;
5887 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5888 if (comp_meth) {
5889 *comp_meth = ci_comp_meth;
5890 }
5891
5892 /* ciCompOpt */
5893 uint32_t opt;
5894 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5895 *comp_opt = opt;
5896 offset += 1;
5897
5898 /* Summary */
5899 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5900 hdr_iq_width,
5901 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5902 (*comp_opt) ? "compression per PRB" : "compression per UE");
5903 return offset;
5904}
5905
5906static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5907{
5908 unsigned version;
5909 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5910 if (version != 1) {
5911 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5912 "PayloadVersion %u not supported by dissector (only 1 is known)",
5913 version);
5914 /* TODO: should throw an exception? */
5915 }
5916}
5917
5918static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5919 ack_nack_request_t *request)
5920{
5921 /* Request frame */
5922 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5923 tvb, 0, 0, request->request_frame_number);
5924 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5925
5926 /* Work out gap between frames (in ms) */
5927 int seconds_between_packets = (int)
5928 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5929 int nseconds_between_packets =
5930 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5931
5932 int total_gap = (seconds_between_packets*1000) +
5933 ((nseconds_between_packets+500000) / 1000000);
5934
5935 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5936 tvb, 0, 0, total_gap);
5937 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5938
5939 /* Type of request */
5940 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5941 tvb, 0, 0, request->requestType);
5942 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5943}
5944
5945static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5946 ack_nack_request_t *response)
5947{
5948 if (response->response_frame_number == 0) {
5949 /* Requests may not get a response, and can't always tell when to expect one */
5950 return;
5951 }
5952
5953 /* Response frame */
5954 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5955 tvb, 0, 0, response->response_frame_number);
5956 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5957
5958 /* Work out gap between frames (in ms) */
5959 int seconds_between_packets = (int)
5960 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5961 int nseconds_between_packets =
5962 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5963
5964 int total_gap = (seconds_between_packets*1000) +
5965 ((nseconds_between_packets+500000) / 1000000);
5966
5967 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5968 tvb, 0, 0, total_gap);
5969 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5970}
5971
5972
5973
5974/* Control plane dissector (section 7). */
5975static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5976 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5977{
5978 /* Hidden filter for plane */
5979 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5980 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5981
5982 /* Set up structures needed to add the protocol subtree and manage it */
5983 unsigned offset = 0;
5984
5985 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5986 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5987
5988 tap_info->userplane = false0;
5989
5990 /* Create display subtree for the protocol */
5991 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5992 proto_item_append_text(protocol_item, "-C");
5993 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5994
5995 /* ecpriRtcid (eAxC ID) */
5996 uint16_t eAxC;
5997 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5998 tap_info->eaxc = eAxC;
5999
6000 /* Look up any existing conversation state for eAxC+plane */
6001 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
6002 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
6003
6004 /* Message identifier */
6005 uint32_t seq_id, sub_seq_id, e;
6006 proto_item *seq_id_ti;
6007 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
6008
6009 /* Section common subtree */
6010 int section_tree_offset = offset;
6011 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
6012 tvb, offset, 0, "", "C-Plane Section Type ");
6013 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
6014
6015 /* Peek ahead at the section type */
6016 uint32_t sectionType = 0;
6017 sectionType = tvb_get_uint8(tvb, offset+5);
6018
6019 uint32_t scs = 0;
6020 proto_item *scs_ti = NULL((void*)0);
6021
6022 /* dataDirection */
6023 uint32_t direction = 0;
6024 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6025 tap_info->uplink = (direction==0);
6026
6027 /* Update/report status of conversation */
6028 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6029
6030 if (state == NULL((void*)0)) {
6031 /* Allocate new state */
6032 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
6033 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
6034 wmem_tree_insert32(flow_states_table, key, state);
6035 /* Tables for each direction */
6036 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
6037 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
6038 }
6039
6040 /* Check sequence analysis status */
6041 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
6042 /* Store this result */
6043 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
6044 result->unexpected_seq_number = true1;
6045 result->expected_sequence_number = state->next_expected_sequence_number[direction];
6046 result->previous_frame = state->last_frame[direction];
6047 result->u_plane_frames = wmem_list_new(wmem_file_scope());
6048 wmem_tree_insert32(flow_results_table, pinfo->num, result);
6049 }
6050 /* Update conversation info */
6051 state->last_frame[direction] = pinfo->num;
6052 state->last_frame_seen[direction] = true1;
6053 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
6054 }
6055
6056 /* Show any issues associated with this frame number */
6057 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
6058 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
6059 expert_add_info_format(pinfo, seq_id_ti,
6060 (direction == DIR_UPLINK0) ?
6061 &ei_oran_cplane_unexpected_sequence_number_ul :
6062 &ei_oran_cplane_unexpected_sequence_number_dl,
6063 "Sequence number %u expected, but got %u",
6064 result->expected_sequence_number, seq_id);
6065
6066 /* Update tap info */
6067 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
6068 /* Don't get confused by being slightly out of order.. */
6069 if (missing_sns < 128) {
6070 tap_info->missing_sns = missing_sns;
6071 }
6072 else {
6073 tap_info->missing_sns = 0;
6074 }
6075
6076 /* TODO: could add previous/next frames (in seqId tree?) ? */
6077 }
6078
6079 /* payloadVersion */
6080 dissect_payload_version(section_tree, tvb, pinfo, offset);
6081
6082 /* filterIndex */
6083 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6084 /* scs (for ST4 and ST8) */
6085 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
6086 }
6087 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
6088 /* reserved (4 bits) */
6089 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
6090 }
6091 else if (sectionType != SEC_C_LAA) {
6092 /* filterIndex (most common case) */
6093 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6094 }
6095 offset += 1;
6096
6097 unsigned ref_a_offset = offset;
6098 /* frameId */
6099 uint32_t frameId = 0;
6100 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6101 tap_info->frame = frameId;
6102 offset += 1;
6103
6104 /* subframeId */
6105 uint32_t subframeId = 0;
6106 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6107 /* slotId */
6108 uint32_t slotId = 0;
6109 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6110 tap_info->slot = slotId;
6111 offset++;
6112
6113 /* startSymbolId */
6114 uint32_t startSymbolId = 0;
6115 proto_item *ssid_ti = NULL((void*)0);
6116 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
6117 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
6118 /* symbolId */
6119 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6120 }
6121 else if (sectionType != SEC_C_LAA) {
6122 /* startSymbolId is in most section types */
6123 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6124 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
6125 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
6126 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
6127 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
6128 }
6129 }
6130 else {
6131 /* reserved (6 bits) */
6132 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
6133 }
6134 offset++;
6135
6136
6137 char id[16];
6138 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
6139 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6140 proto_item_set_generated(pi);
6141
6142 uint32_t cmd_scope = 0;
6143 bool_Bool st8_ready = false0;
6144
6145 /* numberOfSections (or whatever section has instead) */
6146 uint32_t nSections = 0;
6147 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
6148 /* Slot Control has these fields instead */
6149 /* reserved (4 bits) */
6150 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6151 /* cmdScope (4 bits) */
6152 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
6153 }
6154 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
6155 /* reserved (7 bits) */
6156 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
6157 /* ready (1 bit) */
6158 /* TODO: when set, ready in slotId+1.. */
6159 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
6160 if (!st8_ready) {
6161 /* SCS value is ignored, and may be set to any value by O-RU */
6162 proto_item_append_text(scs_ti, " (ignored)");
6163 }
6164 }
6165 else if (sectionType != SEC_C_LAA) {
6166 /* numberOfSections */
6167 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
6168 }
6169 else {
6170 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6171 }
6172 offset++;
6173
6174 /* sectionType */
6175 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
6176 offset += 1;
6177
6178 /* Check that dataDirection is consistent with section type */
6179 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
6180 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
6181 }
6182 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
6183 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
6184 }
6185
6186 /* Note this section type in stats */
6187 if (sectionType < SEC_C_MAX_INDEX) {
6188 tap_info->section_types[sectionType] = true1;
6189 }
6190
6191 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6192 unsigned bit_width = 0;
6193 unsigned comp_meth = 0;
6194 proto_item *comp_meth_ti;
6195 unsigned ci_comp_method = 0;
6196 uint8_t ci_comp_opt = 0;
6197
6198 uint32_t num_ues = 0;
6199 uint32_t number_of_acks = 0, number_of_nacks = 0;
6200
6201 uint32_t num_sinr_per_prb = 0;
6202
6203 switch (sectionType) {
6204 case SEC_C_UNUSED_RB: /* Section Type 0 */
6205 /* timeOffset */
6206 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6207 offset += 2;
6208 /* frameStructure */
6209 offset = dissect_frame_structure(section_tree, tvb, offset,
6210 subframeId, slotId);
6211
6212 /* cpLength */
6213 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6214 offset += 2;
6215 /* reserved (8 bits) */
6216 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6217 offset += 1;
6218 break;
6219
6220 case SEC_C_NORMAL: /* Section Type 1 */
6221 case SEC_C_UE_SCHED: /* Section Type 5 */
6222 /* udCompHdr */
6223 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6224 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6225 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6226 /* reserved (8 bits) */
6227 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6228 offset += 1;
6229 break;
6230
6231 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6232 break;
6233
6234 case SEC_C_PRACH: /* Section Type 3 */
6235 /* timeOffset */
6236 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6237 offset += 2;
6238 /* frameStructure */
6239 offset = dissect_frame_structure(section_tree, tvb, offset,
6240 subframeId, slotId);
6241 /* cpLength */
6242 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6243 offset += 2;
6244 /* udCompHdr */
6245 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6246 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6247 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6248 break;
6249
6250 case SEC_C_CH_INFO: /* Section Type 6 */
6251 /* numberOfUEs */
6252 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6253 offset += 1;
6254 /* ciCompHdr (was reserved) */
6255 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6256
6257 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6258 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6259 if (nSections == 0 || num_ues > nSections) {
6260 nSections = num_ues;
6261 }
6262 break;
6263
6264 case SEC_C_RSVD2:
6265 break;
6266
6267 case SEC_C_LAA: /* Section Type 7 */
6268 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6269 offset += 2;
6270 break;
6271
6272 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6273 /* numberOfAcks (1 byte) */
6274 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6275 offset += 1;
6276 /* numberOfNacks (1 byte) */
6277 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6278 offset += 1;
6279
6280 /* Show ACKs and NACKs. For both, try to link back to request. */
6281 for (unsigned int n=1; n <= number_of_acks; n++) {
6282 uint32_t ackid;
6283 proto_item *ack_ti;
6284 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6285 offset += 2;
6286
6287 /* Look up request table in state (which really should be set by now, but test anyway). */
6288 if (state && state->ack_nack_requests) {
6289 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6290 if (request != NULL((void*)0)) {
6291 /* On first pass, update with this response */
6292 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6293 request->response_frame_number = pinfo->num;
6294 request->response_frame_time = pinfo->abs_ts;
6295 }
6296
6297 /* Show request details */
6298 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6299 }
6300 else {
6301 /* Request not found */
6302 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6303 "Response for ackId=%u received, but no request found",
6304 ackid);
6305 }
6306 }
6307 }
6308 for (unsigned int m=1; m <= number_of_nacks; m++) {
6309 uint32_t nackid;
6310 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6311 offset += 2;
6312
6313 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6314 "Received Nack for ackNackId=%u",
6315 nackid);
6316
6317 /* Look up request table in state. */
6318 if (state && state->ack_nack_requests) {
6319 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6320 if (request) {
6321 /* On first pass, update with this response */
6322 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6323 request->response_frame_number = pinfo->num;
6324 request->response_frame_time = pinfo->abs_ts;
6325 }
6326
6327 /* Show request details */
6328 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6329 }
6330 else {
6331 /* Request not found */
6332 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6333 "Response for nackId=%u received, but no request found",
6334 nackid);
6335 }
6336 }
6337 }
6338 break;
6339
6340 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6341 {
6342 /* numSinrPerPrb (3 bits) */
6343 proto_item *nspp_ti;
6344 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);
6345 switch (num_sinr_per_prb) {
6346 case 0:
6347 num_sinr_per_prb = 1; break;
6348 case 1:
6349 num_sinr_per_prb = 2; break;
6350 case 2:
6351 num_sinr_per_prb = 3; break;
6352 case 3:
6353 num_sinr_per_prb = 4; break;
6354 case 4:
6355 num_sinr_per_prb = 6; break;
6356 case 5:
6357 num_sinr_per_prb = 12; break;
6358
6359 default:
6360 proto_item_append_text(nspp_ti, " (invalid)");
6361 num_sinr_per_prb = 1;
6362 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6363 "Invalid numSinrPerPrb value (%u)",
6364 num_sinr_per_prb);
6365 }
6366
6367 /* oruControlSinrSlotMaskId (5 bits) */
6368 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6369 offset += 1;
6370 /* reserved (8 bits) */
6371 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6372 offset += 1;
6373 break;
6374 }
6375
6376 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6377 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6378 /* reserved (16 bits) */
6379 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6380 offset += 2;
6381 break;
6382 };
6383
6384 /* Update udCompHdr details in state for UL U-Plane */
6385 if (state && direction==0) {
6386 switch (sectionType) {
6387 case SEC_C_NORMAL: /* Section Type 1 */
6388 case SEC_C_PRACH: /* Section Type 3 */
6389 case SEC_C_UE_SCHED: /* Section Type 5 */
6390 state->ul_ud_comp_hdr_set = true1;
6391 state->ul_ud_comp_hdr_bit_width = bit_width;
6392 state->ul_ud_comp_hdr_compression = comp_meth;
6393 state->ul_ud_comp_hdr_frame = pinfo->num;
6394 break;
6395 default:
6396 break;
6397 }
6398 }
6399
6400
6401 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6402 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6403 frameId, subframeId, slotId, startSymbolId);
6404 if (nSections) {
6405 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6406 }
6407
6408 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6409 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6410
6411 /* Set actual length of C-Plane section header */
6412 proto_item_set_len(section_tree, offset - section_tree_offset);
6413
6414 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6415 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6416 (st8_ready) ? " (Ready)" : " (ACK)");
6417 }
6418
6419
6420 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6421 if (sectionType == SEC_C_SLOT_CONTROL) {
6422 /* numberOfST4Cmds */
6423 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6424 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6425 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6426 if (no_st4_cmds == 0) {
6427 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6428 }
6429 offset += 1;
6430
6431 /* reserved (1 byte) */
6432 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6433 offset += 1;
6434
6435 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6436 proto_item *len_ti;
6437 for (uint32_t n=0; n < no_st4_cmds; n++) {
6438 /* Table 7.4.6-2: Section Type 4 Command common header format */
6439 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6440 tvb, offset, 8, "",
6441 "Type 4 Command common header");
6442 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6443
6444 /* st4CmdType */
6445 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6446 offset += 1;
6447
6448 /* st4CmdLen */
6449 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6450 if (st4_cmd_len == 0) {
6451 /* Meaning of 0 not yet defined (v15.00) */
6452 proto_item_append_text(len_ti, " (reserved)");
6453 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6454 }
6455 else {
6456 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6457 }
6458 offset += 2;
6459
6460 /* numSlots */
6461 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);
6462 if (num_slots == 0) {
6463 proto_item_append_text(slots_ti, " (until changed)");
6464 }
6465 offset += 1;
6466
6467 /* ackNackReqId */
6468 proto_item *ack_nack_req_id_ti;
6469 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);
6470 offset += 2;
6471 if (ack_nack_req_id == 0) {
6472 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6473 }
6474
6475 /* reserved (16 bits) */
6476 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6477 offset += 2;
6478
6479 /* Set common header summary */
6480 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6481 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6482 st4_cmd_len, num_slots, ack_nack_req_id);
6483
6484 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6485 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6486
6487
6488 /* Subtree for this command body */
6489 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6490 tvb, offset, 0, "",
6491 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6492 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6493
6494 unsigned command_start_offset = offset;
6495
6496 /* Check fields compatible with chosen command. */
6497 if (st4_cmd_type==1) {
6498 if (num_slots != 0) {
6499 /* "the value of numSlots should be set to zero for this command type" */
6500 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6501 "numSlots should be zero for ST4 command 1 - found %u",
6502 num_slots);
6503 }
6504 }
6505
6506 if (st4_cmd_type==3 || st4_cmd_type==4) {
6507 if (startSymbolId != 0) {
6508 /* "expected reception window for the commands is the symbol zero reception window" */
6509 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6510 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6511 startSymbolId);
6512 }
6513 }
6514
6515 /* Add format for this command */
6516 switch (st4_cmd_type) {
6517 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6518 {
6519 bool_Bool disable_tdbfns;
6520 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6521
6522 /* Hidden filter for bf */
6523 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6524 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6525
6526 /* reserved (2 bits) */
6527 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6528 /* symbolMask (14 bits) */
6529 uint32_t symbol_mask;
6530 proto_item *symbol_mask_ti;
6531 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6532 /* 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 */
6533 /* lsb is symbol 0 */
6534 for (unsigned s=0; s < 14; s++) {
6535 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6536 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6537 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6538 break;
6539 }
6540 }
6541
6542 /* disableTDBFNs (1 bit) */
6543 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6544
6545 /* tdBeamNum (15 bits) */
6546 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6547 offset += 2;
6548
6549 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6550 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6551 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6552 /* reserved (3 bytes) */
6553 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6554 offset += 3;
6555
6556 if (disable_tdbfns) {
6557 /* No beamnum information to show so get out. */
6558 break;
6559 }
6560
6561 /* Read beam entries until reach end of command length */
6562 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6563
6564 /* disableTDBFWs (1 bit) */
6565 bool_Bool disable_tdbfws;
6566 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6567
6568 /* tdBeamNum (15 bits) */
6569 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6570 offset += 2;
6571
6572 /* Showing BFWs? */
6573 if (!disable_tdbfws) {
6574
6575 /* bfwCompParam */
6576 unsigned exponent = 0;
6577 bool_Bool supported = false0;
6578 unsigned num_trx_entries;
6579 uint16_t *trx_entries;
6580 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6581 &bfwcomphdr_comp_meth, &exponent, &supported,
6582 &num_trx_entries, &trx_entries);
6583
6584 /* Antenna count from preference */
6585 unsigned num_trx = pref_num_bf_antennas;
6586 int bit_offset = offset*8;
6587
6588 for (unsigned trx=0; trx < num_trx; trx++) {
6589 /* Create antenna subtree */
6590 int bfw_offset = bit_offset / 8;
6591 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6592 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6593 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6594
6595 /* I value */
6596 /* Get bits, and convert to float. */
6597 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6598 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6599 /* Add to tree. */
6600 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6601 (bfwcomphdr_iq_width+7)/8, value);
6602 bit_offset += bfwcomphdr_iq_width;
6603 proto_item_append_text(bfw_ti, "I=%f ", value);
6604
6605 /* Leave a gap between I and Q values */
6606 proto_item_append_text(bfw_ti, " ");
6607
6608 /* Q value */
6609 /* Get bits, and convert to float. */
6610 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6611 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6612 /* Add to tree. */
6613 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6614 (bfwcomphdr_iq_width+7)/8, value);
6615 bit_offset += bfwcomphdr_iq_width;
6616 proto_item_append_text(bfw_ti, "Q=%f", value);
6617
6618 proto_item_append_text(bfw_ti, ")");
6619 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6620 }
6621 /* Need to round to next byte */
6622 offset = (bit_offset+7)/8;
6623 }
6624 }
6625 break;
6626 }
6627 case 2: /* TDD_CONFIG_PATTERN */
6628 /* reserved (2 bits) */
6629 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6630 /* dirPattern (14 bits) */
6631 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6632 offset += 2;
6633
6634 /* reserved (2 bits) */
6635 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6636 /* guardPattern (14 bits) */
6637 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6638 offset += 2;
6639 break;
6640
6641 case 3: /* TRX_CONTROL */
6642 case 5: /* TRX_CONTROL_BIDIR */
6643 {
6644 /* Only allowed cmdScope is ARRAY-COMMAND */
6645 if (cmd_scope != 0) {
6646 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6647 }
6648
6649 /* reserved (2 bits) */
6650 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6651 /* log2MaskBits (4 bits) */
6652 unsigned log2maskbits;
6653 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6654 /* sleepMode (2 bits) */
6655 uint32_t sleep_mode;
6656 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6657 offset += 1;
6658
6659 /* reserved (4 bits) */
6660 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6661 /* numSlotsExt (20 bits) */
6662 uint32_t num_slots_ext;
6663 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);
6664 if (num_slots==0 && num_slots_ext==0) {
6665 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6666 }
6667 else {
6668 /* Time should be rounded up according to SCS */
6669 float total = (float)(num_slots + num_slots_ext);
6670 /* From table 7.5.2.13-3 */
6671 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6672 0, 0, 0, 0, 0, 0, /* reserved */
6673 1000, 1000, 1000, 1000 };
6674 float slot_length = slot_length_by_scs[scs];
6675 /* Only using valid SCS. TODO: is this test ok? */
6676 if (slot_length != 0) {
6677 /* Round up to next slot */
6678 total = ((int)(total / slot_length) + 1) * slot_length;
6679 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6680 }
6681 }
6682 offset += 3;
6683
6684 /* reserved (2 bits) */
6685 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6686
6687 /* symbolMask (14 bits) */
6688 uint32_t symbol_mask;
6689 proto_item *sm_ti;
6690 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6691 if (symbol_mask == 0x0) {
6692 proto_item_append_text(sm_ti, " (wake)");
6693 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6694 }
6695 else if (symbol_mask == 0x3fff) {
6696 proto_item_append_text(sm_ti, " (sleep)");
6697 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6698 }
6699 else {
6700 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6701 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6702 sleep_mode, symbol_mask);
6703 }
6704 offset += 2;
6705
6706 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6707 unsigned antmask_length = 2;
6708 if (log2maskbits >= 4) {
6709 antmask_length = (1 << log2maskbits) / 8;
6710 }
6711 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6712 /* show count */
6713 unsigned antenna_count = 0;
6714 for (unsigned b=0; b < antmask_length; b++) {
6715 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6716 for (unsigned bit=0; bit < 8; bit++) {
6717 if ((1 << bit) & byte) {
6718 antenna_count++;
6719 }
6720 }
6721 }
6722 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6723 offset += antmask_length;
6724
6725 /* Pad to next 4-byte boundary */
6726 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6727 break;
6728 }
6729
6730 case 4: /* ASM (advanced sleep mode) */
6731 /* reserved (2+4=6 bits) */
6732 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6733 /* sleepMode (2 bits) */
6734 uint32_t sleep_mode;
6735 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6736 offset += 1;
6737
6738 /* reserved (4 bits) */
6739 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6740 /* numSlotsExt (20 bits) */
6741 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6742 offset += 3;
6743
6744 /* reserved (2 bits) */
6745 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6746 /* symbolMask (14 bits) */
6747 uint32_t symbol_mask;
6748 proto_item *sm_ti;
6749 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6750 if (symbol_mask == 0x0) {
6751 proto_item_append_text(sm_ti, " (wake)");
6752 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6753 }
6754 else if (symbol_mask == 0x3fff) {
6755 proto_item_append_text(sm_ti, " (sleep)");
6756 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6757 }
6758 else {
6759 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6760 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6761 sleep_mode, symbol_mask);
6762 }
6763 offset += 2;
6764
6765 /* reserved (2 bytes) */
6766 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6767 offset += 2;
6768 break;
6769
6770 default:
6771 /* Error! */
6772 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6773 "Dissected ST4 command (%u) not recognised",
6774 st4_cmd_type);
6775 break;
6776 }
6777
6778 /* Check apparent size of padding (0-3 bytes ok) */
6779 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6780 if (padding_remaining > 3) {
6781 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6782 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6783 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6784 }
6785
6786 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6787 offset = command_start_offset + (st4_cmd_len * 4);
6788
6789 /* Set end of command tree */
6790 proto_item_set_end(command_ti, tvb, offset);
6791
6792 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6793 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6794 /* Add this request into conversation state on first pass */
6795 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)))
;
6796 request_details->request_frame_number = pinfo->num;
6797 request_details->request_frame_time = pinfo->abs_ts;
6798 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6799
6800 wmem_tree_insert32(state->ack_nack_requests,
6801 ack_nack_req_id,
6802 request_details);
6803 }
6804 else {
6805 /* On later passes, try to link forward to ST8 response */
6806 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6807 ack_nack_req_id);
6808 if (response) {
6809 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6810 }
6811 }
6812 }
6813 }
6814 }
6815 /* LAA doesn't have sections either.. */
6816 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6817 /* 7.2.5 Table 6.4-6 */
6818 unsigned mcot;
6819 proto_item *mcot_ti;
6820
6821 /* laaMsgType */
6822 uint32_t laa_msg_type;
6823 proto_item *laa_msg_type_ti;
6824 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6825 /* laaMsgLen */
6826 uint32_t laa_msg_len;
6827 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6828 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6829 if (laa_msg_len == 0) {
6830 proto_item_append_text(len_ti, " (reserved)");
6831 }
6832 offset += 1;
6833
6834 int payload_offset = offset;
6835
6836 /* Payload */
6837 switch (laa_msg_type) {
6838 case 0:
6839 /* LBT_PDSCH_REQ */
6840 /* lbtHandle (16 bits) */
6841 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6842 offset += 2;
6843 /* lbtOffset (10 bits) */
6844 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6845 offset += 1;
6846 /* lbtMode (2 bits) */
6847 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6848 /* reserved (1 bit) */
6849 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6850 /* lbtDeferFactor (3 bits) */
6851 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6852 offset += 1;
6853 /* lbtBackoffCounter (10 bits) */
6854 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6855 offset += 1;
6856 /* MCOT (4 bits) */
6857 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6858 if (mcot<1 || mcot>10) {
6859 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6860 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6861 "MCOT seen with value %u (must be 1-10)", mcot);
6862
6863 }
6864 /* reserved (10 bits) */
6865 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6866 break;
6867 case 1:
6868 /* LBT_DRS_REQ */
6869 /* lbtHandle (16 bits) */
6870 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6871 offset += 2;
6872 /* lbtOffset (10 bits) */
6873 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, 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, 2, ENC_BIG_ENDIAN0x00000000);
6877 /* reserved (28 bits) */
6878 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6879 break;
6880 case 2:
6881 /* LBT_PDSCH_RSP */
6882 /* lbtHandle (16 bits) */
6883 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6884 offset += 2;
6885 /* lbtPdschRes (2 bits) */
6886 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6887 /* inParSF (1 bit) */
6888 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6889 /* sfStatus (1 bit) */
6890 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6891 /* sfnSf (12 bits) */
6892 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6893 offset += 2;
6894 /* reserved (24 bits) */
6895 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6896 break;
6897 case 3:
6898 /* LBT_DRS_RSP */
6899 /* lbtHandle (16 bits) */
6900 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6901 offset += 2;
6902 /* lbtDrsRes (1 bit) */
6903 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6904 /* reserved (7 bits) */
6905 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6906 break;
6907 case 4:
6908 /* LBT_Buffer_Error */
6909 /* lbtHandle (16 bits) */
6910 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6911 offset += 2;
6912 /* lbtBufErr (1 bit) */
6913 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6914 /* reserved (7 bits) */
6915 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6916 break;
6917 case 5:
6918 /* LBT_CWCONFIG_REQ */
6919 /* lbtHandle (16 bits) */
6920 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6921 offset += 2;
6922 /* lbtCWConfig_H (8 bits) */
6923 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6924 offset += 1;
6925 /* lbtCWConfig_T (8 bits) */
6926 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6927 offset += 1;
6928 /* lbtMode (2 bits) */
6929 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6930 /* lbtTrafficClass (3 bits) */
6931 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6932 /* reserved (19 bits) */
6933 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6934 break;
6935 case 6:
6936 /* LBT_CWCONFIG_RSP */
6937 /* lbtHandle (16 bits) */
6938 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6939 offset += 2;
6940 /* lbtCWR_Rst (1 bit) */
6941 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6942 /* reserved (7 bits) */
6943 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6944 break;
6945
6946 default:
6947 /* Unhandled! */
6948 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6949 "laaMsgType %u not supported by dissector",
6950 laa_msg_type);
6951
6952 break;
6953 }
6954 /* For now just skip indicated length of bytes */
6955 offset = payload_offset + 4*(laa_msg_len+1);
6956 }
6957
6958
6959 /* Dissect each C section */
6960 for (uint32_t i = 0; i < nSections; ++i) {
6961 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6962 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6963 protocol_item,
6964 subframeId, frameId, slotId, startSymbolId,
6965 bit_width, ci_comp_method, ci_comp_opt,
6966 num_sinr_per_prb);
6967 }
6968
6969 /* Expert error if we are short of tvb by > 3 bytes */
6970 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6971 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6972 "%u bytes remain at end of frame - should be 0-3",
6973 tvb_reported_length_remaining(tvb, offset));
6974 }
6975
6976 if (PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && result) {
6977 /* Show list of frames that have corresponding U-plane data */
6978 wmem_list_frame_t *list_frame;
6979 for (list_frame = wmem_list_head(result->u_plane_frames); list_frame != NULL((void*)0); list_frame = wmem_list_frame_next(list_frame)) {
6980 corresponding_uplane_frame *frame = wmem_list_frame_data(list_frame);
6981 proto_item *uplane_frame_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frame, tvb, 0, 0,
6982 frame->frame_number);
6983 proto_item_append_text(uplane_frame_ti, " sectionId:%2u symbol:%2u PRBs %3u->%3u (in %uus)",
6984 frame->sectionId, frame->symbol, frame->startPrbu, frame->startPrbu+frame->numPrbu-1, frame->gap_in_usecs);
6985 proto_item_set_generated(uplane_frame_ti);
6986 }
6987 /* Also show total number of corresponding u-plane frames */
6988 proto_item *uplane_frame_count_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frames_total, tvb, 0, 0,
6989 wmem_list_count(result->u_plane_frames));
6990 proto_item_set_generated(uplane_frame_count_ti);
6991 }
6992
6993 return tvb_captured_length(tvb);
6994}
6995
6996static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6997 unsigned sample_number, int samples_offset,
6998 oran_tap_info *tap_info,
6999 unsigned sample_bit_width,
7000 int comp_meth,
7001 uint32_t exponent,
7002 section_mod_compr_config_t *mod_compr_params,
7003 uint8_t re)
7004{
7005 /* I */
7006 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7007 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7008 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7009 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
7010 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
7011 samples_offset += sample_bit_width;
7012 /* Q */
7013 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7014 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7015 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7016 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
7017 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
7018 samples_offset += sample_bit_width;
7019
7020 /* Update RE stats */
7021 tap_info->num_res++;
7022 /* if (i_value == 0.0 && q_value == 0.0) { */
7023 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
7024 if (i_bits == 0 && q_bits == 0) {
7025 tap_info->num_res_zero++;
7026 }
7027 else {
7028 tap_info->non_zero_re_in_current_prb = true1;
7029 }
7030 return samples_offset;
7031}
7032
7033
7034static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
7035{
7036 if (!udcomplen_heuristic_result_set) {
7037 /* All sections will start the same way */
7038 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
7039
7040 /* Move offset back to the start of the section */
7041 offset -= section_bytes_before_field;
7042
7043 do {
7044 /* This field appears several bytes into the U-plane section */
7045 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
7046 /* Are there enough bytes to still read the length field? */
7047 if (section_bytes_before_field+2 > length_remaining) {
7048 udcomplen_heuristic_result = false0;
7049 udcomplen_heuristic_result_set = true1;
7050 break;
7051 }
7052
7053 /* Read the length field */
7054 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
7055
7056 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
7057 * Could take into account numPrbU, etc */
7058 if (udcomplen < section_bytes_before_field+2) {
7059 udcomplen_heuristic_result = false0;
7060 udcomplen_heuristic_result_set = true1;
7061 break;
7062 }
7063
7064 /* Does this section fit into the frame? */
7065 if (udcomplen > length_remaining) {
7066 udcomplen_heuristic_result = false0;
7067 udcomplen_heuristic_result_set = true1;
7068 break;
7069 }
7070
7071 /* Move past this section */
7072 offset += udcomplen;
7073
7074 /* Are we at the end of the frame? */
7075 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
7076 if (tvb_reported_length_remaining(tvb, offset) < 4) {
7077 udcomplen_heuristic_result = true1;
7078 udcomplen_heuristic_result_set = true1;
7079 }
7080 } while (!udcomplen_heuristic_result_set);
7081 }
7082 return udcomplen_heuristic_result;
7083}
7084
7085static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
7086{
7087 if (tvb_captured_length_remaining(tvb, offset) < 2) {
7088 return false0;
7089 }
7090 uint8_t first_byte = tvb_get_uint8(tvb, offset);
7091 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
7092
7093 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
7094 /* - meth should be 0-8 */
7095 /* - reserved byte should be 0 */
7096 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
7097}
7098
7099static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
7100{
7101 /* Should really not happen, but guard against this anyway. */
7102 if (flow == NULL((void*)0)) {
7103 /* No state to update. */
7104 return false0;
7105 }
7106
7107 if (direction == DIR_UPLINK0) {
7108 if (flow->udcomphdrUplink_heuristic_result_set) {
7109 /* Return cached value */
7110 return flow->udcomphdrUplink_heuristic_result;
7111 }
7112 else {
7113 /* Work it out, and save answer for next time */
7114 flow->udcomphdrUplink_heuristic_result_set = true1;
7115 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
7116 return flow->udcomphdrUplink_heuristic_result;
7117 }
7118 }
7119 else {
7120 /* Downlink */
7121 if (flow->udcomphdrDownlink_heuristic_result_set) {
7122 /* Return cached value */
7123 return flow->udcomphdrDownlink_heuristic_result;
7124 }
7125 else {
7126 /* Work it out, and save answer for next time */
7127 flow->udcomphdrDownlink_heuristic_result_set = true1;
7128 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
7129 return flow->udcomphdrDownlink_heuristic_result;
7130 }
7131 }
7132}
7133
7134static bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
7135{
7136 /* Cast parameters to their types */
7137 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
7138 expected_section_data_t *result_value = (expected_section_data_t *)value;
7139 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
7140
7141 /* Deep copy of section data */
7142 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)))
;
7143 *copy = *result_value;
7144
7145 /* Add into result tree */
7146 wmem_tree_insert32(result_tree, sectionId, copy);
7147
7148 return false0;
7149}
7150
7151/* User plane dissector (section 8) */
7152static int
7153dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7154 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
7155{
7156 /* Hidden filter for plane */
7157 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
7158 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
7159
7160 /* Set up structures needed to add the protocol subtree and manage it */
7161 unsigned offset = 0;
7162
7163 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
7164 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
7165
7166 tap_info->userplane = true1;
7167
7168 /* Create display subtree for the protocol */
7169 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
7170 proto_item_append_text(protocol_item, "-U");
7171 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
7172
7173 /* Transport header */
7174 /* Real-time control data / IQ data transfer message series identifier */
7175 uint16_t eAxC;
7176 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
7177 tap_info->eaxc = eAxC;
7178
7179 /* Update/report status of conversation */
7180 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
7181 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
7182
7183 flow_result_t *result = NULL((void*)0);
7184
7185 /* Message identifier */
7186 proto_item *seqIdItem;
7187 uint32_t seqId, subSeqId, e;
7188 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
7189
7190 /* Common header for time reference */
7191 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
7192 tvb, offset, 4, "", "Timing Header (");
7193 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
7194
7195 /* dataDirection */
7196 uint32_t direction;
7197 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
7198 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
7199 /* payloadVersion */
7200 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
7201 /* filterIndex */
7202 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7203 offset += 1;
7204
7205 int ref_a_offset = offset;
7206
7207 /* frameId */
7208 uint32_t frameId = 0;
7209 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7210 tap_info->frame = frameId;
7211 offset += 1;
7212
7213 /* subframeId */
7214 uint32_t subframeId = 0;
7215 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7216 /* slotId */
7217 uint32_t slotId = 0;
7218 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7219 tap_info->slot = slotId;
7220 offset++;
7221 /* symbolId */
7222 uint32_t symbolId = 0;
7223 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7224 offset++;
7225
7226 char id[16];
7227 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7228 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7229 proto_item_set_generated(pi);
7230
7231 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7232 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7233
7234 unsigned sample_bit_width;
7235 unsigned compression;
7236 int includeUdCompHeader;
7237
7238 /* Also lookup C-PLANE state (sent in opposite direction for UL) so may check current compression settings */
7239 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, direction
1.1
'direction' is not equal to 0
== 0);
7240 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7241
7242 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is not equal to 0
3
Taking false branch
7243 /* Create state/conversation if doesn't exist yet */
7244 if (!state) {
7245 /* Allocate new state */
7246 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7247 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7248 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
7249 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
7250 wmem_tree_insert32(flow_states_table, key, state);
7251 }
7252
7253 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7254 result->expected_sections = wmem_tree_new(wmem_file_scope());
7255 result->u_plane_frames = wmem_list_new(wmem_file_scope());
7256
7257 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7258
7259 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7260 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
7261 /* Store this result */
7262 result->unexpected_seq_number = true1;
7263 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7264 result->previous_frame = state->last_frame[direction];
7265 }
7266 /* Update sequence analysis state */
7267 state->last_frame[direction] = pinfo->num;
7268 state->last_frame_seen[direction] = true1;
7269 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7270 }
7271
7272 /* Show any issues associated with this frame number */
7273 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
4
Value assigned to 'result'
7274 if (result) {
5
Assuming 'result' is null
7275 if (result->unexpected_seq_number) {
7276 expert_add_info_format(pinfo, seqIdItem,
7277 (direction == DIR_UPLINK0) ?
7278 &ei_oran_uplane_unexpected_sequence_number_ul :
7279 &ei_oran_uplane_unexpected_sequence_number_dl,
7280 "Sequence number %u expected, but got %u",
7281 result->expected_sequence_number, seqId);
7282 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7283 /* TODO: could add previous/next frame (in seqId tree?) ? */
7284 }
7285 }
7286
7287 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7288 /* N.B., timing is relative to first seen frame,
7289 not some notion of the beginning of the slot from sync, offset by some timing.. */
7290 if (direction
5.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7291 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7292 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7293 /* Set state on first pass */
7294 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7295 if (!timing) {
7296 /* Allocate new state */
7297 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7298 timing->first_frame = pinfo->num;
7299 timing->first_frame_time = pinfo->abs_ts;
7300 timing->frames_seen_in_symbol = 1;
7301 timing->last_frame_in_symbol = pinfo->num;
7302 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7303 }
7304 else {
7305 /* Update existing state */
7306 timing->frames_seen_in_symbol++;
7307 timing->last_frame_in_symbol = pinfo->num;
7308 }
7309 }
7310 else {
7311 /* Subsequent passes - look up result */
7312 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7313 if (timing) { /* Really shouldn't fail! */
7314 if (timing->frames_seen_in_symbol > 1) {
7315 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7316 int seconds_between_packets = (int)
7317 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7318 int nseconds_between_packets =
7319 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7320
7321 /* Round to nearest microsecond. */
7322 uint32_t total_gap = (seconds_between_packets*1000000) +
7323 ((nseconds_between_packets+500) / 1000);
7324
7325 /* Show how long it has been */
7326 proto_item *ti = NULL((void*)0);
7327 if (pinfo->num != timing->first_frame) {
7328 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7329 proto_item_set_generated(ti);
7330 }
7331
7332 if (total_gap > us_allowed_for_ul_in_symbol) {
7333 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7334 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7335 total_gap, us_allowed_for_ul_in_symbol);
7336 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7337 }
7338
7339 /* Show how many frames were received */
7340 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7341 proto_item_set_generated(ti);
7342
7343 /* Link to first frame for this symbol */
7344 if (pinfo->num != timing->first_frame) {
7345 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7346 proto_item_set_generated(ti);
7347 }
7348
7349 /* And also last frame */
7350 if (pinfo->num != timing->last_frame_in_symbol) {
7351 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7352 proto_item_set_generated(ti);
7353 }
7354
7355 tap_info->ul_delay_in_us = total_gap;
7356 }
7357 }
7358 }
7359 }
7360
7361
7362 /* Look up preferences for samples */
7363 if (direction
5.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
6
Taking false branch
7364 sample_bit_width = pref_sample_bit_width_uplink;
7365 compression = pref_iqCompressionUplink;
7366 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7367 } else {
7368 sample_bit_width = pref_sample_bit_width_downlink;
7369 compression = pref_iqCompressionDownlink;
7370 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7371 }
7372
7373 /* If uplink, load any udCompHdr settings written by C-Plane */
7374 bool_Bool ud_cmp_hdr_cplane = false0;
7375 if (cplane_state && direction
7.1
'direction' is not equal to 0
== 0) {
7
Assuming 'cplane_state' is non-null
8
Taking false branch
7376 /* Initialise settings from udpCompHdr from C-Plane */
7377 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7378 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7379 compression = cplane_state->ul_ud_comp_hdr_compression;
7380 ud_cmp_hdr_cplane = true1;
7381 }
7382 }
7383
7384 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7385 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7386 if (sample_bit_width == 0) {
9
Assuming 'sample_bit_width' is not equal to 0
10
Taking false branch
7387 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7388 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7389 (direction == DIR_UPLINK0) ? 'U' : 'D',
7390 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7391 sample_bit_width);
7392 return offset;
7393 }
7394
7395 unsigned bytesLeft;
7396 unsigned number_of_sections = 0;
7397 unsigned nBytesPerPrb =0;
7398
7399 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_state) {
11
Assuming 'link_planes_together' is false
7400 /* Take a deep-copy of this state on first pass */
7401 wmem_tree_foreach(cplane_state->expected_sections[direction], copy_section_entry, result->expected_sections);
7402 }
7403
7404 /* Add each section (not from count, just keep parsing until payload used) */
7405 do {
7406 /* Section subtree */
7407 unsigned section_start_offset = offset;
7408 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7409 tvb, offset, 0, "", "Section");
7410 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7411
7412 /* Section Header fields (darker green part) */
7413
7414 /* sectionId */
7415 uint32_t sectionId = 0;
7416 proto_item *sectionId_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7417 if (sectionId == 4095) {
12
Assuming 'sectionId' is not equal to 4095
13
Taking false branch
7418 proto_item_append_text(sectionId_ti, " (not default coupling C/U planes using sectionId)");
7419 }
7420 offset++;
7421
7422 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
14
Assuming field 'num_section_ids' is >= MAX_SECTION_IDs
15
Taking false branch
7423 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7424 }
7425
7426 section_details_t *section_details = NULL((void*)0);
7427 corresponding_uplane_frame *details = NULL((void*)0);
7428
7429 /* Lookup corresponding C-plane frame/info */
7430 if (link_planes_together) {
16
Assuming 'link_planes_together' is true
17
Taking true branch
7431 if (cplane_state
17.1
'cplane_state' is not equal to NULL
!= NULL((void*)0)) {
18
Taking true branch
7432
7433 expected_section_data_t *section_data = NULL((void*)0);
7434 section_data = wmem_tree_lookup32(result->expected_sections, sectionId);
19
Access to field 'expected_sections' results in a dereference of a null pointer (loaded from variable 'result')
7435
7436 if (section_data) {
7437 /* Need to work out which of 2 entries is in use for this data frame */
7438 unsigned index_to_use = 0;
7439
7440 /* Does the first entry match the timing for this frame? */
7441 if (section_data->details[0].frame == frameId &&
7442 section_data->details[0].subframe == subframeId &&
7443 section_data->details[0].slot == slotId &&
7444 /* Check that symbolId is in range */
7445 section_data->details[0].startSymbol <= symbolId &&
7446 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7447
7448 index_to_use = 0;
7449 }
7450 else if (section_data->details[1].frame == frameId &&
7451 section_data->details[1].subframe == subframeId &&
7452 section_data->details[1].slot == slotId &&
7453 /* Check that symbolId is in range */
7454 section_data->details[1].startSymbol <= symbolId &&
7455 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7456
7457 index_to_use = 1;
7458 }
7459 else {
7460 /* There was a sectionId, but timing header didn't exactly match, so neither index may be used.. */
7461 index_to_use = 2; /* invalid value */
7462 /* Expert info */
7463 expert_add_info_format(NULL((void*)0), sectionId_ti,
7464 &ei_oran_cplane_entry_not_found,
7465 "C-plane entry for %s sectionId %u at timing header %u-%u-%u-%u",
7466 (direction) ? "DL" : "UL", sectionId,
7467 frameId, subframeId, slotId, symbolId);
7468 }
7469
7470 if (index_to_use <= 1) {
7471 section_details = &section_data->details[index_to_use];
7472
7473 /* Cplane frame number */
7474 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7475 section_details->frame_number);
7476 proto_item_set_generated(cplane_frame_ti);
7477
7478 /* usecs since cplane frame */
7479 time_t total_gap = 0;
7480
7481 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7482 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7483 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7484 }
7485
7486 if (total_gap > 0) {
7487 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);
7488 proto_item_set_generated(cplane_delta_ti);
7489 }
7490
7491 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7492 /* Look up 'result' for c-plane frame, and tell it about this frame.. */
7493 flow_result_t *cplane_result = wmem_tree_lookup32(flow_results_table, section_details->frame_number);
7494 if (!cplane_result) {
7495 cplane_result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7496 cplane_result->u_plane_frames = wmem_list_new(wmem_file_scope());
7497 wmem_tree_insert32(flow_results_table, section_details->frame_number, cplane_result);
7498 }
7499 /* PRB range filled in below.. */
7500
7501 details = wmem_new(wmem_file_scope(), corresponding_uplane_frame)((corresponding_uplane_frame*)wmem_alloc((wmem_file_scope()),
sizeof(corresponding_uplane_frame)))
;
7502 details->frame_number = pinfo->num;
7503 details->gap_in_usecs = (uint32_t)total_gap;
7504 details->sectionId = sectionId;
7505 details->symbol = symbolId;
7506
7507 wmem_list_append(cplane_result->u_plane_frames, details);
7508 }
7509 }
7510 }
7511 else {
7512 /* No section entry at all */
7513 expert_add_info_format(NULL((void*)0), sectionId_ti,
7514 &ei_oran_cplane_entry_not_found,
7515 "C-plane entry for %s sectionId %u not found",
7516 (direction) ? "DL" : "UL", sectionId);
7517 }
7518 }
7519 }
7520
7521 /* rb */
7522 uint32_t rb;
7523 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7524 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7525 uint8_t syminc;
7526 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7527 if (syminc) {
7528 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7529 }
7530 /* startPrbu */
7531 uint32_t startPrbu = 0;
7532 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7533 offset += 2;
7534
7535 /* numPrbu */
7536 uint32_t numPrbu = 0;
7537 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7538 offset += 1;
7539
7540 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && details) {
7541 details->startPrbu = startPrbu;
7542 details->numPrbu = (numPrbu) ? numPrbu : 273;
7543 }
7544
7545 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7546 uint32_t ud_comp_len = 0;
7547
7548 /* udCompHdr (if preferences indicate will be present) */
7549 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7550 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7551 if (included) {
7552 /* 7.5.2.10 */
7553 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7554 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7555 &compression, &ud_comp_meth_item, tap_info);
7556
7557 /* Not part of udCompHdr */
7558 uint32_t reserved;
7559 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7560 offset += 1;
7561 if (reserved != 0) {
7562 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7563 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7564 reserved);
7565 }
7566 }
7567 else {
7568 /* No fields to dissect - just showing comp values from prefs */
7569 /* iqWidth */
7570 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7571 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7572 proto_item_set_generated(iq_width_item);
7573
7574 /* udCompMethod */
7575 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7576 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7577 proto_item_set_generated(ud_comp_meth_item);
7578
7579 /* Point back to C-Plane, if used */
7580 /* TODO: doesn't work with multiple port mappings using SE10.. */
7581 if (ud_cmp_hdr_cplane) {
7582 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);
7583 proto_item_set_generated(cplane_ti);
7584 }
7585
7586 tap_info->compression_methods |= (1 << compression);
7587 tap_info->compression_width = sample_bit_width;
7588 }
7589
7590 /* Consider fragmentation after first section header */
7591 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7592
7593 /* Set fragmented flag. */
7594 bool_Bool save_fragmented = pinfo->fragmented;
7595 pinfo->fragmented = true1;
7596 fragment_head *fh;
7597 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7598
7599 /* Add this fragment into reassembly table */
7600 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7601 frameId, subframeId, slotId, symbolId);
7602 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7603 reassembly_id, /* id */
7604 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7605 subSeqId, /* frag_number */
7606 frag_data_len, /* frag_data_len */
7607 !e, /* more_frags */
7608 0);
7609
7610 bool_Bool update_col_info = true1;
7611
7612 /* See if this completes an SDU */
7613 tvbuff_t *original_tvb = tvb;
7614 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7615 fh, &oran_frag_items,
7616 &update_col_info, oran_tree);
7617 if (next_tvb) {
7618 /* Have reassembled data */
7619 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7620 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7621 /* Dissection should resume at start of reassembled tvb */
7622 offset = 0;
7623 }
7624 /* Will continue with either reassembled tvb or NULL */
7625 tvb = next_tvb;
7626
7627 /* Restore fragmented flag */
7628 pinfo->fragmented = save_fragmented;
7629
7630 /* Don't dissect any more if not complete yet.. */
7631 if (tvb == NULL((void*)0)) {
7632 return tvb_captured_length(original_tvb);
7633 }
7634 }
7635
7636
7637 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7638 switch (compression) {
7639 case COMP_NONE0:
7640 case COMP_BLOCK_FP1:
7641 case BFP_AND_SELECTIVE_RE5:
7642 case COMP_MODULATION4:
7643 case MOD_COMPR_AND_SELECTIVE_RE6:
7644 break;
7645 default:
7646 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7647 "Compression method %u (%s) not supported by dissector",
7648 compression,
7649 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7650 }
7651
7652 /* udCompLen (when supported, methods 5,6,7,8) */
7653 if (compression >= BFP_AND_SELECTIVE_RE5) {
7654 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7655 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7656
7657 if (supported) {
7658 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7659 if (ud_comp_len <= 1) {
7660 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7661 }
7662 /* TODO: report if less than a viable section in frame? */
7663 /* Check that there is this much length left in the frame */
7664 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7665 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7666 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7667 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7668 }
7669 /* Actual length of section will be checked below, at the end of the section */
7670 offset += 2;
7671 }
7672 }
7673
7674 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7675 uint64_t sresmask1=0, sresmask2=0;
7676 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7677 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7678 {
7679 static int * const sres_mask1_2_flags[] = {
7680 &hf_oran_sReSMask1_2_re12,
7681 &hf_oran_sReSMask1_2_re11,
7682 &hf_oran_sReSMask1_2_re10,
7683 &hf_oran_sReSMask1_2_re9,
7684 &hf_oran_sReSMask_re8,
7685 &hf_oran_sReSMask_re7,
7686 &hf_oran_sReSMask_re6,
7687 &hf_oran_sReSMask_re5,
7688 &hf_oran_sReSMask_re4,
7689 &hf_oran_sReSMask_re3,
7690 &hf_oran_sReSMask_re2,
7691 &hf_oran_sReSMask_re1,
7692 NULL((void*)0)
7693 };
7694
7695 /* reserved (4 bits) */
7696 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7697 /* sReSMask1 (12 bits) */
7698 proto_item *sresmask_ti;
7699 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7700 hf_oran_sReSMask1,
7701 ett_oran_sresmask,
7702 sres_mask1_2_flags,
7703 ENC_NA0x00000000,
7704 &sresmask1);
7705 offset += 2;
7706 /* Count REs present */
7707 unsigned res = 0;
7708 for (unsigned n=0; n < 12; n++) {
7709 if ((sresmask1 >> n) & 0x1) {
7710 res++;
7711 }
7712 }
7713 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7714
7715
7716 /* reserved (4 bits) */
7717 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7718 /* sReSMask2 (12 bits) */
7719 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7720 hf_oran_sReSMask2,
7721 ett_oran_sresmask,
7722 sres_mask1_2_flags,
7723 ENC_NA0x00000000,
7724 &sresmask2);
7725 offset += 2;
7726
7727 if (rb == 1) {
7728 proto_item_append_text(sresmask_ti, " (ignored)");
7729 if (sresmask2 != 0) {
7730 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7731 }
7732 }
7733 else {
7734 /* Count REs present */
7735 res = 0;
7736 for (unsigned n=0; n < 12; n++) {
7737 if ((sresmask2 >> n) & 0x1) {
7738 res++;
7739 }
7740 }
7741 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7742 }
7743 }
7744
7745 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7746
7747 /* TODO: should this use the same pref as c-plane? */
7748 if (numPrbu == 0) {
7749 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7750 numPrbu = pref_data_plane_section_total_rbs;
7751 startPrbu = 0; /* may already be 0... */
7752 }
7753
7754 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_state, sectionId);
7755
7756 /* Add each PRB */
7757 for (unsigned i = 0; i < numPrbu; i++) {
7758 /* Create subtree */
7759 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7760 tvb, offset, 0,
7761 "", "PRB");
7762 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7763 uint32_t exponent = 0;
7764 uint16_t sresmask = 0;
7765
7766 /* udCompParam (depends upon compression method) */
7767 int before = offset;
7768 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7769 int udcompparam_len = offset-before;
7770
7771 /* Show PRB number in root */
7772 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7773
7774 /* Work out how many REs / PRB */
7775 unsigned res_per_prb = 12;
7776 uint16_t sresmask_to_use = 0x0fff;
7777
7778 if (compression >= BFP_AND_SELECTIVE_RE5) {
7779 /* Work out which mask should be used */
7780 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7781 /* Selective RE cases, use value from compModParam */
7782 sresmask_to_use = (uint16_t)sresmask;
7783 }
7784 else {
7785 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7786 if (rb==1 || (i%2)==0) {
7787 /* Even values */
7788 sresmask_to_use = (uint16_t)sresmask1;
7789 }
7790 else {
7791 /* Odd values */
7792 sresmask_to_use = (uint16_t)sresmask2;
7793 }
7794 }
7795
7796 /* Count REs present using sresmask */
7797 res_per_prb = 0;
7798 /* Use sresmask to pick out which REs are present */
7799 for (unsigned n=0; n<12; n++) {
7800 if (sresmask_to_use & (1<<n)) {
7801 res_per_prb++;
7802 }
7803 }
7804 }
7805
7806 /* N.B. bytes for samples need to be padded out to next byte
7807 (certainly where there aren't 12 REs in PRB..) */
7808 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7809 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7810
7811 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7812
7813 if (section_details) {
7814 if ((startPrbu + i*(1+rb)) < 273) {
7815 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7816 section_details->beamIds[startPrbu + i*(1+rb)]);
7817 proto_item_set_generated(beamid_ti);
7818 }
7819 }
7820
7821
7822 tap_info->non_zero_re_in_current_prb = false0;
7823
7824 /* Optionally trying to show I/Q RE values */
7825 if (pref_showIQSampleValues) {
7826 /* Individual values */
7827 unsigned samples_offset = offset*8;
7828 unsigned samples_start = offset;
7829 unsigned samples = 0;
7830
7831 if (compression >= BFP_AND_SELECTIVE_RE5) {
7832 /* Use sresmask to pick out which REs are present */
7833 for (unsigned n=1; n<=12; n++) {
7834 if (sresmask_to_use & (1<<(n-1))) {
7835 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7836 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7837 samples++;
7838 }
7839 }
7840 }
7841 else {
7842 /* All 12 REs are present */
7843 for (unsigned n=1; n<=12; n++) {
7844 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7845 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7846 samples++;
7847 }
7848 }
7849 proto_item_append_text(prbHeading, " (%u REs)", samples);
7850 if (section_details) {
7851 if ((startPrbu + i*(1+rb)) < 273) {
7852 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7853 }
7854 }
7855
7856 /* Was this PRB all zeros? */
7857 if (!tap_info->non_zero_re_in_current_prb) {
7858 tap_info->num_prbs_zero++;
7859 /* Add a filter to make zero-valued PRBs more findable */
7860 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7861 samples_start, nBytesForSamples, ENC_NA0x00000000);
7862 proto_item_set_hidden(zero_ti);
7863 proto_item_append_text(prbHeading, " (all zeros)");
7864 }
7865 else {
7866 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7867 proto_item_set_hidden(nonzero_ti);
7868 }
7869 }
7870
7871 tap_info->num_prbs++;
7872
7873
7874 /* Advance past samples */
7875 offset += nBytesForSamples;
7876
7877 /* Set end of prb subtree */
7878 proto_item_set_end(prbHeading, tvb, offset);
7879 }
7880
7881 /* Set extent of section */
7882 proto_item_set_len(sectionHeading, offset-section_start_offset);
7883 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7884 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7885 "udCompLen indicates %u bytes in section, but dissected %u instead",
7886 ud_comp_len, offset-section_start_offset);
7887 }
7888
7889 bytesLeft = tvb_captured_length(tvb) - offset;
7890 number_of_sections++;
7891 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7892
7893 /* Show number of sections found */
7894 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7895 proto_item_set_generated(ti);
7896
7897 /* Expert error if we are short of tvb by > 3 bytes */
7898 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7899 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7900 "%u bytes remain at end of frame - should be 0-3",
7901 tvb_reported_length_remaining(tvb, offset));
7902 }
7903
7904 return tvb_captured_length(tvb);
7905}
7906
7907
7908/**********************************************************************/
7909/* Main dissection function. */
7910/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7911static int
7912dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7913{
7914 uint32_t ecpri_message_type = *(uint32_t *)data;
7915 unsigned offset = 0;
7916
7917 /* Allocate and zero tap struct */
7918 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
)))
;
7919 tap_info->pdu_size = pinfo->fd->pkt_len;
7920 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7921
7922 switch (ecpri_message_type) {
7923 case ECPRI_MT_IQ_DATA0:
7924 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7925 break;
7926 case ECPRI_MT_RT_CTRL_DATA2:
7927 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7928 break;
7929 default:
7930 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7931 return 0;
7932 }
7933
7934 tap_queue_packet(oran_tap, pinfo, tap_info);
7935
7936 return offset;
7937}
7938
7939static void oran_init_protocol(void)
7940{
7941 udcomplen_heuristic_result_set = false0;
7942 udcomplen_heuristic_result = false0;
7943}
7944
7945
7946/* Register the protocol with Wireshark. */
7947void
7948proto_register_oran(void)
7949{
7950 static hf_register_info hf[] = {
7951
7952 /* Section 5.1.3.2.7 */
7953 { &hf_oran_du_port_id,
7954 { "DU Port ID", "oran_fh_cus.du_port_id",
7955 FT_UINT16, BASE_DEC,
7956 NULL((void*)0), 0x0,
7957 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7958 },
7959
7960 /* Section 5.1.3.2.7 */
7961 { &hf_oran_bandsector_id,
7962 { "BandSector ID", "oran_fh_cus.bandsector_id",
7963 FT_UINT16, BASE_DEC,
7964 NULL((void*)0), 0x0,
7965 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7966 },
7967
7968 /* Section 5.1.3.2.7 */
7969 { &hf_oran_cc_id,
7970 { "CC ID", "oran_fh_cus.cc_id",
7971 FT_UINT16, BASE_DEC,
7972 NULL((void*)0), 0x0,
7973 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7974 },
7975
7976 /* Section 5.1.3.2.7 */
7977 { &hf_oran_ru_port_id,
7978 { "RU Port ID", "oran_fh_cus.ru_port_id",
7979 FT_UINT16, BASE_DEC,
7980 NULL((void*)0), 0x0,
7981 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7982 },
7983
7984 /* Section 5.1.3.2.8 */
7985 { &hf_oran_sequence_id,
7986 { "Sequence ID", "oran_fh_cus.sequence_id",
7987 FT_UINT8, BASE_DEC,
7988 NULL((void*)0), 0x0,
7989 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7990 },
7991
7992 /* Section 5.1.3.2.8 */
7993 { &hf_oran_e_bit,
7994 { "E Bit", "oran_fh_cus.e_bit",
7995 FT_UINT8, BASE_DEC,
7996 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7997 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7998 },
7999
8000 /* Section 5.1.3.2.8 */
8001 { &hf_oran_subsequence_id,
8002 { "Subsequence ID", "oran_fh_cus.subsequence_id",
8003 FT_UINT8, BASE_DEC,
8004 NULL((void*)0), 0x7f,
8005 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8006 },
8007
8008 { &hf_oran_previous_frame,
8009 { "Previous frame in stream", "oran_fh_cus.previous-frame",
8010 FT_FRAMENUM, BASE_NONE,
8011 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8012 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8013 },
8014
8015 /* Section 7.5.2.1 */
8016 { &hf_oran_data_direction,
8017 { "Data Direction", "oran_fh_cus.data_direction",
8018 FT_UINT8, BASE_DEC,
8019 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
8020 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8021 },
8022
8023 /* Section 7.5.2.2 */
8024 { &hf_oran_payload_version,
8025 { "Payload Version", "oran_fh_cus.payloadVersion",
8026 FT_UINT8, BASE_DEC,
8027 NULL((void*)0), 0x70,
8028 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8029 },
8030
8031 /* Section 7.5.2.3 */
8032 { &hf_oran_filter_index,
8033 { "Filter Index", "oran_fh_cus.filterIndex",
8034 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8035 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
8036 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8037 },
8038
8039 /* Section 7.5.2.4 */
8040 { &hf_oran_frame_id,
8041 { "Frame ID", "oran_fh_cus.frameId",
8042 FT_UINT8, BASE_DEC,
8043 NULL((void*)0), 0x0,
8044 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8045 },
8046
8047 /* Section 7.5.2.5 */
8048 { &hf_oran_subframe_id,
8049 { "Subframe ID", "oran_fh_cus.subframe_id",
8050 FT_UINT8, BASE_DEC,
8051 NULL((void*)0), 0xf0,
8052 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8053 },
8054
8055 /* Section 7.5.2.6 */
8056 { &hf_oran_slot_id,
8057 { "Slot ID", "oran_fh_cus.slotId",
8058 FT_UINT16, BASE_DEC,
8059 NULL((void*)0), 0x0fc0,
8060 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8061 },
8062
8063 /* Generated for convenience */
8064 { &hf_oran_slot_within_frame,
8065 { "Slot within frame", "oran_fh_cus.slot-within-frame",
8066 FT_UINT16, BASE_DEC,
8067 NULL((void*)0), 0x0,
8068 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8069 },
8070
8071 /* Section 7.5.2.7 */
8072 { &hf_oran_start_symbol_id,
8073 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
8074 FT_UINT8, BASE_DEC,
8075 NULL((void*)0), 0x3f,
8076 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8077 },
8078
8079 /* Section 7.5.2.8 */
8080 { &hf_oran_numberOfSections,
8081 { "Number of Sections", "oran_fh_cus.numberOfSections",
8082 FT_UINT8, BASE_DEC,
8083 NULL((void*)0), 0x0,
8084 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8085 },
8086
8087 /* Section 7.5.2.9 */
8088 { &hf_oran_sectionType,
8089 { "Section Type", "oran_fh_cus.sectionType",
8090 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8091 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
8092 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8093 },
8094
8095 /* Section 7.5.2.10 */
8096 { &hf_oran_udCompHdr,
8097 { "udCompHdr", "oran_fh_cus.udCompHdr",
8098 FT_STRING, BASE_NONE,
8099 NULL((void*)0), 0x0,
8100 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8101 },
8102
8103 /* Section 7.5.2.11 */
8104 { &hf_oran_numberOfUEs,
8105 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
8106 FT_UINT8, BASE_DEC,
8107 NULL((void*)0), 0x0,
8108 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8109 },
8110
8111 /* Section 7.5.2.12 */
8112 { &hf_oran_timeOffset,
8113 { "Time Offset", "oran_fh_cus.timeOffset",
8114 FT_UINT16, BASE_DEC,
8115 NULL((void*)0), 0x0,
8116 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8117 },
8118
8119 /* Section 7.5.2.13 */
8120 { &hf_oran_frameStructure_fft,
8121 { "FFT Size", "oran_fh_cus.frameStructure.fft",
8122 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8123 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
8124 "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) }
8125 },
8126
8127 /* Section 7.5.2.13 */
8128 { &hf_oran_frameStructure_subcarrier_spacing,
8129 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
8130 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8131 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
8132 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
8133 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8134 },
8135
8136 /* Section 7.5.2.14 */
8137 { &hf_oran_cpLength,
8138 { "cpLength", "oran_fh_cus.cpLength",
8139 FT_UINT16, BASE_DEC,
8140 NULL((void*)0), 0x0,
8141 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8142 },
8143
8144 { &hf_oran_timing_header,
8145 { "Timing Header", "oran_fh_cus.timingHeader",
8146 FT_STRING, BASE_NONE,
8147 NULL((void*)0), 0x0,
8148 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8149 },
8150
8151 /* Section 7.5.3.1 */
8152 { &hf_oran_section_id,
8153 { "sectionId", "oran_fh_cus.sectionId",
8154 FT_UINT16, BASE_DEC,
8155 NULL((void*)0), 0xfff0,
8156 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8157 },
8158
8159 /* Section 7.5.3.2 */
8160 { &hf_oran_rb,
8161 { "rb", "oran_fh_cus.rb",
8162 FT_UINT8, BASE_DEC,
8163 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
8164 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8165 },
8166
8167 /* Section 7.5.5.3 */
8168 { &hf_oran_symInc,
8169 { "symInc", "oran_fh_cus.symInc",
8170 FT_UINT8, BASE_DEC,
8171 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
8172 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8173 },
8174
8175 /* Section 7.5.3.4 */
8176 { &hf_oran_startPrbc,
8177 { "startPrbc", "oran_fh_cus.startPrbc",
8178 FT_UINT16, BASE_DEC,
8179 NULL((void*)0), 0x03ff,
8180 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8181 },
8182
8183 /* Section 7.5.3.5 */
8184 { &hf_oran_reMask_re1,
8185 { "RE 1", "oran_fh_cus.reMask-RE1",
8186 FT_BOOLEAN, 16,
8187 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
8188 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8189 },
8190 { &hf_oran_reMask_re2,
8191 { "RE 2", "oran_fh_cus.reMask-RE2",
8192 FT_BOOLEAN, 16,
8193 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
8194 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8195 },
8196 { &hf_oran_reMask_re3,
8197 { "RE 3", "oran_fh_cus.reMask-RE3",
8198 FT_BOOLEAN, 16,
8199 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
8200 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8201 },
8202 { &hf_oran_reMask_re4,
8203 { "RE 4", "oran_fh_cus.reMask-RE4",
8204 FT_BOOLEAN, 16,
8205 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
8206 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8207 },
8208 { &hf_oran_reMask_re5,
8209 { "RE 5", "oran_fh_cus.reMask-RE5",
8210 FT_BOOLEAN, 16,
8211 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
8212 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8213 },
8214 { &hf_oran_reMask_re6,
8215 { "RE 6", "oran_fh_cus.reMask-RE6",
8216 FT_BOOLEAN, 16,
8217 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
8218 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8219 },
8220 { &hf_oran_reMask_re7,
8221 { "RE 7", "oran_fh_cus.reMask-RE7",
8222 FT_BOOLEAN, 16,
8223 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
8224 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8225 },
8226 { &hf_oran_reMask_re8,
8227 { "RE 8", "oran_fh_cus.reMask-RE8",
8228 FT_BOOLEAN, 16,
8229 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
8230 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8231 },
8232 { &hf_oran_reMask_re9,
8233 { "RE 9", "oran_fh_cus.reMask-RE9",
8234 FT_BOOLEAN, 16,
8235 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
8236 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8237 },
8238 { &hf_oran_reMask_re10,
8239 { "RE 10", "oran_fh_cus.reMask-RE10",
8240 FT_BOOLEAN, 16,
8241 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8242 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8243 },
8244 { &hf_oran_reMask_re11,
8245 { "RE 11", "oran_fh_cus.reMask-RE11",
8246 FT_BOOLEAN, 16,
8247 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8248 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8249 },
8250 { &hf_oran_reMask_re12,
8251 { "RE 12", "oran_fh_cus.reMask-RE12",
8252 FT_BOOLEAN, 16,
8253 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8254 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8255 },
8256 { &hf_oran_reMask,
8257 { "RE Mask", "oran_fh_cus.reMask",
8258 FT_UINT16, BASE_HEX,
8259 NULL((void*)0), 0xfff0,
8260 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8261 },
8262
8263 /* Section 7.5.3.6 */
8264 { &hf_oran_numPrbc,
8265 { "numPrbc", "oran_fh_cus.numPrbc",
8266 FT_UINT8, BASE_DEC,
8267 NULL((void*)0), 0x0,
8268 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8269 },
8270 /* Section 7.5.3.7 */
8271 { &hf_oran_numSymbol,
8272 { "Number of Symbols", "oran_fh_cus.numSymbol",
8273 FT_UINT8, BASE_DEC,
8274 NULL((void*)0), 0x0f,
8275 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8276 },
8277 /* Section 7.5.3.8 */
8278 { &hf_oran_ef,
8279 { "Extension Flag", "oran_fh_cus.ef",
8280 FT_BOOLEAN, 8,
8281 NULL((void*)0), 0x80,
8282 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8283 },
8284 /* Section 7.5.3.9 */
8285 { &hf_oran_beamId,
8286 { "Beam ID", "oran_fh_cus.beamId",
8287 FT_UINT16, BASE_DEC,
8288 NULL((void*)0), 0x7fff,
8289 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8290 },
8291
8292 { &hf_oran_extension,
8293 { "Extension", "oran_fh_cus.extension",
8294 FT_STRING, BASE_NONE,
8295 NULL((void*)0), 0x0,
8296 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8297 },
8298
8299 /* Section 7.6.2.1 */
8300 { &hf_oran_exttype,
8301 { "extType", "oran_fh_cus.extType",
8302 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8303 &exttype_vals_ext, 0x7f,
8304 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8305 },
8306
8307 /* Section 7.6.2.3 */
8308 { &hf_oran_extlen,
8309 { "extLen", "oran_fh_cus.extLen",
8310 FT_UINT16, BASE_DEC,
8311 NULL((void*)0), 0x0,
8312 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8313 },
8314
8315 /* Section 7.7.1 */
8316 { &hf_oran_bfw,
8317 { "bfw", "oran_fh_cus.bfw",
8318 FT_STRING, BASE_NONE,
8319 NULL((void*)0), 0x0,
8320 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8321 },
8322 { &hf_oran_bfw_bundle,
8323 { "Bundle", "oran_fh_cus.bfw.bundle",
8324 FT_STRING, BASE_NONE,
8325 NULL((void*)0), 0x0,
8326 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8327 },
8328 { &hf_oran_bfw_bundle_id,
8329 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8330 FT_UINT32, BASE_DEC,
8331 NULL((void*)0), 0x0,
8332 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8333 },
8334 /* Section 7.7.1.4 */
8335 { &hf_oran_bfw_i,
8336 { "bfwI", "oran_fh_cus.bfwI",
8337 FT_FLOAT, BASE_NONE,
8338 NULL((void*)0), 0x0,
8339 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8340 },
8341 /* Section 7.7.1.5 */
8342 { &hf_oran_bfw_q,
8343 { "bfwQ", "oran_fh_cus.bfwQ",
8344 FT_FLOAT, BASE_NONE,
8345 NULL((void*)0), 0x0,
8346 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8347 },
8348
8349 /* Section 7.5.3.10 */
8350 { &hf_oran_ueId,
8351 { "UE ID", "oran_fh_cus.ueId",
8352 FT_UINT16, BASE_DEC,
8353 NULL((void*)0), 0x7fff,
8354 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8355 },
8356 /* Section 7.5.3.11 */
8357 { &hf_oran_freqOffset,
8358 { "Frequency Offset", "oran_fh_cus.freqOffset",
8359 FT_UINT24, BASE_DEC,
8360 NULL((void*)0), 0x0,
8361 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8362 },
8363
8364 /* Section 7.5.3.12 */
8365 { &hf_oran_regularizationFactor,
8366 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8367 FT_INT16, BASE_DEC,
8368 NULL((void*)0), 0x0,
8369 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8370 },
8371 /* Section 7.5.3.14 */
8372 { &hf_oran_laaMsgType,
8373 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8374 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8375 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8376 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8377 },
8378 /* Section 7.5.3.15 */
8379 { &hf_oran_laaMsgLen,
8380 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8381 FT_UINT8, BASE_DEC,
8382 NULL((void*)0), 0x0f,
8383 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8384 },
8385 /* Section 7.5.3.16 */
8386 { &hf_oran_lbtHandle,
8387 { "LBT Handle", "oran_fh_cus.lbtHandle",
8388 FT_UINT16, BASE_HEX,
8389 NULL((void*)0), 0x0,
8390 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8391 },
8392 /* Section 7.5.3.17 */
8393 { &hf_oran_lbtDeferFactor,
8394 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8395 FT_UINT8, BASE_DEC,
8396 NULL((void*)0), 0x07,
8397 "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)}
8398 },
8399 /* Section 7.5.3.18 */
8400 { &hf_oran_lbtBackoffCounter,
8401 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8402 FT_UINT16, BASE_DEC,
8403 NULL((void*)0), 0xffc0,
8404 "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)}
8405 },
8406 /* Section 7.5.3.19 */
8407 { &hf_oran_lbtOffset,
8408 { "LBT Offset", "oran_fh_cus.lbtOffset",
8409 FT_UINT16, BASE_DEC,
8410 NULL((void*)0), 0xffc0,
8411 "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)}
8412 },
8413 /* Section 7.5.3.20 */
8414 { &hf_oran_MCOT,
8415 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8416 FT_UINT8, BASE_DEC,
8417 NULL((void*)0), 0x3c,
8418 "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)}
8419 },
8420 /* Section 7.5.3.21 */
8421 { &hf_oran_lbtMode,
8422 { "LBT Mode", "oran_fh_cus.lbtMode",
8423 FT_UINT8, BASE_DEC,
8424 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8425 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8426 },
8427 /* Section 7.5.3.22 */
8428 { &hf_oran_lbtPdschRes,
8429 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8430 FT_UINT8, BASE_DEC,
8431 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8432 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8433 },
8434 /* Section 7.5.3.23 */
8435 { &hf_oran_sfStatus,
8436 { "sfStatus", "oran_fh_cus.sfStatus",
8437 FT_BOOLEAN, 8,
8438 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8439 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8440 },
8441 /* Section 7.5.3.24 */
8442 { &hf_oran_lbtDrsRes,
8443 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8444 FT_BOOLEAN, 8,
8445 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8446 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8447 },
8448 /* Section 7.5.3.25 */
8449 { &hf_oran_initialPartialSF,
8450 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8451 FT_BOOLEAN, 8,
8452 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8453 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8454 },
8455 /* Section 7.5.3.26. */
8456 { &hf_oran_lbtBufErr,
8457 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8458 FT_BOOLEAN, 8,
8459 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8460 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8461 },
8462 /* Section 7.5.3.27 */
8463 { &hf_oran_sfnSfEnd,
8464 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8465 FT_UINT16, BASE_DEC,
8466 NULL((void*)0), 0x0fff,
8467 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8468 },
8469 /* Section 7.5.3.28 */
8470 { &hf_oran_lbtCWConfig_H,
8471 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8472 FT_UINT8, BASE_DEC,
8473 NULL((void*)0), 0x0,
8474 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8475 },
8476 /* Section 7.5.3.29 */
8477 { &hf_oran_lbtCWConfig_T,
8478 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8479 FT_UINT8, BASE_DEC,
8480 NULL((void*)0), 0x0,
8481 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8482 },
8483 /* Section 7.5.3.30 */
8484 { &hf_oran_lbtTrafficClass,
8485 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8486 FT_UINT8, BASE_DEC,
8487 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8488 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8489 },
8490 /* Section 7.5.3.31 */
8491 { &hf_oran_lbtCWR_Rst,
8492 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8493 FT_BOOLEAN, 8,
8494 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8495 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8496 },
8497
8498 /* Reserved fields */
8499 { &hf_oran_reserved,
8500 { "reserved", "oran_fh_cus.reserved",
8501 FT_UINT64, BASE_HEX,
8502 NULL((void*)0), 0x0,
8503 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8504 },
8505 { &hf_oran_reserved_1bit,
8506 { "reserved", "oran_fh_cus.reserved",
8507 FT_UINT8, BASE_HEX,
8508 NULL((void*)0), 0x80,
8509 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8510 },
8511 { &hf_oran_reserved_2bits,
8512 { "reserved", "oran_fh_cus.reserved",
8513 FT_UINT8, BASE_HEX,
8514 NULL((void*)0), 0xc0,
8515 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8516 },
8517 { &hf_oran_reserved_3bits,
8518 { "reserved", "oran_fh_cus.reserved",
8519 FT_UINT8, BASE_HEX,
8520 NULL((void*)0), 0xe0,
8521 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8522 },
8523 { &hf_oran_reserved_4bits,
8524 { "reserved", "oran_fh_cus.reserved",
8525 FT_UINT8, BASE_HEX,
8526 NULL((void*)0), 0xf0,
8527 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8528 },
8529 { &hf_oran_reserved_last_4bits,
8530 { "reserved", "oran_fh_cus.reserved",
8531 FT_UINT8, BASE_HEX,
8532 NULL((void*)0), 0x0f,
8533 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8534 },
8535 { &hf_oran_reserved_last_5bits,
8536 { "reserved", "oran_fh_cus.reserved",
8537 FT_UINT8, BASE_HEX,
8538 NULL((void*)0), 0x1f,
8539 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8540 },
8541 { &hf_oran_reserved_6bits,
8542 { "reserved", "oran_fh_cus.reserved",
8543 FT_UINT8, BASE_HEX,
8544 NULL((void*)0), 0xfc,
8545 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8546 },
8547 { &hf_oran_reserved_last_6bits,
8548 { "reserved", "oran_fh_cus.reserved",
8549 FT_UINT8, BASE_HEX,
8550 NULL((void*)0), 0x3f,
8551 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8552 },
8553 { &hf_oran_reserved_7bits,
8554 { "reserved", "oran_fh_cus.reserved",
8555 FT_UINT8, BASE_HEX,
8556 NULL((void*)0), 0xfe,
8557 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8558 },
8559 { &hf_oran_reserved_last_7bits,
8560 { "reserved", "oran_fh_cus.reserved",
8561 FT_UINT8, BASE_HEX,
8562 NULL((void*)0), 0x7f,
8563 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8564 },
8565 { &hf_oran_reserved_8bits,
8566 { "reserved", "oran_fh_cus.reserved",
8567 FT_UINT8, BASE_HEX,
8568 NULL((void*)0), 0x0,
8569 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8570 },
8571 { &hf_oran_reserved_16bits,
8572 { "reserved", "oran_fh_cus.reserved",
8573 FT_UINT16, BASE_HEX,
8574 NULL((void*)0), 0x0,
8575 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8576 },
8577 { &hf_oran_reserved_15bits,
8578 { "reserved", "oran_fh_cus.reserved",
8579 FT_UINT16, BASE_HEX,
8580 NULL((void*)0), 0x7fff,
8581 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8582 },
8583 { &hf_oran_reserved_bit1,
8584 { "reserved", "oran_fh_cus.reserved",
8585 FT_UINT8, BASE_HEX,
8586 NULL((void*)0), 0x40,
8587 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8588 },
8589 { &hf_oran_reserved_bit2,
8590 { "reserved", "oran_fh_cus.reserved",
8591 FT_UINT8, BASE_HEX,
8592 NULL((void*)0), 0x20,
8593 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8594 },
8595 { &hf_oran_reserved_bit4,
8596 { "reserved", "oran_fh_cus.reserved",
8597 FT_UINT8, BASE_HEX,
8598 NULL((void*)0), 0x08,
8599 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8600 },
8601 { &hf_oran_reserved_bit5,
8602 { "reserved", "oran_fh_cus.reserved",
8603 FT_UINT8, BASE_HEX,
8604 NULL((void*)0), 0x04,
8605 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8606 },
8607 { &hf_oran_reserved_bits123,
8608 { "reserved", "oran_fh_cus.reserved",
8609 FT_UINT8, BASE_HEX,
8610 NULL((void*)0), 0x70,
8611 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8612 },
8613 { &hf_oran_reserved_bits456,
8614 { "reserved", "oran_fh_cus.reserved",
8615 FT_UINT8, BASE_HEX,
8616 NULL((void*)0), 0x0e,
8617 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8618 },
8619
8620 /* 7.7.11.9 */
8621 { &hf_oran_cont_ind,
8622 { "contInd", "oran_fh_cus.contInd",
8623 FT_BOOLEAN, 8,
8624 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8625 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8626 },
8627 /* 7.7.11.10 */
8628 { &hf_oran_bundle_offset,
8629 { "BundleOffset", "oran_fh_cus.bundleOffset",
8630 FT_UINT8, BASE_DEC,
8631 NULL((void*)0), 0x3f,
8632 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8633 },
8634
8635 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8636 { &hf_oran_bfwCompHdr,
8637 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8638 FT_STRING, BASE_NONE,
8639 NULL((void*)0), 0x0,
8640 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8641 },
8642 { &hf_oran_bfwCompHdr_iqWidth,
8643 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8644 FT_UINT8, BASE_HEX,
8645 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8646 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8647 },
8648 { &hf_oran_bfwCompHdr_compMeth,
8649 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8650 FT_UINT8, BASE_HEX,
8651 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8652 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8653 },
8654
8655 /* 7.5.3.32 */
8656 { &hf_oran_ciCompParam,
8657 { "ciCompParam", "oran_fh_cus.ciCompParam",
8658 FT_STRING, BASE_NONE,
8659 NULL((void*)0), 0x0,
8660 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8661 },
8662
8663 /* Table 7.5.3.32-1 */
8664 { &hf_oran_blockScaler,
8665 { "blockScaler", "oran_fh_cus.blockScaler",
8666 FT_UINT8, BASE_HEX,
8667 NULL((void*)0), 0x0,
8668 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8669 },
8670 { &hf_oran_compBitWidth,
8671 { "compBitWidth", "oran_fh_cus.compBitWidth",
8672 FT_UINT8, BASE_DEC,
8673 NULL((void*)0), 0xf0,
8674 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8675 },
8676 { &hf_oran_compShift,
8677 { "compShift", "oran_fh_cus.compShift",
8678 FT_UINT8, BASE_DEC,
8679 NULL((void*)0), 0x0f,
8680 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8681 },
8682
8683 { &hf_oran_active_beamspace_coefficient_n1,
8684 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8685 FT_BOOLEAN, 8,
8686 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8687 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8688 },
8689 { &hf_oran_active_beamspace_coefficient_n2,
8690 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8691 FT_BOOLEAN, 8,
8692 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8693 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8694 },
8695 { &hf_oran_active_beamspace_coefficient_n3,
8696 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8697 FT_BOOLEAN, 8,
8698 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8699 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8700 },
8701 { &hf_oran_active_beamspace_coefficient_n4,
8702 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8703 FT_BOOLEAN, 8,
8704 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8705 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8706 },
8707 { &hf_oran_active_beamspace_coefficient_n5,
8708 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8709 FT_BOOLEAN, 8,
8710 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8711 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8712 },
8713 { &hf_oran_active_beamspace_coefficient_n6,
8714 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8715 FT_BOOLEAN, 8,
8716 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8717 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8718 },
8719 { &hf_oran_active_beamspace_coefficient_n7,
8720 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8721 FT_BOOLEAN, 8,
8722 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8723 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8724 },
8725 { &hf_oran_active_beamspace_coefficient_n8,
8726 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8727 FT_BOOLEAN, 8,
8728 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8729 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8730 },
8731
8732 { &hf_oran_activeBeamspaceCoefficientMask,
8733 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8734 FT_UINT8, BASE_HEX,
8735 NULL((void*)0), 0xff,
8736 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8737 },
8738 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8739 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8740 FT_UINT32, BASE_DEC,
8741 NULL((void*)0), 0x0,
8742 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8743 },
8744
8745 /* Section 7.7.6.6 */
8746 { &hf_oran_se6_repetition,
8747 { "repetition", "oran_fh_cus.repetition",
8748 FT_BOOLEAN, BASE_NONE,
8749 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8750 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8751 },
8752 /* 7.7.20.9 */
8753 { &hf_oran_rbgSize,
8754 { "rbgSize", "oran_fh_cus.rbgSize",
8755 FT_UINT8, BASE_HEX,
8756 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8757 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8758 },
8759 /* 7.7.20.10 */
8760 { &hf_oran_rbgMask,
8761 { "rbgMask", "oran_fh_cus.rbgMask",
8762 FT_UINT32, BASE_HEX,
8763 NULL((void*)0), 0x0fffffff,
8764 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8765 },
8766 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8767 { &hf_oran_noncontig_priority,
8768 { "priority", "oran_fh_cus.priority",
8769 FT_UINT8, BASE_HEX,
8770 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8771 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8772 },
8773
8774 /* 7.7.6.4 */
8775 { &hf_oran_symbol_mask,
8776 { "symbolMask", "oran_fh_cus.symbolMask",
8777 FT_UINT16, BASE_HEX,
8778 NULL((void*)0), 0x3fff,
8779 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8780 },
8781 { &hf_oran_symbol_mask_s13,
8782 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8783 FT_BOOLEAN, 16,
8784 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8785 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8786 },
8787 { &hf_oran_symbol_mask_s12,
8788 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8789 FT_BOOLEAN, 16,
8790 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8791 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8792 },
8793 { &hf_oran_symbol_mask_s11,
8794 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8795 FT_BOOLEAN, 16,
8796 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8797 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8798 },
8799 { &hf_oran_symbol_mask_s10,
8800 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8801 FT_BOOLEAN, 16,
8802 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8803 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8804 },
8805 { &hf_oran_symbol_mask_s9,
8806 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8807 FT_BOOLEAN, 16,
8808 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8809 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8810 },
8811 { &hf_oran_symbol_mask_s8,
8812 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8813 FT_BOOLEAN, 16,
8814 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8815 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8816 },
8817 { &hf_oran_symbol_mask_s7,
8818 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8819 FT_BOOLEAN, 16,
8820 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8821 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8822 },
8823 { &hf_oran_symbol_mask_s6,
8824 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8825 FT_BOOLEAN, 16,
8826 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8827 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8828 },
8829 { &hf_oran_symbol_mask_s5,
8830 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8831 FT_BOOLEAN, 16,
8832 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8833 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8834 },
8835 { &hf_oran_symbol_mask_s4,
8836 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8837 FT_BOOLEAN, 16,
8838 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8839 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8840 },
8841 { &hf_oran_symbol_mask_s3,
8842 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8843 FT_BOOLEAN, 16,
8844 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8845 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8846 },
8847 { &hf_oran_symbol_mask_s2,
8848 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8849 FT_BOOLEAN, 16,
8850 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8851 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8852 },
8853 { &hf_oran_symbol_mask_s1,
8854 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8855 FT_BOOLEAN, 16,
8856 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8857 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8858 },
8859 { &hf_oran_symbol_mask_s0,
8860 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8861 FT_BOOLEAN, 16,
8862 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8863 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8864 },
8865
8866
8867 /* 7.7.22.2 */
8868 { &hf_oran_ack_nack_req_id,
8869 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8870 FT_UINT16, BASE_HEX,
8871 NULL((void*)0), 0x0,
8872 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8873 },
8874
8875 /* Subtree for next 2 items */
8876 { &hf_oran_frequency_range,
8877 { "Frequency Range", "oran_fh_cus.frequencyRange",
8878 FT_STRING, BASE_NONE,
8879 NULL((void*)0), 0x0,
8880 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8881 },
8882
8883 /* 7.7.12.4 */
8884 { &hf_oran_off_start_prb,
8885 { "offStartPrb", "oran_fh_cus.offStartPrb",
8886 FT_UINT8, BASE_DEC,
8887 NULL((void*)0), 0x0,
8888 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8889 },
8890 /* 7.7.12.5 */
8891 { &hf_oran_num_prb,
8892 { "numPrb", "oran_fh_cus.numPrb",
8893 FT_UINT8, BASE_DEC,
8894 NULL((void*)0), 0x0,
8895 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8896 },
8897
8898 /* symbolId 8.3.3.7 */
8899 { &hf_oran_symbolId,
8900 { "Symbol Identifier", "oran_fh_cus.symbolId",
8901 FT_UINT8, BASE_DEC,
8902 NULL((void*)0), 0x3f,
8903 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8904 },
8905
8906 /* startPrbu 8.3.3.11 */
8907 { &hf_oran_startPrbu,
8908 { "startPrbu", "oran_fh_cus.startPrbu",
8909 FT_UINT16, BASE_DEC,
8910 NULL((void*)0), 0x03ff,
8911 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8912 },
8913
8914 /* numPrbu 8.3.3.12 */
8915 { &hf_oran_numPrbu,
8916 { "numPrbu", "oran_fh_cus.numPrbu",
8917 FT_UINT8, BASE_DEC,
8918 NULL((void*)0), 0x0,
8919 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8920 },
8921
8922 /* 7.7.1.3 */
8923 { &hf_oran_bfwCompParam,
8924 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8925 FT_STRING, BASE_NONE,
8926 NULL((void*)0), 0x0,
8927 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8928 },
8929
8930 /* 6.3.3.13 */
8931 { &hf_oran_udCompHdrMeth,
8932 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8933 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8934 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8935 "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)}
8936 },
8937 { &hf_oran_udCompHdrMeth_pref,
8938 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8939 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8940 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8941 "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)}
8942 },
8943 /* 8.3.3.18 */
8944 { &hf_oran_udCompLen,
8945 { "udCompLen", "oran_fh_cus.udCompLen",
8946 FT_UINT16, BASE_DEC,
8947 NULL((void*)0), 0x0,
8948 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8949 },
8950
8951 /* 7.5.2.10 */
8952 { &hf_oran_udCompHdrIqWidth,
8953 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8954 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8955 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8956 "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)}
8957 },
8958 { &hf_oran_udCompHdrIqWidth_pref,
8959 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8960 FT_UINT8, BASE_DEC,
8961 NULL((void*)0), 0x0,
8962 "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)}
8963 },
8964
8965 { &hf_oran_sinrCompHdrIqWidth_pref,
8966 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8967 FT_UINT8, BASE_DEC,
8968 NULL((void*)0), 0x0,
8969 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8970 },
8971 { &hf_oran_sinrCompHdrMeth_pref,
8972 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8973 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8974 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8975 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8976 },
8977
8978 /* Section 8.3.3.15 (not always present - depends upon meth) */
8979 { &hf_oran_udCompParam,
8980 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8981 FT_STRING, BASE_NONE,
8982 NULL((void*)0), 0x0,
8983 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8984 },
8985 /* 8.3.3.18 */
8986 { &hf_oran_sReSMask,
8987 { "sReSMask", "oran_fh_cus.sReSMask",
8988 FT_UINT16, BASE_HEX,
8989 NULL((void*)0), 0xf0ff,
8990 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8991 },
8992
8993 { &hf_oran_sReSMask_re12,
8994 { "RE-12", "oran_fh_cus.sReSMask-re12",
8995 FT_BOOLEAN, 16,
8996 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8997 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8998 },
8999 { &hf_oran_sReSMask_re11,
9000 { "RE-11", "oran_fh_cus.sReSMask-re11",
9001 FT_BOOLEAN, 16,
9002 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
9003 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9004 },
9005 { &hf_oran_sReSMask_re10,
9006 { "RE-10", "oran_fh_cus.sReSMask-re10",
9007 FT_BOOLEAN, 16,
9008 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
9009 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9010 },
9011 { &hf_oran_sReSMask_re9,
9012 { "RE-9", "oran_fh_cus.sReSMask-re9",
9013 FT_BOOLEAN, 16,
9014 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
9015 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9016 },
9017 { &hf_oran_sReSMask_re8,
9018 { "RE-8", "oran_fh_cus.sReSMask-re8",
9019 FT_BOOLEAN, 16,
9020 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9021 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9022 },
9023 { &hf_oran_sReSMask_re7,
9024 { "RE-7", "oran_fh_cus.sReSMask-re7",
9025 FT_BOOLEAN, 16,
9026 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9027 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9028 },
9029 { &hf_oran_sReSMask_re6,
9030 { "RE-6", "oran_fh_cus.sReSMask-re6",
9031 FT_BOOLEAN, 16,
9032 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
9033 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9034 },
9035 { &hf_oran_sReSMask_re5,
9036 { "RE-5", "oran_fh_cus.sReSMask-re5",
9037 FT_BOOLEAN, 16,
9038 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
9039 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9040 },
9041 { &hf_oran_sReSMask_re4,
9042 { "RE-4", "oran_fh_cus.sReSMask-re4",
9043 FT_BOOLEAN, 16,
9044 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
9045 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9046 },
9047 { &hf_oran_sReSMask_re3,
9048 { "RE-3", "oran_fh_cus.sReSMask-re3",
9049 FT_BOOLEAN, 16,
9050 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
9051 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9052 },
9053 { &hf_oran_sReSMask_re2,
9054 { "RE-2", "oran_fh_cus.sReSMask-re2",
9055 FT_BOOLEAN, 16,
9056 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
9057 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9058 },
9059 { &hf_oran_sReSMask_re1,
9060 { "RE-1", "oran_fh_cus.sReSMask-re1",
9061 FT_BOOLEAN, 16,
9062 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
9063 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9064 },
9065
9066 /* 8.3.3.20 */
9067 { &hf_oran_sReSMask1,
9068 { "sReSMask1", "oran_fh_cus.sReSMask1",
9069 FT_UINT16, BASE_HEX,
9070 NULL((void*)0), 0x0fff,
9071 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9072 },
9073 /* 8.3.3.21 */
9074 { &hf_oran_sReSMask2,
9075 { "sReSMask2", "oran_fh_cus.sReSMask2",
9076 FT_UINT16, BASE_HEX,
9077 NULL((void*)0), 0x0fff,
9078 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9079 },
9080
9081 { &hf_oran_sReSMask1_2_re12,
9082 { "RE-12", "oran_fh_cus.sReSMask-re12",
9083 FT_BOOLEAN, 16,
9084 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9085 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9086 },
9087 { &hf_oran_sReSMask1_2_re11,
9088 { "RE-11", "oran_fh_cus.sReSMask-re11",
9089 FT_BOOLEAN, 16,
9090 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9091 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9092 },
9093 { &hf_oran_sReSMask1_2_re10,
9094 { "RE-10", "oran_fh_cus.sReSMask-re10",
9095 FT_BOOLEAN, 16,
9096 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9097 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9098 },
9099 { &hf_oran_sReSMask1_2_re9,
9100 { "RE-9", "oran_fh_cus.sReSMask-re9",
9101 FT_BOOLEAN, 16,
9102 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9103 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9104 },
9105
9106 /* Section 6.3.3.15 */
9107 { &hf_oran_iSample,
9108 { "iSample", "oran_fh_cus.iSample",
9109 FT_FLOAT, BASE_NONE,
9110 NULL((void*)0), 0x0,
9111 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9112 },
9113
9114 /* Section 6.3.3.16 */
9115 { &hf_oran_qSample,
9116 { "qSample", "oran_fh_cus.qSample",
9117 FT_FLOAT, BASE_NONE,
9118 NULL((void*)0), 0x0,
9119 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9120 },
9121
9122 { &hf_oran_exponent,
9123 { "Exponent", "oran_fh_cus.exponent",
9124 FT_UINT8, BASE_DEC,
9125 NULL((void*)0), 0x0f,
9126 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9127 },
9128
9129 { &hf_oran_iq_user_data,
9130 { "IQ User Data", "oran_fh_cus.iq_user_data",
9131 FT_BYTES, BASE_NONE,
9132 NULL((void*)0), 0x0,
9133 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9134 },
9135
9136
9137 { &hf_oran_u_section_ul_symbol_time,
9138 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
9139 FT_UINT32, BASE_DEC,
9140 NULL((void*)0), 0x0,
9141 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9142 },
9143 { &hf_oran_u_section_ul_symbol_frames,
9144 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
9145 FT_UINT32, BASE_DEC,
9146 NULL((void*)0), 0x0,
9147 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9148 },
9149 { &hf_oran_u_section_ul_symbol_first_frame,
9150 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
9151 FT_FRAMENUM, BASE_NONE,
9152 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9153 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9154 },
9155 { &hf_oran_u_section_ul_symbol_last_frame,
9156 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
9157 FT_FRAMENUM, BASE_NONE,
9158 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9159 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9160 },
9161
9162 { &hf_oran_c_eAxC_ID,
9163 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
9164 FT_STRING, BASE_NONE,
9165 NULL((void*)0), 0x0,
9166 "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) }
9167 },
9168
9169 { &hf_oran_refa,
9170 { "RefA", "oran_fh_cus.refa",
9171 FT_STRING, BASE_NONE,
9172 NULL((void*)0), 0x0,
9173 "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) }
9174 },
9175
9176
9177 /* Section 7.5.2.15 */
9178 { &hf_oran_ciCompHdr,
9179 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
9180 FT_STRING, BASE_NONE,
9181 NULL((void*)0), 0x0,
9182 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9183 },
9184 { &hf_oran_ciCompHdrMeth,
9185 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
9186 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9187 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
9188 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9189 },
9190 { &hf_oran_ciCompHdrIqWidth,
9191 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
9192 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9193 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
9194 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9195 },
9196 { &hf_oran_ciCompOpt,
9197 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
9198 FT_UINT8, BASE_DEC,
9199 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
9200 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9201 },
9202
9203 /* 7.7.11.7 */
9204 { &hf_oran_disable_bfws,
9205 { "disableBFWs", "oran_fh_cus.disableBFWs",
9206 FT_BOOLEAN, 8,
9207 NULL((void*)0), 0x80,
9208 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9209 },
9210 /* 7.7.11.8 */
9211 { &hf_oran_rad,
9212 { "RAD", "oran_fh_cus.rad",
9213 FT_BOOLEAN, 8,
9214 NULL((void*)0), 0x40,
9215 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9216 },
9217 /* 7.7.11.4 */
9218 { &hf_oran_num_bund_prbs,
9219 { "numBundPrb", "oran_fh_cus.numBundPrb",
9220 FT_UINT8, BASE_DEC,
9221 NULL((void*)0), 0x0,
9222 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9223 },
9224 { &hf_oran_beam_id,
9225 { "beamId", "oran_fh_cus.beamId",
9226 FT_UINT16, BASE_DEC,
9227 NULL((void*)0), 0x7fff,
9228 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9229 },
9230 { &hf_oran_num_weights_per_bundle,
9231 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
9232 FT_UINT16, BASE_DEC,
9233 NULL((void*)0), 0x0,
9234 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9235 },
9236
9237 { &hf_oran_samples_prb,
9238 {"PRB", "oran_fh_cus.prb",
9239 FT_STRING, BASE_NONE,
9240 NULL((void*)0), 0x0,
9241 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9242 },
9243
9244 /* 7.5.3.13 */
9245 { &hf_oran_ciSample,
9246 { "ciSample", "oran_fh_cus.ciSample",
9247 FT_STRING, BASE_NONE,
9248 NULL((void*)0), 0x0,
9249 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9250 },
9251 { &hf_oran_ciIsample,
9252 { "ciIsample", "oran_fh_cus.ciISample",
9253 FT_FLOAT, BASE_NONE,
9254 NULL((void*)0), 0x0,
9255 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9256 },
9257 { &hf_oran_ciQsample,
9258 { "ciQsample", "oran_fh_cus.ciQSample",
9259 FT_FLOAT, BASE_NONE,
9260 NULL((void*)0), 0x0,
9261 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9262 },
9263
9264 /* 7.7.10.2 */
9265 { &hf_oran_beamGroupType,
9266 { "beamGroupType", "oran_fh_cus.beamGroupType",
9267 FT_UINT8, BASE_DEC,
9268 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9269 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9270 },
9271 /* 7.7.10.3 */
9272 { &hf_oran_numPortc,
9273 { "numPortc", "oran_fh_cus.numPortc",
9274 FT_UINT8, BASE_DEC,
9275 NULL((void*)0), 0x3f,
9276 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9277 },
9278
9279 /* 7.7.4.2 (1 bit) */
9280 { &hf_oran_csf,
9281 { "csf", "oran_fh_cus.csf",
9282 FT_BOOLEAN, BASE_NONE,
9283 NULL((void*)0), 0x0,
9284 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9285 },
9286 /* 7.7.4.3 */
9287 { &hf_oran_modcompscaler,
9288 { "modCompScaler", "oran_fh_cus.modcompscaler",
9289 FT_UINT16, BASE_DEC,
9290 NULL((void*)0), 0x7fff,
9291 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9292 },
9293
9294 /* 7.7.5.1 */
9295 { &hf_oran_modcomp_param_set,
9296 { "Set", "oran_fh_cus.modcomp-param-set",
9297 FT_STRING, BASE_NONE,
9298 NULL((void*)0), 0x0,
9299 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9300 },
9301
9302
9303
9304 /* mcScaleReMask 7.7.5.2 (12 bits) */
9305
9306 /* First entry (starts with msb within byte) */
9307 { &hf_oran_mc_scale_re_mask_re1,
9308 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9309 FT_BOOLEAN, 16,
9310 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9311 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9312 },
9313 { &hf_oran_mc_scale_re_mask_re2,
9314 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9315 FT_BOOLEAN, 16,
9316 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9317 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9318 },
9319 { &hf_oran_mc_scale_re_mask_re3,
9320 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9321 FT_BOOLEAN, 16,
9322 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9323 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9324 },
9325 { &hf_oran_mc_scale_re_mask_re4,
9326 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9327 FT_BOOLEAN, 16,
9328 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9329 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9330 },
9331 { &hf_oran_mc_scale_re_mask_re5,
9332 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9333 FT_BOOLEAN, 16,
9334 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9335 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9336 },
9337 { &hf_oran_mc_scale_re_mask_re6,
9338 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9339 FT_BOOLEAN, 16,
9340 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9341 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9342 },
9343 { &hf_oran_mc_scale_re_mask_re7,
9344 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9345 FT_BOOLEAN, 16,
9346 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9347 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9348 },
9349 { &hf_oran_mc_scale_re_mask_re8,
9350 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9351 FT_BOOLEAN, 16,
9352 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9353 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9354 },
9355 { &hf_oran_mc_scale_re_mask_re9,
9356 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9357 FT_BOOLEAN, 16,
9358 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9359 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9360 },
9361 { &hf_oran_mc_scale_re_mask_re10,
9362 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9363 FT_BOOLEAN, 16,
9364 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9365 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9366 },
9367 { &hf_oran_mc_scale_re_mask_re11,
9368 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9369 FT_BOOLEAN, 16,
9370 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9371 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9372 },
9373 { &hf_oran_mc_scale_re_mask_re12,
9374 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9375 FT_BOOLEAN, 16,
9376 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9377 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9378 },
9379
9380 /* Even tries entry (starts with 5th bit within byte) */
9381 { &hf_oran_mc_scale_re_mask_re1_even,
9382 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9383 FT_BOOLEAN, 16,
9384 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9385 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9386 },
9387 { &hf_oran_mc_scale_re_mask_re2_even,
9388 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9389 FT_BOOLEAN, 16,
9390 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9391 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9392 },
9393 { &hf_oran_mc_scale_re_mask_re3_even,
9394 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9395 FT_BOOLEAN, 16,
9396 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9397 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9398 },
9399 { &hf_oran_mc_scale_re_mask_re4_even,
9400 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9401 FT_BOOLEAN, 16,
9402 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9403 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9404 },
9405 { &hf_oran_mc_scale_re_mask_re5_even,
9406 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9407 FT_BOOLEAN, 16,
9408 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9409 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9410 },
9411 { &hf_oran_mc_scale_re_mask_re6_even,
9412 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9413 FT_BOOLEAN, 16,
9414 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9415 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9416 },
9417 { &hf_oran_mc_scale_re_mask_re7_even,
9418 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9419 FT_BOOLEAN, 16,
9420 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9421 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9422 },
9423 { &hf_oran_mc_scale_re_mask_re8_even,
9424 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9425 FT_BOOLEAN, 16,
9426 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9427 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9428 },
9429 { &hf_oran_mc_scale_re_mask_re9_even,
9430 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9431 FT_BOOLEAN, 16,
9432 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9433 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9434 },
9435 { &hf_oran_mc_scale_re_mask_re10_even,
9436 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9437 FT_BOOLEAN, 16,
9438 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9439 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9440 },
9441 { &hf_oran_mc_scale_re_mask_re11_even,
9442 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9443 FT_BOOLEAN, 16,
9444 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9445 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9446 },
9447 { &hf_oran_mc_scale_re_mask_re12_even,
9448 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9449 FT_BOOLEAN, 16,
9450 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9451 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9452 },
9453
9454 { &hf_oran_mc_scale_re_mask,
9455 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9456 FT_UINT16, BASE_HEX,
9457 NULL((void*)0), 0xfff0,
9458 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9459 },
9460 { &hf_oran_mc_scale_re_mask_even,
9461 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9462 FT_UINT16, BASE_HEX,
9463 NULL((void*)0), 0x0fff,
9464 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9465 },
9466
9467 /* mcScaleOffset 7.7.5.4 (15 bits) */
9468 { &hf_oran_mc_scale_offset,
9469 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9470 FT_UINT24, BASE_DEC,
9471 NULL((void*)0), 0x0,
9472 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9473 },
9474 /* eAxCmask (7.7.7.2) */
9475 { &hf_oran_eAxC_mask,
9476 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9477 FT_UINT16, BASE_HEX,
9478 NULL((void*)0), 0xffff,
9479 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9480 },
9481 /* technology (interface name) 7.7.9.2 */
9482 { &hf_oran_technology,
9483 { "Technology", "oran_fh_cus.technology",
9484 FT_UINT8, BASE_DEC,
9485 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9486 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9487 },
9488 /* Exttype 14 (7.7.14.2) */
9489 { &hf_oran_nullLayerInd,
9490 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9491 FT_BOOLEAN, BASE_NONE,
9492 NULL((void*)0), 0x0,
9493 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9494 },
9495
9496 /* Exttype 19 */
9497 /* 7.7.19.3 */
9498 { &hf_oran_se19_repetition,
9499 { "repetition", "oran_fh_cus.repetition",
9500 FT_BOOLEAN, BASE_NONE,
9501 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9502 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9503 },
9504 /* 7.7.19.8 */
9505 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9506 { &hf_oran_portReMask,
9507 { "portReMask", "oran_fh_cus.portReMask",
9508 FT_BOOLEAN, 16,
9509 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9510 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9511 },
9512 /* 7.7.19.9 */
9513 { &hf_oran_portSymbolMask,
9514 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9515 FT_BOOLEAN, 16,
9516 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9517 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9518 },
9519
9520 { &hf_oran_ext19_port,
9521 {"Port", "oran_fh_cus.ext19.port",
9522 FT_STRING, BASE_NONE,
9523 NULL((void*)0), 0x0,
9524 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9525 },
9526
9527 /* Ext 13 */
9528 { &hf_oran_prb_allocation,
9529 {"PRB allocation", "oran_fh_cus.prb-allocation",
9530 FT_STRING, BASE_NONE,
9531 NULL((void*)0), 0x0,
9532 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9533 },
9534 /* 7.7.13.2 */
9535 { &hf_oran_nextSymbolId,
9536 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9537 FT_UINT8, BASE_DEC,
9538 NULL((void*)0), 0x3c,
9539 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9540 },
9541 /* 7.7.13.3 */
9542 { &hf_oran_nextStartPrbc,
9543 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9544 FT_UINT16, BASE_DEC,
9545 NULL((void*)0), 0x03ff,
9546 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9547 },
9548
9549 /* Puncturing patters as appears in SE 20 */
9550 { &hf_oran_puncPattern,
9551 { "puncPattern", "oran_fh_cus.puncPattern",
9552 FT_STRING, BASE_NONE,
9553 NULL((void*)0), 0x0,
9554 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9555 },
9556
9557 /* 7.7.20.2 numPuncPatterns */
9558 { &hf_oran_numPuncPatterns,
9559 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9560 FT_UINT8, BASE_DEC,
9561 NULL((void*)0), 0x0,
9562 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9563 },
9564 /* 7.7.20.3 symbolMask */
9565 { &hf_oran_symbolMask_ext20,
9566 { "symbolMask", "oran_fh_cus.symbolMask",
9567 FT_UINT16, BASE_HEX,
9568 NULL((void*)0), 0xfffc,
9569 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9570 },
9571 /* 7.7.20.4 startPuncPrb */
9572 { &hf_oran_startPuncPrb,
9573 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9574 FT_UINT16, BASE_DEC,
9575 NULL((void*)0), 0x03ff,
9576 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9577 },
9578 /* 7.7.20.5 numPuncPrb */
9579 { &hf_oran_numPuncPrb,
9580 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9581 FT_UINT8, BASE_DEC,
9582 NULL((void*)0), 0x0,
9583 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9584 },
9585 /* 7.7.20.6 puncReMask */
9586 { &hf_oran_puncReMask,
9587 { "puncReMask", "oran_fh_cus.puncReMask",
9588 FT_UINT16, BASE_DEC,
9589 NULL((void*)0), 0xffc0,
9590 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9591 },
9592 /* 7.7.20.12 multiSDScope */
9593 { &hf_oran_multiSDScope,
9594 { "multiSDScope", "oran_fh_cus.multiSDScope",
9595 FT_BOOLEAN, 8,
9596 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9597 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9598 },
9599 /* 7.7.20.4 rbgIncl */
9600 { &hf_oran_RbgIncl,
9601 { "rbgIncl", "oran_fh_cus.rbgIncl",
9602 FT_BOOLEAN, 8,
9603 NULL((void*)0), 0x01,
9604 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9605 },
9606
9607 /* 7.7.21.2 ciPrbGroupSize */
9608 { &hf_oran_ci_prb_group_size,
9609 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9610 FT_UINT8, BASE_DEC,
9611 NULL((void*)0), 0x0,
9612 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9613 },
9614 /* 7.21.3 */
9615 { &hf_oran_prg_size_st5,
9616 { "prgSize", "oran_fh_cus.prgSize",
9617 FT_UINT8, BASE_DEC,
9618 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9619 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9620 },
9621 { &hf_oran_prg_size_st6,
9622 { "prgSize", "oran_fh_cus.prgSize",
9623 FT_UINT8, BASE_DEC,
9624 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9625 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9626 },
9627
9628 /* 7.7.17.2 numUeID */
9629 { &hf_oran_num_ueid,
9630 { "numUeID", "oran_fh_cus.numUeID",
9631 FT_UINT8, BASE_DEC,
9632 NULL((void*)0), 0x0,
9633 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9634 },
9635
9636 /* 7.7.16.2 antMask */
9637 { &hf_oran_antMask,
9638 { "antMask", "oran_fh_cus.antMask",
9639 FT_UINT64, BASE_HEX,
9640 NULL((void*)0), 0xffffffffffffffff,
9641 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9642 },
9643
9644 /* 7.7.18.2 transmissionWindowOffset */
9645 { &hf_oran_transmissionWindowOffset,
9646 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9647 FT_UINT16, BASE_DEC,
9648 NULL((void*)0), 0x0,
9649 "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)}
9650 },
9651 /* 7.7.18.3 transmissionWindowSize */
9652 { &hf_oran_transmissionWindowSize,
9653 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9654 FT_UINT16, BASE_DEC,
9655 NULL((void*)0), 0x3fff,
9656 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9657 },
9658 /* 7.7.18.4 toT */
9659 { &hf_oran_toT,
9660 { "toT", "oran_fh_cus.toT",
9661 FT_UINT8, BASE_DEC,
9662 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9663 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9664 },
9665
9666 /* 7.7.2.2 bfaCompHdr */
9667 { &hf_oran_bfaCompHdr,
9668 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9669 FT_STRING, BASE_NONE,
9670 NULL((void*)0), 0x0,
9671 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9672 },
9673 /* 7.7.2.2-2: bfAzPtWidth */
9674 { &hf_oran_bfAzPtWidth,
9675 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9676 FT_UINT8, BASE_DEC,
9677 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9678 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9679 },
9680 /* 7.7.2.2-3: bfZePtWidth */
9681 { &hf_oran_bfZePtWidth,
9682 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9683 FT_UINT8, BASE_DEC,
9684 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9685 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9686 },
9687 /* 7.7.2.2-4: bfAz3ddWidth */
9688 { &hf_oran_bfAz3ddWidth,
9689 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9690 FT_UINT8, BASE_DEC,
9691 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9692 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9693 },
9694 /* 7.7.2.2-5: bfZe3ddWidth */
9695 { &hf_oran_bfZe3ddWidth,
9696 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9697 FT_UINT8, BASE_DEC,
9698 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9699 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9700 },
9701
9702 /* 7.7.2.3 bfAzPt */
9703 { &hf_oran_bfAzPt,
9704 { "bfAzPt", "oran_fh_cus.bfAzPt",
9705 FT_UINT8, BASE_DEC,
9706 NULL((void*)0), 0x0,
9707 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9708 },
9709 /* 7.7.2.4 bfZePt */
9710 { &hf_oran_bfZePt,
9711 { "bfZePt", "oran_fh_cus.bfZePt",
9712 FT_UINT8, BASE_DEC,
9713 NULL((void*)0), 0x0,
9714 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9715 },
9716 /* 7.7.2.5 bfAz3dd */
9717 { &hf_oran_bfAz3dd,
9718 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9719 FT_UINT8, BASE_DEC,
9720 NULL((void*)0), 0x0,
9721 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9722 },
9723 /* 7.7.2.6 bfZe3dd */
9724 { &hf_oran_bfZe3dd,
9725 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9726 FT_UINT8, BASE_DEC,
9727 NULL((void*)0), 0x0,
9728 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9729 },
9730
9731 /* 7.7.2.7 bfAzSl */
9732 { &hf_oran_bfAzSl,
9733 { "bfAzSl", "oran_fh_cus.bfAzSl",
9734 FT_UINT8, BASE_DEC,
9735 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9736 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9737 },
9738 /* 7.7.2.8 bfZeSl */
9739 { &hf_oran_bfZeSl,
9740 { "bfZeSl", "oran_fh_cus.bfZeSl",
9741 FT_UINT8, BASE_DEC,
9742 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9743 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9744 },
9745
9746 /* 7.5.2.17 */
9747 { &hf_oran_cmd_scope,
9748 { "cmdScope", "oran_fh_cus.cmdScope",
9749 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9750 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9751 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9752 },
9753 /* 7.5.2.18 */
9754 { &hf_oran_number_of_st4_cmds,
9755 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9756 FT_UINT8, BASE_DEC,
9757 NULL((void*)0), 0x0,
9758 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9759 },
9760
9761 { &hf_oran_st4_cmd_header,
9762 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9763 FT_STRING, BASE_NONE,
9764 NULL((void*)0), 0x0,
9765 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9766 },
9767
9768 /* 7.5.3.38 */
9769 { &hf_oran_st4_cmd_type,
9770 { "st4CmdType", "oran_fh_cus.st4CmdType",
9771 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9772 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9773 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9774 },
9775 /* 7.5.3.39 */
9776 { &hf_oran_st4_cmd_len,
9777 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9778 FT_UINT16, BASE_DEC,
9779 NULL((void*)0), 0x0,
9780 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9781 },
9782 /* 7.5.3.40 */
9783 { &hf_oran_st4_cmd_num_slots,
9784 { "numSlots", "oran_fh_cus.st4NumSlots",
9785 FT_UINT8, BASE_DEC,
9786 NULL((void*)0), 0x0,
9787 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9788 },
9789 /* 7.5.3.41 */
9790 { &hf_oran_st4_cmd_ack_nack_req_id,
9791 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9792 FT_UINT16, BASE_DEC,
9793 NULL((void*)0), 0x0,
9794 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9795 },
9796
9797 { &hf_oran_st4_cmd,
9798 { "Command", "oran_fh_cus.st4Cmd",
9799 FT_STRING, BASE_NONE,
9800 NULL((void*)0), 0x0,
9801 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9802 },
9803
9804 /* 7.5.3.52 */
9805 { &hf_oran_sleepmode_trx,
9806 { "sleepMode", "oran_fh_cus.sleepMode",
9807 FT_UINT8, BASE_HEX,
9808 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9809 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9810 },
9811 { &hf_oran_sleepmode_asm,
9812 { "sleepMode", "oran_fh_cus.sleepMode",
9813 FT_UINT8, BASE_HEX,
9814 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9815 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9816 },
9817
9818 /* 7.5.3.51 */
9819 { &hf_oran_log2maskbits,
9820 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9821 FT_UINT8, BASE_HEX,
9822 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9823 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9824 },
9825 /* 7.5.3.53 */
9826 { &hf_oran_num_slots_ext,
9827 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9828 FT_UINT24, BASE_HEX,
9829 NULL((void*)0), 0x0fffff,
9830 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9831 },
9832 /* 7.5.3.54 */
9833 { &hf_oran_antMask_trx_control,
9834 { "antMask", "oran_fh_cus.trxControl.antMask",
9835 FT_BYTES, BASE_NONE,
9836 NULL((void*)0), 0x0,
9837 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9838 },
9839 /* 7.5.3.55 */
9840 { &hf_oran_ready,
9841 { "ready", "oran_fh_cus.ready",
9842 FT_BOOLEAN, 8,
9843 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9844 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9845 },
9846 /* 7.5.3.34 */
9847 { &hf_oran_number_of_acks,
9848 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9849 FT_UINT8, BASE_DEC,
9850 NULL((void*)0), 0x0,
9851 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9852 },
9853 /* 7.5.3.35 */
9854 { &hf_oran_number_of_nacks,
9855 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9856 FT_UINT8, BASE_DEC,
9857 NULL((void*)0), 0x0,
9858 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9859 },
9860 /* 7.5.3.36 */
9861 { &hf_oran_ackid,
9862 { "ackId", "oran_fh_cus.ackId",
9863 FT_UINT16, BASE_DEC,
9864 NULL((void*)0), 0x0,
9865 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9866 },
9867 /* 7.5.3.37 */
9868 { &hf_oran_nackid,
9869 { "nackId", "oran_fh_cus.nackId",
9870 FT_UINT16, BASE_DEC,
9871 NULL((void*)0), 0x0,
9872 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9873 },
9874
9875 /* Links between acknack requests & responses */
9876 { &hf_oran_acknack_request_frame,
9877 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9878 FT_FRAMENUM, BASE_NONE,
9879 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9880 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9881 },
9882 { &hf_oran_acknack_request_time,
9883 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9884 FT_UINT32, BASE_DEC,
9885 NULL((void*)0), 0x0,
9886 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9887 },
9888 { &hf_oran_acknack_request_type,
9889 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9890 FT_UINT32, BASE_DEC,
9891 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9892 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9893 },
9894 { &hf_oran_acknack_response_frame,
9895 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9896 FT_FRAMENUM, BASE_NONE,
9897 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9898 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9899 },
9900 { &hf_oran_acknack_response_time,
9901 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9902 FT_UINT32, BASE_DEC,
9903 NULL((void*)0), 0x0,
9904 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9905 },
9906
9907 /* 7.5.3.43 */
9908 { &hf_oran_disable_tdbfns,
9909 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9910 FT_BOOLEAN, 8,
9911 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9912 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9913 },
9914
9915 /* 7.5.3.44 */
9916 { &hf_oran_td_beam_group,
9917 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9918 FT_UINT16, BASE_HEX,
9919 NULL((void*)0), 0x7fff,
9920 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9921 },
9922 /* 7.5.3.43 */
9923 { &hf_oran_disable_tdbfws,
9924 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9925 FT_BOOLEAN, 8,
9926 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9927 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9928 },
9929
9930 /* 7.5.3.56 */
9931 { &hf_oran_td_beam_num,
9932 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9933 FT_UINT16, BASE_HEX,
9934 NULL((void*)0), 0x7fff,
9935 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9936 },
9937
9938 /* 7.5.3.49 */
9939 { &hf_oran_dir_pattern,
9940 { "dirPattern", "oran_fh_cus.dirPattern",
9941 FT_BOOLEAN, 16,
9942 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9943 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9944 },
9945 /* 7.5.3.50 */
9946 { &hf_oran_guard_pattern,
9947 { "guardPattern", "oran_fh_cus.guardPattern",
9948 FT_BOOLEAN, 16,
9949 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9950 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9951 },
9952
9953 /* For convenient filtering */
9954 { &hf_oran_cplane,
9955 { "C-Plane", "oran_fh_cus.c-plane",
9956 FT_NONE, BASE_NONE,
9957 NULL((void*)0), 0x0,
9958 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9959 },
9960 { &hf_oran_uplane,
9961 { "U-Plane", "oran_fh_cus.u-plane",
9962 FT_NONE, BASE_NONE,
9963 NULL((void*)0), 0x0,
9964 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9965 },
9966 { &hf_oran_bf,
9967 { "BeamForming", "oran_fh_cus.bf",
9968 FT_NONE, BASE_NONE,
9969 NULL((void*)0), 0x0,
9970 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9971 },
9972 { &hf_oran_zero_prb,
9973 { "Zero PRB", "oran_fh_cus.zero-prb",
9974 FT_NONE, BASE_NONE,
9975 NULL((void*)0), 0x0,
9976 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9977 },
9978 { &hf_oran_nonzero_prb,
9979 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9980 FT_NONE, BASE_NONE,
9981 NULL((void*)0), 0x0,
9982 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9983 },
9984 { &hf_oran_bundle_weights_all_zero,
9985 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9986 FT_NONE, BASE_NONE,
9987 NULL((void*)0), 0x0,
9988 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9989 },
9990
9991
9992 /* 5.1.3.2.7 */
9993 { &hf_oran_ecpri_pcid,
9994 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9995 FT_NONE, BASE_NONE,
9996 NULL((void*)0), 0x0,
9997 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9998 },
9999 { &hf_oran_ecpri_rtcid,
10000 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
10001 FT_NONE, BASE_NONE,
10002 NULL((void*)0), 0x0,
10003 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10004 },
10005 /* 5.1.3.2.8 */
10006 { &hf_oran_ecpri_seqid,
10007 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
10008 FT_NONE, BASE_NONE,
10009 NULL((void*)0), 0x0,
10010 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10011 },
10012
10013 /* 7.7.23.2 */
10014 { &hf_oran_num_sym_prb_pattern,
10015 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
10016 FT_UINT8, BASE_DEC,
10017 NULL((void*)0), 0xf0,
10018 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10019 },
10020 /* 7.7.23.9 */
10021 { &hf_oran_prb_mode,
10022 { "prbMode", "oran_fh_cus.prbMode",
10023 FT_BOOLEAN, 8,
10024 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
10025 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10026 },
10027 /* 7.7.23.4 */
10028 { &hf_oran_sym_prb_pattern,
10029 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
10030 FT_STRING, BASE_NONE,
10031 NULL((void*)0), 0x0,
10032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10033 },
10034 /* 7.7.23.3 */
10035 { &hf_oran_sym_mask,
10036 { "symMask", "oran_fh_cus.symMask",
10037 FT_UINT16, BASE_HEX,
10038 NULL((void*)0), 0x3fff,
10039 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10040 },
10041 /* 7.7.23.5 */
10042 {&hf_oran_num_mc_scale_offset,
10043 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
10044 FT_UINT8, BASE_DEC,
10045 NULL((void*)0), 0xf0,
10046 "number of modulation compression scaling value per symPrbPattern",
10047 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10048 },
10049 /* 7.7.23.4 */
10050 { &hf_oran_prb_pattern,
10051 { "prbPattern", "oran_fh_cus.prbPattern",
10052 FT_UINT8, BASE_DEC,
10053 NULL((void*)0), 0x0f,
10054 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10055 },
10056 /* 7.7.23.10 */
10057 { &hf_oran_prb_blk_offset,
10058 { "prbBlkOffset", "oran_fh_cus.prbBlkOffset",
10059 FT_UINT16, BASE_DEC,
10060 NULL((void*)0), 0x0ff0,
10061 "offset to start of PRB block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10062 },
10063
10064 /* 7.7.23.11 */
10065 { &hf_oran_prb_blk_size,
10066 { "prbBlkSize", "oran_fh_cus.prbBlkSize",
10067 FT_UINT16, BASE_DEC,
10068 NULL((void*)0), 0x0ff0,
10069 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10070 },
10071
10072 /* 7.7.3.2 */
10073 { &hf_oran_codebook_index,
10074 { "codebookIndex", "oran_fh_cus.codebookIndex",
10075 FT_UINT8, BASE_DEC,
10076 NULL((void*)0), 0x0,
10077 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10078 },
10079 /* 7.7.3.3 */
10080 { &hf_oran_layerid,
10081 { "layerID", "oran_fh_cus.layerID",
10082 FT_UINT8, BASE_DEC,
10083 NULL((void*)0), 0xf0,
10084 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10085 },
10086 /* 7.7.3.5 */
10087 { &hf_oran_numlayers,
10088 { "numLayers", "oran_fh_cus.numLayers",
10089 FT_UINT8, BASE_DEC,
10090 NULL((void*)0), 0x0f,
10091 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10092 },
10093 /* 7.7.3.4 */
10094 { &hf_oran_txscheme,
10095 { "txScheme", "oran_fh_cus.txScheme",
10096 FT_UINT8, BASE_DEC,
10097 NULL((void*)0), 0xf0,
10098 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10099 },
10100 /* 7.7.3.6 */
10101 { &hf_oran_crs_remask,
10102 { "crsReMask", "oran_fh_cus.crsReMask",
10103 FT_UINT16, BASE_HEX,
10104 NULL((void*)0), 0x0fff,
10105 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10106 },
10107 /* 7.7.3.8 */
10108 { &hf_oran_crs_shift,
10109 { "crsShift", "oran_fh_cus.crsShift",
10110 FT_UINT8, BASE_HEX,
10111 NULL((void*)0), 0x80,
10112 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10113 },
10114 /* 7.7.3.7 */
10115 { &hf_oran_crs_symnum,
10116 { "crsSymNum", "oran_fh_cus.crsSymNum",
10117 FT_UINT8, BASE_DEC,
10118 NULL((void*)0), 0x0f,
10119 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10120 },
10121 /* 7.7.3.9 */
10122 { &hf_oran_beamid_ap1,
10123 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
10124 FT_UINT16, BASE_DEC,
10125 NULL((void*)0), 0x7f,
10126 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10127 },
10128 /* 7.7.3.10 */
10129 { &hf_oran_beamid_ap2,
10130 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
10131 FT_UINT16, BASE_DEC,
10132 NULL((void*)0), 0x7f,
10133 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10134 },
10135 /* 7.7.3.11 */
10136 { &hf_oran_beamid_ap3,
10137 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
10138 FT_UINT16, BASE_DEC,
10139 NULL((void*)0), 0x7f,
10140 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10141 },
10142
10143 /* 7.7.10.3a */
10144 { &hf_oran_port_list_index,
10145 { "portListIndex", "oran_fh_cus.portListIndex",
10146 FT_UINT8, BASE_DEC,
10147 NULL((void*)0), 0x0,
10148 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10149 },
10150
10151 { &hf_oran_alpn_per_sym,
10152 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
10153 FT_UINT8, BASE_HEX,
10154 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
10155 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10156 },
10157 { &hf_oran_ant_dmrs_snr,
10158 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
10159 FT_UINT8, BASE_HEX,
10160 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
10161 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10162 },
10163
10164 /* 7.7.24.6 */
10165 { &hf_oran_user_group_size,
10166 { "userGroupSize", "oran_fh_cus.userGroupSize",
10167 FT_UINT8, BASE_DEC,
10168 NULL((void*)0), 0x1f,
10169 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10170 },
10171 /* 7.7.24.7 */
10172 { &hf_oran_user_group_id,
10173 { "userGroupId", "oran_fh_cus.userGroupId",
10174 FT_UINT8, BASE_DEC,
10175 NULL((void*)0), 0x0,
10176 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10177 },
10178 /* 7.7.24.8 */
10179 { &hf_oran_entry_type,
10180 { "entryType", "oran_fh_cus.entryType",
10181 FT_UINT8, BASE_DEC,
10182 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
10183 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10184 },
10185 /* 7.7.24.9 */
10186 { &hf_oran_dmrs_port_number,
10187 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
10188 FT_UINT8, BASE_DEC,
10189 NULL((void*)0), 0x1f,
10190 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10191 },
10192 /* 7.7.24.10 */
10193 { &hf_oran_ueid_reset,
10194 { "ueidReset", "oran_fh_cus.ueidReset",
10195 FT_BOOLEAN, 8,
10196 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
10197 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10198 },
10199 /* 7.7.24.11 */
10200 { &hf_oran_dmrs_symbol_mask,
10201 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
10202 FT_UINT16, BASE_HEX,
10203 NULL((void*)0), 0x3fff,
10204 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10205 },
10206 { &hf_oran_dmrs_symbol_mask_s13,
10207 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
10208 FT_BOOLEAN, 16,
10209 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
10210 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10211 },
10212 { &hf_oran_dmrs_symbol_mask_s12,
10213 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
10214 FT_BOOLEAN, 16,
10215 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
10216 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10217 },
10218 { &hf_oran_dmrs_symbol_mask_s11,
10219 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
10220 FT_BOOLEAN, 16,
10221 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
10222 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10223 },
10224 { &hf_oran_dmrs_symbol_mask_s10,
10225 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
10226 FT_BOOLEAN, 16,
10227 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
10228 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10229 },
10230 { &hf_oran_dmrs_symbol_mask_s9,
10231 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
10232 FT_BOOLEAN, 16,
10233 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
10234 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10235 },
10236 { &hf_oran_dmrs_symbol_mask_s8,
10237 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
10238 FT_BOOLEAN, 16,
10239 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
10240 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10241 },
10242 { &hf_oran_dmrs_symbol_mask_s7,
10243 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
10244 FT_BOOLEAN, 16,
10245 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
10246 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10247 },
10248 { &hf_oran_dmrs_symbol_mask_s6,
10249 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
10250 FT_BOOLEAN, 16,
10251 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
10252 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10253 },
10254 { &hf_oran_dmrs_symbol_mask_s5,
10255 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10256 FT_BOOLEAN, 16,
10257 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10258 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10259 },
10260 { &hf_oran_dmrs_symbol_mask_s4,
10261 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10262 FT_BOOLEAN, 16,
10263 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10264 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10265 },
10266 { &hf_oran_dmrs_symbol_mask_s3,
10267 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10268 FT_BOOLEAN, 16,
10269 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10270 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10271 },
10272 { &hf_oran_dmrs_symbol_mask_s2,
10273 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10274 FT_BOOLEAN, 16,
10275 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10276 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10277 },
10278 { &hf_oran_dmrs_symbol_mask_s1,
10279 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10280 FT_BOOLEAN, 16,
10281 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10282 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10283 },
10284 { &hf_oran_dmrs_symbol_mask_s0,
10285 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10286 FT_BOOLEAN, 16,
10287 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10288 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10289 },
10290
10291 /* 7.7.24.12 */
10292 { &hf_oran_scrambling,
10293 { "scrambling", "oran_fh_cus.scrambling",
10294 FT_UINT16, BASE_HEX,
10295 NULL((void*)0), 0x0,
10296 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10297 },
10298 /* 7.7.24.13 */
10299 { &hf_oran_nscid,
10300 { "nscid", "oran_fh_cus.nscid",
10301 FT_UINT8, BASE_HEX,
10302 NULL((void*)0), 0x80,
10303 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10304 },
10305 /* 7.7.24.14 */
10306 { &hf_oran_dtype,
10307 { "dType", "oran_fh_cus.dType",
10308 FT_UINT8, BASE_HEX,
10309 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10310 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10311 },
10312 /* 7.7.24.15 */
10313 { &hf_oran_cmd_without_data,
10314 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10315 FT_UINT8, BASE_HEX,
10316 NULL((void*)0), 0x30,
10317 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10318 },
10319 /* 7.7.24.16 */
10320 { &hf_oran_lambda,
10321 { "lambda", "oran_fh_cus.lambda",
10322 FT_UINT8, BASE_HEX,
10323 NULL((void*)0), 0x0c,
10324 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10325 },
10326 /* 7.7.24.19 */
10327 { &hf_oran_first_prb,
10328 { "firstPrb", "oran_fh_cus.firstPrb",
10329 FT_UINT16, BASE_DEC,
10330 NULL((void*)0), 0x03fe,
10331 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10332 },
10333 /* 7.7.24.20 */
10334 { &hf_oran_last_prb,
10335 { "lastPrb", "oran_fh_cus.lastPrb",
10336 FT_UINT16, BASE_DEC,
10337 NULL((void*)0), 0x01ff,
10338 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10339 },
10340
10341 /* 7.7.24.17 */
10342 /* TODO: add value_string */
10343 { &hf_oran_low_papr_type,
10344 { "lowPaprType", "oran_fh_cus.lowPaprType",
10345 FT_UINT8, BASE_HEX,
10346 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10347 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10348 },
10349 /* 7.7.24.18 */
10350 { &hf_oran_hopping_mode,
10351 { "hoppingMode", "oran_fh_cus.hoppingMode",
10352 FT_UINT8, BASE_HEX,
10353 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10354 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10355 },
10356
10357 { &hf_oran_tx_win_for_on_air_symbol_l,
10358 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10359 FT_UINT8, BASE_DEC,
10360 NULL((void*)0), 0xf0,
10361 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10362 },
10363 { &hf_oran_tx_win_for_on_air_symbol_r,
10364 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10365 FT_UINT8, BASE_DEC,
10366 NULL((void*)0), 0x0f,
10367 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10368 },
10369 /* 7.7.26.2 */
10370 { &hf_oran_num_fo_fb,
10371 { "numFoFb", "oran_fh_cus.numFoFb",
10372 FT_UINT8, BASE_DEC,
10373 NULL((void*)0), 0x7f,
10374 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10375 },
10376 /* 7.7.26.3 */
10377 { &hf_oran_freq_offset_fb,
10378 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10379 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10380 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10381 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10382 },
10383
10384 /* 7.7.28.2 */
10385 { &hf_oran_num_ue_sinr_rpt,
10386 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10387 FT_UINT8, BASE_DEC,
10388 NULL((void*)0), 0x1f,
10389 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10390 },
10391
10392 /* 7.5.2.19 */
10393 { &hf_oran_num_sinr_per_prb,
10394 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10395 FT_UINT8, BASE_DEC,
10396 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10397 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10398 },
10399 { &hf_oran_num_sinr_per_prb_right,
10400 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10401 FT_UINT8, BASE_DEC,
10402 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10403 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10404 },
10405
10406 /* 7.5.3.68 */
10407 { &hf_oran_sinr_value,
10408 { "sinrValue", "oran_fh_cus.sinrValue",
10409 FT_FLOAT, BASE_NONE,
10410 NULL((void*)0), 0x0,
10411 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10412 },
10413
10414 { &hf_oran_measurement_report,
10415 { "Measurement Report", "oran_fh_cus.measurement-report",
10416 FT_STRING, BASE_NONE,
10417 NULL((void*)0), 0x0,
10418 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10419 },
10420 /* 7.5.3.57 */
10421 { &hf_oran_mf,
10422 { "mf", "oran_fh_cus.mf",
10423 FT_BOOLEAN, 8,
10424 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10425 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10426 },
10427 /* 7.5.3.59 */
10428 { &hf_oran_meas_data_size,
10429 { "measDataSize", "oran_fh_cus.measDataSize",
10430 FT_UINT16, BASE_DEC,
10431 NULL((void*)0), 0x0,
10432 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10433 },
10434
10435 /* 7.5.3.58 */
10436 { &hf_oran_meas_type_id,
10437 { "measTypeId", "oran_fh_cus.measTypeId",
10438 FT_UINT8, BASE_DEC,
10439 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10440 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10441 },
10442 /* 7.5.3.66 */
10443 { &hf_oran_num_elements,
10444 { "numElements", "oran_fh_cus.numElements",
10445 FT_UINT8, BASE_DEC,
10446 NULL((void*)0), 0x0,
10447 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10448 },
10449 /* 7.5.3.60 */
10450 { &hf_oran_ue_tae,
10451 { "ueTae", "oran_fh_cus.ueTae",
10452 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10453 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10454 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10455 },
10456 /* 7.5.3.61 */
10457 { &hf_oran_ue_layer_power,
10458 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10459 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10460 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10461 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10462 },
10463
10464 /* 7.5.3.62 */
10465 { &hf_oran_ue_freq_offset,
10466 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10467 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10468 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10469 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10470 },
10471 /* 7.5.3.63 */
10472 { &hf_oran_ipn_power,
10473 { "ipnPower", "oran_fh_cus.ipnPower",
10474 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10475 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10476 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10477 },
10478 /* 7.5.3.64 */
10479 { &hf_oran_ant_dmrs_snr_val,
10480 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10481 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10482 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10483 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10484 },
10485
10486 { &hf_oran_measurement_command,
10487 { "Measurement Command", "oran_fh_cus.measurement-command",
10488 FT_STRING, BASE_NONE,
10489 NULL((void*)0), 0x0,
10490 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10491 },
10492
10493 /* 7.5.27.2 */
10494 { &hf_oran_beam_type,
10495 {"beamType", "oran_fh_cus.beamType",
10496 FT_UINT16, BASE_DEC,
10497 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10498 NULL((void*)0),
10499 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10500 },
10501 /* 7.5.3.65 */
10502 { &hf_oran_meas_cmd_size,
10503 {"measCmdSize", "oran_fh_cus.measCmdSize",
10504 FT_UINT16, BASE_DEC,
10505 NULL((void*)0), 0x0,
10506 "measurement command size in words",
10507 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10508 },
10509
10510 { &hf_oran_symbol_reordering_layer,
10511 { "Layer", "oran_fh_cus.layer",
10512 FT_STRING, BASE_NONE,
10513 NULL((void*)0), 0x0,
10514 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10515 },
10516 { &hf_oran_dmrs_entry,
10517 { "Entry", "oran_fh_cus.dmrs-entry",
10518 FT_STRING, BASE_NONE,
10519 NULL((void*)0), 0x0,
10520 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10521 },
10522
10523 /* 7.7.29.3 */
10524 { &hf_oran_cd_scg_size,
10525 {"cdScgSize", "oran_fh_cus.cdScgSize",
10526 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10527 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10528 "Cyclic delay subcarrier group size",
10529 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10530 },
10531 /* 7.7.29.4 */
10532 { &hf_oran_cd_scg_phase_step,
10533 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10534 FT_INT8, BASE_DEC,
10535 NULL((void*)0), 0x0,
10536 "Cyclic delay subcarrier group phase step",
10537 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10538 },
10539
10540 { &hf_oran_sinr_prb,
10541 { "PRB", "oran_fh_cus.sinr.prb",
10542 FT_STRING, BASE_NONE,
10543 NULL((void*)0), 0x0,
10544 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10545 },
10546 /* 7.5.2.20 */
10547 { &hf_oran_oru_control_sinr_slot_mask_id,
10548 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10549 FT_UINT8, BASE_DEC,
10550 NULL((void*)0), 0x1f,
10551 "SINR time resolution",
10552 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10553 },
10554 /* 7.7.24.21 */
10555 { &hf_oran_pos_meas,
10556 {"posMeas", "oran_fh_cus.posMeas",
10557 FT_BOOLEAN, 8,
10558 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10559 "Positioning measurement report request",
10560 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10561 },
10562
10563 /* 7.5.3.69 */
10564 { &hf_oran_ue_radial_speed,
10565 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10566 FT_UINT16, BASE_DEC,
10567 NULL((void*)0), 0x0,
10568 "UE radial speed",
10569 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10570 },
10571 /* 7.5.3.70 */
10572 { &hf_oran_ue_az_aoa,
10573 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10574 FT_UINT16, BASE_DEC,
10575 NULL((void*)0), 0x0,
10576 "UE azimuth angle of arrival",
10577 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10578 },
10579 /* 7.5.3.71 */
10580 { &hf_oran_ue_ze_aoa,
10581 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10582 FT_UINT16, BASE_DEC,
10583 NULL((void*)0), 0x0,
10584 "UE zenith angle of arrival",
10585 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10586 },
10587 /* 7.5.3.72 */
10588 { &hf_oran_ue_pos_toa_offset,
10589 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10590 FT_UINT16, BASE_DEC,
10591 NULL((void*)0), 0x0,
10592 "UE positioning time of arrival offset",
10593 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10594 },
10595
10596 /* 7.7.30.2 */
10597 { &hf_oran_num_rep_ue,
10598 {"numRepUe", "oran_fh_cus.numRepUe",
10599 FT_UINT8, BASE_DEC,
10600 NULL((void*)0), 0x0f,
10601 "Number of UEs with PUSCH repetition",
10602 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10603 },
10604 /* 7.7.30.3 */
10605 { &hf_oran_rep_ueid,
10606 {"repUeId", "oran_fh_cus.repUeId",
10607 FT_UINT16, BASE_DEC,
10608 NULL((void*)0), 0x7fff,
10609 "UEId the PUSCH is part of",
10610 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10611 },
10612 /* 7.7.30.4 */
10613 { &hf_oran_is_last_rep,
10614 {"isLastRep", "oran_fh_cus.isLastRep",
10615 FT_BOOLEAN, 8,
10616 NULL((void*)0), 0x40,
10617 "Last transmission in the repetition",
10618 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10619 },
10620 /* 7.7.30.5 */
10621 { &hf_oran_rep_index,
10622 {"repIndex", "oran_fh_cus.repIndex",
10623 FT_UINT8, BASE_DEC,
10624 NULL((void*)0), 0x3f,
10625 "Repetition index of the PUSCH transmission",
10626 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10627 },
10628 /* 7.7.30.6 */
10629 { &hf_oran_num_reps,
10630 {"numReps", "oran_fh_cus.numReps",
10631 FT_UINT8, BASE_DEC,
10632 NULL((void*)0), 0x3f,
10633 "The number of total PUSCH repetitions",
10634 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10635 },
10636
10637 /* 7.7.31.2 */
10638 { &hf_oran_mcs_table,
10639 {"mcsTable", "oran_fh_cus.mcsTable",
10640 FT_UINT8, BASE_DEC,
10641 VALS(mcs_table_vals)((0 ? (const struct _value_string*)0 : ((mcs_table_vals)))), 0x0f,
10642 "MCS index table",
10643 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10644 },
10645 /* 7.7.31.3 */
10646 { &hf_oran_mcs_index,
10647 {"mcsIndex", "oran_fh_cus.mcsIndex",
10648 FT_UINT8, BASE_DEC,
10649 NULL((void*)0), 0x3f,
10650 "MCS index value",
10651 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10652 },
10653
10654 /* 7.7.33.3 */
10655 { &hf_oran_num_meas_req,
10656 {"numMeasReq", "oran_fh_cus.numMeasReq",
10657 FT_UINT8, BASE_DEC,
10658 NULL((void*)0), 0x1f,
10659 "Number of UEs for which meas is requested",
10660 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10661 },
10662 /* 7.7.32.5 */
10663 { &hf_oran_ue_rank,
10664 {"ueRank", "oran_fh_cus.ueRank",
10665 FT_UINT8, BASE_DEC,
10666 VALS(ue_rank_vals)((0 ? (const struct _value_string*)0 : ((ue_rank_vals)))), 0x0f,
10667 "Number of UE layers under evaluation",
10668 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10669 },
10670 /* 7.7.32.6 */
10671 { &hf_oran_num_of_ue_ant_ports,
10672 {"numOfUeAntPorts", "oran_fh_cus.numofUeAntPorts",
10673 FT_UINT8, BASE_DEC,
10674 VALS(num_of_ue_ant_ports_vals)((0 ? (const struct _value_string*)0 : ((num_of_ue_ant_ports_vals
))))
, 0xf0,
10675 "Used for the PUSCH tx under evaluation",
10676 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10677 },
10678 /* 7.7.32.8 */
10679 { &hf_oran_codebook_subset,
10680 {"codebookSubset", "oran_fh_cus.codebookSubset",
10681 FT_UINT8, BASE_DEC,
10682 VALS(codebook_subset_vals)((0 ? (const struct _value_string*)0 : ((codebook_subset_vals
))))
, 0xc0,
10683 "UE capability wrt ULTPMI sets",
10684 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10685 },
10686 /* 7.7.32.9 */
10687 { &hf_oran_full_pwr_mode,
10688 {"fullPwrMode", "oran_fh_cus.fullPwrMode",
10689 FT_UINT8, BASE_DEC,
10690 VALS(full_pwr_mode_vals)((0 ? (const struct _value_string*)0 : ((full_pwr_mode_vals))
))
, 0xc0,
10691 "Transmission mode",
10692 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10693 },
10694 /* 7.7.32.10 */
10695 { &hf_oran_full_pwr_mode_2_tpmi_group,
10696 {"fullPwrMode2TpmiGroup", "oran_fh_cus.fullPwrMode2TpmiGroup",
10697 FT_UINT16, BASE_HEX,
10698 NULL((void*)0), 0x3fff,
10699 "Capabilities",
10700 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10701 },
10702
10703 /* 7.5.3.75 */
10704 { &hf_oran_num_cand_ranks,
10705 {"numCandRanks", "oran_fh_cus.numCandRanks",
10706 FT_UINT8, BASE_DEC,
10707 NULL((void*)0), 0xf0,
10708 NULL((void*)0),
10709 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10710 },
10711 /* 7.5.3.76 */
10712 { &hf_oran_ue_pref_rank,
10713 {"uePrefRank", "oran_fh_cus.uePrefRank",
10714 FT_UINT8, BASE_DEC,
10715 NULL((void*)0), 0x0f,
10716 "Most optimal UL Tx rank for UE",
10717 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10718 },
10719 /* 7.5.3.77 */
10720 { &hf_oran_ue_tpmi_rank_y,
10721 {"ueTpmiRankY", "oran_fh_cus.ueTpmiRankY",
10722 FT_UINT8, BASE_DEC,
10723 NULL((void*)0), 0x0,
10724 "TPMI index for codebook-based PUSCH tx",
10725 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10726 },
10727 /* 7.5.3.78 */
10728 { &hf_oran_ue_tpmi_rank_y_sinr_lx,
10729 {"ueTpmiRankYSinrLX", "oran_fh_cus.ueTpmiRankYSinrLX",
10730 FT_UINT16, BASE_HEX | BASE_RANGE_STRING0x00000100,
10731 RVALS(ue_tmpi_rank_sinr_vals)((0 ? (const struct _range_string*)0 : ((ue_tmpi_rank_sinr_vals
))))
, 0x0,
10732 "Estimation of post-equalization SINR",
10733 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10734 },
10735 /* 7.5.3.79 */
10736 { &hf_oran_ue_layer_pre_eq_sinr,
10737 {"ueLayerPreEqSinr", "oran_fh_cus.ueLayerPreEqSinr",
10738 FT_UINT16, BASE_HEX,
10739 NULL((void*)0), 0x0,
10740 "Pre-equalization SINR of a UE layer",
10741 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10742 },
10743
10744 { &hf_oran_c_section_common,
10745 { "Common Section", "oran_fh_cus.c-plane.section.common",
10746 FT_STRING, BASE_NONE,
10747 NULL((void*)0), 0x0,
10748 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10749 },
10750 { &hf_oran_c_section,
10751 { "Section", "oran_fh_cus.c-plane.section",
10752 FT_STRING, BASE_NONE,
10753 NULL((void*)0), 0x0,
10754 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10755 },
10756 { &hf_oran_u_section,
10757 { "Section", "oran_fh_cus.u-plane.section",
10758 FT_STRING, BASE_NONE,
10759 NULL((void*)0), 0x0,
10760 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10761 },
10762
10763 /* Link back to UL C-plane where udCompHdr was recorded */
10764 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10765 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10766 FT_FRAMENUM, BASE_NONE,
10767 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10768 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10769 },
10770
10771 /* For ext11, where was a beamId (last) defined? */
10772 { &hf_oran_bfws_frame_defined,
10773 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10774 FT_FRAMENUM, BASE_NONE,
10775 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10776 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10777 },
10778 { &hf_oran_bfws_symbols_since_defined,
10779 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10780 FT_UINT32, BASE_DEC,
10781 NULL((void*)0), 0x0,
10782 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10783 },
10784
10785 /* Corresponding C-plane frame for DL U-plane */
10786 { &hf_oran_corresponding_cplane_frame,
10787 { "C-plane frame", "oran_fh_cus.cplane-frame",
10788 FT_FRAMENUM, BASE_NONE,
10789 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10790 },
10791 /* Time since corresponding C-plane frame for U-plane */
10792 { &hf_oran_corresponding_cplane_frame_time_delta,
10793 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10794 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10795 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10796 },
10797 /* Corresponding U-plane frame for C-plane */
10798 { &hf_oran_corresponding_uplane_frame,
10799 { "U-plane frame", "oran_fh_cus.uplane-frame",
10800 FT_FRAMENUM, BASE_NONE,
10801 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10802 },
10803 { &hf_oran_corresponding_uplane_frames_total,
10804 { "U-plane frames total", "oran_fh_cus.u-plane-frames-total",
10805 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10806 "Number of corresponding U-plane frames", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10807 },
10808
10809 /* Reassembly */
10810 { &hf_oran_fragment,
10811 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10812 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10813 { &hf_oran_fragments,
10814 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10815 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10816 { &hf_oran_fragment_overlap,
10817 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10818 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10819 { &hf_oran_fragment_overlap_conflict,
10820 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10821 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10822 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10823 { &hf_oran_fragment_multiple_tails,
10824 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10825 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10826 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10827 { &hf_oran_fragment_too_long_fragment,
10828 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10829 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10830 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10831 { &hf_oran_fragment_error,
10832 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10833 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10834 { &hf_oran_fragment_count,
10835 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10836 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10837 { &hf_oran_reassembled_in,
10838 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10839 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10840 { &hf_oran_reassembled_length,
10841 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10842 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10843 { &hf_oran_reassembled_data,
10844 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10845 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10846
10847 { &hf_oran_payload,
10848 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10849 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10850 };
10851
10852 /* Setup protocol subtree array */
10853 static int *ett[] = {
10854 &ett_oran,
10855 &ett_oran_ecpri_pcid,
10856 &ett_oran_ecpri_rtcid,
10857 &ett_oran_ecpri_seqid,
10858 &ett_oran_section_type,
10859 &ett_oran_u_timing,
10860 &ett_oran_u_section,
10861 &ett_oran_u_prb,
10862 &ett_oran_section,
10863 &ett_oran_iq,
10864 &ett_oran_bfw_bundle,
10865 &ett_oran_bfw,
10866 &ett_oran_frequency_range,
10867 &ett_oran_prb_cisamples,
10868 &ett_oran_cisample,
10869 &ett_oran_udcomphdr,
10870 &ett_oran_udcompparam,
10871 &ett_oran_cicomphdr,
10872 &ett_oran_cicompparam,
10873 &ett_oran_bfwcomphdr,
10874 &ett_oran_bfwcompparam,
10875 &ett_oran_ext19_port,
10876 &ett_oran_prb_allocation,
10877 &ett_oran_punc_pattern,
10878 &ett_oran_bfacomphdr,
10879 &ett_oran_modcomp_param_set,
10880 &ett_oran_st4_cmd_header,
10881 &ett_oran_st4_cmd,
10882 &ett_oran_sym_prb_pattern,
10883 &ett_oran_measurement_report,
10884 &ett_oran_measurement_command,
10885 &ett_oran_sresmask,
10886 &ett_oran_c_section_common,
10887 &ett_oran_c_section,
10888 &ett_oran_remask,
10889 &ett_oran_mc_scale_remask,
10890 &ett_oran_symbol_reordering_layer,
10891 &ett_oran_dmrs_entry,
10892 &ett_oran_dmrs_symbol_mask,
10893 &ett_oran_symbol_mask,
10894 &ett_oran_active_beamspace_coefficient_mask,
10895 &ett_oran_sinr_prb,
10896
10897 &ett_oran_fragment,
10898 &ett_oran_fragments
10899 };
10900
10901 /* Separate subtree array for extensions. Used with [ext-1] */
10902 static int *ext_ett[HIGHEST_EXTTYPE32];
10903 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10904 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10905 }
10906
10907 expert_module_t* expert_oran;
10908
10909 static ei_register_info ei[] = {
10910 { &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)}}
}},
10911 { &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)}}
}},
10912 { &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)}}
}},
10913 { &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)}}
}},
10914 { &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)}}
}},
10915 { &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)}}
}},
10916 { &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)}}
}},
10917 { &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)}}
}},
10918 { &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)}}
}},
10919 { &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)}}
}},
10920 { &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)}}
}},
10921 { &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)}}
}},
10922 { &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)}}
}},
10923 { &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)}}
}},
10924 { &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)}}
}},
10925 { &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)}}
}},
10926 { &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)}}
}},
10927 { &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)}}
}},
10928 { &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)}}
}},
10929 { &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)}}
}},
10930 { &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)}}
}},
10931 { &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)}}
}},
10932 { &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)}}
}},
10933 { &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)}}
}},
10934 { &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)}}
}},
10935 { &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)}}
}},
10936 { &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)}}
}},
10937 { &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)}}
}},
10938 { &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)}}
}},
10939 { &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)}}
}},
10940 { &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)}}
}},
10941 { &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)}}
}},
10942 { &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)}}
}},
10943 { &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)}}
}},
10944 { &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)}}
}},
10945 { &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)}}
}},
10946 { &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)}}
}},
10947 { &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)}}
}},
10948 { &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)}}
}},
10949 { &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)}}
}},
10950 { &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)}}
}},
10951 { &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)}}
}},
10952 { &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)}}
}},
10953 { &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)}}
}},
10954 { &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)}}
}},
10955 { &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)}}
}},
10956 { &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)}}
}},
10957 { &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)}}
}},
10958 { &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)}}
}},
10959 { &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)}}
}},
10960 { &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)}}
}},
10961 { &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)}}
}},
10962 { &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)}}
}},
10963 { &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)}}
}},
10964 { &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)}}
}},
10965 { &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)}}
}},
10966 { &ei_oran_cplane_entry_not_found, { "oran_fh_cus.cplane_entry_not_found", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "C-plane for this U-plane section not 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)}}
}},
10967 };
10968
10969
10970 /* Register the protocol name and description */
10971 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10972
10973 /* Allow dissector to find be found by name. */
10974 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10975
10976 /* Register the tap name. */
10977 oran_tap = register_tap("oran-fh-cus");
10978
10979 /* Required function calls to register the header fields and subtrees */
10980 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10981 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10982 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10983
10984 expert_oran = expert_register_protocol(proto_oran);
10985 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10986
10987
10988 /* Preferences */
10989 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10990
10991 /* Register bit width/compression preferences separately by direction. */
10992 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10993 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10994 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10995 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10996 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10997 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10998 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10999 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
11000
11001 /* Uplink userplane */
11002 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
11003 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
11004 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
11005 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
11006 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
11007 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
11008 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
11009 "configuration of the O-RU. This preference instructs the dissector to expect "
11010 "this field to be present in uplink messages",
11011 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
11012 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
11013 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
11014 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
11015 "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",
11016 10, &us_allowed_for_ul_in_symbol);
11017
11018 /* Downlink userplane */
11019 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
11020 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
11021 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
11022 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
11023 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
11024 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
11025 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
11026 "configuration of the O-RU. This preference instructs the dissector to expect "
11027 "this field to be present in downlink messages",
11028 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
11029
11030 /* SINR */
11031 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
11032 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
11033 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
11034 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
11035 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
11036
11037 /* BF-related */
11038 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
11039 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
11040 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
11041 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
11042 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
11043 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
11044 "Default is 1-byte alignment", &st6_4byte_alignment);
11045
11046 /* Misc (and will seldom need to be accessed) */
11047 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
11048 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
11049 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
11050 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
11051 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
11052 &pref_support_udcompLen, udcomplen_support_options, false0);
11053 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
11054 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
11055 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
11056 "", &show_unscaled_values);
11057 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
11058 "Attempt Radio Transport layer reassembly", "",
11059 &do_radio_transport_layer_reassembly);
11060 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
11061
11062 prefs_register_bool_preference(oran_module, "oran.link_planes",
11063 "Link C-plane and U-plane using sectionId", "",
11064 &link_planes_together);
11065
11066
11067 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11068 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11069 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11070
11071 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11072 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11073
11074 register_init_routine(&oran_init_protocol);
11075
11076 /* Register reassembly table. */
11077 reassembly_table_register(&oran_reassembly_table,
11078 &oran_reassembly_table_functions);
11079}
11080
11081/*
11082* Editor modelines - http://www.wireshark.org/tools/modelines.html
11083*
11084* Local Variables:
11085* c-basic-offset: 4
11086* tab-width: 8
11087* indent-tabs-mode: nil
11088* End:
11089*
11090* ex: set shiftwidth=4 tabstop=8 expandtab:
11091* :indentSize=4:tabSize=8:noTabs=true:
11092*/