Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-oran.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-08-07-100414-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-v21.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;
713static expert_field ei_oran_se12_rb_set;
714
715
716/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
717#define ECPRI_MT_IQ_DATA0 0
718#define ECPRI_MT_RT_CTRL_DATA2 2
719
720
721/* Preference settings - try to set reasonable defaults */
722static unsigned pref_du_port_id_bits = 4;
723static unsigned pref_bandsector_id_bits = 4;
724static unsigned pref_cc_id_bits = 4;
725static unsigned pref_ru_port_id_bits = 4;
726
727/* TODO: ideally should be per-flow */
728static unsigned pref_sample_bit_width_uplink = 14;
729static unsigned pref_sample_bit_width_downlink = 14;
730static unsigned pref_sample_bit_width_sinr = 14;
731
732/* TODO: these ideally should be per-flow too */
733static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
734static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
735
736static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
737
738
739/* Is udCompHeader present (both directions) */
740static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
741static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
742
743/* Are we ignoring UL C-Plane udCompHdr? */
744static bool_Bool pref_override_ul_compression = false0;
745
746static unsigned pref_data_plane_section_total_rbs = 273;
747static unsigned pref_num_bf_antennas = 32;
748static bool_Bool pref_showIQSampleValues = true1;
749
750/* Based upon m-plane param, so will be system-wide */
751static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
752static bool_Bool udcomplen_heuristic_result_set = false0;
753static bool_Bool udcomplen_heuristic_result = false0;
754
755/* st6-4byte-alignment-required */
756static bool_Bool st6_4byte_alignment = false0;
757
758/* Requested, allows I/Q to be stored as integers.. */
759static bool_Bool show_unscaled_values = false0;
760
761/* Initialized off. Timing is in microseconds. */
762static unsigned us_allowed_for_ul_in_symbol = 0;
763
764/* Reassemble U-Plane (at Radio Transport layer) */
765static bool_Bool do_radio_transport_layer_reassembly = true1;
766
767/* Link U-plane back to C-plane using sectionIds */
768static bool_Bool link_planes_together = true1;
769
770static const enum_val_t dl_compression_options[] = {
771 { "COMP_NONE", "No Compression", COMP_NONE0 },
772 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
773 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
774 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
775 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
776 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
777 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
778 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
779 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
780 { NULL((void*)0), NULL((void*)0), 0 }
781};
782
783/* No Modulation compression in UL.. */
784static const enum_val_t ul_compression_options[] = {
785 { "COMP_NONE", "No Compression", COMP_NONE0 },
786 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
787 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
788 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
789 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
790 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
791 { NULL((void*)0), NULL((void*)0), 0 }
792};
793
794static const enum_val_t udcomplen_support_options[] = {
795 { "NOT_SUPPORTED", "Not Supported", 0 },
796 { "SUPPORTED", "Supported", 1 },
797 { "HEURISTIC", "Attempt Heuristic", 2 },
798 { NULL((void*)0), NULL((void*)0), 0 }
799};
800
801static const enum_val_t udcomphdr_present_options[] = {
802 { "NOT_PRESENT", "Not Present", 0 },
803 { "PRESENT", "Present", 1 },
804 { "HEURISTIC", "Attempt Heuristic", 2 },
805 { NULL((void*)0), NULL((void*)0), 0 }
806};
807
808
809
810static const value_string e_bit[] = {
811 { 0, "More fragments follow" },
812 { 1, "Last fragment" },
813 { 0, NULL((void*)0)}
814};
815
816#define DIR_UPLINK0 0
817#define DIR_DOWNLINK1 1
818
819
820static const value_string data_direction_vals[] = {
821 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
822 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
823 { 0, NULL((void*)0)}
824};
825
826static const value_string rb_vals[] = {
827 { 0, "Every RB used" },
828 { 1, "Every other RB used" },
829 { 0, NULL((void*)0)}
830};
831
832static const value_string sym_inc_vals[] = {
833 { 0, "Use the current symbol number" },
834 { 1, "Increment the current symbol number" },
835 { 0, NULL((void*)0)}
836};
837
838static const value_string lbtMode_vals[] = {
839 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
840 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
841 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
842 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
843 { 0, NULL((void*)0)}
844};
845
846static const value_string ue_rank_vals[] = {
847 { 1, "1" },
848 { 2, "2" },
849 { 3, "3" },
850 { 4, "4" },
851 { 0, NULL((void*)0)}
852};
853
854static const value_string num_of_ue_ant_ports_vals[] = {
855 { 2, "2" },
856 { 4, "4" },
857 { 0, NULL((void*)0)}
858};
859
860static const value_string codebook_subset_vals[] = {
861 { 0, "nonCoherent" },
862 { 1, "partialAndNonCoherent" },
863 { 2, "fullyAndPartialAndNonCoherent" },
864 { 3, "reserved" },
865 { 0, NULL((void*)0)}
866};
867
868
869static const range_string filter_indices[] = {
870 {0, 0, "standard channel filter"},
871 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
872 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
873 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
874 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
875 {5, 5, "UL filter for PRACH preamble formats"},
876 {8, 8, "UL filter NPUSCH"},
877 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
878 {9, 15, "Reserved"},
879 {0, 0, NULL((void*)0)}
880};
881
882/* 7.3.1-1 */
883static const range_string section_types[] = {
884 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
885 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
886 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
887 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
888 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
889 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
890 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
891 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
892 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
893 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
894 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
895 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
896 { 12, 255, "Reserved for future use" },
897 { 0, 0, NULL((void*)0)} };
898
899static const range_string section_types_short[] = {
900 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
901 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
902 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
903 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
904 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
905 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
906 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
907 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
908 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
909 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
910 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
911 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
912 { 12, 255, "Reserved for future use" },
913 { 0, 0, NULL((void*)0) }
914};
915
916static const range_string ud_comp_header_width[] = {
917 {0, 0, "I and Q are each 16 bits wide"},
918 {1, 15, "Bit width of I and Q"},
919 {0, 0, NULL((void*)0)} };
920
921/* Table 8.3.3.13-3 */
922static const range_string ud_comp_header_meth[] = {
923 {COMP_NONE0, COMP_NONE0, "No compression" },
924 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
925 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
926 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
927 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
928 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
929 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
930 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
931 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
932 {9, 15, "Reserved"},
933 {0, 0, NULL((void*)0)}
934};
935
936/* Table 7.5.2.13-2 */
937static const range_string frame_structure_fft[] = {
938 {0, 0, "Reserved (no FFT/iFFT processing)"},
939 {1, 3, "Reserved"},
940 {4, 4, "FFT size 16"},
941 {5, 5, "FFT size 32"},
942 {6, 6, "FFT size 64"},
943 {7, 7, "FFT size 128"},
944 {8, 8, "FFT size 256"},
945 {9, 9, "FFT size 512"},
946 {10, 10, "FFT size 1024"},
947 {11, 11, "FFT size 2048"},
948 {12, 12, "FFT size 4096"},
949 {13, 13, "FFT size 1536"},
950 {14, 14, "FFT size 3072"},
951 {15, 15, "Reserved"},
952 {0, 0, NULL((void*)0)}
953};
954
955/* Table 7.5.2.13-3 */
956static const range_string subcarrier_spacings[] = {
957 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
958 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
959 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
960 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
961 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
962 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
963 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
964 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
965 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
966 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
967 { 0, 0, NULL((void*)0) }
968};
969
970/* Table 7.5.3.14-1 laaMsgType definition */
971static const range_string laaMsgTypes[] = {
972 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
973 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
974 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
975 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
976 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
977 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
978 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
979 {7, 15, "reserved for future methods"},
980 {0, 0, NULL((void*)0)}
981};
982
983/* 7.7.26.3 */
984static const range_string freq_offset_fb_values[] = {
985 {0, 0, "no frequency offset"},
986 {8000, 8000, "value not provided"},
987 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
988 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
989 {0x0, 0xffff, "reserved"},
990 {0, 0, NULL((void*)0)}
991};
992
993/* 7.5.3.78 */
994static const range_string ue_tmpi_rank_sinr_vals[] = {
995 {0, 0, "0 dB SINR"},
996 {0x0001, 0x07ff, "positive SINR"},
997 {0xf800, 0xffff, "-ve SINR"},
998 {0x8000, 0x8000, "invalid measurement result"},
999 {0x0, 0xffff, "reserved"},
1000 {0, 0, NULL((void*)0)}
1001};
1002
1003
1004
1005/* Table 7.5.2.19-1 */
1006static const value_string num_sinr_per_prb_vals[] = {
1007 { 0, "1" },
1008 { 1, "2" },
1009 { 2, "3" },
1010 { 3, "4" },
1011 { 4, "6" },
1012 { 5, "12" },
1013 { 6, "1 SINR value per section for DFT-s-OFDM" },
1014 { 7, "reserved" },
1015 { 0, NULL((void*)0)}
1016};
1017
1018static const value_string meas_type_id_vals[] = {
1019 { 1, "UE Timing Advance Error" },
1020 { 2, "UE Layer power" },
1021 { 3, "UE frequency offset" },
1022 { 4, "Interference plus Noise for allocated PRBs" },
1023 { 5, "Interference plus Noise for unallocated PRBs" },
1024 { 6, "DMRS-SNR per antenna" },
1025 { 7, "UE positioning measurement report" },
1026 { 8, "UE radial speed measurement report" },
1027 { 9, "UE post-equalization MU inteference measurement" },
1028 { 10, "UE TPMI and rank recommendation measurement" },
1029 { 11, "UE layer pre-equalization SINR report" },
1030 { 0, NULL((void*)0)}
1031};
1032
1033static const value_string beam_type_vals[] = {
1034 { 0, "List of beamId values" },
1035 { 1, "Range of beamId values" },
1036 { 0, NULL((void*)0)}
1037};
1038
1039/* 7.7.24.3 */
1040static const value_string entry_type_vals[] = {
1041 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
1042 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
1043 { 2, "related parameters if have transform precoding disabled " },
1044 { 3, "related parameters if have transform precoding enabled " },
1045 { 0, NULL((void*)0)}
1046};
1047
1048/* Table 7.7.29.3-1 */
1049static const range_string cd_scg_size_vals[] = {
1050 { 0, 0, "1 subcarrier" },
1051 { 1, 1, "1 RB x N subcarriers" },
1052 { 2, 2, "2 RB x N subcarriers" },
1053 { 3, 3, "4 RB x N subcarriers" },
1054 { 4, 4, "8 RB x N subcarriers" },
1055 { 5, 5, "16 RB x N subcarriers" },
1056 { 6, 6, "32 RB x N subcarriers" },
1057 { 7, 15, "reserved"},
1058 { 0, 0, NULL((void*)0)}
1059};
1060
1061
1062/* Table 7.6.1-1 */
1063static const value_string exttype_vals[] = {
1064 {0, "Reserved"},
1065 {1, "Beamforming weights"},
1066 {2, "Beamforming attributes"},
1067 {3, "DL Precoding configuration parameters and indications"},
1068 {4, "Modulation compr. params"},
1069 {5, "Modulation compression additional scaling parameters"},
1070 {6, "Non-contiguous PRB allocation"},
1071 {7, "Multiple-eAxC designation"},
1072 {8, "Regularization factor"},
1073 {9, "Dynamic Spectrum Sharing parameters"},
1074 {10, "Multiple ports grouping"},
1075 {11, "Flexible BF weights"},
1076 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1077 {13, "PRB Allocation with Frequency Hopping"},
1078 {14, "Nulling-layer Info. for ueId-based beamforming"},
1079 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1080 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1081 {17, "Section description for indication of user port group"},
1082 {18, "Section description for Uplink Transmission Management"},
1083 {19, "Compact beamforming information for multiple port"},
1084 {20, "Puncturing extension"},
1085 {21, "Variable PRB group size for channel information"},
1086 {22, "ACK/NACK request"},
1087 {23, "Multiple symbol modulation compression parameters"},
1088 {24, "PUSCH DMRS configuration"},
1089 {25, "Symbol reordering for DMRS-BF"},
1090 {26, "Frequency offset feedback"},
1091 {27, "O-DU controlled dimensionality reduction"},
1092 {28, "O-DU controlled frequency resolution for SINR reporting"},
1093 {29, "Cyclic delay adjustment"},
1094 {30, "PUSCH repetition indication"},
1095 {31, "MCS Information"},
1096 {32, "Rank and TPMI measurement request"},
1097 {0, NULL((void*)0)}
1098};
1099static value_string_ext exttype_vals_ext = VALUE_STRING_EXT_INIT(exttype_vals){ _try_val_to_str_ext_init, 0, (sizeof (exttype_vals) / sizeof
((exttype_vals)[0]))-1, exttype_vals, "exttype_vals", ((void
*)0) }
;
1100
1101
1102/**************************************************************************************/
1103/* Keep track for each Section Extension, which section types are allowed to carry it */
1104typedef struct {
1105 bool_Bool ST0;
1106 bool_Bool ST1;
1107 bool_Bool ST3;
1108 bool_Bool ST5;
1109 bool_Bool ST6;
1110 bool_Bool ST10;
1111 bool_Bool ST11;
1112} AllowedCTs_t;
1113
1114
1115static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE32] = {
1116 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1117 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1118 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1119 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1120 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1121 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1122 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1123 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1124 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1125 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1126 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1127 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1128 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1129 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1130 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1131 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1132 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1133 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1134 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1135 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1136 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1137 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1138 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1139 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1140 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1141 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1142 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1143 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1144 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1145 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1146 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1147 { false0, true1, true1, true1, false0, false0, false0}, // SE 31 (1,3,5)
1148 { false0, false0, false0, true1, false0, false0, false0}, // SE 32 (5)
1149};
1150
1151static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1152{
1153 if (se==0 || se>HIGHEST_EXTTYPE32) {
1154 /* Don't know about new SE, so don't complain.. */
1155 return true1;
1156 }
1157
1158 switch (st) {
1159 case 0:
1160 return ext_cts[se-1].ST0;
1161 case 1:
1162 return ext_cts[se-1].ST1;
1163 case 3:
1164 return ext_cts[se-1].ST3;
1165 case 5:
1166 return ext_cts[se-1].ST5;
1167 case 6:
1168 return ext_cts[se-1].ST6;
1169 case 10:
1170 return ext_cts[se-1].ST10;
1171 case 11:
1172 return ext_cts[se-1].ST11;
1173 default:
1174 /* New/unknown section type that includes 'ef'.. assume ok */
1175 return true1;
1176 }
1177}
1178
1179/************************************************************************************/
1180
1181/* Table 7.7.1.2-2 */
1182static const value_string bfw_comp_headers_iq_width[] = {
1183 {0, "I and Q are 16 bits wide"},
1184 {1, "I and Q are 1 bit wide"},
1185 {2, "I and Q are 2 bits wide"},
1186 {3, "I and Q are 3 bits wide"},
1187 {4, "I and Q are 4 bits wide"},
1188 {5, "I and Q are 5 bits wide"},
1189 {6, "I and Q are 6 bits wide"},
1190 {7, "I and Q are 7 bits wide"},
1191 {8, "I and Q are 8 bits wide"},
1192 {9, "I and Q are 9 bits wide"},
1193 {10, "I and Q are 10 bits wide"},
1194 {11, "I and Q are 11 bits wide"},
1195 {12, "I and Q are 12 bits wide"},
1196 {13, "I and Q are 13 bits wide"},
1197 {14, "I and Q are 14 bits wide"},
1198 {15, "I and Q are 15 bits wide"},
1199 {0, NULL((void*)0)}
1200};
1201
1202/* Table 7.7.1.2-3 */
1203static const value_string bfw_comp_headers_comp_meth[] = {
1204 {COMP_NONE0, "no compression"},
1205 {COMP_BLOCK_FP1, "block floating point"},
1206 {COMP_BLOCK_SCALE2, "block scaling"},
1207 {COMP_U_LAW3, "u-law"},
1208 {4, "beamspace compression type I"},
1209 {5, "beamspace compression type II"},
1210 {0, NULL((void*)0)}
1211};
1212
1213/* 7.7.6.2 rbgSize (resource block group size) */
1214static const value_string rbg_size_vals[] = {
1215 {0, "reserved"},
1216 {1, "1"},
1217 {2, "2"},
1218 {3, "3"},
1219 {4, "4"},
1220 {5, "6"},
1221 {6, "8"},
1222 {7, "16"},
1223 {0, NULL((void*)0)}
1224};
1225
1226/* 7.7.6.5 */
1227static const value_string priority_vals[] = {
1228 {0, "0"},
1229 {1, "+1"},
1230 {2, "-2 (reserved, should not be used)"},
1231 {3, "-1"},
1232 {0, NULL((void*)0)}
1233};
1234
1235/* 7.7.10.2 beamGroupType */
1236static const value_string beam_group_type_vals[] = {
1237 {0x0, "common beam"},
1238 {0x1, "beam matrix indication"},
1239 {0x2, "beam vector listing"},
1240 {0x3, "beamId/ueId listing with associated port-list index"},
1241 {0, NULL((void*)0)}
1242};
1243
1244/* 7.7.9.2 technology (interface name) */
1245static const value_string interface_name_vals[] = {
1246 {0x0, "LTE"},
1247 {0x1, "NR"},
1248 {0, NULL((void*)0)}
1249};
1250
1251/* 7.7.18.4 toT (type of transmission) */
1252static const value_string type_of_transmission_vals[] = {
1253 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1254 {0x1, "uniformly distributed over the transmission window"},
1255 {0x2, "Reserved"},
1256 {0x3, "Reserved"},
1257 {0, NULL((void*)0)}
1258};
1259
1260/* 7.7.2.2 (width of bfa parameters) */
1261static const value_string bfa_bw_vals[] = {
1262 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1263 {1, "2-bit bitwidth"},
1264 {2, "3-bit bitwidth"},
1265 {3, "4-bit bitwidth"},
1266 {4, "5-bit bitwidth"},
1267 {5, "6-bit bitwidth"},
1268 {6, "7-bit bitwidth"},
1269 {7, "8-bit bitwidth"},
1270 {0, NULL((void*)0)}
1271};
1272
1273/* 7.7.2.7 & 7.7.2.8 */
1274static const value_string sidelobe_suppression_vals[] = {
1275 {0, "10 dB"},
1276 {1, "15 dB"},
1277 {2, "20 dB"},
1278 {3, "25 dB"},
1279 {4, "30 dB"},
1280 {5, "35 dB"},
1281 {6, "40 dB"},
1282 {7, ">= 45 dB"},
1283 {0, NULL((void*)0)}
1284};
1285
1286static const value_string lbtTrafficClass_vals[] = {
1287 {1, "Priority 1"},
1288 {2, "Priority 2"},
1289 {3, "Priority 3"},
1290 {4, "Priority 4"},
1291 {0, NULL((void*)0)}
1292};
1293
1294/* 7.5.3.22 */
1295static const value_string lbtPdschRes_vals[] = {
1296 {0, "not sensing – indicates that the O-RU is transmitting data"},
1297 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1298 {2, "success – indicates that the channel was successfully acquired"},
1299 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1300 {0, NULL((void*)0)}
1301};
1302
1303/* Table 7.5.2.15-3 */
1304static const value_string ci_comp_opt_vals[] = {
1305 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1306 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1307 {0, NULL((void*)0)}
1308};
1309
1310/* 7.5.2.17 */
1311static const range_string cmd_scope_vals[] = {
1312 {0, 0, "ARRAY-COMMAND"},
1313 {1, 1, "CARRIER-COMMAND"},
1314 {2, 2, "O-RU-COMMAND"},
1315 {3, 15, "reserved"},
1316 {0, 0, NULL((void*)0)}
1317};
1318
1319/* N.B., table in 7.5.3.38 is truncated.. */
1320static const range_string st4_cmd_type_vals[] = {
1321 {0, 0, "reserved for future command types"},
1322 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1323 {2, 2, "TDD_CONFIG_PATTERN"},
1324 {3, 3, "TRX_CONTROL"},
1325 {4, 4, "ASM"},
1326 {5, 5, "TRX_CONTROL_BIDIR"},
1327 {6, 255, "reserved for future command types"},
1328 {0, 0, NULL((void*)0)}
1329};
1330
1331/* Table 7.5.3.51-1 */
1332static const value_string log2maskbits_vals[] = {
1333 {0, "reserved"},
1334 {1, "min antMask size is 16 bits.."},
1335 {2, "min antMask size is 16 bits.."},
1336 {3, "min antMask size is 16 bits.."},
1337 {4, "16 bits"},
1338 {5, "32 bits"},
1339 {6, "64 bits"},
1340 {7, "128 bits"},
1341 {8, "256 bits"},
1342 {9, "512 bits"},
1343 {10, "1024 bits"},
1344 {11, "2048 bits"},
1345 {12, "4096 bits"},
1346 {13, "8192 bits"},
1347 {14, "16384 bits"},
1348 {15, "reserved"},
1349 {0, NULL((void*)0)}
1350};
1351
1352/* Table 16.1-1 Sleep modes */
1353static const value_string sleep_mode_trx_vals[] = {
1354 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1355 { 1, "TRXC-mode1-wake-up-duration (L)"},
1356 { 2, "TRXC-mode2-wake-up-duration (M)"},
1357 { 3, "TRXC-mode3-wake-up-duration (N)"},
1358 { 0, NULL((void*)0)}
1359};
1360
1361static const value_string sleep_mode_asm_vals[] = {
1362 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1363 { 1, "ASM-mode1-wake-up-duration (L)"},
1364 { 2, "ASM-mode2-wake-up-duration (M)"},
1365 { 3, "ASM-mode3-wake-up-duration (N)"},
1366 { 0, NULL((void*)0)}
1367};
1368
1369/* 7.7.21.3.1 */
1370static const value_string prg_size_st5_vals[] = {
1371 { 0, "reserved"},
1372 { 1, "Precoding resource block group size as WIDEBAND"},
1373 { 2, "Precoding resource block group size 2"},
1374 { 3, "Precoding resource block group size 4"},
1375 { 0, NULL((void*)0)}
1376};
1377
1378/* 7.7.21.3.2 */
1379static const value_string prg_size_st6_vals[] = {
1380 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1381 { 1, "Precoding resource block group size as WIDEBAND"},
1382 { 2, "Precoding resource block group size 2"},
1383 { 3, "Precoding resource block group size 4"},
1384 { 0, NULL((void*)0)}
1385};
1386
1387/* 7.7.24.4 */
1388static const value_string alpn_per_sym_vals[] = {
1389 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1390 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1391 { 0, NULL((void*)0)}
1392};
1393
1394/* 7.7.24.5 */
1395static const value_string ant_dmrs_snr_vals[] = {
1396 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1397 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1398 { 0, NULL((void*)0)}
1399};
1400
1401/* 7.7.24.14 */
1402static const value_string dtype_vals[] = {
1403 { 0, "assume DMRS configuration type 1"},
1404 { 1, "assume DMRS configuration type 2"},
1405 { 0, NULL((void*)0)}
1406};
1407
1408/* 7.7.24.17 */
1409static const value_string papr_type_vals[] = {
1410 { 0, "sequence generator type 1 for short sequence lengths"},
1411 { 1, "sequence generator type 1 for long sequence lengths"},
1412 { 2, "sequence generator type 2 for short sequence lengths"},
1413 { 3, "sequence generator type 2 for long sequence lengths"},
1414 { 0, NULL((void*)0)}
1415};
1416
1417/* 7.7.24.18 */
1418static const value_string hopping_mode_vals[] = {
1419 { 0, "neither group, nor sequence hopping is enabled"},
1420 { 1, "group hopping is enabled and sequence hopping is disabled"},
1421 { 2, "sequence hopping is enabled and group hopping is disabled"},
1422 { 3, "reserved"},
1423 { 0, NULL((void*)0)}
1424};
1425
1426/* Table 7.7.31.2-1 */
1427static const value_string mcs_table_vals[] = {
1428 { 0, "MCS index table 1 for PDSCH and PUSCH without transform precoding" },
1429 { 1, "MCS index table 2 for PDSCH and PUSCH without transform precoding" },
1430 { 2, "MCS index table 3 for PDSCH and PUSCH without transform precoding" },
1431 { 3, "MCS index table 4 for PDSCH" },
1432 { 4, "MCS index table for PUSCH with transform precoding and 64QAM" },
1433 { 5, "MCS index table 2 for PUSCH with transform precoding and 64QAM" },
1434 { 0, NULL((void*)0)}
1435};
1436
1437/* 7.7.32.9 */
1438static const value_string full_pwr_mode_vals[] = {
1439 { 0, "not configured"},
1440 { 1, "full power mode 0"},
1441 { 2, "full power mode 1"},
1442 { 3, "full power mode 2"},
1443 { 0, NULL((void*)0)}
1444};
1445
1446
1447static const true_false_string tfs_sfStatus =
1448{
1449 "subframe was transmitted",
1450 "subframe was dropped"
1451};
1452
1453static const true_false_string tfs_lbtBufErr =
1454{
1455 "buffer overflow – data received at O-RU is larger than the available buffer size",
1456 "reserved"
1457};
1458
1459static const true_false_string tfs_partial_full_sf = {
1460 "partial SF",
1461 "full SF"
1462};
1463
1464static const true_false_string disable_tdbfns_tfs = {
1465 "beam numbers excluded",
1466 "beam numbers included"
1467};
1468
1469static const true_false_string continuity_indication_tfs = {
1470 "continuity between current and next bundle",
1471 "discontinuity between current and next bundle"
1472};
1473
1474static const true_false_string prb_mode_tfs = {
1475 "PRB-BLOCK mode",
1476 "PRB-MASK mode"
1477};
1478
1479static const true_false_string symbol_direction_tfs = {
1480 "DL symbol",
1481 "UL symbol"
1482};
1483
1484static const true_false_string symbol_guard_tfs = {
1485 "guard symbol",
1486 "non-guard symbol"
1487};
1488
1489static const true_false_string beam_numbers_included_tfs = {
1490 "time-domain beam numbers excluded in this command",
1491 "time-domain beam numbers included in this command"
1492};
1493
1494static const true_false_string measurement_flag_tfs = {
1495 "at least one additional measurement report or command after the current one",
1496 "no additional measurement report or command"
1497};
1498
1499static const true_false_string repetition_se6_tfs = {
1500 "repeated highest priority data section in the C-Plane message",
1501 "no repetition"
1502};
1503
1504static const true_false_string repetition_se19_tfs = {
1505 "per port information not present in the extension",
1506 "per port info present in the extension"
1507};
1508
1509static const true_false_string tfs_report_no_report_pos_meas =
1510{
1511 "Report MEAS_UE_POS for UE",
1512 "Do not report UE_POS for UE"
1513};
1514
1515
1516/* Forward declaration */
1517static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1518 unsigned comp_meth,
1519 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1520
1521
1522static const true_false_string ready_tfs = {
1523 "message is a \"ready\" message",
1524 "message is a ACK message"
1525};
1526
1527static const true_false_string multi_sd_scope_tfs = {
1528 "Puncturing pattern applies to current and following sections",
1529 "Puncturing pattern applies to current section"
1530};
1531
1532static const true_false_string tfs_ueid_reset = {
1533 "cannot assume same UE as in preceding slot",
1534 "can assume same UE as in preceding slot"
1535};
1536
1537
1538/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1539typedef struct {
1540 /* Ext 6 config */
1541 bool_Bool ext6_set;
1542 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1543
1544 uint8_t ext6_num_bits_set;
1545 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1546 /* TODO: store an f value for each bit position? */
1547
1548 /* Ext 12 config */
1549 bool_Bool ext12_set;
1550 unsigned ext12_num_pairs;
1551#define MAX_BFW_EXT12_PAIRS128 128
1552 struct {
1553 uint8_t off_start_prb;
1554 uint8_t num_prb;
1555 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1556
1557 /* Ext 13 config */
1558 bool_Bool ext13_set;
1559 unsigned ext13_num_start_prbs;
1560#define MAX_BFW_EXT13_ALLOCATIONS128 128
1561 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1562 /* TODO: store nextSymbolId here too? */
1563
1564 /* Ext 21 config */
1565 bool_Bool ext21_set;
1566 uint8_t ext21_ci_prb_group_size;
1567
1568 /* Results/settings (after calling ext11_work_out_bundles()) */
1569 uint32_t num_bundles;
1570#define MAX_BFW_BUNDLES512 512
1571 struct {
1572 uint32_t start; /* first prb of bundle */
1573 uint32_t end; /* last prb of bundle*/
1574 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1575 } bundles[MAX_BFW_BUNDLES512];
1576} ext11_settings_t;
1577
1578
1579/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1580/* Won't be called with numBundPrb=0 */
1581static void ext11_work_out_bundles(unsigned startPrbc,
1582 unsigned numPrbc,
1583 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1584 ext11_settings_t *settings)
1585{
1586 /* Allocation configured by ext 6 */
1587 if (settings->ext6_set) {
1588 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1589
1590 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1591 rbg size. i.e. each bundle gets the correct number of PRBs until
1592 all rbg entries are consumed... */
1593
1594 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1595
1596 if (bundles_per_entry == 0) {
1597 bundles_per_entry = 1;
1598 }
1599
1600 /* Ext6 behaviour may also be affected by ext 21 */
1601 if (settings->ext21_set) {
1602 /* N.B., have already checked that numPrbc is not 0 */
1603
1604 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1605 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1606
1607 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1608 }
1609
1610 unsigned bundles_set = 0;
1611 bool_Bool reached_orphan = false0;
1612 /* For each bit set in ext6 rbg mask.. */
1613 for (unsigned n=0;
1614 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1615 n++) {
1616
1617 /* Watch out for array bound */
1618 if (n >= 28) {
1619 break;
1620 }
1621
1622 /* For each bundle... */
1623
1624 /* TODO: Work out where first PRB is */
1625 /* May not be the start of an rbg block... */
1626 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1627
1628 /* For each bundle within identified rbgSize block */
1629 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1630
1631 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1632
1633 /* Start already beyond end, so doesn't count. */
1634 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1635 settings->num_bundles = bundles_set;
1636 return;
1637 }
1638
1639 /* Bundle consists of numBundPrb bundles */
1640 /* TODO: may involve PRBs from >1 rbg blocks.. */
1641 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1642 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1643 /* Extends beyond end, so counts but is an orphan bundle */
1644 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1645 settings->bundles[bundles_set].is_orphan = true1;
1646 reached_orphan = true1;
1647 }
1648
1649 /* Get out if have reached array bound */
1650 if (++bundles_set == MAX_BFW_BUNDLES512) {
1651 return;
1652 }
1653 }
1654 }
1655 settings->num_bundles = bundles_set;
1656 }
1657
1658 /* Allocation configured by ext 12 */
1659 else if (settings->ext12_set) {
1660 /* First, allocate normally from startPrbc, numPrbc */
1661 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1662
1663 /* Don't overflow settings->bundles[] ! */
1664 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1665
1666 for (uint32_t n=0; n < settings->num_bundles; n++) {
1667 settings->bundles[n].start = startPrbc + n*numBundPrb;
1668 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1669 /* Does it go beyond the end? */
1670 if (settings->bundles[n].end > startPrbc+numPrbc) {
1671 settings->bundles[n].end = startPrbc+numPrbc;
1672 settings->bundles[n].is_orphan = true1;
1673 }
1674 }
1675 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1676 return;
1677 }
1678
1679 unsigned prb_offset = startPrbc + numPrbc;
1680
1681 /* Loop over pairs, adding bundles for each */
1682 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1683 prb_offset += settings->ext12_pairs[p].off_start_prb;
1684 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1685
1686 for (uint32_t n=0; n < pair_bundles; n++) {
1687 unsigned idx = settings->num_bundles;
1688
1689 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1690 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1691 /* Does it go beyond the end? */
1692 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1693 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1694 settings->bundles[idx].is_orphan = true1;
1695 }
1696 /* Range check / return */
1697 settings->num_bundles++;
1698 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1699 return;
1700 }
1701 }
1702
1703 prb_offset += settings->ext12_pairs[p].num_prb;
1704 }
1705 }
1706
1707 /* Allocation configured by ext 13 */
1708 else if (settings->ext13_set) {
1709 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1710 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1711
1712 /* Don't overflow settings->bundles[] ! */
1713 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1714
1715 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1716 unsigned alloc_start = alloc * alloc_size;
1717 for (uint32_t n=0; n < alloc_size; n++) {
1718 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1719 /* ERROR */
1720 return;
1721 }
1722 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1723 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1724 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1725 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1726 settings->bundles[alloc_start+n].is_orphan = true1;
1727 }
1728 }
1729 }
1730 }
1731
1732 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1733 else {
1734 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1735
1736 /* Don't overflow settings->bundles[] */
1737 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1738
1739 /* For each bundle.. */
1740 for (uint32_t n=0; n < settings->num_bundles; n++) {
1741 /* Allocate start and end */
1742 settings->bundles[n].start = startPrbc + n*numBundPrb;
1743 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1744 /* If would go beyond end of PRBs, limit and identify as orphan */
1745 if (settings->bundles[n].end > startPrbc+numPrbc) {
1746 settings->bundles[n].end = startPrbc+numPrbc;
1747 settings->bundles[n].is_orphan = true1;
1748 }
1749 }
1750 }
1751}
1752
1753
1754/* Modulation Compression configuration */
1755typedef struct {
1756 /* Application of each entry is filtered by RE.
1757 * TODO: should also be filtered by PRB + symbol... */
1758 uint16_t mod_compr_re_mask;
1759
1760 /* Settings to apply */
1761 bool_Bool mod_compr_csf;
1762 float mod_compr_scaler;
1763} mod_compr_config_t;
1764
1765/* Multiple configs with a section */
1766typedef struct {
1767 uint16_t section_id;
1768 uint32_t num_configs;
1769
1770 #define MAX_MOD_COMPR_CONFIGS12 12
1771 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1772} section_mod_compr_config_t;
1773
1774/* Flow has separate configs for each section */
1775typedef struct {
1776 uint16_t num_sections;
1777
1778 /* Separate config for each section */
1779 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1780} mod_compr_params_t;
1781
1782
1783typedef struct {
1784 uint32_t frame_number;
1785 nstime_t frame_time;
1786
1787 /* Timing to match */
1788 uint8_t frame;
1789 uint8_t subframe;
1790 uint8_t slot;
1791 uint8_t startSymbol;
1792
1793 bool_Bool in_use;
1794 uint16_t startPrb;
1795 uint16_t numPrb;
1796 uint16_t numSymbols;
1797 uint16_t beamIds[273];
1798} section_details_t;
1799
1800typedef struct {
1801 uint16_t sectionId;
1802 /* For the same sectionId, can have 2 currently active entries.. */
1803 section_details_t details[2];
1804} expected_section_data_t;
1805
1806
1807/*******************************************************/
1808/* Overall state of a flow (eAxC/plane) */
1809typedef struct {
1810 /* State for sequence analysis [each direction] */
1811 bool_Bool last_frame_seen[2];
1812 uint32_t last_frame[2];
1813 uint8_t next_expected_sequence_number[2];
1814
1815 /* expected frames. sectionId -> expected_section_data_t* */
1816 wmem_tree_t *expected_sections[2]; /* [direction] */
1817
1818 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1819 Note that this assumes that the same ackNackId will not be reused within a state,
1820 which may well not be valid */
1821 wmem_tree_t *ack_nack_requests;
1822
1823 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1824 Note that this appears in the common section header parts of ST1, ST3, ST5,
1825 so can still be over-written per sectionId in the U-Plane */
1826 unsigned ul_ud_comp_hdr_frame;
1827 bool_Bool ul_ud_comp_hdr_set;
1828 unsigned ul_ud_comp_hdr_bit_width;
1829 int ul_ud_comp_hdr_compression;
1830
1831 bool_Bool udcomphdrDownlink_heuristic_result_set;
1832 bool_Bool udcomphdrDownlink_heuristic_result;
1833 bool_Bool udcomphdrUplink_heuristic_result_set;
1834 bool_Bool udcomphdrUplink_heuristic_result;
1835
1836 /* Modulation compression params */
1837 mod_compr_params_t mod_comp_params;
1838} flow_state_t;
1839
1840static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1841 unsigned sectionId)
1842{
1843 if (flow == NULL((void*)0)) {
1844 return NULL((void*)0);
1845 }
1846
1847 /* Look for this section among existing entries */
1848 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1849 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1850 return &flow->mod_comp_params.sections[s];
1851 }
1852 }
1853
1854 /* Not found, so try to add a new one */
1855 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1856 /* Can't allocate one! */
1857 return NULL((void*)0);
1858 }
1859 else {
1860 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1861 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1862 }
1863}
1864
1865static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1866 unsigned sectionId)
1867{
1868 if (flow == NULL((void*)0)) {
1869 return NULL((void*)0);
1870 }
1871
1872 /* Look for this section among existing entries */
1873 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1874 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1875 return &flow->mod_comp_params.sections[s];
1876 }
1877 }
1878
1879 /* Not found */
1880 return NULL((void*)0);
1881}
1882
1883
1884
1885typedef struct {
1886 uint32_t request_frame_number;
1887 nstime_t request_frame_time;
1888 enum {
1889 SE22,
1890 ST4Cmd1,
1891 ST4Cmd2,
1892 ST4Cmd3,
1893 ST4Cmd4
1894 } requestType;
1895
1896 uint32_t response_frame_number;
1897 nstime_t response_frame_time;
1898} ack_nack_request_t;
1899
1900static const value_string acknack_type_vals[] = {
1901 { SE22, "SE 22" },
1902 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1903 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1904 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1905 { ST4Cmd4, "ST4 (ASM)" },
1906 { 0, NULL((void*)0)}
1907};
1908
1909#define ORAN_C_PLANE0 0
1910#define ORAN_U_PLANE1 1
1911
1912/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1913static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1914{
1915 uint16_t eth_bits = 0;
1916 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1917 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1918 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1919 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1920 if (!opposite_dir) {
1921 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1922 }
1923 else {
1924 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1925 }
1926 }
1927 return eaxc_id | (plane << 16) | (eth_bits << 17);
1928}
1929
1930
1931/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1932static wmem_tree_t *flow_states_table;
1933
1934typedef struct {
1935 uint32_t frame_number;
1936 uint16_t sectionId;
1937 uint32_t gap_in_usecs;
1938 uint8_t symbol;
1939 uint16_t startPrbu;
1940 uint16_t numPrbu;
1941} corresponding_uplane_frame;
1942
1943/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1944static wmem_tree_t *flow_results_table;
1945
1946typedef struct {
1947 /* Sequence analysis */
1948 bool_Bool unexpected_seq_number;
1949 uint8_t expected_sequence_number;
1950 uint32_t previous_frame;
1951
1952 /* sectionId -> expected_section_data_t* */
1953 /* Frame only covers one direction */
1954 wmem_tree_t *expected_sections;
1955
1956 /* List of u-plane frames (corresponding_uplane_frame*) corresponding to a c-plane frame */
1957 wmem_list_t *u_plane_frames;
1958} flow_result_t;
1959
1960
1961/* Uplink timing */
1962/* For a given symbol, track first to last UL frame to find out first-last time */
1963/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1964/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1965static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1966{
1967 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1968}
1969
1970typedef struct {
1971 uint32_t first_frame;
1972 nstime_t first_frame_time;
1973 uint32_t frames_seen_in_symbol;
1974 uint32_t last_frame_in_symbol;
1975} ul_timing_for_slot;
1976
1977/* Set during first pass. timing_key -> ul_timing_for_slot* */
1978static wmem_tree_t *ul_symbol_timing;
1979
1980
1981/* Tracking lifetimes of DL beamIds */
1982typedef struct {
1983 uint32_t frame_defined;
1984 uint32_t symbol_when_defined;
1985} bfw_definition;
1986
1987/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1988static wmem_tree_t *dl_beam_ids_defined;
1989/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1990static wmem_tree_t *dl_beam_ids_results;
1991
1992
1993static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1994 ack_nack_request_t *response);
1995
1996
1997
1998
1999static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2000 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
2001
2002 /* Write the given formatted text to:
2003 - the info column (if pinfo != NULL)
2004 - 1 or 2 other labels (optional)
2005 */
2006static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2007 packet_info *pinfo, const char *format, ...)
2008{
2009#define MAX_INFO_BUFFER256 256
2010 char info_buffer[MAX_INFO_BUFFER256];
2011 va_list ap;
2012
2013 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
2014 return;
2015 }
2016
2017 va_start(ap, format)__builtin_va_start(ap, format);
2018 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
2019 va_end(ap)__builtin_va_end(ap);
2020
2021 /* Add to indicated places */
2022 if (pinfo != NULL((void*)0)) {
2023 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2024 }
2025 if (ti1 != NULL((void*)0)) {
2026 proto_item_append_text(ti1, "%s", info_buffer);
2027 }
2028 if (ti2 != NULL((void*)0)) {
2029 proto_item_append_text(ti2, "%s", info_buffer);
2030 }
2031}
2032
2033/* Add section labels (type + PRB range) for C-Plane, U-Plane */
2034static void
2035write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
2036 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
2037{
2038 switch (num_prbx) {
2039 case 0:
2040 /* None -> all */
2041 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
2042 break;
2043 case 1:
2044 /* Single PRB */
2045 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
2046 break;
2047 default:
2048 /* Range */
2049 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
2050 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
2051 }
2052}
2053
2054static void
2055write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
2056 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
2057 uint32_t num_trx)
2058{
2059 switch (num_prbx) {
2060 case 0:
2061 /* TODO: ?? */
2062 break;
2063 case 1:
2064 /* Single PRB */
2065 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2066 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
2067 section_id, ueId, start_prbx, num_trx);
2068 break;
2069 default:
2070 /* Range */
2071 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2072 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
2073 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
2074 }
2075}
2076
2077/* Add a reserved field, and warn if value isn't 0 */
2078/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
2079static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
2080{
2081 uint32_t reserved;
2082 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
2083 if (reserved != 0) {
2084 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
2085 "reserved field saw value of 0x%x", reserved);
2086 }
2087}
2088
2089/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2090static void
2091addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2092{
2093 /* Subtree */
2094 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2095 tvb, *offset, 2, ENC_NA0x00000000);
2096 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2097
2098 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2099 int id_offset = *offset;
2100
2101 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2102 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2103 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2104 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2105 *eAxC = 0;
2106 *offset += 2;
2107 return;
2108 }
2109
2110 unsigned bit_offset = *offset * 8;
2111
2112 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2113 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2114
2115 /* DU Port ID */
2116 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_du_port_id, tvb, bit_offset, pref_du_port_id_bits, &duPortId, ENC_BIG_ENDIAN0x00000000);
2117 bit_offset += pref_du_port_id_bits;
2118 /* BandSector ID */
2119 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2120 bit_offset += pref_bandsector_id_bits;
2121 /* CC ID */
2122 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2123 bit_offset += pref_cc_id_bits;
2124 /* RU Port ID */
2125 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_ru_port_id, tvb, bit_offset, pref_ru_port_id_bits, &ruPortId, ENC_BIG_ENDIAN0x00000000);
2126 *offset += 2;
2127
2128 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2129 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2130 char id[16];
2131 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2132 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2133 proto_item_set_generated(pi);
2134
2135 tap_info->eaxc = *eAxC;
2136 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2137 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2138 tap_info->eaxc_cc_id = (uint16_t)ccId;
2139 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2140}
2141
2142/* Uniquely identify the U-plane stream that may need to be reassembled */
2143static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2144 uint8_t frameid, uint8_t subframeid,
2145 uint8_t slotid, uint8_t symbolid)
2146{
2147 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2148 and hope for no collisions */
2149 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2150 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2151}
2152
2153/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2154/* Return out info that may be used for sequence number analysis and reassembly */
2155static int
2156addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2157 uint32_t *subseqid, uint32_t *e)
2158{
2159 /* Subtree */
2160 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2161 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2162
2163 /* Sequence ID (8 bits) */
2164 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2165 offset += 1;
2166
2167 /* Show link back to previous sequence ID, if set */
2168 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2169 if (result) {
2170 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2171 proto_item_set_generated(prev_ti);
2172 }
2173
2174 /* E bit */
2175 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2176 /* Subsequence ID (7 bits) */
2177 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2178 offset += 1;
2179
2180 /* radio-transport fragmentation not allowed for C-Plane messages */
2181 if (plane == ORAN_C_PLANE0) {
2182 if (*e !=1 || *subseqid != 0) {
2183 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2184 }
2185 }
2186
2187 /* Summary */
2188 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2189 return offset;
2190}
2191
2192static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2193{
2194 uint64_t temp_val;
2195
2196 static int * const symbol_mask_flags[] = {
2197 &hf_oran_symbol_mask_s13,
2198 &hf_oran_symbol_mask_s12,
2199 &hf_oran_symbol_mask_s11,
2200 &hf_oran_symbol_mask_s10,
2201 &hf_oran_symbol_mask_s9,
2202 &hf_oran_symbol_mask_s8,
2203 &hf_oran_symbol_mask_s7,
2204 &hf_oran_symbol_mask_s6,
2205 &hf_oran_symbol_mask_s5,
2206 &hf_oran_symbol_mask_s4,
2207 &hf_oran_symbol_mask_s3,
2208 &hf_oran_symbol_mask_s2,
2209 &hf_oran_symbol_mask_s1,
2210 &hf_oran_symbol_mask_s0,
2211 NULL((void*)0)
2212 };
2213
2214 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2215 hf_oran_symbol_mask,
2216 ett_oran_symbol_mask, symbol_mask_flags,
2217 ENC_BIG_ENDIAN0x00000000, &temp_val);
2218 /* Set out parameters */
2219 if (symbol_mask) {
2220 *symbol_mask = (uint32_t)temp_val;
2221 }
2222 if (ti) {
2223 *ti = temp_ti;
2224 }
2225 return offset+2;
2226}
2227
2228/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2229static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2230 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2231{
2232 /* Subtree */
2233 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2234 tvb, offset, 1, "",
2235 "bfwCompHdr");
2236 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2237
2238 /* Width and method */
2239 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2240 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2241 /* Special case: 0 -> 16 */
2242 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2243 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2244 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2245 offset++;
2246
2247 /* Summary */
2248 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2249 *iq_width,
2250 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2251
2252 return offset;
2253}
2254
2255/* Return offset */
2256/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2257 each BFW is actually for.. */
2258static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2259{
2260 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2261 /* K is the number of elements in uncompressed beamforming weight vector.
2262 * Calculated from parameters describing tx-array or tx-array */
2263 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2264
2265 static uint16_t trx_enabled[1024];
2266
2267 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2268 static int * const mask_bits[] = {
2269 &hf_oran_active_beamspace_coefficient_n1,
2270 &hf_oran_active_beamspace_coefficient_n2,
2271 &hf_oran_active_beamspace_coefficient_n3,
2272 &hf_oran_active_beamspace_coefficient_n4,
2273 &hf_oran_active_beamspace_coefficient_n5,
2274 &hf_oran_active_beamspace_coefficient_n6,
2275 &hf_oran_active_beamspace_coefficient_n7,
2276 &hf_oran_active_beamspace_coefficient_n8,
2277 NULL((void*)0)
2278 };
2279
2280 *num_trx_entries = 0;
2281 uint64_t val;
2282 for (unsigned n=0; n < k_octets; n++) {
2283 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2284 hf_oran_activeBeamspaceCoefficientMask,
2285 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2286 ENC_BIG_ENDIAN0x00000000, &val);
2287 offset++;
2288 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2289 for (unsigned b=0; b < 8; b++) {
2290 if ((1 << b) & (unsigned)val) {
2291 if (((n*8)+b) < pref_num_bf_antennas) {
2292 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2293 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2294 }
2295 }
2296 }
2297 }
2298 }
2299 /* Set pointer to static array */
2300 *trx_entries = trx_enabled;
2301
2302 /* Show how many bits set */
2303 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2304 offset-k_octets, k_octets, *num_trx_entries);
2305 proto_item_set_generated(ti);
2306
2307 return offset;
2308}
2309
2310static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2311{
2312 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2313 tap_info->beams[tap_info->num_beams++] = beam_id;
2314 }
2315}
2316
2317
2318/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2319 * Depends upon passed-in bfwCompMeth (field may be empty) */
2320static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2321 proto_item *meth_ti, uint32_t *bfw_comp_method,
2322 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2323{
2324 if (*bfw_comp_method == COMP_NONE0) {
2325 /* Absent! */
2326 *num_trx_entries = 0;
2327 *supported = true1;
2328 return offset;
2329 }
2330
2331 /* Subtree */
2332 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2333 tvb, offset, 1, "",
2334 "bfwCompParam");
2335 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2336
2337 proto_item_append_text(bfwcompparam_ti,
2338 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2339
2340 *num_trx_entries = 0;
2341 *supported = false0;
2342 switch (*bfw_comp_method) {
2343 case COMP_BLOCK_FP1: /* block floating point */
2344 /* 4 reserved bits + exponent */
2345 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2346 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2347 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2348 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2349 *supported = true1;
2350 offset++;
2351 break;
2352 case COMP_BLOCK_SCALE2: /* block scaling */
2353 /* Separate into integer and fractional bits? */
2354 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2355 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2356 offset++;
2357 break;
2358 case COMP_U_LAW3: /* u-law */
2359 /* compBitWidth, compShift */
2360 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2361 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2362 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2363 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2364 offset++;
2365 break;
2366 case 4: /* beamspace I (BLOCK SCALING) */
2367 /* activeBeamspaceCoefficientMask */
2368 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2369 *bfw_comp_method = COMP_BLOCK_SCALE2;
2370 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2371 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2372 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2373 offset++;
2374 break;
2375 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2376 /* activeBeamspaceCoefficientMask */
2377 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2378 /* reserved (4 bits) + exponent (4 bits) */
2379 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2380 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2381 offset += 1;
2382 *bfw_comp_method = COMP_BLOCK_FP1;
2383 *supported = true1;
2384 break;
2385
2386 default:
2387 /* Not handled */
2388 break;
2389 }
2390
2391 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2392
2393 /* Can't go on if compression scheme not supported */
2394 if (!(*supported) && meth_ti) {
2395 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2396 "BFW Compression method %u (%s) not decompressed by dissector",
2397 *bfw_comp_method,
2398 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2399 }
2400 return offset;
2401}
2402
2403
2404/* Special case for uncompressed value with given iq_width */
2405static float uncompressed_to_float(uint32_t bits, uint32_t iq_width)
2406{
2407 if (iq_width == 0 || iq_width > 16) {
2408 /* Not valid */
2409 return 0.0;
2410 }
2411
2412 uint16_t mask = (1U << (iq_width-1)) - 1;
2413 int16_t i16 = (bits < mask) ? (bits & mask) : (bits - (1<<iq_width));
2414
2415 if (show_unscaled_values) {
2416 return (float)i16;
2417 }
2418 return ((float)i16) / (mask);
2419}
2420
2421/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2422static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2423 uint32_t exponent,
2424 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2425 section_mod_compr_config_t *m_c_p, uint8_t re)
2426{
2427 switch (comp_method) {
2428 case COMP_NONE0: /* no compression */
2429 return uncompressed_to_float(bits, iq_width);
2430
2431 case COMP_BLOCK_FP1: /* block floating point */
2432 case BFP_AND_SELECTIVE_RE5:
2433 {
2434 /* A.1.3 Block Floating Point Decompression Algorithm */
2435 int32_t cPRB = bits;
2436 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2437
2438 /* Check last bit, in case we need to flip to -ve */
2439 if (cPRB >= (1<<(iq_width-1))) {
2440 cPRB -= (1<<iq_width);
2441 }
2442
2443 /* Unscale (8.1.3.1) */
2444 cPRB *= scaler;
2445 if (show_unscaled_values) {
2446 return (float)cPRB;
2447 }
2448
2449 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2450 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 */
2451
2452 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2453 return ret;
2454 }
2455
2456 case COMP_BLOCK_SCALE2:
2457 case COMP_U_LAW3:
2458 /* Not supported! But will be reported as expert info outside of this function! */
2459 return 0.0;
2460
2461 case COMP_MODULATION4:
2462 case MOD_COMPR_AND_SELECTIVE_RE6:
2463 {
2464 /* Described in A.5 (with pseudo code) */
2465 /* N.B., Applies to downlink data only - is not used for BFW */
2466
2467 /* Defaults if not overridden. TODO: what should these be? */
2468 bool_Bool csf = false0;
2469 float mcScaler = (float)(1 << 11);
2470
2471 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2472 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2473 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2474 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2475 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2476 /* Return first (should be only) found */
2477 csf = m_c_p->configs[c].mod_compr_csf;
2478 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2479 break;
2480 }
2481 }
2482 }
2483
2484 int32_t cPRB = bits;
2485
2486 /* 2) Map iqSample to iqSampleFx */
2487 /* Check last bit, in case we need to flip to -ve */
2488 if (cPRB >= (1<<(iq_width-1))) {
2489 cPRB -= (1<<iq_width);
2490 }
2491 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2492
2493
2494 /* 3) or 4) (b) - add unshifted value if csf set */
2495 float csf_to_add = 0.0;
2496 if (csf) {
2497 /* Unshift the constellation point */
2498 csf_to_add = (float)1.0 / (1 << (iq_width));
2499 }
2500 iqSampleFx += csf_to_add;
2501
2502 /* 3) or 4) (c) - unscaling */
2503 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2504 return iqSampleScaled;
2505 }
2506
2507 default:
2508 /* Not supported! But will be reported as expert info outside of this function! */
2509 return 0.0;
2510 }
2511}
2512
2513/* Out-of-range value used for special case */
2514#define ORPHAN_BUNDLE_NUMBER999 999
2515
2516/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2517static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2518 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2519 section_mod_compr_config_t *mod_compr_params,
2520 uint32_t num_weights_per_bundle,
2521 uint8_t iq_width,
2522 unsigned bundle_number,
2523 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2524 uint32_t symbol_count,
2525 section_details_t *section_details,
2526 oran_tap_info *tap_info)
2527{
2528 /* Set bundle name */
2529 char bundle_name[32];
2530 if (!is_orphan) {
2531 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2532 }
2533 else {
2534 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2535 }
2536
2537 /* Create Bundle root */
2538 proto_item *bundle_ti;
2539 if (first_prb != last_prb) {
2540 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2541 tvb, offset, 0, "",
2542 "%s: (PRBs %3u-%3u)",
2543 bundle_name,
2544 first_prb, last_prb);
2545 }
2546 else {
2547 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2548 tvb, offset, 0, "",
2549 "%s: (PRB %3u)",
2550 bundle_name,
2551 first_prb);
2552 }
2553 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2554
2555 /* Generated bundle id */
2556 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2557 bundle_number);
2558 proto_item_set_generated(bundleid_ti);
2559 proto_item_set_hidden(bundleid_ti);
2560
2561 /* bfwCompParam */
2562 bool_Bool compression_method_supported = false0;
2563 unsigned exponent = 0;
2564 unsigned num_trx_entries = 0;
2565 uint16_t *trx_entries;
2566 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2567 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2568 &num_trx_entries, &trx_entries);
2569
2570 /* Create Bundle subtree */
2571 int bit_offset = offset*8;
2572 int bfw_offset;
2573
2574 /* contInd */
2575 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2576 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2577 /* beamId */
2578 uint32_t beam_id;
2579 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2580 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2581 bit_offset += 16;
2582 add_beam_id_to_tap(tap_info, beam_id);
2583
2584 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2585 if (section_details) {
2586 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2587 if (prb < 273) {
2588 section_details->beamIds[prb] = beam_id;
2589 }
2590 }
2591 }
2592 }
2593
2594 /* On first pass, record that beamId was defined here */
2595 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2596 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2597 definition->frame_defined = pinfo->num;
2598 definition->symbol_when_defined = symbol_count;
2599 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2600 }
2601
2602
2603 /* Number of weights per bundle (from preference) */
2604 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2605 num_weights_per_bundle);
2606 proto_item_set_generated(wpb_ti);
2607
2608 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2609 if (num_trx_entries != 0) {
2610 num_weights_per_bundle = num_trx_entries;
2611 }
2612
2613 bool_Bool non_zero_weights_seen = false0;
2614 int bit_offset_before_weights = bit_offset;
2615 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2616
2617 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2618
2619 /* Create subtree */
2620 bfw_offset = bit_offset / 8;
2621 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2622 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2623 tvb, bfw_offset, bfw_extent,
2624 "", "TRX %3u: (", trx_index);
2625 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2626
2627 /* I */
2628 /* Get bits, and convert to float. */
2629 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2630 if (bits) {
2631 non_zero_weights_seen = true1;
2632 }
2633 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2634 exponent, mod_compr_params, 0 /* RE */);
2635 /* Add to tree. */
2636 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);
2637 bit_offset += iq_width;
2638 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2639
2640 /* Q */
2641 /* Get bits, and convert to float. */
2642 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2643 if (bits) {
2644 non_zero_weights_seen = true1;
2645 }
2646
2647 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2648 exponent, mod_compr_params, 0 /* RE */);
2649 /* Add to tree. */
2650 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);
2651 bit_offset += iq_width;
2652 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2653 }
2654
2655 if (!non_zero_weights_seen) {
2656 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2657 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2658 }
2659
2660 /* Set extent of bundle */
2661 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2662
2663 return (bit_offset+7)/8;
2664}
2665
2666/* Return new bit offset. in/out will always be byte-aligned.. */
2667static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2668 unsigned comp_meth, uint8_t *exponent)
2669{
2670 if (comp_meth == COMP_NONE0) {
2671 /* Nothing in frame so don't even create subtree */
2672 return bit_offset;
2673 }
2674
2675 /* Subtree */
2676 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2677 tvb, bit_offset/8, 1, "",
2678 "ciCompParam");
2679 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2680 uint32_t ci_exponent;
2681
2682 /* Contents differ by compression method */
2683 switch (comp_meth) {
2684 case COMP_BLOCK_FP1:
2685 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2686 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2687 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2688 *exponent = ci_exponent;
2689 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2690 bit_offset += 8; /* one byte */
2691 break;
2692 case COMP_BLOCK_SCALE2:
2693 /* Separate into integer (1) and fractional (7) bits? */
2694 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2695 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2696 bit_offset += 8;
2697 break;
2698 case COMP_U_LAW3:
2699 /* compBitWidth, compShift (4 bits each) */
2700 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2701 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2702 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2703 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2704 bit_offset += 8;
2705 break;
2706
2707 default:
2708 /* reserved, ? bytes of zeros.. */
2709 break;
2710 }
2711
2712 return bit_offset;
2713}
2714
2715/* frameStructure (7.5.2.13) */
2716static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2717 uint32_t subframeId, uint32_t slotId)
2718{
2719 uint32_t scs;
2720 /* FFT Size (4 bits) */
2721 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2722 /* Subcarrier spacing (SCS) */
2723 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2724
2725 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2726 uint32_t slots_per_subframe = 1;
2727 if (scs <= 4) {
2728 slots_per_subframe = 1 << scs;
2729 }
2730 if (scs <= 4 || scs >= 12) {
2731 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2732 (slots_per_subframe*subframeId) + slotId);
2733 proto_item_set_generated(ti);
2734 }
2735 return offset + 1;
2736}
2737
2738static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2739 unsigned iq_width, bool_Bool *p_csf)
2740{
2741 proto_item *csf_ti;
2742 uint64_t csf;
2743 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2744 if (csf) {
2745 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2746 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2747 if (iq_width >=1 && iq_width <= 5) {
2748 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2749 }
2750 }
2751
2752 /* Set out parameter */
2753 if (p_csf != NULL((void*)0)) {
2754 *p_csf = (csf!=0);
2755 }
2756 return bit_offset+1;
2757}
2758
2759
2760/* Section 7.
2761 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2762static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2763 flow_state_t* state,
2764 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2765 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2766 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2767 unsigned num_sinr_per_prb)
2768{
2769 unsigned offset = 0;
2770 proto_tree *c_section_tree = NULL((void*)0);
2771 proto_item *sectionHeading = NULL((void*)0);
2772
2773 /* Section subtree */
2774 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2775 tvb, offset, 0, "", "Section");
2776 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2777
2778 uint32_t sectionId = 0;
2779
2780 uint32_t startPrbc=0, startPrbu=0;
2781 uint32_t numPrbc=0, numPrbu=0;
2782 uint32_t ueId = 0;
2783 proto_item *ueId_ti = NULL((void*)0);
2784 uint32_t section_beamId = 0;
2785 proto_item *section_beamId_ti = NULL((void*)0);
2786 bool_Bool section_beamId_ignored = false0;
2787
2788 proto_item *numsymbol_ti = NULL((void*)0);
2789 bool_Bool numsymbol_ignored = false0;
2790
2791 proto_item *numprbc_ti = NULL((void*)0);
2792
2793 proto_item *rb_ti = NULL((void*)0);
2794 uint32_t rb;
2795
2796 /* Config affecting ext11 bundles (initially unset) */
2797 ext11_settings_t ext11_settings;
2798 memset(&ext11_settings, 0, sizeof(ext11_settings));
2799
2800 /* Section Type 10 needs to keep track of PRB range that should be reported
2801 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2802 /* All PRBs start as false */
2803#define MAX_PRBS273 273
2804 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2805 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2806
2807 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2808#define MAX_UEIDS16 16
2809 uint32_t ueids[MAX_UEIDS16];
2810 uint32_t number_of_ueids = 0;
2811
2812
2813 bool_Bool extension_flag = false0;
2814
2815 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2816 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2817 (sectionType != SEC_C_SLOT_CONTROL)) {
2818
2819 /* sectionID */
2820 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2821 if (sectionId == 4095) {
2822 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2823 }
2824 offset++;
2825
2826 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2827 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2828 }
2829
2830 /* rb */
2831 rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2832
2833 /* symInc (1 bit) */
2834 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2835 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2836 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2837 unsigned int sym_inc;
2838 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2839 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2840 /* "0 shall be used" */
2841 proto_item_append_text(sym_inc_ti, " (should be 0)");
2842 }
2843 }
2844 else {
2845 /* reserved (1 bit) */
2846 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2847 }
2848
2849 /* startPrbx and numPrbx */
2850 if (sectionType == SEC_C_SINR_REPORTING) {
2851 /* startPrbu (10 bits) */
2852 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2853 offset += 2;
2854
2855 /* numPrbu */
2856 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2857 if (numPrbu == 0) {
2858 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2859 numPrbu = pref_data_plane_section_total_rbs;
2860 }
2861 offset += 1;
2862 }
2863 else {
2864 /* startPrbc (10 bits) */
2865 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2866 offset += 2;
2867
2868 /* numPrbc */
2869 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2870 if (numPrbc == 0) {
2871 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2872 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2873 numPrbc = MAX_PRBS273;
2874 }
2875 offset += 1;
2876 }
2877
2878 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2879 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2880 if (n < MAX_PRBS273) {
2881 prbs_for_st10_type5[n] = true1;
2882 }
2883 }
2884
2885 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2886 static int * const remask_flags[] = {
2887 &hf_oran_reMask_re1,
2888 &hf_oran_reMask_re2,
2889 &hf_oran_reMask_re3,
2890 &hf_oran_reMask_re4,
2891 &hf_oran_reMask_re5,
2892 &hf_oran_reMask_re6,
2893 &hf_oran_reMask_re7,
2894 &hf_oran_reMask_re8,
2895 &hf_oran_reMask_re9,
2896 &hf_oran_reMask_re10,
2897 &hf_oran_reMask_re11,
2898 &hf_oran_reMask_re12,
2899 NULL((void*)0)
2900 };
2901
2902 /* reMask */
2903 uint64_t remask;
2904 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2905 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2906 offset++;
2907 /* numSymbol */
2908 uint32_t numSymbol;
2909 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2910 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2911 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2912 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2913 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2914 }
2915 if ((startSymbolId + numSymbol) > 14) {
2916 /* Warn if startSymbol + numSymbol would be > 14 */
2917 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2918 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2919 startSymbolId, numSymbol);
2920 }
2921 offset++;
2922
2923 /* [ef] (extension flag) */
2924 switch (sectionType) {
2925 case SEC_C_UNUSED_RB: /* Section Type 0 */
2926 case SEC_C_NORMAL: /* Section Type 1 */
2927 case SEC_C_PRACH: /* Section Type 3 */
2928 case SEC_C_UE_SCHED: /* Section Type 5 */
2929 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2930 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2931 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2932 break;
2933 default:
2934 /* Other section types don't support extensions */
2935 break;
2936 }
2937
2938 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2939 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2940
2941 if (numPrbc == 0) {
2942 /* Special case for all PRBs */
2943 numPrbc = pref_data_plane_section_total_rbs;
2944 startPrbc = 0; /* may already be 0... */
2945 }
2946 }
2947 else {
2948 /* Section Type 9 */
2949 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2950 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2951 }
2952
2953 /* Section type specific fields (after 'numSymbol') */
2954 switch (sectionType) {
2955 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2956 /* reserved (15 bits) */
2957 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2958 offset += 2;
2959 break;
2960
2961 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2962 /* beamId */
2963 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2964 offset += 2;
2965
2966 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2967 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2968 break;
2969
2970 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2971 {
2972 /* beamId */
2973 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2974 offset += 2;
2975
2976 /* freqOffset */
2977 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2978 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);
2979 freqOffset |= 0xff000000; /* Must sign-extend */
2980 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2981 offset += 3;
2982
2983 /* reserved (8 bits) */
2984 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2985 offset += 1;
2986
2987 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2988 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2989 break;
2990 }
2991
2992 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2993 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2994 /* ueId */
2995 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2996 offset += 2;
2997 if (ueId == 0x7fff) {
2998 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2999 }
3000 else {
3001 ueids[number_of_ueids++] = ueId;
3002 }
3003
3004 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
3005 break;
3006
3007 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
3008 {
3009 /* Hidden filter for bf (DMFS-BF) */
3010 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3011 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3012
3013 unsigned bit_offset = offset*8;
3014
3015 /* sinr iqWidth */
3016 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
3017 proto_item_append_text(iq_width_item, " (from preferences)");
3018 proto_item_set_generated(iq_width_item);
3019
3020 /* sinr compMethod */
3021 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
3022 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
3023 proto_item_set_generated(sinr_comp_meth_item);
3024
3025 /* Add SINR entries for each PRB */
3026 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
3027 /* Create a subtree for each PRB */
3028 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
3029 tvb, offset, 0, "", "PRB %3u (", prb);
3030 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
3031
3032 /* Each prb starts byte-aligned */
3033 bit_offset = ((bit_offset+7)/8) * 8;
3034
3035 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
3036
3037 /* sinrCompParam (udCompParam format, may be empty) */
3038 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
3039 uint16_t sReSMask;
3040 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
3041 pref_iqCompressionSINR, &exponent, &sReSMask,
3042 true1) * 8; /* last param is for_sinr */
3043
3044 /* sinrValues for this PRB. */
3045 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
3046 for (unsigned n=0; n < num_sinr_per_prb; n++) {
3047 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
3048
3049 /* Using SINR compression settings from preferences */
3050 float value = decompress_value(sinr_bits,
3051 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
3052 exponent,
3053 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
3054 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
3055 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
3056 bit_offset/8, sample_len_in_bytes, value);
3057 proto_item_append_text(prb_ti, " %8f", value);
3058
3059 /* Show here which subcarriers share which values (they all divide 12..) */
3060 if (num_sinr_per_prb == 12) {
3061 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
3062 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
3063 }
3064 else {
3065 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
3066 startPrbu+((prb-startPrbu)*(rb+1)),
3067 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
3068 }
3069 bit_offset += pref_sample_bit_width_sinr;
3070 }
3071
3072 /* 1-byte alignment per PRB (7.2.11) */
3073 offset = (bit_offset+7)/8;
3074 bit_offset = offset*8;
3075
3076 proto_item_append_text(prb_ti, ")");
3077 proto_item_set_end(prb_ti, tvb, offset);
3078 }
3079 break;
3080 }
3081 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
3082 /* Reserved (15 bits) */
3083 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
3084 offset += 2;
3085 break;
3086
3087 default:
3088 break;
3089 }
3090 }
3091 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
3092 /* ef */
3093 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3094 /* ueId */
3095 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
3096 offset += 2;
3097 /* regularizationFactor */
3098 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3099 offset += 2;
3100 /* reserved (4 bits) */
3101 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3102 /* rb ("Value=0 shall be set") */
3103 rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3104 if (rb != 0) {
3105 proto_item_append_text(rb_ti, " (should be set to 0)");
3106 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3107 }
3108 /* symInc */
3109 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3110 /* startPrbc */
3111 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3112 offset += 2;
3113 /* numPrbc */
3114 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3115 offset += 1;
3116
3117 /* Hidden filter for bf */
3118 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3119 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3120
3121 /* ciIsample,ciQsample pairs */
3122 unsigned m;
3123 unsigned prb;
3124 uint32_t bit_offset = offset*8;
3125
3126 /* Antenna count from preference */
3127 unsigned num_trx = pref_num_bf_antennas;
3128
3129 write_channel_section_info(sectionHeading, pinfo,
3130 sectionId, ueId, startPrbc, numPrbc, num_trx);
3131
3132 bool_Bool first_prb = true1;
3133 uint8_t exponent = 0;
3134 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3135
3136 /* PRB subtree */
3137 unsigned prb_start_offset = bit_offset;
3138 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3139 tvb, bit_offset/8, 0,
3140 "", "PRB=%u", prb);
3141 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3142
3143 /* There may be a ciCompParam here.. */
3144 if (first_prb || ci_comp_opt==1) {
3145 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3146 }
3147 first_prb = false0;
3148
3149 /* Antennas */
3150 for (m=0; m < num_trx; m++) {
3151
3152 unsigned sample_offset = bit_offset / 8;
3153 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3154
3155 /* Create subtree for antenna */
3156 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3157 tvb, sample_offset, sample_extent,
3158 "", "TRX=%2u: ", m);
3159 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3160
3161 /* I */
3162 /* Get bits, and convert to float. */
3163 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3164 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3165
3166 /* Add to tree. */
3167 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);
3168 bit_offset += ci_iq_width;
3169 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3170
3171 /* Q */
3172 /* Get bits, and convert to float. */
3173 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3174 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3175
3176 /* Add to tree. */
3177 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);
3178 bit_offset += ci_iq_width;
3179 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3180 }
3181 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3182 }
3183
3184 /* Pad out by 1 or 4 bytes, according to preference */
3185 if (!st6_4byte_alignment) {
3186 offset = (bit_offset + 7) / 8;
3187 }
3188 else {
3189 int mode = bit_offset % 32;
3190 if (mode != 0) {
3191 offset = (bit_offset + (32-mode))/8;
3192 }
3193 else {
3194 offset = bit_offset/8;
3195 }
3196 }
3197 proto_item_set_end(c_section_tree, tvb, offset);
3198 }
3199
3200
3201 expected_section_data_t *data_section = NULL((void*)0);
3202 unsigned index_to_use = 0;
3203
3204 /* On first pass, allocate a section entry to use */
3205 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3206
3207 /* Look for existing entry for sectionId to overwrite first. */
3208 uint8_t direction = !tap_info->uplink;
3209 data_section = wmem_tree_lookup32(state->expected_sections[direction],
3210 sectionId);
3211 if (data_section == NULL((void*)0)) {
3212 /* None, so create */
3213 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)))
;
3214 wmem_tree_insert32(state->expected_sections[direction],
3215 sectionId,
3216 data_section);
3217 }
3218
3219 /* If 2nd entry not in use, use that one */
3220 if (!data_section->details[1].in_use) {
3221 index_to_use = 1;
3222 }
3223 else {
3224 /* Both in use, so replace the older of the 2 entries */
3225 if (data_section->details[1].frame_number < data_section->details[0].frame_number) {
3226 index_to_use = 1;
3227 }
3228 }
3229
3230 if (data_section) {
3231 section_details_t *details = &data_section->details[index_to_use];
3232
3233 details->in_use = true1;
3234 details->frame = frameId;
3235 details->subframe = subframeId;
3236 details->slot = slotId;
3237 details->startSymbol = startSymbolId;
3238
3239 details->frame_number = pinfo->num;
3240 details->frame_time = pinfo->abs_ts;
3241 data_section->sectionId = sectionId;
3242 details->startPrb = startPrbc;
3243 details->numPrb = numPrbc;
3244 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3245 if (prb < 273) {
3246 details->beamIds[prb] = section_beamId;
3247 }
3248 }
3249 }
3250 }
3251
3252 bool_Bool seen_se10 = false0;
3253 uint32_t numPortc = 0;
3254 proto_item *bf_ti = NULL((void*)0);
3255
3256 /* Section extension commands */
3257 while (extension_flag) {
3258 int extension_start_offset = offset;
3259
3260 /* Prefetch extType so can use specific extension type ett */
3261 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3262 uint32_t exttype_ett_index = exttype;
3263 if (exttype == 0 || exttype > HIGHEST_EXTTYPE32) {
3264 /* Just use first one if out of range */
3265 exttype_ett_index = 1;
3266 }
3267
3268 /* Create subtree for each extension (with summary) */
3269 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3270 tvb, offset, 0, "", "Extension");
3271 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3272
3273 /* ef (i.e. another extension after this one?) */
3274 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3275
3276 /* extType */
3277 proto_item *exttype_ti;
3278 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3279 offset++;
3280 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3281
3282 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3283
3284 /* Don't tap if out of range. */
3285 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE32) {
3286 tap_info->extensions[exttype] = true1;
3287 }
3288
3289 /* Is this SE allowed for this section type? */
3290 if (!se_allowed_in_st(exttype, sectionType)) {
3291 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3292 "SE %u (%s) should not appear in ST %u (%s)!",
3293 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3294 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3295 }
3296
3297
3298 /* extLen (number of 32-bit words) */
3299 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3300 uint32_t extlen;
3301 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3302 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3303 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3304 offset += extlen_len;
3305 if (extlen == 0) {
3306 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3307 /* Break out to avoid infinitely looping! */
3308 break;
3309 }
3310
3311 bool_Bool ext_unhandled = false0;
3312
3313 switch (exttype) {
3314
3315 case 1: /* SE 1: Beamforming Weights */
3316 {
3317 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3318 proto_item *comp_meth_ti = NULL((void*)0);
3319
3320 /* Hidden filter for bf */
3321 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3322 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3323
3324 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3325 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3326 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3327
3328 /* bfwCompParam */
3329 uint32_t exponent = 0;
3330 bool_Bool compression_method_supported = false0;
3331 unsigned num_trx = 0;
3332 uint16_t *trx; /* ptr to array */
3333 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3334 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3335 &num_trx, &trx);
3336
3337 /* Can't show details of unsupported compression method */
3338 if (!compression_method_supported) {
3339 break;
3340 }
3341
3342 /* We know:
3343 - iq_width (above)
3344 - numBfWeights (taken from preference)
3345 - remaining bytes in extension
3346 We can therefore derive TRX (number of antennas).
3347 */
3348
3349 bool_Bool using_array = false0;
3350
3351 /* I & Q samples
3352 May know how many entries from activeBeamspaceCoefficientMask. */
3353 if (num_trx == 0) {
3354 /* Don't know how many there will be, so just fill available bytes... */
3355 unsigned weights_bytes = (extlen*4)-3;
3356 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3357 num_trx = num_weights_pairs;
3358 }
3359 else {
3360 using_array = true1;
3361 num_trx = pref_num_bf_antennas;
3362 }
3363
3364 int bit_offset = offset*8;
3365
3366 for (unsigned n=0; n < num_trx; n++) {
3367 /* Create antenna subtree */
3368 int bfw_offset = bit_offset / 8;
3369
3370 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3371
3372 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3373 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3374 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3375
3376 /* I value */
3377 /* Get bits, and convert to float. */
3378 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3379 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3380 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3381 /* Add to tree. */
3382 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3383 (bfwcomphdr_iq_width+7)/8, value);
3384 bit_offset += bfwcomphdr_iq_width;
3385 proto_item_append_text(bfw_ti, "I=%f ", value);
3386
3387 /* Leave a gap between I and Q values */
3388 proto_item_append_text(bfw_ti, " ");
3389
3390 /* Q value */
3391 /* Get bits, and convert to float. */
3392 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3393 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3394 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3395 /* Add to tree. */
3396 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3397 (bfwcomphdr_iq_width+7)/8, value);
3398 bit_offset += bfwcomphdr_iq_width;
3399 proto_item_append_text(bfw_ti, "Q=%f", value);
3400
3401 proto_item_append_text(bfw_ti, ")");
3402 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3403 }
3404 /* Need to round to next byte */
3405 offset = (bit_offset+7)/8;
3406
3407 break;
3408 }
3409
3410 case 2: /* SE 2: Beamforming attributes */
3411 {
3412 /* Hidden filter for bf */
3413 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3414 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3415
3416 /* bfaCompHdr (get widths of fields to follow) */
3417 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3418 /* subtree */
3419 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3420 tvb, offset, 2, "", "bfaCompHdr");
3421 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3422
3423 /* reserved (2 bits) */
3424 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3425 /* bfAzPtWidth (3 bits) */
3426 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3427 /* bfZePtWidth (3 bits) */
3428 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3429 offset += 1;
3430
3431 /* reserved (2 bits) */
3432 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3433 /* bfAz3ddWidth (3 bits) */
3434 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3435 /* bfZe3ddWidth (3 bits) */
3436 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3437 offset += 1;
3438
3439 unsigned bit_offset = offset*8;
3440
3441 /* bfAzPt */
3442 if (bfAzPtWidth > 0) {
3443 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3444 bit_offset += (bfAzPtWidth+1);
3445 }
3446 /* bfZePt */
3447 if (bfZePtWidth > 0) {
3448 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3449 bit_offset += (bfZePtWidth+1);
3450 }
3451 /* bfAz3dd */
3452 if (bfAz3ddWidth > 0) {
3453 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3454 bit_offset += (bfAz3ddWidth+1);
3455 }
3456 /* bfZe3dd */
3457 if (bfZe3ddWidth > 0) {
3458 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3459 bit_offset += (bfZe3ddWidth+1);
3460 }
3461
3462 /* Pad to next byte (unless last 2 fields already fit in this one) */
3463 if ((bit_offset % 8) > 2) {
3464 offset = (bit_offset+7) / 8;
3465 }
3466 else {
3467 offset = bit_offset / 8;
3468 }
3469
3470 /* bfAzSl (3 bits) */
3471 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3472 /* bfZeSl (3 bits) */
3473 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3474 offset += 1;
3475 break;
3476 }
3477
3478 case 3: /* SE 3: DL precoding parameters */
3479 {
3480 /* codebookindex (8 bits) */
3481 /* "This parameter is not used and shall be set to zero." */
3482 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3483 offset += 1;
3484 /* layerid */
3485 uint32_t layerid;
3486 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3487 /* numLayers */
3488 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3489 offset += 1;
3490
3491 /* Stop here for non-first data layer */
3492 if (layerid != 0 && layerid != 0xf) {
3493 break;
3494 }
3495
3496 /* First data layer case */
3497 /* txScheme */
3498 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3499 /* crsReMask */
3500 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3501 offset += 2;
3502
3503 /* crsShift (1 bit) */
3504 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3505 /* reserved (3 bits) */
3506 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3507 /* crsSymNum (4 bits) */
3508 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3509 offset += 1;
3510 /* reserved (8 bits) */
3511 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3512 offset += 1;
3513
3514 /* reserved (1 bit) */
3515 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3516 /* beamIdAP1 (15 bits) */
3517 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3518 offset += 2;
3519 /* reserved (1 bit) */
3520 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3521 /* beamIdAP2 (15 bits) */
3522 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3523 offset += 2;
3524 /* reserved (1 bit) */
3525 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3526 /* beamIdAP3 (15 bits) */
3527 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3528 offset += 2;
3529 break;
3530 }
3531
3532 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3533 {
3534 /* csf */
3535 bool_Bool csf;
3536 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3537
3538 /* modCompScaler */
3539 uint32_t modCompScaler;
3540 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3541 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3542 offset += 2;
3543
3544 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3545 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3546 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3547 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3548 proto_item_append_text(ti, " (%f)", value);
3549
3550 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3551
3552 /* Store these params in this flow's state */
3553 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3554 unsigned i = sect_config->num_configs;
3555 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3556 sect_config->configs[i].mod_compr_csf = csf;
3557 sect_config->configs[i].mod_compr_scaler = value;
3558 sect_config->num_configs++;
3559 }
3560 break;
3561 }
3562
3563 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3564 {
3565 /* Applies only to section types 1,3 and 5 */
3566 /* N.B. there may be multiple instances of this SE in the same frame */
3567
3568 /* There may be one or 2 entries, depending upon extlen */
3569 int sets = 1, reserved_bits = 0;
3570 switch (extlen) {
3571 case 2:
3572 sets = 1;
3573 reserved_bits = 20;
3574 break;
3575 case 3:
3576 sets = 2;
3577 reserved_bits = 24;
3578 break;
3579 case 4:
3580 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3581 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3582 sets = 3;
3583 reserved_bits = 28;
3584 }
3585 else {
3586 sets = 4;
3587 reserved_bits = 0;
3588 }
3589 break;
3590
3591 default:
3592 /* Malformed error!!! */
3593 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3594 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3595 extlen);
3596 break;
3597 }
3598
3599 unsigned bit_offset = offset*8;
3600 /* Dissect each set */
3601 for (int n=0; n < sets; n++) {
3602 /* Subtree for each set */
3603 unsigned set_start_offset = bit_offset/8;
3604 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3605 tvb, set_start_offset, 0, "");
3606 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3607
3608 uint64_t mcScaleReMask, mcScaleOffset;
3609 bool_Bool csf;
3610
3611 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3612 static int * const remask_flags[] = {
3613 &hf_oran_mc_scale_re_mask_re1,
3614 &hf_oran_mc_scale_re_mask_re2,
3615 &hf_oran_mc_scale_re_mask_re3,
3616 &hf_oran_mc_scale_re_mask_re4,
3617 &hf_oran_mc_scale_re_mask_re5,
3618 &hf_oran_mc_scale_re_mask_re6,
3619 &hf_oran_mc_scale_re_mask_re7,
3620 &hf_oran_mc_scale_re_mask_re8,
3621 &hf_oran_mc_scale_re_mask_re9,
3622 &hf_oran_mc_scale_re_mask_re10,
3623 &hf_oran_mc_scale_re_mask_re11,
3624 &hf_oran_mc_scale_re_mask_re12,
3625 NULL((void*)0)
3626 };
3627 /* Same as above, but offset by 4 bits */
3628 static int * const remask_flags_even[] = {
3629 &hf_oran_mc_scale_re_mask_re1_even,
3630 &hf_oran_mc_scale_re_mask_re2_even,
3631 &hf_oran_mc_scale_re_mask_re3_even,
3632 &hf_oran_mc_scale_re_mask_re4_even,
3633 &hf_oran_mc_scale_re_mask_re5_even,
3634 &hf_oran_mc_scale_re_mask_re6_even,
3635 &hf_oran_mc_scale_re_mask_re7_even,
3636 &hf_oran_mc_scale_re_mask_re8_even,
3637 &hf_oran_mc_scale_re_mask_re9_even,
3638 &hf_oran_mc_scale_re_mask_re10_even,
3639 &hf_oran_mc_scale_re_mask_re11_even,
3640 &hf_oran_mc_scale_re_mask_re12_even,
3641 NULL((void*)0)
3642 };
3643
3644 /* RE Mask (12 bits) */
3645 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3646 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3647 ett_oran_mc_scale_remask,
3648 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3649 bit_offset += 12;
3650
3651 /* csf (1 bit) */
3652 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3653 /* mcScaleOffset (15 bits) */
3654 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3655 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3656 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3657 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3658 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3659 bit_offset += 15;
3660
3661 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3662
3663 /* Record this config */
3664 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3665 unsigned i = sect_config->num_configs;
3666 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3667 sect_config->configs[i].mod_compr_csf = csf;
3668 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3669 sect_config->num_configs++;
3670 }
3671
3672 /* Summary */
3673 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3674 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3675 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3676 }
3677
3678 proto_item_append_text(extension_ti, " (%u sets)", sets);
3679
3680 /* Reserved (variable-length) */
3681 if (reserved_bits) {
3682 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3683 bit_offset += reserved_bits;
3684 }
3685
3686 offset = bit_offset/8;
3687 break;
3688 }
3689
3690 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3691 {
3692 /* numSymbol not used in this case */
3693 if (numsymbol_ti && !numsymbol_ignored) {
3694 proto_item_append_text(numsymbol_ti, " (ignored)");
3695 numsymbol_ignored = true1;
3696 }
3697
3698 /* Will update ext6 recorded info */
3699 ext11_settings.ext6_set = true1;
3700
3701 /* repetition */
3702 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3703 /* rbgSize (PRBs per bit set in rbgMask) */
3704 uint32_t rbgSize;
3705 proto_item *rbg_size_ti;
3706 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3707 if (rbgSize == 0) {
3708 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3709 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3710 }
3711 /* rbgMask (28 bits) */
3712 uint32_t rbgMask;
3713 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3714 if (rbgSize == 0) {
3715 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3716 }
3717
3718 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3719 offset += 4;
3720 /* priority */
3721 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3722 /* symbolMask */
3723 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3724
3725 /* Look up rbg_size enum -> value */
3726 switch (rbgSize) {
3727 case 0:
3728 /* N.B. reserved, but covered above with expert info (would remain 0) */
3729 break;
3730 case 1:
3731 ext11_settings.ext6_rbg_size = 1; break;
3732 case 2:
3733 ext11_settings.ext6_rbg_size = 2; break;
3734 case 3:
3735 ext11_settings.ext6_rbg_size = 3; break;
3736 case 4:
3737 ext11_settings.ext6_rbg_size = 4; break;
3738 case 5:
3739 ext11_settings.ext6_rbg_size = 6; break;
3740 case 6:
3741 ext11_settings.ext6_rbg_size = 8; break;
3742 case 7:
3743 ext11_settings.ext6_rbg_size = 16; break;
3744 /* N.B., encoded in 3 bits, so no other values are possible */
3745 }
3746
3747 /* Set to looked-up value */
3748 rbgSize = ext11_settings.ext6_rbg_size;
3749
3750 uint32_t lastRbgid = 0;
3751 if (rbgSize != 0) {
3752 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3753 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3754 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3755 if (lastRbgid > 27) {
3756 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3757 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3758 rbgSize, startPrbc, numPrbc);
3759 break;
3760 }
3761 }
3762
3763 /* Record (and count) which bits are set in rbgMask */
3764 bool_Bool first_seen = false0;
3765 unsigned first_seen_pos=0, last_seen_pos=0;
3766 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3767 if ((rbgMask >> n) & 0x01) {
3768 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3769 if (!first_seen) {
3770 first_seen = true1;
3771 first_seen_pos = n;
3772 }
3773 last_seen_pos = n;
3774 }
3775 }
3776
3777 /* Show how many bits were set in rbgMask */
3778 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3779 /* Also, that is the range of bits */
3780 if (first_seen) {
3781 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3782
3783 /* Complain if last set bit is beyond lastRbgid */
3784 if (last_seen_pos > lastRbgid) {
3785 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3786 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3787 rbgMask, last_seen_pos, lastRbgid);
3788 }
3789 }
3790
3791 /* Also update prbs_for_st10_type5[] */
3792 if (sectionType == 10 && rbgSize != 0) {
3793 /* Unset all entries */
3794 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3795
3796 /* Work out which PRB first bit corresponds to */
3797 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3798
3799 /* Add PRBs corresponding to each bit set */
3800 for (unsigned n=0; n < 28 ; n++) {
3801 if ((rbgMask >> n) & 0x01) {
3802 /* Lazy way to clip any values that lie outside of range for section */
3803 for (unsigned p=0; p < rbgSize; p++) {
3804 unsigned start = firstPrbStart + (n*rbgSize);
3805 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3806 prbs_for_st10_type5[start+p] = true1;
3807 }
3808 }
3809 }
3810 }
3811 }
3812
3813 break;
3814 }
3815
3816 case 7: /* SE 7: eAxC mask */
3817 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3818 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3819 offset += 2;
3820 break;
3821
3822 case 8: /* SE 8: Regularization factor */
3823 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3824 offset += 2;
3825 break;
3826
3827 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3828 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3829 offset += 1;
3830 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3831 offset += 1;
3832 break;
3833
3834 case 10: /* SE 10: Group configuration of multiple ports */
3835 {
3836 seen_se10 = true1;
3837
3838 /* beamGroupType */
3839 uint32_t beam_group_type = 0;
3840 proto_item *bgt_ti;
3841 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3842 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3843 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3844
3845 /* numPortc */
3846 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3847 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3848 offset++;
3849
3850 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3851 unsigned n;
3852
3853 switch (beam_group_type) {
3854 case 0x0: /* common beam */
3855 case 0x1: /* beam matrix indication */
3856 /* Reserved byte */
3857 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3858 offset++;
3859
3860 /* Explain how entries are allocated */
3861 if (beam_group_type == 0x0) {
3862 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3863 }
3864 else {
3865 /* 'numPortc' consecutive BeamIds from section header */
3866 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3867 }
3868
3869 if (sectionType == 5) {
3870 /* These types are not allowed */
3871 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3872 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3873 }
3874 break;
3875
3876 case 0x2: /* beam vector listing */
3877 {
3878 proto_item_append_text(extension_ti, " [ ");
3879
3880 /* Beam listing vector case */
3881 /* Work out how many port beam entries there is room for */
3882 /* Using numPortC as visible in issue 18116 */
3883 for (n=0; n < numPortc; n++) {
3884 /* 1 reserved bit */
3885 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3886
3887 /* port beam ID (or UEID) (15 bits) */
3888 uint32_t id;
3889 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3890 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3891 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3892 offset += 2;
3893
3894 if (id != 0x7fff) {
3895 if (number_of_ueids < MAX_UEIDS16) {
3896 ueids[number_of_ueids++] = id;
3897 }
3898 }
3899
3900 proto_item_append_text(extension_ti, "%u ", id);
3901 }
3902
3903 proto_item_append_text(extension_ti, "]");
3904 break;
3905 }
3906 case 0x3: /* beamId/ueId listing with associated port-list index */
3907 {
3908 proto_item_append_text(extension_ti, " [ ");
3909
3910 if (numPortc > 0) {
3911 /* first portListIndex is outside loop */
3912 uint32_t port_list_index;
3913 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3914 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3915 if (port_list_index == 0) {
3916 /* Value 0 is reserved */
3917 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3918 }
3919 offset += 1;
3920
3921 for (n=0; n < numPortc-1; n++) {
3922 /* 1 reserved bit */
3923 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3924
3925 /* port beam ID (or UEID) */
3926 uint32_t id;
3927 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3928 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3929 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3930 offset += 2;
3931
3932 if (id != 0x7fff) {
3933 if (number_of_ueids < MAX_UEIDS16) {
3934 ueids[number_of_ueids++] = id;
3935 }
3936 }
3937
3938 /* subsequent portListIndex */
3939 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3940 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3941 if (port_list_index == 0) {
3942 /* Value 0 is reserved */
3943 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3944 }
3945 offset += 1;
3946
3947 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3948 }
3949 }
3950
3951 proto_item_append_text(extension_ti, "]");
3952 break;
3953 }
3954
3955
3956 default:
3957 /* Warning for unsupported/reserved value */
3958 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3959 break;
3960 }
3961 break;
3962 }
3963
3964 case 11: /* SE 11: Flexible Weights Extension Type */
3965 {
3966 /* Hidden filter for bf */
3967 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3968 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3969
3970 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3971 if (section_beamId_ti && !section_beamId_ignored) {
3972 proto_item_append_text(section_beamId_ti, " (ignored)");
3973 section_beamId_ignored = true1;
3974 }
3975
3976 bool_Bool disableBFWs;
3977 uint32_t numBundPrb;
3978 bool_Bool rad;
3979
3980 /* disableBFWs */
3981 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3982 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3983 if (disableBFWs) {
3984 proto_item_append_text(extension_ti, " (disableBFWs)");
3985 }
3986
3987 /* RAD */
3988 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3989 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3990 /* bundleOffset (6 bits) */
3991 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3992 offset, 1, ENC_BIG_ENDIAN0x00000000);
3993 offset++;
3994
3995 /* numBundPrb (number of prbs in each bundle) */
3996 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3997 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3998 offset++;
3999 /* value zero is reserved.. */
4000 if (numBundPrb == 0) {
4001 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
4002 }
4003
4004 uint32_t num_bundles;
4005 bool_Bool orphaned_prbs = false0;
4006
4007 /* N.B. glibly assuming that Mu=1 */
4008 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
4009
4010 if (!disableBFWs) {
4011 /********************************************/
4012 /* Table 7.7.1.1-1 */
4013 /********************************************/
4014
4015 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4016 proto_item *comp_meth_ti = NULL((void*)0);
4017
4018 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
4019 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4020 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4021
4022 /* Work out number of bundles, but take care not to divide by zero. */
4023 if (numBundPrb == 0) {
4024 break;
4025 }
4026
4027 /* Work out bundles! */
4028 /* TODO: assuming that these modifying SEs appear before SE 11, but not sure that this is guaranteed?! */
4029 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4030 num_bundles = ext11_settings.num_bundles;
4031
4032 /* Add (complete) bundles */
4033 for (unsigned b=0; b < num_bundles; b++) {
4034 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
4035 comp_meth_ti, bfwcomphdr_comp_meth,
4036 NULL((void*)0) /* no ModCompr */,
4037 (ext11_settings.ext21_set) ?
4038 numPrbc :
4039 pref_num_bf_antennas,
4040 bfwcomphdr_iq_width,
4041 b, /* bundle number */
4042 ext11_settings.bundles[b].start,
4043 ext11_settings.bundles[b].end,
4044 ext11_settings.bundles[b].is_orphan,
4045 symbol_count,
4046 (link_planes_together && data_section) ? &data_section->details[index_to_use] : NULL((void*)0),
4047 tap_info);
4048 if (!offset) {
4049 break;
4050 }
4051 }
4052 if (num_bundles > 0) {
4053 /* Set flag from last bundle entry */
4054 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
4055 }
4056 }
4057 else {
4058 /********************************************/
4059 /* Table 7.7.1.1-2 */
4060 /* No weights in this case */
4061 /********************************************/
4062
4063 /* Work out number of bundles, but take care not to divide by zero. */
4064 if (numBundPrb == 0) {
4065 break;
4066 }
4067
4068 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4069 num_bundles = ext11_settings.num_bundles;
4070
4071 for (unsigned n=0; n < num_bundles; n++) {
4072 /* contInd */
4073 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
4074 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4075 /* beamId */
4076 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
4077 uint32_t beam_id;
4078 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
4079 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
4080 if (!ext11_settings.bundles[n].is_orphan) {
4081 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
4082 ext11_settings.bundles[n].start,
4083 ext11_settings.bundles[n].end,
4084 n);
4085 }
4086 else {
4087 orphaned_prbs = true1;
4088 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
4089 ext11_settings.bundles[n].start,
4090 ext11_settings.bundles[n].end);
4091 }
4092 offset += 2;
4093
4094 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4095 if (data_section) {
4096 /* Set beamId only for range of PRBs */
4097 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4098 if (prb < 273) {
4099 data_section->details[index_to_use].beamIds[prb] = beam_id;
4100 }
4101 }
4102 }
4103 }
4104
4105 /* Look for where BFWs were sent for this beamId */
4106 bfw_definition *definition;
4107
4108 wmem_tree_key_t key[3];
4109 key[0].length = 1;
4110 key[0].key = &pinfo->num;
4111 key[1].length = 1;
4112 key[1].key = &beam_id;
4113 key[2].length = 0;
4114 key[2].key = NULL((void*)0);
4115
4116 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4117 /* Look up current result */
4118 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4119 if (definition != NULL((void*)0)) {
4120 /* Add to results table for this frame */
4121 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4122 }
4123 }
4124 else {
4125 /* Look up from result table */
4126 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4127 }
4128
4129 /* Show link back to frame where/when beamId was defined */
4130 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4131 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4132 proto_item_set_generated(defined_ti);
4133 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4134 symbol_count - definition->symbol_when_defined);
4135 proto_item_set_generated(since_ti);
4136 }
4137 else {
4138 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4139 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4140 }
4141 }
4142
4143 }
4144
4145 /* Add summary to extension root */
4146 if (orphaned_prbs) {
4147 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4148 }
4149 else {
4150 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4151 }
4152 }
4153
4154 break;
4155
4156 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4157 {
4158 /* numSymbol not used in this case */
4159 if (numsymbol_ti && !numsymbol_ignored) {
4160 proto_item_append_text(numsymbol_ti, " (ignored)");
4161 numsymbol_ignored = true1;
4162 }
4163
4164 /* rb must be zero if this SE is present */
4165 if (rb != 0) {
4166 expert_add_info(NULL((void*)0), rb_ti, &ei_oran_se12_rb_set);
4167 }
4168
4169 ext11_settings.ext12_set = true1;
4170
4171 /* priority */
4172 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4173
4174 /* symbolMask */
4175 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4176
4177 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4178 should be populated with 0s. */
4179 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4180 uint8_t prb_index;
4181
4182 /* This is for ST10/ST11. First pair starts after frames signalled there */
4183 uint16_t st10_st11_offset = startPrbc + numPrbc;
4184
4185 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4186 {
4187 /* Create a subtree for each pair */
4188 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4189 tvb, offset, 2, "");
4190 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4191
4192 /* offStartPrb */
4193 uint32_t off_start_prb;
4194 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4195 offset++;
4196
4197 /* numPrb */
4198 uint32_t num_prb;
4199 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4200 offset++;
4201
4202 extlen_remaining_bytes -= 2;
4203
4204 /* Last pair may be 0,0 if not used. Check for this */
4205 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4206 proto_item_append_text(pair_ti, " (not used)");
4207 }
4208 /* Add summary to pair root item, and configure details in ext11_settings */
4209 else {
4210 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4211 prb_index, off_start_prb, num_prb);
4212 proto_item_append_text(extension_ti, "[%u : %u]",
4213 off_start_prb, num_prb);
4214 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4215 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4216 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4217 }
4218
4219 /* Also update PRBs to be covered for ST10 type 5 */
4220 /* Original range from section is added to.. */
4221 /* TODO: I don't think this is quite right.. */
4222 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4223 if (prb < MAX_PRBS273) {
4224 prbs_for_st10_type5[prb] = true1;
4225 }
4226 }
4227
4228 /* Any next pair will begin after this one */
4229 st10_st11_offset += (off_start_prb + num_prb);
4230 }
4231 }
4232 break;
4233 }
4234
4235 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4236 {
4237 /* Will update settings for ext11 */
4238 ext11_settings.ext13_set = true1;
4239
4240 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4241 uint8_t allocation_index;
4242
4243 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4244
4245 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4246 {
4247 /* Subtree for allocation */
4248 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4249 tvb, offset, 2, "");
4250 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4251
4252 /* Reserved (2 bits) */
4253 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4254
4255 /* nextSymbolId (4 bits) */
4256 uint32_t next_symbol_id;
4257 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4258
4259 /* nextStartPrbc (10 bits) */
4260 uint32_t next_start_prbc;
4261 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4262 offset += 2;
4263
4264 /* Add summary to allocation root item */
4265 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4266 allocation_index, next_symbol_id, next_start_prbc);
4267
4268 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4269 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4270 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4271 }
4272 else {
4273 /* Add entry for configuring ext11. don't store out of range */
4274 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4275 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4276 }
4277 }
4278 prev_next_symbol_id = next_symbol_id;
4279 prev_next_start_prbc = next_start_prbc;
4280
4281 extlen_remaining_bytes -= 2;
4282 }
4283 break;
4284 }
4285
4286 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4287 /* Hidden filter for bf (DMRS BF) */
4288 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4289 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4290
4291 if (!seen_se10) {
4292 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4293 offset += 1;
4294 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4295 offset += 1;
4296 }
4297 else {
4298 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4299 for (unsigned port=0; port < numPortc+1; port++) {
4300 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4301 offset += 1;
4302 }
4303 }
4304 break;
4305
4306 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4307 {
4308 /* frameStructure */
4309 offset = dissect_frame_structure(extension_tree, tvb, offset,
4310 subframeId, slotId);
4311 /* freqOffset */
4312 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4313 offset += 3;
4314 /* cpLength */
4315 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4316 if (sectionType != 0 && sectionType != 3) {
4317 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4318 }
4319 offset += 2;
4320 break;
4321 }
4322
4323 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4324 {
4325 /* Just filling available bytes with antMask entries.
4326 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4327 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4328 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4329 for (unsigned n=0; n < num_ant_masks; n++) {
4330 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4331 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4332 offset += 8;
4333 }
4334 break;
4335 }
4336
4337 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4338 {
4339 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4340 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4341 uint32_t ueid_index = 1;
4342
4343 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4344 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4345 /* numUeId (Number of UE Ids per user) */
4346 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4347 /* TODO: show ueids[ueid_index] here too? */
4348 proto_item_append_text(ti, " (user #%u)", ueid_index);
4349 }
4350 break;
4351 }
4352
4353 case 18: /* SE 18: Uplink transmission management */
4354 /* transmissionWindowOffset */
4355 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4356 offset += 2;
4357 /* reserved (2 bits) */
4358 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4359 /* transmissionWindowSize (14 bits) */
4360 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4361 offset += 2;
4362
4363 /* reserved (6 bits) */
4364 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4365 /* toT (2 bits) */
4366 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4367 offset += 1;
4368 break;
4369
4370 case 19: /* SE 19: Compact beamforming information for multiple port */
4371 {
4372 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4373 if (section_beamId_ti && !section_beamId_ignored) {
4374 proto_item_append_text(section_beamId_ti, " (ignored)");
4375 section_beamId_ignored = true1;
4376 }
4377
4378 /* numSymbol not used in this case */
4379 if (numsymbol_ti && !numsymbol_ignored) {
4380 proto_item_append_text(numsymbol_ti, " (ignored)");
4381 numsymbol_ignored = true1;
4382 }
4383
4384 /* disableBFWs */
4385 bool_Bool disableBFWs;
4386 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4387 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4388 if (disableBFWs) {
4389 proto_item_append_text(extension_ti, " (disableBFWs)");
4390 }
4391 /* repetition (1 bit) */
4392 uint64_t repetition;
4393 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4394 /* numPortc (6 bits) */
4395 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4396 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4397 offset++;
4398
4399 /* priority (2 bits) */
4400 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4401 /* symbolMask (14 bits) */
4402 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4403
4404 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4405 proto_item *comp_meth_ti = NULL((void*)0);
4406
4407 if (!repetition) {
4408
4409 if (!disableBFWs) {
4410 /* bfwCompHdr */
4411 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4412 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4413 }
4414
4415 /* Add entries for each port */
4416 for (unsigned port=0; port < numPortc; port++) {
4417
4418 /* Create subtree for port entry*/
4419 int port_start_offset = offset;
4420 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4421 tvb, offset, 0,
4422 "", "Port %u: ", port);
4423 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4424
4425 /* Reserved (4 bits) */
4426 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4427 /* portReMask (12 bits) */
4428 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4429 offset += 2;
4430
4431 /* Reserved (2 bits) */
4432 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4433 /* portSymbolMask (14 bits) */
4434 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4435 offset += 2;
4436
4437 /* Reserved (1 bit) */
4438 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4439 /* beamID (15 bits) */
4440 uint16_t beamId;
4441 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4442 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4443 offset += 2;
4444
4445 /* No weights present */
4446 if (!disableBFWs) {
4447 /*******************************************************************/
4448 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4449 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4450 /*******************************************************************/
4451
4452 /* bfwCompParam */
4453 bool_Bool compression_method_supported = false0;
4454 uint32_t exponent = 0;
4455 unsigned num_trx_entries = 0;
4456 uint16_t *trx;
4457 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4458 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4459 &num_trx_entries, &trx);
4460
4461 int bit_offset = offset*8;
4462 int bfw_offset;
4463
4464 /* Add weights for each TRX */
4465 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4466 for (unsigned b=0; b < trx_to_add; b++) {
4467
4468 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4469
4470 /* Create BFW subtree */
4471 bfw_offset = bit_offset / 8;
4472 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4473 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4474 tvb, bfw_offset, bfw_extent,
4475 "", "TRX %u: (", trx_index);
4476 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4477
4478 /* I */
4479 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4480 float 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_i, 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, "I%u=%f ", b, value);
4486
4487 /* Q */
4488 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4489 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4490 /* Add to tree. */
4491 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4492 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4493 bit_offset += bfwcomphdr_iq_width;
4494 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4495 }
4496
4497 offset = (bit_offset+7)/8;
4498 }
4499 else {
4500 /* No weights... */
4501 }
4502
4503 /* Set length of this port entry */
4504 proto_item_set_len(port_ti, offset-port_start_offset);
4505 }
4506 }
4507 break;
4508 }
4509
4510 case 20: /* SE 20: Puncturing extension */
4511 {
4512 /* numPuncPatterns */
4513 uint32_t numPuncPatterns;
4514 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4515 offset += 1;
4516
4517 /* Add each puncturing pattern */
4518 for (uint32_t n=0; n < numPuncPatterns; n++) {
4519 unsigned pattern_start_offset = offset;
4520
4521 /* Subtree for this puncturing pattern */
4522 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4523 tvb, offset, 0,
4524 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4525 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4526
4527 /* SymbolMask (14 bits) */
4528 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4529 offset += 1;
4530
4531 uint32_t startPuncPrb, numPuncPrb;
4532
4533 /* startPuncPrb (10 bits) */
4534 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4535 offset += 2;
4536 /* numPuncPrb (8 bits) */
4537 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4538 offset += 1;
4539
4540 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4541
4542 /* Make a hole in range of PRBs to report */
4543 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4544 if (p < MAX_PRBS273) {
4545 prbs_for_st10_type5[p] = false0;
4546 }
4547 }
4548
4549 /* puncReMask (12 bits) */
4550 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4551 offset += 1;
4552 /* rb (1 bit) */
4553 proto_item *se20_rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4554 /* reserved (1 bit) */
4555 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4556 /* multiSDScope (1 bit) */
4557 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4558 /* rbgIncl (1 bit) */
4559 bool_Bool rbgIncl;
4560 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4561 offset += 1;
4562
4563 if (rbgIncl) {
4564 /* reserved (1 bit) */
4565 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4566 /* rbgSize(3 bits) */
4567 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4568 /* rbgMask (28 bits) */
4569 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4570 offset += 4;
4571
4572 proto_item_append_text(se20_rb_ti, " (ignored)");
4573 }
4574
4575 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4576 }
4577
4578 break;
4579 }
4580 case 21: /* SE 21: Variable PRB group size for channel information */
4581 {
4582 /* ciPrbGroupSize */
4583 uint32_t ci_prb_group_size;
4584 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);
4585 offset += 1;
4586
4587 switch (ci_prb_group_size) {
4588 case 0:
4589 case 1:
4590 case 255:
4591 /* Reserved value */
4592 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4593 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4594 ci_prb_group_size);
4595 break;
4596 default:
4597 /* This value affects how SE 11 is interpreted */
4598 ext11_settings.ext21_set = true1;
4599 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4600
4601 if (numPrbc == 0) {
4602 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4603 }
4604 break;
4605 }
4606
4607 /* reserved (6 bits) */
4608 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4609
4610 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4611 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4612 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4613 }
4614 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4615 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4616 }
4617 offset += 1;
4618 break;
4619 }
4620
4621 case 22: /* SE 22: ACK/NACK request */
4622 {
4623 uint32_t ack_nack_req_id;
4624 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4625 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4626 offset += 2;
4627
4628 if (state) {
4629 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4630 /* Add this request into conversation state on first pass */
4631 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)))
;
4632 request_details->request_frame_number = pinfo->num;
4633 request_details->request_frame_time = pinfo->abs_ts;
4634 request_details->requestType = SE22;
4635 /* Insert into flow's tree */
4636 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4637 }
4638 else {
4639 /* Try to link forward to ST8 response */
4640 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4641 ack_nack_req_id);
4642 if (response) {
4643 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4644 }
4645 }
4646 }
4647 break;
4648 }
4649
4650 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4651 {
4652 /* Green common header */
4653
4654 /* numSymPrbPattern (4 bits) */
4655 uint32_t num_sym_prb_pattern;
4656 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4657 /* reserved (3 bits) */
4658 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4659 /* prbMode (1 bit) */
4660 bool_Bool prb_mode;
4661 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4662 offset += 1;
4663
4664 /* reserved (8 bits) */
4665 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4666 offset += 1;
4667
4668 /* Dissect each SymPrbPattern */
4669 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4670
4671 /* Subtree */
4672 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4673 tvb, offset, 1, "",
4674 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4675 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4676
4677
4678 /* Orange part */
4679
4680 /* Reserved (2 bits) */
4681 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4682 /* symMask (14 bits) */
4683 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4684 offset += 2;
4685 /* numMcScaleOffset (4 bits) */
4686 uint32_t numMcScaleOffset;
4687 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4688
4689 if (!prb_mode) { /* PRB-MASK */
4690 /* prbPattern (4 bits) */
4691 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4692 offset += 1;
4693 /* reserved (8 bits) */
4694 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4695 offset += 1;
4696 /* reserved (4 bits) */
4697 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4698 }
4699 else { /* PRB-BLOCK */
4700 /* prbBlkOffset (8 bits) */
4701 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_offset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4702 offset += 1;
4703 /* prbBlkSize (8 bits) */
4704 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_size, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4705 offset += 1;
4706 }
4707
4708 for (unsigned c=0; c < numMcScaleOffset; c++) {
4709 if (c > 0) {
4710 /* reserved (4 bits) */
4711 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4712 }
4713
4714 static int * const remask_flags_even[] = {
4715 &hf_oran_mc_scale_re_mask_re1_even,
4716 &hf_oran_mc_scale_re_mask_re2_even,
4717 &hf_oran_mc_scale_re_mask_re3_even,
4718 &hf_oran_mc_scale_re_mask_re4_even,
4719 &hf_oran_mc_scale_re_mask_re5_even,
4720 &hf_oran_mc_scale_re_mask_re6_even,
4721 &hf_oran_mc_scale_re_mask_re7_even,
4722 &hf_oran_mc_scale_re_mask_re8_even,
4723 &hf_oran_mc_scale_re_mask_re9_even,
4724 &hf_oran_mc_scale_re_mask_re10_even,
4725 &hf_oran_mc_scale_re_mask_re11_even,
4726 &hf_oran_mc_scale_re_mask_re12_even,
4727 NULL((void*)0)
4728 };
4729
4730 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4731 uint64_t mcScaleReMask, mcScaleOffset;
4732 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4733 hf_oran_mc_scale_re_mask_even,
4734 ett_oran_mc_scale_remask,
4735 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4736 offset += 2;
4737
4738 /* csf (1 bit) */
4739 bool_Bool csf;
4740 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4741 /* mcScaleOffset (15 bits) */
4742 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);
4743 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4744 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4745 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4746 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4747
4748 offset += 2;
4749
4750 /* Record this config. */
4751 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4752 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4753
4754 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4755 unsigned i = sect_config->num_configs;
4756 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4757 sect_config->configs[i].mod_compr_csf = csf;
4758 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4759 sect_config->num_configs++;
4760 }
4761 }
4762
4763 proto_item_set_end(pattern_ti, tvb, offset);
4764 }
4765 break;
4766 }
4767
4768 case 24: /* SE 24: PUSCH DMRS configuration */
4769 {
4770 /* Hidden filter for bf (DMRS BF) */
4771 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4772 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4773
4774 /* alpnPerSym (1 bit) */
4775 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4776 /* antDmrsSnr (1 bit) */
4777 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4778 /* reserved (1 bit) */
4779 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4780 /* userGroupSize (5 bits) */
4781 uint32_t user_group_size;
4782 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);
4783 if (user_group_size == 0) {
4784 proto_item_append_text(ugs_ti, " (not used)");
4785 }
4786 else if (user_group_size > 12) {
4787 proto_item_append_text(ugs_ti, " (reserved)");
4788 }
4789 offset += 1;
4790 /* userGroupId (8 bits)*/
4791 uint32_t user_group_id;
4792 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);
4793 if (user_group_id == 0) {
4794 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4795 }
4796 if (user_group_id == 255) {
4797 /* Value 255 is reserved */
4798 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4799 }
4800 offset += 1;
4801
4802 bool_Bool seen_value_to_inherit = false0;
4803 bool_Bool inherited_config_has_transform_precoding = false0;
4804 int dmrs_configs_seen = 0;
4805
4806 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4807 uint32_t ueid_index = 0;
4808 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4809 dmrs_configs_seen++;
4810
4811 /* Subtree */
4812 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4813 tvb, offset, 0, "",
4814 "Entry");
4815 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4816
4817 /* entryType (3 bits) */
4818 uint32_t entry_type;
4819 proto_item *entry_type_ti;
4820 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4821 if (entry_type > 3) {
4822 proto_item_append_text(entry_type_ti, " (reserved)");
4823 }
4824
4825 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4826 unsigned int dmrs_port_number;
4827 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);
4828 if (dmrs_port_number > 11) {
4829 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4830 }
4831 offset += 1;
4832
4833 /* What follows depends upon entryType */
4834 switch (entry_type) {
4835 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4836 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4837 /* No further fields for these */
4838 /* Error here if no previous values to inherit!! */
4839 if (!seen_value_to_inherit) {
4840 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4841 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4842
4843 }
4844 /* TODO: would be useful to repeat whole inherited config here? */
4845 break;
4846
4847 case 2: /* transform precoding disabled */
4848 case 3: /* transform precoding enabled */
4849 {
4850 /* Type 2/3 are very similar.. */
4851
4852 /* ueIdReset (1 bit) */
4853 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4854 /* posMeas (1 bit) */
4855 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4856
4857 /* dmrsSymbolMask (14 bits) */
4858 static int * const dmrs_symbol_mask_flags[] = {
4859 &hf_oran_dmrs_symbol_mask_s13,
4860 &hf_oran_dmrs_symbol_mask_s12,
4861 &hf_oran_dmrs_symbol_mask_s11,
4862 &hf_oran_dmrs_symbol_mask_s10,
4863 &hf_oran_dmrs_symbol_mask_s9,
4864 &hf_oran_dmrs_symbol_mask_s8,
4865 &hf_oran_dmrs_symbol_mask_s7,
4866 &hf_oran_dmrs_symbol_mask_s6,
4867 &hf_oran_dmrs_symbol_mask_s5,
4868 &hf_oran_dmrs_symbol_mask_s4,
4869 &hf_oran_dmrs_symbol_mask_s3,
4870 &hf_oran_dmrs_symbol_mask_s2,
4871 &hf_oran_dmrs_symbol_mask_s1,
4872 &hf_oran_dmrs_symbol_mask_s0,
4873 NULL((void*)0)
4874 };
4875 proto_tree_add_bitmask(entry_tree, tvb, offset,
4876 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4877 offset += 2;
4878
4879 /* scrambling */
4880 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4881 offset += 2;
4882
4883 /* nscid (1 bit) */
4884 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4885
4886 /* These 5 bits differ depending upon entry type */
4887 if (entry_type == 2) { /* type 2 */
4888 /* dType (1 bit) */
4889 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4890 /* cdmWithoutData (2 bits) */
4891 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4892 /* lambda (2 bits) */
4893 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4894 }
4895 else { /* type 3 */
4896 /* reserved (1 bit) */
4897 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4898 /* lowPaprType (2 bits) */
4899 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4900 /* hoppingMode (2 bits) */
4901 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4902 }
4903
4904 /* firstPrb (9 bits) */
4905 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4906 offset += 1;
4907 /* lastPrb (9 bits) */
4908 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4909 offset += 2;
4910 /* Reserved (16 bits) */
4911 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4912 offset += 2;
4913
4914 /* Could now see entry types 0 or 1 - they have these values to inherit */
4915 seen_value_to_inherit = true1;
4916 inherited_config_has_transform_precoding = (entry_type == 3);
4917 break;
4918 }
4919
4920 default:
4921 /* reserved - expert info */
4922 break;
4923 }
4924
4925 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4926 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4927 proto_item_set_end(entry_ti, tvb, offset);
4928
4929 if (entry_type <= 1) {
4930 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4931 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4932 }
4933 }
4934
4935 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4936 break;
4937 }
4938
4939 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4940 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4941 where each layer could be one or apply to all layers. */
4942 {
4943 /* TODO: should only appear in one section of a message - check? */
4944 unsigned layer = 0;
4945 proto_item *layer_ti;
4946 while (offset+7 <= (extension_start_offset + extlen*4)) {
4947 /* Layer subtree */
4948 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4949 tvb, offset, 7, "",
4950 "Layer");
4951 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4952
4953 /* All 14 symbols for a layer (or all layers) */
4954 for (unsigned s=0; s < 14; s++) {
4955 proto_item *sym_ti;
4956 /* txWinForOnAirSymbol */
4957 unsigned int tx_win_for_on_air_symbol;
4958 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4959 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4960 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4961 if (tx_win_for_on_air_symbol == 0x0F) {
4962 /* Ordering not affected */
4963 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4964 }
4965 else {
4966 proto_item_append_text(sym_ti, " (sym %u)", s);
4967 }
4968 if (s % 2) {
4969 offset += 1;
4970 }
4971 }
4972
4973 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4974 proto_item_append_text(extension_ti, " (layer %u)", layer);
4975 }
4976 /* Set layer subtree label */
4977 if (layer == 1) {
4978 proto_item_append_text(layer_ti, " (all)");
4979 proto_item_append_text(extension_ti, " (all)");
4980 }
4981 if (layer == 0) {
4982 /* TODO: are no layers valid? What does it mean? */
4983 proto_item_append_text(extension_ti, " (none)");
4984 }
4985 break;
4986 }
4987
4988 case 26: /* SE 26: Frequency offset feedback */
4989 /* Reserved (8 bits) */
4990 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4991 offset += 1;
4992 /* Reserved (1 bit) */
4993 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4994 /* numFoFb (7 bits) */
4995 unsigned num_fo_fb;
4996 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4997 offset += 1;
4998
4999 /* Add each freqOffsetFb value */
5000 for (unsigned n=0; n < num_fo_fb; n++) {
5001 unsigned freq_offset_fb;
5002 /* freqOffsetFb (16 bits) */
5003 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
5004 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
5005 /* Show if maps onto a -ve number */
5006 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
5007 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
5008 }
5009 proto_item_append_text(offset_ti, " [#%u]", n+1);
5010 offset += 2;
5011 }
5012 break;
5013
5014 case 27: /* SE 27: O-DU controlled dimensionality reduction */
5015 {
5016 /* Hidden filter for bf (DMRS BF) */
5017 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5018 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5019
5020 /* beamType (2 bits) */
5021 unsigned beam_type;
5022 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
5023 /* reserved (6 bits) */
5024 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5025 offset += 1;
5026
5027 /* numElements */
5028 unsigned num_elements;
5029 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);
5030 if (num_elements == 0) {
5031 num_elements = 256;
5032 proto_item_append_text(num_elements_ti, " (256");
5033 }
5034
5035 offset += 1;
5036
5037 /* beamId value(s) */
5038 switch (beam_type) {
5039 case 0:
5040 for (unsigned n=0; n < num_elements; n++) {
5041 /* reserved (1 bit) + beamId */
5042 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5043 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5044 offset += 2;
5045 }
5046 break;
5047 case 1:
5048 /* reserved (1 bit) + beamId */
5049 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5050 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5051 offset += 2;
5052 break;
5053 default:
5054 /* Unknown type... */
5055 break;
5056 }
5057 break;
5058 }
5059
5060 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
5061 {
5062 /* reserved (3 bits) */
5063 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5064 /* numUeSinrRpt (5 bits) */
5065 uint32_t num_ue_sinr_rpt;
5066 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
5067 offset += 1;
5068
5069 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
5070 /* reserved (1 bit) */
5071 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
5072 tvb, offset, 1);
5073
5074 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
5075 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
5076 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5077 if (n % 2) {
5078 offset += 1;
5079 }
5080 }
5081
5082 /* May need to skip beyond half-used byte */
5083 if (num_ue_sinr_rpt % 2) {
5084 offset += 1;
5085 }
5086 break;
5087 }
5088
5089 case 29: /* SE 29: Cyclic delay adjustment */
5090 /* reserved (4 bits) */
5091 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5092 /* cdScgSize (4 bits) */
5093 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5094 offset += 1;
5095
5096 /* cdScgPhaseStep */
5097 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5098 offset += 1;
5099 break;
5100
5101 case 30: /* SE 30: PUSCH repetition indication */
5102 {
5103 /* Only valid for UL */
5104 if (!tap_info->uplink) {
5105 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5106 }
5107
5108 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5109
5110 /* reserved (4 bits) */
5111 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5112 /* numRepUe (4 bits) */
5113 uint8_t num_rep_ue;
5114 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5115 offset ++;
5116 /* reserved (8 bits) */
5117 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5118 offset += 1;
5119
5120 if (num_rep_ue == 1) {
5121 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5122 /* reserved (1 bit) */
5123 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5124 /* isLastRep (1 bit). Value meaningless here? */
5125 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5126 /* repIndex (6 bits) */
5127 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5128 offset += 1;
5129
5130 /* reserved (2 bits) */
5131 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5132 /* numReps (6 bits) */
5133 uint8_t num_reps;
5134 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5135 /* TODO: should numReps be 0 here? */
5136 offset += 1;
5137
5138 /* reserved (2 bits) */
5139 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5140 offset += 2;
5141
5142 }
5143 else {
5144 /* SE10 present */
5145 bool_Bool is_last_rep = false0;
5146 /* TODO: should is_last_rep (also) cause loop exit? */
5147 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5148 /* reserved (1 bit) */
5149 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5150 /* isLastRep (1 bit) */
5151 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5152 /* repIndex (6 bits) */
5153 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5154 offset += 1;
5155
5156 /* reserved (2 bits) */
5157 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5158 /* numReps (6 bits) */
5159 uint8_t num_reps;
5160 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);
5161 /* TODO: values 33-63 are reserved */
5162 if (num_reps > 32) {
5163 proto_item_append_text(num_reps_ti, " (reserved)");
5164 }
5165 offset += 1;
5166
5167 for (uint8_t rep=0; rep < num_reps; rep++) {
5168 /* reserved (1 bit) */
5169 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5170 /* repUeId (15 bits) */
5171 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5172 uint16_t ueid;
5173 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5174
5175 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5176 bool_Bool matched = false0;
5177 for (unsigned u=0; u < number_of_ueids; u++) {
5178 if (ueid == ueids[u])
5179 matched = true1;
5180 }
5181 if (!matched) {
5182 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5183 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5184 }
5185 offset += 2;
5186 }
5187 }
5188 }
5189 break;
5190 }
5191 case 31: /* SE 31: MCS Information */
5192 {
5193 /* TODO: show ueid (from ST5 or SE10) as generated field? Maybe add a subtree for each entry? */
5194 for (uint32_t u=0; u < number_of_ueids; u++) {
5195 /* reserved (4 bits) */
5196 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5197 /* mcsTable (4 bits) */
5198 proto_tree_add_item(extension_tree, hf_oran_mcs_table, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5199 offset += 1;
5200
5201 /* reserved (2 bits) */
5202 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5203 /* mcsIndex (6 bits) */
5204 proto_tree_add_item(extension_tree, hf_oran_mcs_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5205 }
5206 break;
5207 }
5208
5209 case 32: /* SE 32: Rank and TPMI measurement request */
5210 {
5211 /* reserved (3 bits) */
5212 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5213 /* numMeasReq (5 bits) */
5214 uint8_t num_meas_req;
5215 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_meas_req, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_meas_req);
5216 offset += 1;
5217
5218 /* reserved (8 bits) */
5219 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5220 offset += 1;
5221
5222 /* Show each measurement request */
5223 for (unsigned r=0; r < num_meas_req; r++) {
5224 /* Reserved (1 bit) */
5225 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5226 /* ueId (14 bits) */
5227 proto_tree_add_item(extension_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5228 offset += 2;
5229
5230 /* numOfUeAntPorts (4 bits) */
5231 proto_tree_add_item(extension_tree, hf_oran_num_of_ue_ant_ports, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5232 /* ueRank (4 bits) */
5233 proto_tree_add_item(extension_tree, hf_oran_ue_rank, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5234 offset += 1;
5235
5236 /* codebookSubset (2 bits) */
5237 proto_tree_add_item(extension_tree, hf_oran_codebook_subset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5238 /* TODO: tpmiIndex (6 bits) */
5239 offset += 1;
5240
5241 /* fullPwrMode (2 bits) */
5242 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5243 /* fullPwrMode2TmpiGroup (14 bits) */
5244 /* TODO: add as a bitset */
5245 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode_2_tpmi_group, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5246 offset += 2;
5247
5248 /* reserved (2 bytes) */
5249 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5250 offset += 2;
5251 }
5252 break;
5253 }
5254
5255 default:
5256 /* Other/unexpected extension types */
5257 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5258 "SE %u (%s) not supported by dissector",
5259 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5260 ext_unhandled = true1;
5261 break;
5262 }
5263
5264 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5265 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5266 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5267 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5268 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5269 extlen*4, offset-extension_start_offset);
5270 }
5271
5272 /* Move offset to beyond signalled length of extension */
5273 offset = extension_start_offset + (extlen*4);
5274
5275 /* Set length of extension header. */
5276 proto_item_set_len(extension_ti, extlen*4);
5277 }
5278 /* End of section extension handling */
5279
5280 /* Tap section beamId if not overwritten by SEs */
5281 if (!section_beamId_ignored && section_beamId != 0) {
5282 add_beam_id_to_tap(tap_info, section_beamId);
5283 }
5284
5285
5286 /* RRM measurement reports have measurement reports *after* extensions */
5287 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5288 {
5289 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5290 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5291 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5292
5293 bool_Bool mf;
5294 do {
5295 /* Measurement report subtree */
5296 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5297 tvb, offset, 1, "", "Measurement Report");
5298 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5299 unsigned report_start_offset = offset;
5300
5301 /* measurement flag (i.e., more reports after this one) (1 bit) */
5302 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5303
5304 /* measTypeId (7 bits) */
5305 uint32_t meas_type_id;
5306 proto_item *meas_type_id_ti;
5307 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);
5308 offset += 1;
5309
5310 /* Common to all measurement types */
5311 unsigned num_elements = 0;
5312 if (meas_type_id == 6) {
5313 /* numElements */
5314 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5315 }
5316 else {
5317 /* All other meas ids have a reserved byte */
5318 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5319 }
5320 offset += 1;
5321
5322 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5323 unsigned meas_data_size;
5324 proto_item *meas_data_size_ti;
5325 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);
5326 meas_data_size *= 4;
5327 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5328 offset += 2;
5329
5330 /* Summary for measurement report root */
5331 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5332 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5333 /* And section header */
5334 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5335 /* And Info column */
5336 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5337
5338 /* Handle specific message type fields */
5339 switch (meas_type_id) {
5340 case 1:
5341 {
5342 /* ueTae */
5343 unsigned ue_tae;
5344 proto_item *ue_tae_ti;
5345 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5346 /* Show if maps onto a -ve number */
5347 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5348 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5349 }
5350 offset += 2;
5351
5352 /* Reserved (16 bits) */
5353 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5354 offset += 2;
5355 break;
5356 }
5357 case 2:
5358 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5359 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5360 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5361 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5362 unsigned ue_layer_power;
5363 proto_item *ue_layer_power_ti;
5364 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);
5365 /* Show if maps onto a -ve number */
5366 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5367 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5368 }
5369 offset += 2;
5370 }
5371 /* padding out to 4 bytes */
5372 break;
5373 case 3:
5374 {
5375 /* ueFreqOffset */
5376 unsigned ue_freq_offset;
5377 proto_item *ue_freq_offset_ti;
5378 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);
5379 /* Show if maps onto a -ve number */
5380 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5381 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5382 }
5383 offset += 2;
5384
5385 /* Reserved (16 bits) */
5386 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5387 offset += 2;
5388 break;
5389 }
5390 case 4:
5391 case 5:
5392 /* reserved (2 bits) */
5393 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5394 /* symbolMask (14 bits) */
5395 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5396
5397 /* 2 bytes for each PRB ipnPower */
5398 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5399 /* Skip if should not be reported */
5400 if (!prbs_for_st10_type5[prb]) {
5401 continue;
5402 }
5403 unsigned ipn_power;
5404 proto_item *ipn_power_ti;
5405 /* ipnPower (2 bytes) */
5406 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5407 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5408 /* Show if maps onto a -ve number */
5409 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5410 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5411 }
5412 offset += 2;
5413 }
5414 /* padding out to 4 bytes */
5415 break;
5416 case 6:
5417 /* antDmrsSnrVal entries */
5418 for (unsigned n=0; n < num_elements; n++) {
5419 unsigned snr_value;
5420 proto_item *snr_value_ti;
5421 /* antDmrsSnrVal (2 bytes) */
5422 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);
5423 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5424 /* Show if maps onto a -ve number */
5425 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5426 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5427 }
5428 offset += 2;
5429 }
5430 break;
5431 case 7:
5432 {
5433 /* UE positioning measurement report */
5434 float start_value;
5435
5436 /* ueAzAoa (16 bits) */
5437 uint32_t ue_az_aoa;
5438 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);
5439 if (ue_az_aoa <= 0xE0F) {
5440 if (ue_az_aoa >= 0x0708) {
5441 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5442 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5443 }
5444 else {
5445 start_value = 180 + (ue_az_aoa * (float)0.1);
5446 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5447 }
5448 }
5449 else if (ue_az_aoa == 0xffff) {
5450 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5451 }
5452 else {
5453 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5454 }
5455 offset += 2;
5456
5457 /* Reserved (16 bits) */
5458 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5459 offset += 2;
5460
5461 /* ueZeAoa (16 bits) */
5462 uint32_t ue_ze_aoa;
5463 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);
5464 if (ue_ze_aoa <= 0x707) {
5465 start_value = ue_ze_aoa * (float)0.1;
5466 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5467 }
5468 else if (ue_az_aoa == 0xffff) {
5469 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5470 }
5471 else {
5472 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5473 }
5474 offset += 2;
5475
5476 /* Reserved (16 bits) */
5477 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5478 offset += 2;
5479
5480 /* uePosToaOffset (16 bits) */
5481 uint32_t ue_pos_toa_offset;
5482 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);
5483 if (ue_pos_toa_offset == 0) {
5484 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5485 }
5486 else if (ue_pos_toa_offset <= 0x7fff) {
5487 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5488 }
5489 else if (ue_pos_toa_offset == 0x8000) {
5490 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5491 }
5492 else {
5493 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5494 }
5495 offset += 2;
5496
5497 /* Reserved (16 bits) */
5498 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5499 offset += 2;
5500 break;
5501 }
5502 case 8:
5503 {
5504 /* UE radial speed measurement report */
5505
5506 /* ueRadialSpeed (16 bits) */
5507 uint32_t radial_speed;
5508 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);
5509 if (radial_speed <= 10000) {
5510 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5511 }
5512 else if (radial_speed == 0x8000) {
5513 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5514 }
5515 else {
5516 proto_item_append_text(radial_speed_ti, " (reserved value)");
5517 }
5518 offset += 2;
5519
5520 /* Reserved (16 bits) */
5521 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5522 offset += 2;
5523 break;
5524 }
5525 case 9:
5526 {
5527 /* TODO: UE post-equalization MU interference measurement */
5528
5529 /* reserved (16 bits) */
5530 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5531 offset += 2;
5532
5533 /* TODO: muInterferenceLevel (all layers * all PRB blocks) */
5534 break;
5535 }
5536 case 10:
5537 {
5538 /* UE TPMI and rank recommendation measurement */
5539
5540 /* numCandRanks (4 bits - only 1-4 valid) */
5541 uint8_t num_cand_ranks;
5542 proto_tree_add_item_ret_uint8(mr_tree, hf_oran_num_cand_ranks, tvb, offset, 1, ENC_NA0x00000000, &num_cand_ranks);
5543 if (num_cand_ranks > 4) {
5544 num_cand_ranks = 4;
5545 }
5546 if (num_cand_ranks < 1) {
5547 num_cand_ranks = 1;
5548 }
5549
5550 /* uePrefRank (4 bits) */
5551 add_reserved_field(mr_tree, hf_oran_ue_pref_rank, tvb, offset, 1);
5552 offset += 1;
5553
5554 for (uint8_t cand_rank=1; cand_rank <= num_cand_ranks; cand_rank++) {
5555 /* ueTpmiRankY (1 byte) */
5556 proto_item *rank_y_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y,
5557 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5558 proto_item_append_text(rank_y_ti, " (rank %u)", cand_rank);
5559
5560 offset += 1;
5561
5562 for (uint8_t sinr = 1; sinr <= cand_rank; sinr++) {
5563 /* ueTpmiRankYSinrLX (2 bytes) */
5564 proto_item *rank_y_sinr_x_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y_sinr_lx,
5565 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5566 proto_item_append_text(rank_y_sinr_x_ti, " (rank %u, sinr %u)", cand_rank, sinr);
5567 offset += 2;
5568 }
5569 }
5570 break;
5571 }
5572 case 11:
5573 {
5574 /* UE layer pre-equalization SINR report */
5575 /* TODO: how to know how many layers? Just fill up available data? */
5576 unsigned num_layers = (meas_data_size-1) * 4;
5577 for (unsigned layer=0; layer < num_layers; layer++) {
5578 /* ueLayerPreEqSinr (2 bytes each) */
5579 proto_item *pre_eq_sinr_ti = proto_tree_add_item(mr_tree, hf_oran_ue_layer_pre_eq_sinr,
5580 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5581 proto_item_append_text(pre_eq_sinr_ti, " (layer %u)", layer);
5582 offset += 2;
5583 }
5584 break;
5585 }
5586
5587 default:
5588 /* Anything else is not expected */
5589 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5590 "measTypeId %u (%s) not supported - only 1-6 are expected",
5591 meas_type_id,
5592 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5593 break;
5594
5595 }
5596
5597 /* Pad out to next 4 bytes */
5598 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5599
5600 /* TODO: verify dissected size of report vs meas_data_size? */
5601
5602 /* End of measurement report tree */
5603 proto_item_set_end(mr_ti, tvb, offset);
5604 } while (mf);
5605 }
5606
5607 /* Request for RRM Measurements has measurement commands after extensions */
5608 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5609 {
5610 bool_Bool mf = true1;
5611 do {
5612 /* Measurement command subtree */
5613 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5614 tvb, offset, 8, "", "Measurement Command");
5615 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5616
5617 /* mf (1 bit). 1st measurement command is always preset */
5618 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5619
5620 /* measTypeId (7 bits) */
5621 uint32_t meas_type_id;
5622 proto_item *meas_type_id_ti;
5623 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);
5624 offset += 1;
5625
5626 proto_item *meas_command_ti;
5627 uint32_t meas_command_size;
5628
5629 switch (meas_type_id) {
5630 case 5: /* command for IpN for unallocated PRBs */
5631 /* reserved (1 byte) */
5632 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5633 offset += 1;
5634 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5635 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);
5636 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5637 offset += 2;
5638 /* reserved (2 bits) */
5639 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5640 /* symbolMask (14 bits) */
5641 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5642 /* reserved (16 bits) */
5643 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5644 offset += 2;
5645 break;
5646
5647 default:
5648 /* Anything else is not expected */
5649 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5650 "measTypeId %u (%s) not supported - only 5 is expected",
5651 meas_type_id,
5652 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5653 break;
5654 }
5655 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5656
5657 } while (mf);
5658 }
5659
5660 /* Set extent of overall section */
5661 proto_item_set_len(sectionHeading, offset);
5662
5663 return offset;
5664}
5665
5666/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5667/* bit_width and comp_meth are out params */
5668static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5669 bool_Bool cplane, bool_Bool ignore,
5670 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5671 oran_tap_info *tap_info)
5672{
5673 /* Subtree */
5674 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5675 tvb, offset, 1, "",
5676 "udCompHdr");
5677 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5678
5679 /* udIqWidth */
5680 uint32_t hdr_iq_width;
5681 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5682 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5683 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5684
5685 /* udCompMeth */
5686 uint32_t ud_comp_meth;
5687 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5688 if (comp_meth) {
5689 *comp_meth = ud_comp_meth;
5690 }
5691
5692 /* Populate tap header with compression settings */
5693 if (!ignore) {
5694 tap_info->compression_methods |= (1 << ud_comp_meth);
5695 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))
;
5696 /* Summary */
5697 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5698 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5699 }
5700 else {
5701 proto_item_append_text(udcomphdr_ti, " (ignored)");
5702 if (hdr_iq_width || ud_comp_meth) {
5703 if (cplane) {
5704 /* Only ignore DL for cplane */
5705 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5706 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5707 tvb_get_uint8(tvb, offset));
5708 }
5709 else {
5710 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5711 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5712 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5713 tvb_get_uint8(tvb, offset));
5714 */
5715 }
5716
5717 }
5718 }
5719 return offset+1;
5720}
5721
5722/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5723/* bit_width and comp_meth are out params */
5724static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5725 unsigned comp_meth,
5726 uint32_t *exponent, uint16_t *sReSMask,
5727 bool_Bool for_sinr)
5728{
5729 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5730 /* sinrCompParam only present when bfp is used */
5731 return offset;
5732 }
5733
5734 if (comp_meth == COMP_NONE0 ||
5735 comp_meth == COMP_MODULATION4 ||
5736 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5737
5738 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5739 return offset;
5740 }
5741
5742 /* Subtree */
5743 unsigned start_offset = offset;
5744 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5745 tvb, offset, 1, "",
5746 (for_sinr) ? "sinrCompParam" : "udCompParam");
5747 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5748
5749 /* Show comp_meth as a generated field */
5750 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5751 proto_item_set_generated(meth_ti);
5752
5753 uint32_t param_exponent;
5754 uint64_t param_sresmask;
5755
5756 static int * const sres_mask_flags[] = {
5757 &hf_oran_sReSMask_re12,
5758 &hf_oran_sReSMask_re11,
5759 &hf_oran_sReSMask_re10,
5760 &hf_oran_sReSMask_re9,
5761 &hf_oran_sReSMask_re8,
5762 &hf_oran_sReSMask_re7,
5763 &hf_oran_sReSMask_re6,
5764 &hf_oran_sReSMask_re5,
5765 &hf_oran_sReSMask_re4,
5766 &hf_oran_sReSMask_re3,
5767 &hf_oran_sReSMask_re2,
5768 &hf_oran_sReSMask_re1,
5769 NULL((void*)0)
5770 };
5771
5772 switch (comp_meth) {
5773 case COMP_BLOCK_FP1: /* 1 */
5774 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5775 /* reserved (4 bits) */
5776 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5777 /* exponent (4 bits) */
5778 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5779 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5780 *exponent = param_exponent;
5781 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5782 offset += 1;
5783 break;
5784
5785 case COMP_BLOCK_SCALE2: /* 2 */
5786 /* Separate into integer and fractional bits? */
5787 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5788 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5789 offset++;
5790 break;
5791
5792 case COMP_U_LAW3: /* 3 */
5793 /* compBitWidth, compShift */
5794 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5795 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5796 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5797 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5798 offset += 1;
5799 break;
5800
5801 case BFP_AND_SELECTIVE_RE5: /* 5 */
5802 {
5803 /* sReSMask (exponent in middle!) */
5804 proto_item *sresmask_ti;
5805 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5806 hf_oran_sReSMask,
5807 ett_oran_sresmask,
5808 sres_mask_flags,
5809 ENC_NA0x00000000,
5810 &param_sresmask);
5811
5812 /* Get rid of exponent-shaped gap */
5813 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5814 unsigned res = 0;
5815 for (unsigned n=0; n < 12; n++) {
5816 if ((param_sresmask >> n) & 0x1) {
5817 res++;
5818 }
5819 }
5820 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5821
5822 /* exponent */
5823 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5824 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5825 *sReSMask = (uint16_t)param_sresmask;
5826 *exponent = param_exponent;
5827
5828 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5829 offset += 2;
5830 break;
5831 }
5832
5833 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5834 {
5835 /* sReSMask (exponent in middle!) */
5836 proto_item *sresmask_ti;
5837
5838 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5839 hf_oran_sReSMask,
5840 ett_oran_sresmask,
5841 sres_mask_flags,
5842 ENC_NA0x00000000,
5843 &param_sresmask);
5844
5845 /* Get rid of reserved-shaped gap */
5846 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5847 unsigned res = 0;
5848 for (unsigned n=0; n < 12; n++) {
5849 if ((param_sresmask >> n) & 0x1) {
5850 res++;
5851 }
5852 }
5853 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5854
5855 /* reserved (4 bits) */
5856 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5857 *sReSMask = (uint16_t)param_sresmask;
5858
5859 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5860 offset += 2;
5861 break;
5862 }
5863
5864 default:
5865 /* reserved (set to all zeros), but how many bytes?? */
5866 break;
5867 }
5868
5869 proto_item_set_len(udcompparam_ti, offset-start_offset);
5870 return offset;
5871}
5872
5873
5874/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5875/* bit_width and comp_meth are out params */
5876static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5877 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5878{
5879 /* Subtree */
5880 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5881 tvb, offset, 1, "",
5882 "ciCompHdr");
5883 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5884
5885 /* ciIqWidth */
5886 uint32_t hdr_iq_width;
5887 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5888 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5889 if (bit_width) {
5890 *bit_width = hdr_iq_width;
5891 }
5892 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5893
5894 /* ciCompMeth */
5895 uint32_t ci_comp_meth;
5896 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5897 if (comp_meth) {
5898 *comp_meth = ci_comp_meth;
5899 }
5900
5901 /* ciCompOpt */
5902 uint32_t opt;
5903 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5904 *comp_opt = opt;
5905 offset += 1;
5906
5907 /* Summary */
5908 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5909 hdr_iq_width,
5910 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5911 (*comp_opt) ? "compression per PRB" : "compression per UE");
5912 return offset;
5913}
5914
5915static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5916{
5917 unsigned version;
5918 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5919 if (version != 1) {
5920 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5921 "PayloadVersion %u not supported by dissector (only 1 is known)",
5922 version);
5923 /* TODO: should throw an exception? */
5924 }
5925}
5926
5927static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5928 ack_nack_request_t *request)
5929{
5930 /* Request frame */
5931 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5932 tvb, 0, 0, request->request_frame_number);
5933 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5934
5935 /* Work out gap between frames (in ms) */
5936 int seconds_between_packets = (int)
5937 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5938 int nseconds_between_packets =
5939 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5940
5941 int total_gap = (seconds_between_packets*1000) +
5942 ((nseconds_between_packets+500000) / 1000000);
5943
5944 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5945 tvb, 0, 0, total_gap);
5946 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5947
5948 /* Type of request */
5949 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5950 tvb, 0, 0, request->requestType);
5951 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5952}
5953
5954static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5955 ack_nack_request_t *response)
5956{
5957 if (response->response_frame_number == 0) {
5958 /* Requests may not get a response, and can't always tell when to expect one */
5959 return;
5960 }
5961
5962 /* Response frame */
5963 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5964 tvb, 0, 0, response->response_frame_number);
5965 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5966
5967 /* Work out gap between frames (in ms) */
5968 int seconds_between_packets = (int)
5969 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5970 int nseconds_between_packets =
5971 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5972
5973 int total_gap = (seconds_between_packets*1000) +
5974 ((nseconds_between_packets+500000) / 1000000);
5975
5976 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5977 tvb, 0, 0, total_gap);
5978 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5979}
5980
5981
5982
5983/* Control plane dissector (section 7). */
5984static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5985 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5986{
5987 /* Hidden filter for plane */
5988 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5989 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5990
5991 /* Set up structures needed to add the protocol subtree and manage it */
5992 unsigned offset = 0;
5993
5994 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5995 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5996
5997 tap_info->userplane = false0;
5998
5999 /* Create display subtree for the protocol */
6000 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
6001 proto_item_append_text(protocol_item, "-C");
6002 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
6003
6004 /* ecpriRtcid (eAxC ID) */
6005 uint16_t eAxC;
6006 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
6007 tap_info->eaxc = eAxC;
6008
6009 /* Look up any existing conversation state for eAxC+plane */
6010 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
6011 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
6012
6013 /* Message identifier */
6014 uint32_t seq_id, sub_seq_id, e;
6015 proto_item *seq_id_ti;
6016 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
6017
6018 /* Section common subtree */
6019 int section_tree_offset = offset;
6020 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
6021 tvb, offset, 0, "", "C-Plane Section Type ");
6022 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
6023
6024 /* Peek ahead at the section type */
6025 uint32_t sectionType = 0;
6026 sectionType = tvb_get_uint8(tvb, offset+5);
6027
6028 uint32_t scs = 0;
6029 proto_item *scs_ti = NULL((void*)0);
6030
6031 /* dataDirection */
6032 uint32_t direction = 0;
6033 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6034 tap_info->uplink = (direction==0);
6035
6036 /* Update/report status of conversation */
6037 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6038
6039 if (state == NULL((void*)0)) {
6040 /* Allocate new state */
6041 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
6042 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
6043 wmem_tree_insert32(flow_states_table, key, state);
6044 /* Tables for each direction */
6045 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
6046 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
6047 }
6048
6049 /* Check sequence analysis status */
6050 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
6051 /* Store this result */
6052 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
6053 result->unexpected_seq_number = true1;
6054 result->expected_sequence_number = state->next_expected_sequence_number[direction];
6055 result->previous_frame = state->last_frame[direction];
6056 result->u_plane_frames = wmem_list_new(wmem_file_scope());
6057 wmem_tree_insert32(flow_results_table, pinfo->num, result);
6058 }
6059 /* Update conversation info */
6060 state->last_frame[direction] = pinfo->num;
6061 state->last_frame_seen[direction] = true1;
6062 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
6063 }
6064
6065 /* Show any issues associated with this frame number */
6066 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
6067 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
6068 expert_add_info_format(pinfo, seq_id_ti,
6069 (direction == DIR_UPLINK0) ?
6070 &ei_oran_cplane_unexpected_sequence_number_ul :
6071 &ei_oran_cplane_unexpected_sequence_number_dl,
6072 "Sequence number %u expected, but got %u",
6073 result->expected_sequence_number, seq_id);
6074
6075 /* Update tap info */
6076 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
6077 /* Don't get confused by being slightly out of order.. */
6078 if (missing_sns < 128) {
6079 tap_info->missing_sns = missing_sns;
6080 }
6081 else {
6082 tap_info->missing_sns = 0;
6083 }
6084
6085 /* TODO: could add previous/next frames (in seqId tree?) ? */
6086 }
6087
6088 /* payloadVersion */
6089 dissect_payload_version(section_tree, tvb, pinfo, offset);
6090
6091 /* filterIndex */
6092 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6093 /* scs (for ST4 and ST8) */
6094 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
6095 }
6096 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
6097 /* reserved (4 bits) */
6098 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
6099 }
6100 else if (sectionType != SEC_C_LAA) {
6101 /* filterIndex (most common case) */
6102 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6103 }
6104 offset += 1;
6105
6106 unsigned ref_a_offset = offset;
6107 /* frameId */
6108 uint32_t frameId = 0;
6109 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6110 tap_info->frame = frameId;
6111 offset += 1;
6112
6113 /* subframeId */
6114 uint32_t subframeId = 0;
6115 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6116 /* slotId */
6117 uint32_t slotId = 0;
6118 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6119 tap_info->slot = slotId;
6120 offset++;
6121
6122 /* startSymbolId */
6123 uint32_t startSymbolId = 0;
6124 proto_item *ssid_ti = NULL((void*)0);
6125 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
6126 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
6127 /* symbolId */
6128 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6129 }
6130 else if (sectionType != SEC_C_LAA) {
6131 /* startSymbolId is in most section types */
6132 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6133 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
6134 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
6135 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
6136 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
6137 }
6138 }
6139 else {
6140 /* reserved (6 bits) */
6141 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
6142 }
6143 offset++;
6144
6145
6146 char id[16];
6147 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
6148 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6149 proto_item_set_generated(pi);
6150
6151 uint32_t cmd_scope = 0;
6152 bool_Bool st8_ready = false0;
6153
6154 /* numberOfSections (or whatever section has instead) */
6155 uint32_t nSections = 0;
6156 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
6157 /* Slot Control has these fields instead */
6158 /* reserved (4 bits) */
6159 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6160 /* cmdScope (4 bits) */
6161 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
6162 }
6163 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
6164 /* reserved (7 bits) */
6165 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
6166 /* ready (1 bit) */
6167 /* TODO: when set, ready in slotId+1.. */
6168 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
6169 if (!st8_ready) {
6170 /* SCS value is ignored, and may be set to any value by O-RU */
6171 proto_item_append_text(scs_ti, " (ignored)");
6172 }
6173 }
6174 else if (sectionType != SEC_C_LAA) {
6175 /* numberOfSections */
6176 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
6177 }
6178 else {
6179 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6180 }
6181 offset++;
6182
6183 /* sectionType */
6184 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
6185 offset += 1;
6186
6187 /* Check that dataDirection is consistent with section type */
6188 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
6189 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
6190 }
6191 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
6192 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
6193 }
6194
6195 /* Note this section type in stats */
6196 if (sectionType < SEC_C_MAX_INDEX) {
6197 tap_info->section_types[sectionType] = true1;
6198 }
6199
6200 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6201 unsigned bit_width = 0;
6202 unsigned comp_meth = 0;
6203 proto_item *comp_meth_ti;
6204 unsigned ci_comp_method = 0;
6205 uint8_t ci_comp_opt = 0;
6206
6207 uint32_t num_ues = 0;
6208 uint32_t number_of_acks = 0, number_of_nacks = 0;
6209
6210 uint32_t num_sinr_per_prb = 0;
6211
6212 switch (sectionType) {
6213 case SEC_C_UNUSED_RB: /* Section Type 0 */
6214 /* timeOffset */
6215 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6216 offset += 2;
6217 /* frameStructure */
6218 offset = dissect_frame_structure(section_tree, tvb, offset,
6219 subframeId, slotId);
6220
6221 /* cpLength */
6222 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6223 offset += 2;
6224 /* reserved (8 bits) */
6225 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6226 offset += 1;
6227 break;
6228
6229 case SEC_C_NORMAL: /* Section Type 1 */
6230 case SEC_C_UE_SCHED: /* Section Type 5 */
6231 /* udCompHdr */
6232 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6233 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6234 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6235 /* reserved (8 bits) */
6236 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6237 offset += 1;
6238 break;
6239
6240 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6241 break;
6242
6243 case SEC_C_PRACH: /* Section Type 3 */
6244 /* timeOffset */
6245 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6246 offset += 2;
6247 /* frameStructure */
6248 offset = dissect_frame_structure(section_tree, tvb, offset,
6249 subframeId, slotId);
6250 /* cpLength */
6251 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6252 offset += 2;
6253 /* udCompHdr */
6254 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6255 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6256 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6257 break;
6258
6259 case SEC_C_CH_INFO: /* Section Type 6 */
6260 /* numberOfUEs */
6261 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6262 offset += 1;
6263 /* ciCompHdr (was reserved) */
6264 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6265
6266 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6267 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6268 if (nSections == 0 || num_ues > nSections) {
6269 nSections = num_ues;
6270 }
6271 break;
6272
6273 case SEC_C_RSVD2:
6274 break;
6275
6276 case SEC_C_LAA: /* Section Type 7 */
6277 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6278 offset += 2;
6279 break;
6280
6281 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6282 /* numberOfAcks (1 byte) */
6283 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6284 offset += 1;
6285 /* numberOfNacks (1 byte) */
6286 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6287 offset += 1;
6288
6289 /* Show ACKs and NACKs. For both, try to link back to request. */
6290 for (unsigned int n=1; n <= number_of_acks; n++) {
6291 uint32_t ackid;
6292 proto_item *ack_ti;
6293 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6294 offset += 2;
6295
6296 /* Look up request table in state (which really should be set by now, but test anyway). */
6297 if (state && state->ack_nack_requests) {
6298 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6299 if (request != NULL((void*)0)) {
6300 /* On first pass, update with this response */
6301 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6302 request->response_frame_number = pinfo->num;
6303 request->response_frame_time = pinfo->abs_ts;
6304 }
6305
6306 /* Show request details */
6307 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6308 }
6309 else {
6310 /* Request not found */
6311 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6312 "Response for ackId=%u received, but no request found",
6313 ackid);
6314 }
6315 }
6316 }
6317 for (unsigned int m=1; m <= number_of_nacks; m++) {
6318 uint32_t nackid;
6319 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6320 offset += 2;
6321
6322 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6323 "Received Nack for ackNackId=%u",
6324 nackid);
6325
6326 /* Look up request table in state. */
6327 if (state && state->ack_nack_requests) {
6328 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6329 if (request) {
6330 /* On first pass, update with this response */
6331 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6332 request->response_frame_number = pinfo->num;
6333 request->response_frame_time = pinfo->abs_ts;
6334 }
6335
6336 /* Show request details */
6337 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6338 }
6339 else {
6340 /* Request not found */
6341 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6342 "Response for nackId=%u received, but no request found",
6343 nackid);
6344 }
6345 }
6346 }
6347 break;
6348
6349 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6350 {
6351 /* numSinrPerPrb (3 bits) */
6352 proto_item *nspp_ti;
6353 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);
6354 switch (num_sinr_per_prb) {
6355 case 0:
6356 num_sinr_per_prb = 1; break;
6357 case 1:
6358 num_sinr_per_prb = 2; break;
6359 case 2:
6360 num_sinr_per_prb = 3; break;
6361 case 3:
6362 num_sinr_per_prb = 4; break;
6363 case 4:
6364 num_sinr_per_prb = 6; break;
6365 case 5:
6366 num_sinr_per_prb = 12; break;
6367
6368 default:
6369 proto_item_append_text(nspp_ti, " (invalid)");
6370 num_sinr_per_prb = 1;
6371 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6372 "Invalid numSinrPerPrb value (%u)",
6373 num_sinr_per_prb);
6374 }
6375
6376 /* oruControlSinrSlotMaskId (5 bits) */
6377 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6378 offset += 1;
6379 /* reserved (8 bits) */
6380 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6381 offset += 1;
6382 break;
6383 }
6384
6385 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6386 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6387 /* reserved (16 bits) */
6388 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6389 offset += 2;
6390 break;
6391 };
6392
6393 /* Update udCompHdr details in state for UL U-Plane */
6394 if (state && direction==0) {
6395 switch (sectionType) {
6396 case SEC_C_NORMAL: /* Section Type 1 */
6397 case SEC_C_PRACH: /* Section Type 3 */
6398 case SEC_C_UE_SCHED: /* Section Type 5 */
6399 state->ul_ud_comp_hdr_set = true1;
6400 state->ul_ud_comp_hdr_bit_width = bit_width;
6401 state->ul_ud_comp_hdr_compression = comp_meth;
6402 state->ul_ud_comp_hdr_frame = pinfo->num;
6403 break;
6404 default:
6405 break;
6406 }
6407 }
6408
6409
6410 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6411 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6412 frameId, subframeId, slotId, startSymbolId);
6413 if (nSections) {
6414 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6415 }
6416
6417 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6418 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6419
6420 /* Set actual length of C-Plane section header */
6421 proto_item_set_len(section_tree, offset - section_tree_offset);
6422
6423 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6424 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6425 (st8_ready) ? " (Ready)" : " (ACK)");
6426 }
6427
6428
6429 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6430 if (sectionType == SEC_C_SLOT_CONTROL) {
6431 /* numberOfST4Cmds */
6432 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6433 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6434 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6435 if (no_st4_cmds == 0) {
6436 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6437 }
6438 offset += 1;
6439
6440 /* reserved (1 byte) */
6441 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6442 offset += 1;
6443
6444 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6445 proto_item *len_ti;
6446 for (uint32_t n=0; n < no_st4_cmds; n++) {
6447 /* Table 7.4.6-2: Section Type 4 Command common header format */
6448 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6449 tvb, offset, 8, "",
6450 "Type 4 Command common header");
6451 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6452
6453 /* st4CmdType */
6454 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6455 offset += 1;
6456
6457 /* st4CmdLen */
6458 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6459 if (st4_cmd_len == 0) {
6460 /* Meaning of 0 not yet defined (v15.00) */
6461 proto_item_append_text(len_ti, " (reserved)");
6462 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6463 }
6464 else {
6465 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6466 }
6467 offset += 2;
6468
6469 /* numSlots */
6470 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);
6471 if (num_slots == 0) {
6472 proto_item_append_text(slots_ti, " (until changed)");
6473 }
6474 offset += 1;
6475
6476 /* ackNackReqId */
6477 proto_item *ack_nack_req_id_ti;
6478 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);
6479 offset += 2;
6480 if (ack_nack_req_id == 0) {
6481 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6482 }
6483
6484 /* reserved (16 bits) */
6485 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6486 offset += 2;
6487
6488 /* Set common header summary */
6489 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6490 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6491 st4_cmd_len, num_slots, ack_nack_req_id);
6492
6493 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6494 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6495
6496
6497 /* Subtree for this command body */
6498 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6499 tvb, offset, 0, "",
6500 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6501 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6502
6503 unsigned command_start_offset = offset;
6504
6505 /* Check fields compatible with chosen command. */
6506 if (st4_cmd_type==1) {
6507 if (num_slots != 0) {
6508 /* "the value of numSlots should be set to zero for this command type" */
6509 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6510 "numSlots should be zero for ST4 command 1 - found %u",
6511 num_slots);
6512 }
6513 }
6514
6515 if (st4_cmd_type==3 || st4_cmd_type==4) {
6516 if (startSymbolId != 0) {
6517 /* "expected reception window for the commands is the symbol zero reception window" */
6518 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6519 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6520 startSymbolId);
6521 }
6522 }
6523
6524 /* Add format for this command */
6525 switch (st4_cmd_type) {
6526 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6527 {
6528 bool_Bool disable_tdbfns;
6529 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6530
6531 /* Hidden filter for bf */
6532 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6533 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6534
6535 /* reserved (2 bits) */
6536 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6537 /* symbolMask (14 bits) */
6538 uint32_t symbol_mask;
6539 proto_item *symbol_mask_ti;
6540 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6541 /* 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 */
6542 /* lsb is symbol 0 */
6543 for (unsigned s=0; s < 14; s++) {
6544 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6545 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6546 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6547 break;
6548 }
6549 }
6550
6551 /* disableTDBFNs (1 bit) */
6552 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6553
6554 /* tdBeamNum (15 bits) */
6555 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6556 offset += 2;
6557
6558 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6559 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6560 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6561 /* reserved (3 bytes) */
6562 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6563 offset += 3;
6564
6565 if (disable_tdbfns) {
6566 /* No beamnum information to show so get out. */
6567 break;
6568 }
6569
6570 /* Read beam entries until reach end of command length */
6571 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6572
6573 /* disableTDBFWs (1 bit) */
6574 bool_Bool disable_tdbfws;
6575 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6576
6577 /* tdBeamNum (15 bits) */
6578 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6579 offset += 2;
6580
6581 /* Showing BFWs? */
6582 if (!disable_tdbfws) {
6583
6584 /* bfwCompParam */
6585 unsigned exponent = 0;
6586 bool_Bool supported = false0;
6587 unsigned num_trx_entries;
6588 uint16_t *trx_entries;
6589 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6590 &bfwcomphdr_comp_meth, &exponent, &supported,
6591 &num_trx_entries, &trx_entries);
6592
6593 /* Antenna count from preference */
6594 unsigned num_trx = pref_num_bf_antennas;
6595 int bit_offset = offset*8;
6596
6597 for (unsigned trx=0; trx < num_trx; trx++) {
6598 /* Create antenna subtree */
6599 int bfw_offset = bit_offset / 8;
6600 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6601 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6602 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6603
6604 /* I value */
6605 /* Get bits, and convert to float. */
6606 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6607 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6608 /* Add to tree. */
6609 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6610 (bfwcomphdr_iq_width+7)/8, value);
6611 bit_offset += bfwcomphdr_iq_width;
6612 proto_item_append_text(bfw_ti, "I=%f ", value);
6613
6614 /* Leave a gap between I and Q values */
6615 proto_item_append_text(bfw_ti, " ");
6616
6617 /* Q value */
6618 /* Get bits, and convert to float. */
6619 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6620 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6621 /* Add to tree. */
6622 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6623 (bfwcomphdr_iq_width+7)/8, value);
6624 bit_offset += bfwcomphdr_iq_width;
6625 proto_item_append_text(bfw_ti, "Q=%f", value);
6626
6627 proto_item_append_text(bfw_ti, ")");
6628 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6629 }
6630 /* Need to round to next byte */
6631 offset = (bit_offset+7)/8;
6632 }
6633 }
6634 break;
6635 }
6636 case 2: /* TDD_CONFIG_PATTERN */
6637 /* reserved (2 bits) */
6638 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6639 /* dirPattern (14 bits) */
6640 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6641 offset += 2;
6642
6643 /* reserved (2 bits) */
6644 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6645 /* guardPattern (14 bits) */
6646 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6647 offset += 2;
6648 break;
6649
6650 case 3: /* TRX_CONTROL */
6651 case 5: /* TRX_CONTROL_BIDIR */
6652 {
6653 /* Only allowed cmdScope is ARRAY-COMMAND */
6654 if (cmd_scope != 0) {
6655 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6656 }
6657
6658 /* reserved (2 bits) */
6659 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6660 /* log2MaskBits (4 bits) */
6661 unsigned log2maskbits;
6662 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6663 /* sleepMode (2 bits) */
6664 uint32_t sleep_mode;
6665 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6666 offset += 1;
6667
6668 /* reserved (4 bits) */
6669 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6670 /* numSlotsExt (20 bits) */
6671 uint32_t num_slots_ext;
6672 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);
6673 if (num_slots==0 && num_slots_ext==0) {
6674 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6675 }
6676 else {
6677 /* Time should be rounded up according to SCS */
6678 float total = (float)(num_slots + num_slots_ext);
6679 /* From table 7.5.2.13-3 */
6680 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6681 0, 0, 0, 0, 0, 0, /* reserved */
6682 1000, 1000, 1000, 1000 };
6683 float slot_length = slot_length_by_scs[scs];
6684 /* Only using valid SCS. TODO: is this test ok? */
6685 if (slot_length != 0) {
6686 /* Round up to next slot */
6687 total = ((int)(total / slot_length) + 1) * slot_length;
6688 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6689 }
6690 }
6691 offset += 3;
6692
6693 /* reserved (2 bits) */
6694 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6695
6696 /* symbolMask (14 bits) */
6697 uint32_t symbol_mask;
6698 proto_item *sm_ti;
6699 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6700 if (symbol_mask == 0x0) {
6701 proto_item_append_text(sm_ti, " (wake)");
6702 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6703 }
6704 else if (symbol_mask == 0x3fff) {
6705 proto_item_append_text(sm_ti, " (sleep)");
6706 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6707 }
6708 else {
6709 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6710 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6711 sleep_mode, symbol_mask);
6712 }
6713 offset += 2;
6714
6715 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6716 unsigned antmask_length = 2;
6717 if (log2maskbits >= 4) {
6718 antmask_length = (1 << log2maskbits) / 8;
6719 }
6720 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6721 /* show count */
6722 unsigned antenna_count = 0;
6723 for (unsigned b=0; b < antmask_length; b++) {
6724 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6725 for (unsigned bit=0; bit < 8; bit++) {
6726 if ((1 << bit) & byte) {
6727 antenna_count++;
6728 }
6729 }
6730 }
6731 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6732 offset += antmask_length;
6733
6734 /* Pad to next 4-byte boundary */
6735 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6736 break;
6737 }
6738
6739 case 4: /* ASM (advanced sleep mode) */
6740 /* reserved (2+4=6 bits) */
6741 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6742 /* sleepMode (2 bits) */
6743 uint32_t sleep_mode;
6744 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6745 offset += 1;
6746
6747 /* reserved (4 bits) */
6748 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6749 /* numSlotsExt (20 bits) */
6750 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6751 offset += 3;
6752
6753 /* reserved (2 bits) */
6754 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6755 /* symbolMask (14 bits) */
6756 uint32_t symbol_mask;
6757 proto_item *sm_ti;
6758 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6759 if (symbol_mask == 0x0) {
6760 proto_item_append_text(sm_ti, " (wake)");
6761 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6762 }
6763 else if (symbol_mask == 0x3fff) {
6764 proto_item_append_text(sm_ti, " (sleep)");
6765 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6766 }
6767 else {
6768 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6769 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6770 sleep_mode, symbol_mask);
6771 }
6772 offset += 2;
6773
6774 /* reserved (2 bytes) */
6775 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6776 offset += 2;
6777 break;
6778
6779 default:
6780 /* Error! */
6781 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6782 "Dissected ST4 command (%u) not recognised",
6783 st4_cmd_type);
6784 break;
6785 }
6786
6787 /* Check apparent size of padding (0-3 bytes ok) */
6788 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6789 if (padding_remaining > 3) {
6790 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6791 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6792 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6793 }
6794
6795 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6796 offset = command_start_offset + (st4_cmd_len * 4);
6797
6798 /* Set end of command tree */
6799 proto_item_set_end(command_ti, tvb, offset);
6800
6801 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6802 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6803 /* Add this request into conversation state on first pass */
6804 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)))
;
6805 request_details->request_frame_number = pinfo->num;
6806 request_details->request_frame_time = pinfo->abs_ts;
6807 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6808
6809 wmem_tree_insert32(state->ack_nack_requests,
6810 ack_nack_req_id,
6811 request_details);
6812 }
6813 else {
6814 /* On later passes, try to link forward to ST8 response */
6815 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6816 ack_nack_req_id);
6817 if (response) {
6818 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6819 }
6820 }
6821 }
6822 }
6823 }
6824 /* LAA doesn't have sections either.. */
6825 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6826 /* 7.2.5 Table 6.4-6 */
6827 unsigned mcot;
6828 proto_item *mcot_ti;
6829
6830 /* laaMsgType */
6831 uint32_t laa_msg_type;
6832 proto_item *laa_msg_type_ti;
6833 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6834 /* laaMsgLen */
6835 uint32_t laa_msg_len;
6836 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6837 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6838 if (laa_msg_len == 0) {
6839 proto_item_append_text(len_ti, " (reserved)");
6840 }
6841 offset += 1;
6842
6843 int payload_offset = offset;
6844
6845 /* Payload */
6846 switch (laa_msg_type) {
6847 case 0:
6848 /* LBT_PDSCH_REQ */
6849 /* lbtHandle (16 bits) */
6850 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6851 offset += 2;
6852 /* lbtOffset (10 bits) */
6853 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6854 offset += 1;
6855 /* lbtMode (2 bits) */
6856 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6857 /* reserved (1 bit) */
6858 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6859 /* lbtDeferFactor (3 bits) */
6860 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6861 offset += 1;
6862 /* lbtBackoffCounter (10 bits) */
6863 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6864 offset += 1;
6865 /* MCOT (4 bits) */
6866 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6867 if (mcot<1 || mcot>10) {
6868 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6869 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6870 "MCOT seen with value %u (must be 1-10)", mcot);
6871
6872 }
6873 /* reserved (10 bits) */
6874 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6875 break;
6876 case 1:
6877 /* LBT_DRS_REQ */
6878 /* lbtHandle (16 bits) */
6879 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6880 offset += 2;
6881 /* lbtOffset (10 bits) */
6882 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6883 offset += 1;
6884 /* lbtMode (2 bits) */
6885 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6886 /* reserved (28 bits) */
6887 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6888 break;
6889 case 2:
6890 /* LBT_PDSCH_RSP */
6891 /* lbtHandle (16 bits) */
6892 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6893 offset += 2;
6894 /* lbtPdschRes (2 bits) */
6895 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6896 /* inParSF (1 bit) */
6897 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6898 /* sfStatus (1 bit) */
6899 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6900 /* sfnSf (12 bits) */
6901 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6902 offset += 2;
6903 /* reserved (24 bits) */
6904 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6905 break;
6906 case 3:
6907 /* LBT_DRS_RSP */
6908 /* lbtHandle (16 bits) */
6909 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6910 offset += 2;
6911 /* lbtDrsRes (1 bit) */
6912 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6913 /* reserved (7 bits) */
6914 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6915 break;
6916 case 4:
6917 /* LBT_Buffer_Error */
6918 /* lbtHandle (16 bits) */
6919 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6920 offset += 2;
6921 /* lbtBufErr (1 bit) */
6922 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6923 /* reserved (7 bits) */
6924 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6925 break;
6926 case 5:
6927 /* LBT_CWCONFIG_REQ */
6928 /* lbtHandle (16 bits) */
6929 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6930 offset += 2;
6931 /* lbtCWConfig_H (8 bits) */
6932 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6933 offset += 1;
6934 /* lbtCWConfig_T (8 bits) */
6935 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6936 offset += 1;
6937 /* lbtMode (2 bits) */
6938 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6939 /* lbtTrafficClass (3 bits) */
6940 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6941 /* reserved (19 bits) */
6942 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6943 break;
6944 case 6:
6945 /* LBT_CWCONFIG_RSP */
6946 /* lbtHandle (16 bits) */
6947 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6948 offset += 2;
6949 /* lbtCWR_Rst (1 bit) */
6950 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6951 /* reserved (7 bits) */
6952 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6953 break;
6954
6955 default:
6956 /* Unhandled! */
6957 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6958 "laaMsgType %u not supported by dissector",
6959 laa_msg_type);
6960
6961 break;
6962 }
6963 /* For now just skip indicated length of bytes */
6964 offset = payload_offset + 4*(laa_msg_len+1);
6965 }
6966
6967
6968 /* Dissect each C section */
6969 for (uint32_t i = 0; i < nSections; ++i) {
6970 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6971 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6972 protocol_item,
6973 subframeId, frameId, slotId, startSymbolId,
6974 bit_width, ci_comp_method, ci_comp_opt,
6975 num_sinr_per_prb);
6976 }
6977
6978 /* Expert error if we are short of tvb by > 3 bytes */
6979 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6980 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6981 "%u bytes remain at end of frame - should be 0-3",
6982 tvb_reported_length_remaining(tvb, offset));
6983 }
6984
6985 if (PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && result) {
6986 /* Show list of frames that have corresponding U-plane data */
6987 wmem_list_frame_t *list_frame;
6988 for (list_frame = wmem_list_head(result->u_plane_frames); list_frame != NULL((void*)0); list_frame = wmem_list_frame_next(list_frame)) {
6989 corresponding_uplane_frame *frame = wmem_list_frame_data(list_frame);
6990 proto_item *uplane_frame_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frame, tvb, 0, 0,
6991 frame->frame_number);
6992 proto_item_append_text(uplane_frame_ti, " sectionId:%2u symbol:%2u PRBs %3u->%3u (in %uus)",
6993 frame->sectionId, frame->symbol, frame->startPrbu, frame->startPrbu+frame->numPrbu-1, frame->gap_in_usecs);
6994 proto_item_set_generated(uplane_frame_ti);
6995 }
6996 /* Also show total number of corresponding u-plane frames */
6997 proto_item *uplane_frame_count_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frames_total, tvb, 0, 0,
6998 wmem_list_count(result->u_plane_frames));
6999 proto_item_set_generated(uplane_frame_count_ti);
7000 }
7001
7002 return tvb_captured_length(tvb);
7003}
7004
7005static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
7006 unsigned sample_number, int samples_offset,
7007 oran_tap_info *tap_info,
7008 unsigned sample_bit_width,
7009 int comp_meth,
7010 uint32_t exponent,
7011 section_mod_compr_config_t *mod_compr_params,
7012 uint8_t re)
7013{
7014 /* I */
7015 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7016 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7017 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7018 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
7019 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
7020 samples_offset += sample_bit_width;
7021 /* Q */
7022 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7023 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7024 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7025 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
7026 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
7027 samples_offset += sample_bit_width;
7028
7029 /* Update RE stats */
7030 tap_info->num_res++;
7031 /* if (i_value == 0.0 && q_value == 0.0) { */
7032 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
7033 if (i_bits == 0 && q_bits == 0) {
7034 tap_info->num_res_zero++;
7035 }
7036 else {
7037 tap_info->non_zero_re_in_current_prb = true1;
7038 }
7039 return samples_offset;
7040}
7041
7042
7043static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
7044{
7045 if (!udcomplen_heuristic_result_set) {
7046 /* All sections will start the same way */
7047 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
7048
7049 /* Move offset back to the start of the section */
7050 offset -= section_bytes_before_field;
7051
7052 do {
7053 /* This field appears several bytes into the U-plane section */
7054 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
7055 /* Are there enough bytes to still read the length field? */
7056 if (section_bytes_before_field+2 > length_remaining) {
7057 udcomplen_heuristic_result = false0;
7058 udcomplen_heuristic_result_set = true1;
7059 break;
7060 }
7061
7062 /* Read the length field */
7063 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
7064
7065 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
7066 * Could take into account numPrbU, etc */
7067 if (udcomplen < section_bytes_before_field+2) {
7068 udcomplen_heuristic_result = false0;
7069 udcomplen_heuristic_result_set = true1;
7070 break;
7071 }
7072
7073 /* Does this section fit into the frame? */
7074 if (udcomplen > length_remaining) {
7075 udcomplen_heuristic_result = false0;
7076 udcomplen_heuristic_result_set = true1;
7077 break;
7078 }
7079
7080 /* Move past this section */
7081 offset += udcomplen;
7082
7083 /* Are we at the end of the frame? */
7084 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
7085 if (tvb_reported_length_remaining(tvb, offset) < 4) {
7086 udcomplen_heuristic_result = true1;
7087 udcomplen_heuristic_result_set = true1;
7088 }
7089 } while (!udcomplen_heuristic_result_set);
7090 }
7091 return udcomplen_heuristic_result;
7092}
7093
7094static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
7095{
7096 if (tvb_captured_length_remaining(tvb, offset) < 2) {
7097 return false0;
7098 }
7099 uint8_t first_byte = tvb_get_uint8(tvb, offset);
7100 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
7101
7102 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
7103 /* - meth should be 0-8 */
7104 /* - reserved byte should be 0 */
7105 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
7106}
7107
7108static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
7109{
7110 /* Should really not happen, but guard against this anyway. */
7111 if (flow == NULL((void*)0)) {
7112 /* No state to update. */
7113 return false0;
7114 }
7115
7116 if (direction == DIR_UPLINK0) {
7117 if (flow->udcomphdrUplink_heuristic_result_set) {
7118 /* Return cached value */
7119 return flow->udcomphdrUplink_heuristic_result;
7120 }
7121 else {
7122 /* Work it out, and save answer for next time */
7123 flow->udcomphdrUplink_heuristic_result_set = true1;
7124 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
7125 return flow->udcomphdrUplink_heuristic_result;
7126 }
7127 }
7128 else {
7129 /* Downlink */
7130 if (flow->udcomphdrDownlink_heuristic_result_set) {
7131 /* Return cached value */
7132 return flow->udcomphdrDownlink_heuristic_result;
7133 }
7134 else {
7135 /* Work it out, and save answer for next time */
7136 flow->udcomphdrDownlink_heuristic_result_set = true1;
7137 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
7138 return flow->udcomphdrDownlink_heuristic_result;
7139 }
7140 }
7141}
7142
7143static bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
7144{
7145 /* Cast parameters to their types */
7146 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
7147 expected_section_data_t *result_value = (expected_section_data_t *)value;
7148 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
7149
7150 /* Deep copy of section data */
7151 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)))
;
7152 *copy = *result_value;
7153
7154 /* Add into result tree */
7155 wmem_tree_insert32(result_tree, sectionId, copy);
7156
7157 return false0;
7158}
7159
7160/* User plane dissector (section 8) */
7161static int
7162dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7163 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
7164{
7165 /* Hidden filter for plane */
7166 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
7167 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
7168
7169 /* Set up structures needed to add the protocol subtree and manage it */
7170 unsigned offset = 0;
7171
7172 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
7173 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
7174
7175 tap_info->userplane = true1;
7176
7177 /* Create display subtree for the protocol */
7178 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
7179 proto_item_append_text(protocol_item, "-U");
7180 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
7181
7182 /* Transport header */
7183 /* Real-time control data / IQ data transfer message series identifier */
7184 uint16_t eAxC;
7185 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
7186 tap_info->eaxc = eAxC;
7187
7188 /* Update/report status of conversation */
7189 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
7190 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
7191
7192 flow_result_t *result = NULL((void*)0);
7193
7194 /* Message identifier */
7195 proto_item *seqIdItem;
7196 uint32_t seqId, subSeqId, e;
7197 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
7198
7199 /* Common header for time reference */
7200 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
7201 tvb, offset, 4, "", "Timing Header (");
7202 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
7203
7204 /* dataDirection */
7205 uint32_t direction;
7206 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
7207 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
7208 /* payloadVersion */
7209 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
7210 /* filterIndex */
7211 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7212 offset += 1;
7213
7214 int ref_a_offset = offset;
7215
7216 /* frameId */
7217 uint32_t frameId = 0;
7218 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7219 tap_info->frame = frameId;
7220 offset += 1;
7221
7222 /* subframeId */
7223 uint32_t subframeId = 0;
7224 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7225 /* slotId */
7226 uint32_t slotId = 0;
7227 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7228 tap_info->slot = slotId;
7229 offset++;
7230 /* symbolId */
7231 uint32_t symbolId = 0;
7232 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7233 offset++;
7234
7235 char id[16];
7236 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7237 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7238 proto_item_set_generated(pi);
7239
7240 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7241 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7242
7243 unsigned sample_bit_width;
7244 unsigned compression;
7245 int includeUdCompHeader;
7246
7247 /* Also lookup C-PLANE state (sent in opposite direction for UL) so may check current compression settings */
7248 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, direction
1.1
'direction' is not equal to 0
== 0);
7249 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7250
7251 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is 0
3
Taking true branch
7252 /* Create state/conversation if doesn't exist yet */
7253 if (!state) {
4
Assuming 'state' is non-null
5
Taking false branch
7254 /* Allocate new state */
7255 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7256 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7257 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
7258 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
7259 wmem_tree_insert32(flow_states_table, key, state);
7260 }
7261
7262 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7263 result->expected_sections = wmem_tree_new(wmem_file_scope());
7264 result->u_plane_frames = wmem_list_new(wmem_file_scope());
7265
7266 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7267
7268 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7269 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
6
Assuming the condition is true
7
Assuming 'subSeqId' is not equal to 0
7270 /* Store this result */
7271 result->unexpected_seq_number = true1;
7272 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7273 result->previous_frame = state->last_frame[direction];
7274 }
7275 /* Update sequence analysis state */
7276 state->last_frame[direction] = pinfo->num;
7277 state->last_frame_seen[direction] = true1;
7278 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7279 }
7280
7281 /* Show any issues associated with this frame number */
7282 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
8
Value assigned to 'result'
7283 if (result) {
9
Assuming 'result' is null
7284 if (result->unexpected_seq_number) {
7285 expert_add_info_format(pinfo, seqIdItem,
7286 (direction == DIR_UPLINK0) ?
7287 &ei_oran_uplane_unexpected_sequence_number_ul :
7288 &ei_oran_uplane_unexpected_sequence_number_dl,
7289 "Sequence number %u expected, but got %u",
7290 result->expected_sequence_number, seqId);
7291 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7292 /* TODO: could add previous/next frame (in seqId tree?) ? */
7293 }
7294 }
7295
7296 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7297 /* N.B., timing is relative to first seen frame,
7298 not some notion of the beginning of the slot from sync, offset by some timing.. */
7299 if (direction
9.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7300 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7301 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7302 /* Set state on first pass */
7303 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7304 if (!timing) {
7305 /* Allocate new state */
7306 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7307 timing->first_frame = pinfo->num;
7308 timing->first_frame_time = pinfo->abs_ts;
7309 timing->frames_seen_in_symbol = 1;
7310 timing->last_frame_in_symbol = pinfo->num;
7311 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7312 }
7313 else {
7314 /* Update existing state */
7315 timing->frames_seen_in_symbol++;
7316 timing->last_frame_in_symbol = pinfo->num;
7317 }
7318 }
7319 else {
7320 /* Subsequent passes - look up result */
7321 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7322 if (timing) { /* Really shouldn't fail! */
7323 if (timing->frames_seen_in_symbol > 1) {
7324 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7325 int seconds_between_packets = (int)
7326 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7327 int nseconds_between_packets =
7328 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7329
7330 /* Round to nearest microsecond. */
7331 uint32_t total_gap = (seconds_between_packets*1000000) +
7332 ((nseconds_between_packets+500) / 1000);
7333
7334 /* Show how long it has been */
7335 proto_item *ti = NULL((void*)0);
7336 if (pinfo->num != timing->first_frame) {
7337 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7338 proto_item_set_generated(ti);
7339 }
7340
7341 if (total_gap > us_allowed_for_ul_in_symbol) {
7342 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7343 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7344 total_gap, us_allowed_for_ul_in_symbol);
7345 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7346 }
7347
7348 /* Show how many frames were received */
7349 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7350 proto_item_set_generated(ti);
7351
7352 /* Link to first frame for this symbol */
7353 if (pinfo->num != timing->first_frame) {
7354 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7355 proto_item_set_generated(ti);
7356 }
7357
7358 /* And also last frame */
7359 if (pinfo->num != timing->last_frame_in_symbol) {
7360 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7361 proto_item_set_generated(ti);
7362 }
7363
7364 tap_info->ul_delay_in_us = total_gap;
7365 }
7366 }
7367 }
7368 }
7369
7370
7371 /* Look up preferences for samples */
7372 if (direction
9.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
10
Taking false branch
7373 sample_bit_width = pref_sample_bit_width_uplink;
7374 compression = pref_iqCompressionUplink;
7375 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7376 } else {
7377 sample_bit_width = pref_sample_bit_width_downlink;
7378 compression = pref_iqCompressionDownlink;
7379 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7380 }
7381
7382 /* If uplink, load any udCompHdr settings written by C-Plane */
7383 bool_Bool ud_cmp_hdr_cplane = false0;
7384 if (cplane_state && direction
11.1
'direction' is not equal to 0
== 0) {
11
Assuming 'cplane_state' is non-null
12
Taking false branch
7385 /* Initialise settings from udpCompHdr from C-Plane */
7386 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7387 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7388 compression = cplane_state->ul_ud_comp_hdr_compression;
7389 ud_cmp_hdr_cplane = true1;
7390 }
7391 }
7392
7393 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7394 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7395 if (sample_bit_width == 0) {
13
Assuming 'sample_bit_width' is not equal to 0
14
Taking false branch
7396 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7397 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7398 (direction == DIR_UPLINK0) ? 'U' : 'D',
7399 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7400 sample_bit_width);
7401 return offset;
7402 }
7403
7404 unsigned bytesLeft;
7405 unsigned number_of_sections = 0;
7406 unsigned nBytesPerPrb =0;
7407
7408 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_state
15.2
'cplane_state' is non-null
) {
15
Assuming 'link_planes_together' is true
16
Taking true branch
7409 /* Take a deep-copy of this state on first pass */
7410 wmem_tree_foreach(cplane_state->expected_sections[direction], copy_section_entry, result->expected_sections);
17
Access to field 'expected_sections' results in a dereference of a null pointer (loaded from variable 'result')
7411 }
7412
7413 /* Add each section (not from count, just keep parsing until payload used) */
7414 do {
7415 /* Section subtree */
7416 unsigned section_start_offset = offset;
7417 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7418 tvb, offset, 0, "", "Section");
7419 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7420
7421 /* Section Header fields (darker green part) */
7422
7423 /* sectionId */
7424 uint32_t sectionId = 0;
7425 proto_item *sectionId_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7426 if (sectionId == 4095) {
7427 proto_item_append_text(sectionId_ti, " (not default coupling C/U planes using sectionId)");
7428 }
7429 offset++;
7430
7431 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
7432 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7433 }
7434
7435 section_details_t *section_details = NULL((void*)0);
7436 corresponding_uplane_frame *details = NULL((void*)0);
7437
7438 /* Lookup corresponding C-plane frame/info */
7439 if (link_planes_together) {
7440 if (cplane_state != NULL((void*)0)) {
7441
7442 expected_section_data_t *section_data = NULL((void*)0);
7443 section_data = wmem_tree_lookup32(result->expected_sections, sectionId);
7444
7445 if (section_data) {
7446 /* Need to work out which of 2 entries is in use for this data frame */
7447 unsigned index_to_use = 0;
7448
7449 /* Does the first entry match the timing for this frame? */
7450 if (section_data->details[0].frame == frameId &&
7451 section_data->details[0].subframe == subframeId &&
7452 section_data->details[0].slot == slotId &&
7453 /* Check that symbolId is in range */
7454 section_data->details[0].startSymbol <= symbolId &&
7455 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7456
7457 index_to_use = 0;
7458 }
7459 else if (section_data->details[1].frame == frameId &&
7460 section_data->details[1].subframe == subframeId &&
7461 section_data->details[1].slot == slotId &&
7462 /* Check that symbolId is in range */
7463 section_data->details[1].startSymbol <= symbolId &&
7464 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7465
7466 index_to_use = 1;
7467 }
7468 else {
7469 /* There was a sectionId, but timing header didn't exactly match, so neither index may be used.. */
7470 index_to_use = 2; /* invalid value */
7471 /* Expert info */
7472 expert_add_info_format(NULL((void*)0), sectionId_ti,
7473 &ei_oran_cplane_entry_not_found,
7474 "C-plane entry for %s sectionId %u at timing header %u-%u-%u-%u",
7475 (direction) ? "DL" : "UL", sectionId,
7476 frameId, subframeId, slotId, symbolId);
7477 }
7478
7479 if (index_to_use <= 1) {
7480 section_details = &section_data->details[index_to_use];
7481
7482 /* Cplane frame number */
7483 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7484 section_details->frame_number);
7485 proto_item_set_generated(cplane_frame_ti);
7486
7487 /* usecs since cplane frame */
7488 time_t total_gap = 0;
7489
7490 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7491 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7492 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7493 }
7494
7495 if (total_gap > 0) {
7496 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);
7497 proto_item_set_generated(cplane_delta_ti);
7498 }
7499
7500 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7501 /* Look up 'result' for c-plane frame, and tell it about this frame.. */
7502 flow_result_t *cplane_result = wmem_tree_lookup32(flow_results_table, section_details->frame_number);
7503 if (!cplane_result) {
7504 cplane_result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7505 cplane_result->u_plane_frames = wmem_list_new(wmem_file_scope());
7506 wmem_tree_insert32(flow_results_table, section_details->frame_number, cplane_result);
7507 }
7508 /* PRB range filled in below.. */
7509
7510 details = wmem_new(wmem_file_scope(), corresponding_uplane_frame)((corresponding_uplane_frame*)wmem_alloc((wmem_file_scope()),
sizeof(corresponding_uplane_frame)))
;
7511 details->frame_number = pinfo->num;
7512 details->gap_in_usecs = (uint32_t)total_gap;
7513 details->sectionId = sectionId;
7514 details->symbol = symbolId;
7515
7516 wmem_list_append(cplane_result->u_plane_frames, details);
7517 }
7518 }
7519 }
7520 else {
7521 /* No section entry at all */
7522 expert_add_info_format(NULL((void*)0), sectionId_ti,
7523 &ei_oran_cplane_entry_not_found,
7524 "C-plane entry for %s sectionId %u not found",
7525 (direction) ? "DL" : "UL", sectionId);
7526 }
7527 }
7528 }
7529
7530 /* rb */
7531 uint32_t rb;
7532 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7533 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7534 uint8_t syminc;
7535 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7536 if (syminc) {
7537 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7538 }
7539 /* startPrbu */
7540 uint32_t startPrbu = 0;
7541 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7542 offset += 2;
7543
7544 /* numPrbu */
7545 uint32_t numPrbu = 0;
7546 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7547 offset += 1;
7548
7549 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && details) {
7550 details->startPrbu = startPrbu;
7551 details->numPrbu = (numPrbu) ? numPrbu : 273;
7552 }
7553
7554 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7555 uint32_t ud_comp_len = 0;
7556
7557 /* udCompHdr (if preferences indicate will be present) */
7558 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7559 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7560 if (included) {
7561 /* 7.5.2.10 */
7562 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7563 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7564 &compression, &ud_comp_meth_item, tap_info);
7565
7566 /* Not part of udCompHdr */
7567 uint32_t reserved;
7568 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7569 offset += 1;
7570 if (reserved != 0) {
7571 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7572 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7573 reserved);
7574 }
7575 }
7576 else {
7577 /* No fields to dissect - just showing comp values from prefs */
7578 /* iqWidth */
7579 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7580 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7581 proto_item_set_generated(iq_width_item);
7582
7583 /* udCompMethod */
7584 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7585 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7586 proto_item_set_generated(ud_comp_meth_item);
7587
7588 /* Point back to C-Plane, if used */
7589 /* TODO: doesn't work with multiple port mappings using SE10.. */
7590 if (ud_cmp_hdr_cplane) {
7591 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);
7592 proto_item_set_generated(cplane_ti);
7593 }
7594
7595 tap_info->compression_methods |= (1 << compression);
7596 tap_info->compression_width = sample_bit_width;
7597 }
7598
7599 /* Consider fragmentation after first section header */
7600 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7601
7602 /* Set fragmented flag. */
7603 bool_Bool save_fragmented = pinfo->fragmented;
7604 pinfo->fragmented = true1;
7605 fragment_head *fh;
7606 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7607
7608 /* Add this fragment into reassembly table */
7609 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7610 frameId, subframeId, slotId, symbolId);
7611 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7612 reassembly_id, /* id */
7613 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7614 subSeqId, /* frag_number */
7615 frag_data_len, /* frag_data_len */
7616 !e, /* more_frags */
7617 0);
7618
7619 bool_Bool update_col_info = true1;
7620
7621 /* See if this completes an SDU */
7622 tvbuff_t *original_tvb = tvb;
7623 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7624 fh, &oran_frag_items,
7625 &update_col_info, oran_tree);
7626 if (next_tvb) {
7627 /* Have reassembled data */
7628 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7629 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7630 /* Dissection should resume at start of reassembled tvb */
7631 offset = 0;
7632 }
7633 /* Will continue with either reassembled tvb or NULL */
7634 tvb = next_tvb;
7635
7636 /* Restore fragmented flag */
7637 pinfo->fragmented = save_fragmented;
7638
7639 /* Don't dissect any more if not complete yet.. */
7640 if (tvb == NULL((void*)0)) {
7641 return tvb_captured_length(original_tvb);
7642 }
7643 }
7644
7645
7646 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7647 switch (compression) {
7648 case COMP_NONE0:
7649 case COMP_BLOCK_FP1:
7650 case BFP_AND_SELECTIVE_RE5:
7651 case COMP_MODULATION4:
7652 case MOD_COMPR_AND_SELECTIVE_RE6:
7653 break;
7654 default:
7655 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7656 "Compression method %u (%s) not supported by dissector",
7657 compression,
7658 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7659 }
7660
7661 /* udCompLen (when supported, methods 5,6,7,8) */
7662 if (compression >= BFP_AND_SELECTIVE_RE5) {
7663 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7664 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7665
7666 if (supported) {
7667 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7668 if (ud_comp_len <= 1) {
7669 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7670 }
7671 /* TODO: report if less than a viable section in frame? */
7672 /* Check that there is this much length left in the frame */
7673 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7674 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7675 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7676 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7677 }
7678 /* Actual length of section will be checked below, at the end of the section */
7679 offset += 2;
7680 }
7681 }
7682
7683 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7684 uint64_t sresmask1=0, sresmask2=0;
7685 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7686 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7687 {
7688 static int * const sres_mask1_2_flags[] = {
7689 &hf_oran_sReSMask1_2_re12,
7690 &hf_oran_sReSMask1_2_re11,
7691 &hf_oran_sReSMask1_2_re10,
7692 &hf_oran_sReSMask1_2_re9,
7693 &hf_oran_sReSMask_re8,
7694 &hf_oran_sReSMask_re7,
7695 &hf_oran_sReSMask_re6,
7696 &hf_oran_sReSMask_re5,
7697 &hf_oran_sReSMask_re4,
7698 &hf_oran_sReSMask_re3,
7699 &hf_oran_sReSMask_re2,
7700 &hf_oran_sReSMask_re1,
7701 NULL((void*)0)
7702 };
7703
7704 /* reserved (4 bits) */
7705 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7706 /* sReSMask1 (12 bits) */
7707 proto_item *sresmask_ti;
7708 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7709 hf_oran_sReSMask1,
7710 ett_oran_sresmask,
7711 sres_mask1_2_flags,
7712 ENC_NA0x00000000,
7713 &sresmask1);
7714 offset += 2;
7715 /* Count REs present */
7716 unsigned res = 0;
7717 for (unsigned n=0; n < 12; n++) {
7718 if ((sresmask1 >> n) & 0x1) {
7719 res++;
7720 }
7721 }
7722 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7723
7724
7725 /* reserved (4 bits) */
7726 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7727 /* sReSMask2 (12 bits) */
7728 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7729 hf_oran_sReSMask2,
7730 ett_oran_sresmask,
7731 sres_mask1_2_flags,
7732 ENC_NA0x00000000,
7733 &sresmask2);
7734 offset += 2;
7735
7736 if (rb == 1) {
7737 proto_item_append_text(sresmask_ti, " (ignored)");
7738 if (sresmask2 != 0) {
7739 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7740 }
7741 }
7742 else {
7743 /* Count REs present */
7744 res = 0;
7745 for (unsigned n=0; n < 12; n++) {
7746 if ((sresmask2 >> n) & 0x1) {
7747 res++;
7748 }
7749 }
7750 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7751 }
7752 }
7753
7754 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7755
7756 /* TODO: should this use the same pref as c-plane? */
7757 if (numPrbu == 0) {
7758 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7759 numPrbu = pref_data_plane_section_total_rbs;
7760 startPrbu = 0; /* may already be 0... */
7761 }
7762
7763 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_state, sectionId);
7764
7765 /* Add each PRB */
7766 for (unsigned i = 0; i < numPrbu; i++) {
7767 /* Create subtree */
7768 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7769 tvb, offset, 0,
7770 "", "PRB");
7771 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7772 uint32_t exponent = 0;
7773 uint16_t sresmask = 0;
7774
7775 /* udCompParam (depends upon compression method) */
7776 int before = offset;
7777 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7778 int udcompparam_len = offset-before;
7779
7780 /* Show PRB number in root */
7781 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7782
7783 /* Work out how many REs / PRB */
7784 unsigned res_per_prb = 12;
7785 uint16_t sresmask_to_use = 0x0fff;
7786
7787 if (compression >= BFP_AND_SELECTIVE_RE5) {
7788 /* Work out which mask should be used */
7789 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7790 /* Selective RE cases, use value from compModParam */
7791 sresmask_to_use = (uint16_t)sresmask;
7792 }
7793 else {
7794 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7795 if (rb==1 || (i%2)==0) {
7796 /* Even values */
7797 sresmask_to_use = (uint16_t)sresmask1;
7798 }
7799 else {
7800 /* Odd values */
7801 sresmask_to_use = (uint16_t)sresmask2;
7802 }
7803 }
7804
7805 /* Count REs present using sresmask */
7806 res_per_prb = 0;
7807 /* Use sresmask to pick out which REs are present */
7808 for (unsigned n=0; n<12; n++) {
7809 if (sresmask_to_use & (1<<n)) {
7810 res_per_prb++;
7811 }
7812 }
7813 }
7814
7815 /* N.B. bytes for samples need to be padded out to next byte
7816 (certainly where there aren't 12 REs in PRB..) */
7817 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7818 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7819
7820 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7821
7822 if (section_details) {
7823 if ((startPrbu + i*(1+rb)) < 273) {
7824 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7825 section_details->beamIds[startPrbu + i*(1+rb)]);
7826 proto_item_set_generated(beamid_ti);
7827 }
7828 }
7829
7830
7831 tap_info->non_zero_re_in_current_prb = false0;
7832
7833 /* Optionally trying to show I/Q RE values */
7834 if (pref_showIQSampleValues) {
7835 /* Individual values */
7836 unsigned samples_offset = offset*8;
7837 unsigned samples_start = offset;
7838 unsigned samples = 0;
7839
7840 if (compression >= BFP_AND_SELECTIVE_RE5) {
7841 /* Use sresmask to pick out which REs are present */
7842 for (unsigned n=1; n<=12; n++) {
7843 if (sresmask_to_use & (1<<(n-1))) {
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 }
7850 else {
7851 /* All 12 REs are present */
7852 for (unsigned n=1; n<=12; n++) {
7853 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7854 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7855 samples++;
7856 }
7857 }
7858 proto_item_append_text(prbHeading, " (%u REs)", samples);
7859 if (section_details) {
7860 if ((startPrbu + i*(1+rb)) < 273) {
7861 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7862 }
7863 }
7864
7865 /* Was this PRB all zeros? */
7866 if (!tap_info->non_zero_re_in_current_prb) {
7867 tap_info->num_prbs_zero++;
7868 /* Add a filter to make zero-valued PRBs more findable */
7869 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7870 samples_start, nBytesForSamples, ENC_NA0x00000000);
7871 proto_item_set_hidden(zero_ti);
7872 proto_item_append_text(prbHeading, " (all zeros)");
7873 }
7874 else {
7875 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7876 proto_item_set_hidden(nonzero_ti);
7877 }
7878 }
7879
7880 tap_info->num_prbs++;
7881
7882
7883 /* Advance past samples */
7884 offset += nBytesForSamples;
7885
7886 /* Set end of prb subtree */
7887 proto_item_set_end(prbHeading, tvb, offset);
7888 }
7889
7890 /* Set extent of section */
7891 proto_item_set_len(sectionHeading, offset-section_start_offset);
7892 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7893 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7894 "udCompLen indicates %u bytes in section, but dissected %u instead",
7895 ud_comp_len, offset-section_start_offset);
7896 }
7897
7898 bytesLeft = tvb_captured_length(tvb) - offset;
7899 number_of_sections++;
7900 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7901
7902 /* Show number of sections found */
7903 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7904 proto_item_set_generated(ti);
7905
7906 /* Expert error if we are short of tvb by > 3 bytes */
7907 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7908 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7909 "%u bytes remain at end of frame - should be 0-3",
7910 tvb_reported_length_remaining(tvb, offset));
7911 }
7912
7913 return tvb_captured_length(tvb);
7914}
7915
7916
7917/**********************************************************************/
7918/* Main dissection function. */
7919/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7920static int
7921dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7922{
7923 uint32_t ecpri_message_type = *(uint32_t *)data;
7924 unsigned offset = 0;
7925
7926 /* Allocate and zero tap struct */
7927 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
)))
;
7928 tap_info->pdu_size = pinfo->fd->pkt_len;
7929 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7930
7931 switch (ecpri_message_type) {
7932 case ECPRI_MT_IQ_DATA0:
7933 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7934 break;
7935 case ECPRI_MT_RT_CTRL_DATA2:
7936 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7937 break;
7938 default:
7939 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7940 return 0;
7941 }
7942
7943 tap_queue_packet(oran_tap, pinfo, tap_info);
7944
7945 return offset;
7946}
7947
7948static void oran_init_protocol(void)
7949{
7950 udcomplen_heuristic_result_set = false0;
7951 udcomplen_heuristic_result = false0;
7952}
7953
7954
7955/* Register the protocol with Wireshark. */
7956void
7957proto_register_oran(void)
7958{
7959 static hf_register_info hf[] = {
7960
7961 /* Section 5.1.3.2.7 */
7962 { &hf_oran_du_port_id,
7963 { "DU Port ID", "oran_fh_cus.du_port_id",
7964 FT_UINT16, BASE_DEC,
7965 NULL((void*)0), 0x0,
7966 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7967 },
7968
7969 /* Section 5.1.3.2.7 */
7970 { &hf_oran_bandsector_id,
7971 { "BandSector ID", "oran_fh_cus.bandsector_id",
7972 FT_UINT16, BASE_DEC,
7973 NULL((void*)0), 0x0,
7974 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7975 },
7976
7977 /* Section 5.1.3.2.7 */
7978 { &hf_oran_cc_id,
7979 { "CC ID", "oran_fh_cus.cc_id",
7980 FT_UINT16, BASE_DEC,
7981 NULL((void*)0), 0x0,
7982 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7983 },
7984
7985 /* Section 5.1.3.2.7 */
7986 { &hf_oran_ru_port_id,
7987 { "RU Port ID", "oran_fh_cus.ru_port_id",
7988 FT_UINT16, BASE_DEC,
7989 NULL((void*)0), 0x0,
7990 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7991 },
7992
7993 /* Section 5.1.3.2.8 */
7994 { &hf_oran_sequence_id,
7995 { "Sequence ID", "oran_fh_cus.sequence_id",
7996 FT_UINT8, BASE_DEC,
7997 NULL((void*)0), 0x0,
7998 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7999 },
8000
8001 /* Section 5.1.3.2.8 */
8002 { &hf_oran_e_bit,
8003 { "E Bit", "oran_fh_cus.e_bit",
8004 FT_UINT8, BASE_DEC,
8005 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
8006 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8007 },
8008
8009 /* Section 5.1.3.2.8 */
8010 { &hf_oran_subsequence_id,
8011 { "Subsequence ID", "oran_fh_cus.subsequence_id",
8012 FT_UINT8, BASE_DEC,
8013 NULL((void*)0), 0x7f,
8014 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8015 },
8016
8017 { &hf_oran_previous_frame,
8018 { "Previous frame in stream", "oran_fh_cus.previous-frame",
8019 FT_FRAMENUM, BASE_NONE,
8020 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8021 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8022 },
8023
8024 /* Section 7.5.2.1 */
8025 { &hf_oran_data_direction,
8026 { "Data Direction", "oran_fh_cus.data_direction",
8027 FT_UINT8, BASE_DEC,
8028 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
8029 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8030 },
8031
8032 /* Section 7.5.2.2 */
8033 { &hf_oran_payload_version,
8034 { "Payload Version", "oran_fh_cus.payloadVersion",
8035 FT_UINT8, BASE_DEC,
8036 NULL((void*)0), 0x70,
8037 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8038 },
8039
8040 /* Section 7.5.2.3 */
8041 { &hf_oran_filter_index,
8042 { "Filter Index", "oran_fh_cus.filterIndex",
8043 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8044 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
8045 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8046 },
8047
8048 /* Section 7.5.2.4 */
8049 { &hf_oran_frame_id,
8050 { "Frame ID", "oran_fh_cus.frameId",
8051 FT_UINT8, BASE_DEC,
8052 NULL((void*)0), 0x0,
8053 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8054 },
8055
8056 /* Section 7.5.2.5 */
8057 { &hf_oran_subframe_id,
8058 { "Subframe ID", "oran_fh_cus.subframe_id",
8059 FT_UINT8, BASE_DEC,
8060 NULL((void*)0), 0xf0,
8061 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8062 },
8063
8064 /* Section 7.5.2.6 */
8065 { &hf_oran_slot_id,
8066 { "Slot ID", "oran_fh_cus.slotId",
8067 FT_UINT16, BASE_DEC,
8068 NULL((void*)0), 0x0fc0,
8069 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8070 },
8071
8072 /* Generated for convenience */
8073 { &hf_oran_slot_within_frame,
8074 { "Slot within frame", "oran_fh_cus.slot-within-frame",
8075 FT_UINT16, BASE_DEC,
8076 NULL((void*)0), 0x0,
8077 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8078 },
8079
8080 /* Section 7.5.2.7 */
8081 { &hf_oran_start_symbol_id,
8082 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
8083 FT_UINT8, BASE_DEC,
8084 NULL((void*)0), 0x3f,
8085 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8086 },
8087
8088 /* Section 7.5.2.8 */
8089 { &hf_oran_numberOfSections,
8090 { "Number of Sections", "oran_fh_cus.numberOfSections",
8091 FT_UINT8, BASE_DEC,
8092 NULL((void*)0), 0x0,
8093 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8094 },
8095
8096 /* Section 7.5.2.9 */
8097 { &hf_oran_sectionType,
8098 { "Section Type", "oran_fh_cus.sectionType",
8099 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8100 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
8101 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8102 },
8103
8104 /* Section 7.5.2.10 */
8105 { &hf_oran_udCompHdr,
8106 { "udCompHdr", "oran_fh_cus.udCompHdr",
8107 FT_STRING, BASE_NONE,
8108 NULL((void*)0), 0x0,
8109 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8110 },
8111
8112 /* Section 7.5.2.11 */
8113 { &hf_oran_numberOfUEs,
8114 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
8115 FT_UINT8, BASE_DEC,
8116 NULL((void*)0), 0x0,
8117 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8118 },
8119
8120 /* Section 7.5.2.12 */
8121 { &hf_oran_timeOffset,
8122 { "Time Offset", "oran_fh_cus.timeOffset",
8123 FT_UINT16, BASE_DEC,
8124 NULL((void*)0), 0x0,
8125 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8126 },
8127
8128 /* Section 7.5.2.13 */
8129 { &hf_oran_frameStructure_fft,
8130 { "FFT Size", "oran_fh_cus.frameStructure.fft",
8131 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8132 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
8133 "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) }
8134 },
8135
8136 /* Section 7.5.2.13 */
8137 { &hf_oran_frameStructure_subcarrier_spacing,
8138 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
8139 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8140 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
8141 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
8142 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8143 },
8144
8145 /* Section 7.5.2.14 */
8146 { &hf_oran_cpLength,
8147 { "cpLength", "oran_fh_cus.cpLength",
8148 FT_UINT16, BASE_DEC,
8149 NULL((void*)0), 0x0,
8150 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8151 },
8152
8153 { &hf_oran_timing_header,
8154 { "Timing Header", "oran_fh_cus.timingHeader",
8155 FT_STRING, BASE_NONE,
8156 NULL((void*)0), 0x0,
8157 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8158 },
8159
8160 /* Section 7.5.3.1 */
8161 { &hf_oran_section_id,
8162 { "sectionId", "oran_fh_cus.sectionId",
8163 FT_UINT16, BASE_DEC,
8164 NULL((void*)0), 0xfff0,
8165 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8166 },
8167
8168 /* Section 7.5.3.2 */
8169 { &hf_oran_rb,
8170 { "rb", "oran_fh_cus.rb",
8171 FT_UINT8, BASE_DEC,
8172 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
8173 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8174 },
8175
8176 /* Section 7.5.5.3 */
8177 { &hf_oran_symInc,
8178 { "symInc", "oran_fh_cus.symInc",
8179 FT_UINT8, BASE_DEC,
8180 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
8181 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8182 },
8183
8184 /* Section 7.5.3.4 */
8185 { &hf_oran_startPrbc,
8186 { "startPrbc", "oran_fh_cus.startPrbc",
8187 FT_UINT16, BASE_DEC,
8188 NULL((void*)0), 0x03ff,
8189 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8190 },
8191
8192 /* Section 7.5.3.5 */
8193 { &hf_oran_reMask_re1,
8194 { "RE 1", "oran_fh_cus.reMask-RE1",
8195 FT_BOOLEAN, 16,
8196 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
8197 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8198 },
8199 { &hf_oran_reMask_re2,
8200 { "RE 2", "oran_fh_cus.reMask-RE2",
8201 FT_BOOLEAN, 16,
8202 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
8203 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8204 },
8205 { &hf_oran_reMask_re3,
8206 { "RE 3", "oran_fh_cus.reMask-RE3",
8207 FT_BOOLEAN, 16,
8208 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
8209 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8210 },
8211 { &hf_oran_reMask_re4,
8212 { "RE 4", "oran_fh_cus.reMask-RE4",
8213 FT_BOOLEAN, 16,
8214 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
8215 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8216 },
8217 { &hf_oran_reMask_re5,
8218 { "RE 5", "oran_fh_cus.reMask-RE5",
8219 FT_BOOLEAN, 16,
8220 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
8221 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8222 },
8223 { &hf_oran_reMask_re6,
8224 { "RE 6", "oran_fh_cus.reMask-RE6",
8225 FT_BOOLEAN, 16,
8226 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
8227 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8228 },
8229 { &hf_oran_reMask_re7,
8230 { "RE 7", "oran_fh_cus.reMask-RE7",
8231 FT_BOOLEAN, 16,
8232 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
8233 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8234 },
8235 { &hf_oran_reMask_re8,
8236 { "RE 8", "oran_fh_cus.reMask-RE8",
8237 FT_BOOLEAN, 16,
8238 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
8239 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8240 },
8241 { &hf_oran_reMask_re9,
8242 { "RE 9", "oran_fh_cus.reMask-RE9",
8243 FT_BOOLEAN, 16,
8244 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
8245 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8246 },
8247 { &hf_oran_reMask_re10,
8248 { "RE 10", "oran_fh_cus.reMask-RE10",
8249 FT_BOOLEAN, 16,
8250 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8251 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8252 },
8253 { &hf_oran_reMask_re11,
8254 { "RE 11", "oran_fh_cus.reMask-RE11",
8255 FT_BOOLEAN, 16,
8256 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8257 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8258 },
8259 { &hf_oran_reMask_re12,
8260 { "RE 12", "oran_fh_cus.reMask-RE12",
8261 FT_BOOLEAN, 16,
8262 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8263 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8264 },
8265 { &hf_oran_reMask,
8266 { "RE Mask", "oran_fh_cus.reMask",
8267 FT_UINT16, BASE_HEX,
8268 NULL((void*)0), 0xfff0,
8269 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8270 },
8271
8272 /* Section 7.5.3.6 */
8273 { &hf_oran_numPrbc,
8274 { "numPrbc", "oran_fh_cus.numPrbc",
8275 FT_UINT8, BASE_DEC,
8276 NULL((void*)0), 0x0,
8277 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8278 },
8279 /* Section 7.5.3.7 */
8280 { &hf_oran_numSymbol,
8281 { "Number of Symbols", "oran_fh_cus.numSymbol",
8282 FT_UINT8, BASE_DEC,
8283 NULL((void*)0), 0x0f,
8284 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8285 },
8286 /* Section 7.5.3.8 */
8287 { &hf_oran_ef,
8288 { "Extension Flag", "oran_fh_cus.ef",
8289 FT_BOOLEAN, 8,
8290 NULL((void*)0), 0x80,
8291 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8292 },
8293 /* Section 7.5.3.9 */
8294 { &hf_oran_beamId,
8295 { "Beam ID", "oran_fh_cus.beamId",
8296 FT_UINT16, BASE_DEC,
8297 NULL((void*)0), 0x7fff,
8298 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8299 },
8300
8301 { &hf_oran_extension,
8302 { "Extension", "oran_fh_cus.extension",
8303 FT_STRING, BASE_NONE,
8304 NULL((void*)0), 0x0,
8305 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8306 },
8307
8308 /* Section 7.6.2.1 */
8309 { &hf_oran_exttype,
8310 { "extType", "oran_fh_cus.extType",
8311 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8312 &exttype_vals_ext, 0x7f,
8313 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8314 },
8315
8316 /* Section 7.6.2.3 */
8317 { &hf_oran_extlen,
8318 { "extLen", "oran_fh_cus.extLen",
8319 FT_UINT16, BASE_DEC,
8320 NULL((void*)0), 0x0,
8321 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8322 },
8323
8324 /* Section 7.7.1 */
8325 { &hf_oran_bfw,
8326 { "bfw", "oran_fh_cus.bfw",
8327 FT_STRING, BASE_NONE,
8328 NULL((void*)0), 0x0,
8329 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8330 },
8331 { &hf_oran_bfw_bundle,
8332 { "Bundle", "oran_fh_cus.bfw.bundle",
8333 FT_STRING, BASE_NONE,
8334 NULL((void*)0), 0x0,
8335 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8336 },
8337 { &hf_oran_bfw_bundle_id,
8338 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8339 FT_UINT32, BASE_DEC,
8340 NULL((void*)0), 0x0,
8341 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8342 },
8343 /* Section 7.7.1.4 */
8344 { &hf_oran_bfw_i,
8345 { "bfwI", "oran_fh_cus.bfwI",
8346 FT_FLOAT, BASE_NONE,
8347 NULL((void*)0), 0x0,
8348 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8349 },
8350 /* Section 7.7.1.5 */
8351 { &hf_oran_bfw_q,
8352 { "bfwQ", "oran_fh_cus.bfwQ",
8353 FT_FLOAT, BASE_NONE,
8354 NULL((void*)0), 0x0,
8355 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8356 },
8357
8358 /* Section 7.5.3.10 */
8359 { &hf_oran_ueId,
8360 { "UE ID", "oran_fh_cus.ueId",
8361 FT_UINT16, BASE_DEC,
8362 NULL((void*)0), 0x7fff,
8363 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8364 },
8365 /* Section 7.5.3.11 */
8366 { &hf_oran_freqOffset,
8367 { "Frequency Offset", "oran_fh_cus.freqOffset",
8368 FT_UINT24, BASE_DEC,
8369 NULL((void*)0), 0x0,
8370 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8371 },
8372
8373 /* Section 7.5.3.12 */
8374 { &hf_oran_regularizationFactor,
8375 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8376 FT_INT16, BASE_DEC,
8377 NULL((void*)0), 0x0,
8378 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8379 },
8380 /* Section 7.5.3.14 */
8381 { &hf_oran_laaMsgType,
8382 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8383 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8384 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8385 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8386 },
8387 /* Section 7.5.3.15 */
8388 { &hf_oran_laaMsgLen,
8389 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8390 FT_UINT8, BASE_DEC,
8391 NULL((void*)0), 0x0f,
8392 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8393 },
8394 /* Section 7.5.3.16 */
8395 { &hf_oran_lbtHandle,
8396 { "LBT Handle", "oran_fh_cus.lbtHandle",
8397 FT_UINT16, BASE_HEX,
8398 NULL((void*)0), 0x0,
8399 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8400 },
8401 /* Section 7.5.3.17 */
8402 { &hf_oran_lbtDeferFactor,
8403 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8404 FT_UINT8, BASE_DEC,
8405 NULL((void*)0), 0x07,
8406 "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)}
8407 },
8408 /* Section 7.5.3.18 */
8409 { &hf_oran_lbtBackoffCounter,
8410 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8411 FT_UINT16, BASE_DEC,
8412 NULL((void*)0), 0xffc0,
8413 "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)}
8414 },
8415 /* Section 7.5.3.19 */
8416 { &hf_oran_lbtOffset,
8417 { "LBT Offset", "oran_fh_cus.lbtOffset",
8418 FT_UINT16, BASE_DEC,
8419 NULL((void*)0), 0xffc0,
8420 "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)}
8421 },
8422 /* Section 7.5.3.20 */
8423 { &hf_oran_MCOT,
8424 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8425 FT_UINT8, BASE_DEC,
8426 NULL((void*)0), 0x3c,
8427 "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)}
8428 },
8429 /* Section 7.5.3.21 */
8430 { &hf_oran_lbtMode,
8431 { "LBT Mode", "oran_fh_cus.lbtMode",
8432 FT_UINT8, BASE_DEC,
8433 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8434 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8435 },
8436 /* Section 7.5.3.22 */
8437 { &hf_oran_lbtPdschRes,
8438 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8439 FT_UINT8, BASE_DEC,
8440 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8441 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8442 },
8443 /* Section 7.5.3.23 */
8444 { &hf_oran_sfStatus,
8445 { "sfStatus", "oran_fh_cus.sfStatus",
8446 FT_BOOLEAN, 8,
8447 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8448 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8449 },
8450 /* Section 7.5.3.24 */
8451 { &hf_oran_lbtDrsRes,
8452 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8453 FT_BOOLEAN, 8,
8454 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8455 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8456 },
8457 /* Section 7.5.3.25 */
8458 { &hf_oran_initialPartialSF,
8459 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8460 FT_BOOLEAN, 8,
8461 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8462 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8463 },
8464 /* Section 7.5.3.26. */
8465 { &hf_oran_lbtBufErr,
8466 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8467 FT_BOOLEAN, 8,
8468 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8469 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8470 },
8471 /* Section 7.5.3.27 */
8472 { &hf_oran_sfnSfEnd,
8473 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8474 FT_UINT16, BASE_DEC,
8475 NULL((void*)0), 0x0fff,
8476 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8477 },
8478 /* Section 7.5.3.28 */
8479 { &hf_oran_lbtCWConfig_H,
8480 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8481 FT_UINT8, BASE_DEC,
8482 NULL((void*)0), 0x0,
8483 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8484 },
8485 /* Section 7.5.3.29 */
8486 { &hf_oran_lbtCWConfig_T,
8487 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8488 FT_UINT8, BASE_DEC,
8489 NULL((void*)0), 0x0,
8490 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8491 },
8492 /* Section 7.5.3.30 */
8493 { &hf_oran_lbtTrafficClass,
8494 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8495 FT_UINT8, BASE_DEC,
8496 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8497 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8498 },
8499 /* Section 7.5.3.31 */
8500 { &hf_oran_lbtCWR_Rst,
8501 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8502 FT_BOOLEAN, 8,
8503 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8504 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8505 },
8506
8507 /* Reserved fields */
8508 { &hf_oran_reserved,
8509 { "reserved", "oran_fh_cus.reserved",
8510 FT_UINT64, BASE_HEX,
8511 NULL((void*)0), 0x0,
8512 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8513 },
8514 { &hf_oran_reserved_1bit,
8515 { "reserved", "oran_fh_cus.reserved",
8516 FT_UINT8, BASE_HEX,
8517 NULL((void*)0), 0x80,
8518 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8519 },
8520 { &hf_oran_reserved_2bits,
8521 { "reserved", "oran_fh_cus.reserved",
8522 FT_UINT8, BASE_HEX,
8523 NULL((void*)0), 0xc0,
8524 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8525 },
8526 { &hf_oran_reserved_3bits,
8527 { "reserved", "oran_fh_cus.reserved",
8528 FT_UINT8, BASE_HEX,
8529 NULL((void*)0), 0xe0,
8530 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8531 },
8532 { &hf_oran_reserved_4bits,
8533 { "reserved", "oran_fh_cus.reserved",
8534 FT_UINT8, BASE_HEX,
8535 NULL((void*)0), 0xf0,
8536 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8537 },
8538 { &hf_oran_reserved_last_4bits,
8539 { "reserved", "oran_fh_cus.reserved",
8540 FT_UINT8, BASE_HEX,
8541 NULL((void*)0), 0x0f,
8542 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8543 },
8544 { &hf_oran_reserved_last_5bits,
8545 { "reserved", "oran_fh_cus.reserved",
8546 FT_UINT8, BASE_HEX,
8547 NULL((void*)0), 0x1f,
8548 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8549 },
8550 { &hf_oran_reserved_6bits,
8551 { "reserved", "oran_fh_cus.reserved",
8552 FT_UINT8, BASE_HEX,
8553 NULL((void*)0), 0xfc,
8554 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8555 },
8556 { &hf_oran_reserved_last_6bits,
8557 { "reserved", "oran_fh_cus.reserved",
8558 FT_UINT8, BASE_HEX,
8559 NULL((void*)0), 0x3f,
8560 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8561 },
8562 { &hf_oran_reserved_7bits,
8563 { "reserved", "oran_fh_cus.reserved",
8564 FT_UINT8, BASE_HEX,
8565 NULL((void*)0), 0xfe,
8566 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8567 },
8568 { &hf_oran_reserved_last_7bits,
8569 { "reserved", "oran_fh_cus.reserved",
8570 FT_UINT8, BASE_HEX,
8571 NULL((void*)0), 0x7f,
8572 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8573 },
8574 { &hf_oran_reserved_8bits,
8575 { "reserved", "oran_fh_cus.reserved",
8576 FT_UINT8, BASE_HEX,
8577 NULL((void*)0), 0x0,
8578 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8579 },
8580 { &hf_oran_reserved_16bits,
8581 { "reserved", "oran_fh_cus.reserved",
8582 FT_UINT16, BASE_HEX,
8583 NULL((void*)0), 0x0,
8584 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8585 },
8586 { &hf_oran_reserved_15bits,
8587 { "reserved", "oran_fh_cus.reserved",
8588 FT_UINT16, BASE_HEX,
8589 NULL((void*)0), 0x7fff,
8590 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8591 },
8592 { &hf_oran_reserved_bit1,
8593 { "reserved", "oran_fh_cus.reserved",
8594 FT_UINT8, BASE_HEX,
8595 NULL((void*)0), 0x40,
8596 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8597 },
8598 { &hf_oran_reserved_bit2,
8599 { "reserved", "oran_fh_cus.reserved",
8600 FT_UINT8, BASE_HEX,
8601 NULL((void*)0), 0x20,
8602 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8603 },
8604 { &hf_oran_reserved_bit4,
8605 { "reserved", "oran_fh_cus.reserved",
8606 FT_UINT8, BASE_HEX,
8607 NULL((void*)0), 0x08,
8608 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8609 },
8610 { &hf_oran_reserved_bit5,
8611 { "reserved", "oran_fh_cus.reserved",
8612 FT_UINT8, BASE_HEX,
8613 NULL((void*)0), 0x04,
8614 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8615 },
8616 { &hf_oran_reserved_bits123,
8617 { "reserved", "oran_fh_cus.reserved",
8618 FT_UINT8, BASE_HEX,
8619 NULL((void*)0), 0x70,
8620 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8621 },
8622 { &hf_oran_reserved_bits456,
8623 { "reserved", "oran_fh_cus.reserved",
8624 FT_UINT8, BASE_HEX,
8625 NULL((void*)0), 0x0e,
8626 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8627 },
8628
8629 /* 7.7.11.9 */
8630 { &hf_oran_cont_ind,
8631 { "contInd", "oran_fh_cus.contInd",
8632 FT_BOOLEAN, 8,
8633 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8634 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8635 },
8636 /* 7.7.11.10 */
8637 { &hf_oran_bundle_offset,
8638 { "BundleOffset", "oran_fh_cus.bundleOffset",
8639 FT_UINT8, BASE_DEC,
8640 NULL((void*)0), 0x3f,
8641 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8642 },
8643
8644 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8645 { &hf_oran_bfwCompHdr,
8646 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8647 FT_STRING, BASE_NONE,
8648 NULL((void*)0), 0x0,
8649 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8650 },
8651 { &hf_oran_bfwCompHdr_iqWidth,
8652 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8653 FT_UINT8, BASE_HEX,
8654 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8655 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8656 },
8657 { &hf_oran_bfwCompHdr_compMeth,
8658 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8659 FT_UINT8, BASE_HEX,
8660 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8661 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8662 },
8663
8664 /* 7.5.3.32 */
8665 { &hf_oran_ciCompParam,
8666 { "ciCompParam", "oran_fh_cus.ciCompParam",
8667 FT_STRING, BASE_NONE,
8668 NULL((void*)0), 0x0,
8669 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8670 },
8671
8672 /* Table 7.5.3.32-1 */
8673 { &hf_oran_blockScaler,
8674 { "blockScaler", "oran_fh_cus.blockScaler",
8675 FT_UINT8, BASE_HEX,
8676 NULL((void*)0), 0x0,
8677 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8678 },
8679 { &hf_oran_compBitWidth,
8680 { "compBitWidth", "oran_fh_cus.compBitWidth",
8681 FT_UINT8, BASE_DEC,
8682 NULL((void*)0), 0xf0,
8683 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8684 },
8685 { &hf_oran_compShift,
8686 { "compShift", "oran_fh_cus.compShift",
8687 FT_UINT8, BASE_DEC,
8688 NULL((void*)0), 0x0f,
8689 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8690 },
8691
8692 { &hf_oran_active_beamspace_coefficient_n1,
8693 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8694 FT_BOOLEAN, 8,
8695 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8696 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8697 },
8698 { &hf_oran_active_beamspace_coefficient_n2,
8699 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8700 FT_BOOLEAN, 8,
8701 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8702 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8703 },
8704 { &hf_oran_active_beamspace_coefficient_n3,
8705 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8706 FT_BOOLEAN, 8,
8707 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8708 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8709 },
8710 { &hf_oran_active_beamspace_coefficient_n4,
8711 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8712 FT_BOOLEAN, 8,
8713 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8714 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8715 },
8716 { &hf_oran_active_beamspace_coefficient_n5,
8717 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8718 FT_BOOLEAN, 8,
8719 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8720 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8721 },
8722 { &hf_oran_active_beamspace_coefficient_n6,
8723 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8724 FT_BOOLEAN, 8,
8725 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8726 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8727 },
8728 { &hf_oran_active_beamspace_coefficient_n7,
8729 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8730 FT_BOOLEAN, 8,
8731 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8732 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8733 },
8734 { &hf_oran_active_beamspace_coefficient_n8,
8735 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8736 FT_BOOLEAN, 8,
8737 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8738 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8739 },
8740
8741 { &hf_oran_activeBeamspaceCoefficientMask,
8742 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8743 FT_UINT8, BASE_HEX,
8744 NULL((void*)0), 0xff,
8745 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8746 },
8747 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8748 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8749 FT_UINT32, BASE_DEC,
8750 NULL((void*)0), 0x0,
8751 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8752 },
8753
8754 /* Section 7.7.6.6 */
8755 { &hf_oran_se6_repetition,
8756 { "repetition", "oran_fh_cus.repetition",
8757 FT_BOOLEAN, BASE_NONE,
8758 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8759 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8760 },
8761 /* 7.7.20.9 */
8762 { &hf_oran_rbgSize,
8763 { "rbgSize", "oran_fh_cus.rbgSize",
8764 FT_UINT8, BASE_HEX,
8765 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8766 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8767 },
8768 /* 7.7.20.10 */
8769 { &hf_oran_rbgMask,
8770 { "rbgMask", "oran_fh_cus.rbgMask",
8771 FT_UINT32, BASE_HEX,
8772 NULL((void*)0), 0x0fffffff,
8773 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8774 },
8775 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8776 { &hf_oran_noncontig_priority,
8777 { "priority", "oran_fh_cus.priority",
8778 FT_UINT8, BASE_HEX,
8779 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8780 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8781 },
8782
8783 /* 7.7.6.4 */
8784 { &hf_oran_symbol_mask,
8785 { "symbolMask", "oran_fh_cus.symbolMask",
8786 FT_UINT16, BASE_HEX,
8787 NULL((void*)0), 0x3fff,
8788 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8789 },
8790 { &hf_oran_symbol_mask_s13,
8791 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8792 FT_BOOLEAN, 16,
8793 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8794 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8795 },
8796 { &hf_oran_symbol_mask_s12,
8797 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8798 FT_BOOLEAN, 16,
8799 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8800 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8801 },
8802 { &hf_oran_symbol_mask_s11,
8803 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8804 FT_BOOLEAN, 16,
8805 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8806 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8807 },
8808 { &hf_oran_symbol_mask_s10,
8809 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8810 FT_BOOLEAN, 16,
8811 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8812 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8813 },
8814 { &hf_oran_symbol_mask_s9,
8815 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8816 FT_BOOLEAN, 16,
8817 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8818 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8819 },
8820 { &hf_oran_symbol_mask_s8,
8821 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8822 FT_BOOLEAN, 16,
8823 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8824 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8825 },
8826 { &hf_oran_symbol_mask_s7,
8827 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8828 FT_BOOLEAN, 16,
8829 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8830 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8831 },
8832 { &hf_oran_symbol_mask_s6,
8833 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8834 FT_BOOLEAN, 16,
8835 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8836 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8837 },
8838 { &hf_oran_symbol_mask_s5,
8839 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8840 FT_BOOLEAN, 16,
8841 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8842 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8843 },
8844 { &hf_oran_symbol_mask_s4,
8845 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8846 FT_BOOLEAN, 16,
8847 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8848 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8849 },
8850 { &hf_oran_symbol_mask_s3,
8851 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8852 FT_BOOLEAN, 16,
8853 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8854 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8855 },
8856 { &hf_oran_symbol_mask_s2,
8857 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8858 FT_BOOLEAN, 16,
8859 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8860 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8861 },
8862 { &hf_oran_symbol_mask_s1,
8863 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8864 FT_BOOLEAN, 16,
8865 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8866 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8867 },
8868 { &hf_oran_symbol_mask_s0,
8869 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8870 FT_BOOLEAN, 16,
8871 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8872 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8873 },
8874
8875
8876 /* 7.7.22.2 */
8877 { &hf_oran_ack_nack_req_id,
8878 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8879 FT_UINT16, BASE_HEX,
8880 NULL((void*)0), 0x0,
8881 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8882 },
8883
8884 /* Subtree for next 2 items */
8885 { &hf_oran_frequency_range,
8886 { "Frequency Range", "oran_fh_cus.frequencyRange",
8887 FT_STRING, BASE_NONE,
8888 NULL((void*)0), 0x0,
8889 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8890 },
8891
8892 /* 7.7.12.4 */
8893 { &hf_oran_off_start_prb,
8894 { "offStartPrb", "oran_fh_cus.offStartPrb",
8895 FT_UINT8, BASE_DEC,
8896 NULL((void*)0), 0x0,
8897 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8898 },
8899 /* 7.7.12.5 */
8900 { &hf_oran_num_prb,
8901 { "numPrb", "oran_fh_cus.numPrb",
8902 FT_UINT8, BASE_DEC,
8903 NULL((void*)0), 0x0,
8904 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8905 },
8906
8907 /* symbolId 8.3.3.7 */
8908 { &hf_oran_symbolId,
8909 { "Symbol Identifier", "oran_fh_cus.symbolId",
8910 FT_UINT8, BASE_DEC,
8911 NULL((void*)0), 0x3f,
8912 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8913 },
8914
8915 /* startPrbu 8.3.3.11 */
8916 { &hf_oran_startPrbu,
8917 { "startPrbu", "oran_fh_cus.startPrbu",
8918 FT_UINT16, BASE_DEC,
8919 NULL((void*)0), 0x03ff,
8920 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8921 },
8922
8923 /* numPrbu 8.3.3.12 */
8924 { &hf_oran_numPrbu,
8925 { "numPrbu", "oran_fh_cus.numPrbu",
8926 FT_UINT8, BASE_DEC,
8927 NULL((void*)0), 0x0,
8928 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8929 },
8930
8931 /* 7.7.1.3 */
8932 { &hf_oran_bfwCompParam,
8933 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8934 FT_STRING, BASE_NONE,
8935 NULL((void*)0), 0x0,
8936 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8937 },
8938
8939 /* 6.3.3.13 */
8940 { &hf_oran_udCompHdrMeth,
8941 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8942 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8943 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8944 "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)}
8945 },
8946 { &hf_oran_udCompHdrMeth_pref,
8947 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8948 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8949 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8950 "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)}
8951 },
8952 /* 8.3.3.18 */
8953 { &hf_oran_udCompLen,
8954 { "udCompLen", "oran_fh_cus.udCompLen",
8955 FT_UINT16, BASE_DEC,
8956 NULL((void*)0), 0x0,
8957 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8958 },
8959
8960 /* 7.5.2.10 */
8961 { &hf_oran_udCompHdrIqWidth,
8962 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8963 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8964 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8965 "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)}
8966 },
8967 { &hf_oran_udCompHdrIqWidth_pref,
8968 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8969 FT_UINT8, BASE_DEC,
8970 NULL((void*)0), 0x0,
8971 "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)}
8972 },
8973
8974 { &hf_oran_sinrCompHdrIqWidth_pref,
8975 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8976 FT_UINT8, BASE_DEC,
8977 NULL((void*)0), 0x0,
8978 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8979 },
8980 { &hf_oran_sinrCompHdrMeth_pref,
8981 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8982 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8983 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8984 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8985 },
8986
8987 /* Section 8.3.3.15 (not always present - depends upon meth) */
8988 { &hf_oran_udCompParam,
8989 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8990 FT_STRING, BASE_NONE,
8991 NULL((void*)0), 0x0,
8992 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8993 },
8994 /* 8.3.3.18 */
8995 { &hf_oran_sReSMask,
8996 { "sReSMask", "oran_fh_cus.sReSMask",
8997 FT_UINT16, BASE_HEX,
8998 NULL((void*)0), 0xf0ff,
8999 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9000 },
9001
9002 { &hf_oran_sReSMask_re12,
9003 { "RE-12", "oran_fh_cus.sReSMask-re12",
9004 FT_BOOLEAN, 16,
9005 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
9006 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9007 },
9008 { &hf_oran_sReSMask_re11,
9009 { "RE-11", "oran_fh_cus.sReSMask-re11",
9010 FT_BOOLEAN, 16,
9011 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
9012 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9013 },
9014 { &hf_oran_sReSMask_re10,
9015 { "RE-10", "oran_fh_cus.sReSMask-re10",
9016 FT_BOOLEAN, 16,
9017 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
9018 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9019 },
9020 { &hf_oran_sReSMask_re9,
9021 { "RE-9", "oran_fh_cus.sReSMask-re9",
9022 FT_BOOLEAN, 16,
9023 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
9024 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9025 },
9026 { &hf_oran_sReSMask_re8,
9027 { "RE-8", "oran_fh_cus.sReSMask-re8",
9028 FT_BOOLEAN, 16,
9029 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9030 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9031 },
9032 { &hf_oran_sReSMask_re7,
9033 { "RE-7", "oran_fh_cus.sReSMask-re7",
9034 FT_BOOLEAN, 16,
9035 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9036 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9037 },
9038 { &hf_oran_sReSMask_re6,
9039 { "RE-6", "oran_fh_cus.sReSMask-re6",
9040 FT_BOOLEAN, 16,
9041 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
9042 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9043 },
9044 { &hf_oran_sReSMask_re5,
9045 { "RE-5", "oran_fh_cus.sReSMask-re5",
9046 FT_BOOLEAN, 16,
9047 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
9048 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9049 },
9050 { &hf_oran_sReSMask_re4,
9051 { "RE-4", "oran_fh_cus.sReSMask-re4",
9052 FT_BOOLEAN, 16,
9053 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
9054 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9055 },
9056 { &hf_oran_sReSMask_re3,
9057 { "RE-3", "oran_fh_cus.sReSMask-re3",
9058 FT_BOOLEAN, 16,
9059 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
9060 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9061 },
9062 { &hf_oran_sReSMask_re2,
9063 { "RE-2", "oran_fh_cus.sReSMask-re2",
9064 FT_BOOLEAN, 16,
9065 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
9066 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9067 },
9068 { &hf_oran_sReSMask_re1,
9069 { "RE-1", "oran_fh_cus.sReSMask-re1",
9070 FT_BOOLEAN, 16,
9071 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
9072 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9073 },
9074
9075 /* 8.3.3.20 */
9076 { &hf_oran_sReSMask1,
9077 { "sReSMask1", "oran_fh_cus.sReSMask1",
9078 FT_UINT16, BASE_HEX,
9079 NULL((void*)0), 0x0fff,
9080 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9081 },
9082 /* 8.3.3.21 */
9083 { &hf_oran_sReSMask2,
9084 { "sReSMask2", "oran_fh_cus.sReSMask2",
9085 FT_UINT16, BASE_HEX,
9086 NULL((void*)0), 0x0fff,
9087 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9088 },
9089
9090 { &hf_oran_sReSMask1_2_re12,
9091 { "RE-12", "oran_fh_cus.sReSMask-re12",
9092 FT_BOOLEAN, 16,
9093 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9094 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9095 },
9096 { &hf_oran_sReSMask1_2_re11,
9097 { "RE-11", "oran_fh_cus.sReSMask-re11",
9098 FT_BOOLEAN, 16,
9099 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9100 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9101 },
9102 { &hf_oran_sReSMask1_2_re10,
9103 { "RE-10", "oran_fh_cus.sReSMask-re10",
9104 FT_BOOLEAN, 16,
9105 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9106 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9107 },
9108 { &hf_oran_sReSMask1_2_re9,
9109 { "RE-9", "oran_fh_cus.sReSMask-re9",
9110 FT_BOOLEAN, 16,
9111 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9112 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9113 },
9114
9115 /* Section 6.3.3.15 */
9116 { &hf_oran_iSample,
9117 { "iSample", "oran_fh_cus.iSample",
9118 FT_FLOAT, BASE_NONE,
9119 NULL((void*)0), 0x0,
9120 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9121 },
9122
9123 /* Section 6.3.3.16 */
9124 { &hf_oran_qSample,
9125 { "qSample", "oran_fh_cus.qSample",
9126 FT_FLOAT, BASE_NONE,
9127 NULL((void*)0), 0x0,
9128 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9129 },
9130
9131 { &hf_oran_exponent,
9132 { "Exponent", "oran_fh_cus.exponent",
9133 FT_UINT8, BASE_DEC,
9134 NULL((void*)0), 0x0f,
9135 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9136 },
9137
9138 { &hf_oran_iq_user_data,
9139 { "IQ User Data", "oran_fh_cus.iq_user_data",
9140 FT_BYTES, BASE_NONE,
9141 NULL((void*)0), 0x0,
9142 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9143 },
9144
9145
9146 { &hf_oran_u_section_ul_symbol_time,
9147 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
9148 FT_UINT32, BASE_DEC,
9149 NULL((void*)0), 0x0,
9150 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9151 },
9152 { &hf_oran_u_section_ul_symbol_frames,
9153 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
9154 FT_UINT32, BASE_DEC,
9155 NULL((void*)0), 0x0,
9156 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9157 },
9158 { &hf_oran_u_section_ul_symbol_first_frame,
9159 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
9160 FT_FRAMENUM, BASE_NONE,
9161 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9162 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9163 },
9164 { &hf_oran_u_section_ul_symbol_last_frame,
9165 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
9166 FT_FRAMENUM, BASE_NONE,
9167 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9168 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9169 },
9170
9171 { &hf_oran_c_eAxC_ID,
9172 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
9173 FT_STRING, BASE_NONE,
9174 NULL((void*)0), 0x0,
9175 "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) }
9176 },
9177
9178 { &hf_oran_refa,
9179 { "RefA", "oran_fh_cus.refa",
9180 FT_STRING, BASE_NONE,
9181 NULL((void*)0), 0x0,
9182 "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) }
9183 },
9184
9185
9186 /* Section 7.5.2.15 */
9187 { &hf_oran_ciCompHdr,
9188 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
9189 FT_STRING, BASE_NONE,
9190 NULL((void*)0), 0x0,
9191 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9192 },
9193 { &hf_oran_ciCompHdrMeth,
9194 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
9195 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9196 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
9197 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9198 },
9199 { &hf_oran_ciCompHdrIqWidth,
9200 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
9201 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9202 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
9203 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9204 },
9205 { &hf_oran_ciCompOpt,
9206 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
9207 FT_UINT8, BASE_DEC,
9208 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
9209 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9210 },
9211
9212 /* 7.7.11.7 */
9213 { &hf_oran_disable_bfws,
9214 { "disableBFWs", "oran_fh_cus.disableBFWs",
9215 FT_BOOLEAN, 8,
9216 NULL((void*)0), 0x80,
9217 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9218 },
9219 /* 7.7.11.8 */
9220 { &hf_oran_rad,
9221 { "RAD", "oran_fh_cus.rad",
9222 FT_BOOLEAN, 8,
9223 NULL((void*)0), 0x40,
9224 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9225 },
9226 /* 7.7.11.4 */
9227 { &hf_oran_num_bund_prbs,
9228 { "numBundPrb", "oran_fh_cus.numBundPrb",
9229 FT_UINT8, BASE_DEC,
9230 NULL((void*)0), 0x0,
9231 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9232 },
9233 { &hf_oran_beam_id,
9234 { "beamId", "oran_fh_cus.beamId",
9235 FT_UINT16, BASE_DEC,
9236 NULL((void*)0), 0x7fff,
9237 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9238 },
9239 { &hf_oran_num_weights_per_bundle,
9240 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
9241 FT_UINT16, BASE_DEC,
9242 NULL((void*)0), 0x0,
9243 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9244 },
9245
9246 { &hf_oran_samples_prb,
9247 {"PRB", "oran_fh_cus.prb",
9248 FT_STRING, BASE_NONE,
9249 NULL((void*)0), 0x0,
9250 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9251 },
9252
9253 /* 7.5.3.13 */
9254 { &hf_oran_ciSample,
9255 { "ciSample", "oran_fh_cus.ciSample",
9256 FT_STRING, BASE_NONE,
9257 NULL((void*)0), 0x0,
9258 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9259 },
9260 { &hf_oran_ciIsample,
9261 { "ciIsample", "oran_fh_cus.ciISample",
9262 FT_FLOAT, BASE_NONE,
9263 NULL((void*)0), 0x0,
9264 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9265 },
9266 { &hf_oran_ciQsample,
9267 { "ciQsample", "oran_fh_cus.ciQSample",
9268 FT_FLOAT, BASE_NONE,
9269 NULL((void*)0), 0x0,
9270 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9271 },
9272
9273 /* 7.7.10.2 */
9274 { &hf_oran_beamGroupType,
9275 { "beamGroupType", "oran_fh_cus.beamGroupType",
9276 FT_UINT8, BASE_DEC,
9277 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9278 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9279 },
9280 /* 7.7.10.3 */
9281 { &hf_oran_numPortc,
9282 { "numPortc", "oran_fh_cus.numPortc",
9283 FT_UINT8, BASE_DEC,
9284 NULL((void*)0), 0x3f,
9285 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9286 },
9287
9288 /* 7.7.4.2 (1 bit) */
9289 { &hf_oran_csf,
9290 { "csf", "oran_fh_cus.csf",
9291 FT_BOOLEAN, BASE_NONE,
9292 NULL((void*)0), 0x0,
9293 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9294 },
9295 /* 7.7.4.3 */
9296 { &hf_oran_modcompscaler,
9297 { "modCompScaler", "oran_fh_cus.modcompscaler",
9298 FT_UINT16, BASE_DEC,
9299 NULL((void*)0), 0x7fff,
9300 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9301 },
9302
9303 /* 7.7.5.1 */
9304 { &hf_oran_modcomp_param_set,
9305 { "Set", "oran_fh_cus.modcomp-param-set",
9306 FT_STRING, BASE_NONE,
9307 NULL((void*)0), 0x0,
9308 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9309 },
9310
9311
9312
9313 /* mcScaleReMask 7.7.5.2 (12 bits) */
9314
9315 /* First entry (starts with msb within byte) */
9316 { &hf_oran_mc_scale_re_mask_re1,
9317 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9318 FT_BOOLEAN, 16,
9319 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9320 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9321 },
9322 { &hf_oran_mc_scale_re_mask_re2,
9323 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9324 FT_BOOLEAN, 16,
9325 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9326 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9327 },
9328 { &hf_oran_mc_scale_re_mask_re3,
9329 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9330 FT_BOOLEAN, 16,
9331 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9332 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9333 },
9334 { &hf_oran_mc_scale_re_mask_re4,
9335 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9336 FT_BOOLEAN, 16,
9337 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9338 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9339 },
9340 { &hf_oran_mc_scale_re_mask_re5,
9341 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9342 FT_BOOLEAN, 16,
9343 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9344 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9345 },
9346 { &hf_oran_mc_scale_re_mask_re6,
9347 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9348 FT_BOOLEAN, 16,
9349 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9350 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9351 },
9352 { &hf_oran_mc_scale_re_mask_re7,
9353 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9354 FT_BOOLEAN, 16,
9355 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9356 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9357 },
9358 { &hf_oran_mc_scale_re_mask_re8,
9359 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9360 FT_BOOLEAN, 16,
9361 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9362 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9363 },
9364 { &hf_oran_mc_scale_re_mask_re9,
9365 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9366 FT_BOOLEAN, 16,
9367 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9368 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9369 },
9370 { &hf_oran_mc_scale_re_mask_re10,
9371 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9372 FT_BOOLEAN, 16,
9373 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9374 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9375 },
9376 { &hf_oran_mc_scale_re_mask_re11,
9377 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9378 FT_BOOLEAN, 16,
9379 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9380 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9381 },
9382 { &hf_oran_mc_scale_re_mask_re12,
9383 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9384 FT_BOOLEAN, 16,
9385 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9386 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9387 },
9388
9389 /* Even tries entry (starts with 5th bit within byte) */
9390 { &hf_oran_mc_scale_re_mask_re1_even,
9391 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9392 FT_BOOLEAN, 16,
9393 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9394 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9395 },
9396 { &hf_oran_mc_scale_re_mask_re2_even,
9397 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9398 FT_BOOLEAN, 16,
9399 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9400 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9401 },
9402 { &hf_oran_mc_scale_re_mask_re3_even,
9403 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9404 FT_BOOLEAN, 16,
9405 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9406 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9407 },
9408 { &hf_oran_mc_scale_re_mask_re4_even,
9409 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9410 FT_BOOLEAN, 16,
9411 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9412 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9413 },
9414 { &hf_oran_mc_scale_re_mask_re5_even,
9415 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9416 FT_BOOLEAN, 16,
9417 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9418 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9419 },
9420 { &hf_oran_mc_scale_re_mask_re6_even,
9421 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9422 FT_BOOLEAN, 16,
9423 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9424 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9425 },
9426 { &hf_oran_mc_scale_re_mask_re7_even,
9427 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9428 FT_BOOLEAN, 16,
9429 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9430 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9431 },
9432 { &hf_oran_mc_scale_re_mask_re8_even,
9433 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9434 FT_BOOLEAN, 16,
9435 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9436 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9437 },
9438 { &hf_oran_mc_scale_re_mask_re9_even,
9439 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9440 FT_BOOLEAN, 16,
9441 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9442 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9443 },
9444 { &hf_oran_mc_scale_re_mask_re10_even,
9445 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9446 FT_BOOLEAN, 16,
9447 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9448 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9449 },
9450 { &hf_oran_mc_scale_re_mask_re11_even,
9451 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9452 FT_BOOLEAN, 16,
9453 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9454 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9455 },
9456 { &hf_oran_mc_scale_re_mask_re12_even,
9457 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9458 FT_BOOLEAN, 16,
9459 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9460 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9461 },
9462
9463 { &hf_oran_mc_scale_re_mask,
9464 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9465 FT_UINT16, BASE_HEX,
9466 NULL((void*)0), 0xfff0,
9467 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9468 },
9469 { &hf_oran_mc_scale_re_mask_even,
9470 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9471 FT_UINT16, BASE_HEX,
9472 NULL((void*)0), 0x0fff,
9473 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9474 },
9475
9476 /* mcScaleOffset 7.7.5.4 (15 bits) */
9477 { &hf_oran_mc_scale_offset,
9478 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9479 FT_UINT24, BASE_DEC,
9480 NULL((void*)0), 0x0,
9481 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9482 },
9483 /* eAxCmask (7.7.7.2) */
9484 { &hf_oran_eAxC_mask,
9485 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9486 FT_UINT16, BASE_HEX,
9487 NULL((void*)0), 0xffff,
9488 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9489 },
9490 /* technology (interface name) 7.7.9.2 */
9491 { &hf_oran_technology,
9492 { "Technology", "oran_fh_cus.technology",
9493 FT_UINT8, BASE_DEC,
9494 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9495 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9496 },
9497 /* Exttype 14 (7.7.14.2) */
9498 { &hf_oran_nullLayerInd,
9499 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9500 FT_BOOLEAN, BASE_NONE,
9501 NULL((void*)0), 0x0,
9502 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9503 },
9504
9505 /* Exttype 19 */
9506 /* 7.7.19.3 */
9507 { &hf_oran_se19_repetition,
9508 { "repetition", "oran_fh_cus.repetition",
9509 FT_BOOLEAN, BASE_NONE,
9510 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9511 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9512 },
9513 /* 7.7.19.8 */
9514 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9515 { &hf_oran_portReMask,
9516 { "portReMask", "oran_fh_cus.portReMask",
9517 FT_BOOLEAN, 16,
9518 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9519 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9520 },
9521 /* 7.7.19.9 */
9522 { &hf_oran_portSymbolMask,
9523 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9524 FT_BOOLEAN, 16,
9525 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9526 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9527 },
9528
9529 { &hf_oran_ext19_port,
9530 {"Port", "oran_fh_cus.ext19.port",
9531 FT_STRING, BASE_NONE,
9532 NULL((void*)0), 0x0,
9533 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9534 },
9535
9536 /* Ext 13 */
9537 { &hf_oran_prb_allocation,
9538 {"PRB allocation", "oran_fh_cus.prb-allocation",
9539 FT_STRING, BASE_NONE,
9540 NULL((void*)0), 0x0,
9541 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9542 },
9543 /* 7.7.13.2 */
9544 { &hf_oran_nextSymbolId,
9545 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9546 FT_UINT8, BASE_DEC,
9547 NULL((void*)0), 0x3c,
9548 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9549 },
9550 /* 7.7.13.3 */
9551 { &hf_oran_nextStartPrbc,
9552 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9553 FT_UINT16, BASE_DEC,
9554 NULL((void*)0), 0x03ff,
9555 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9556 },
9557
9558 /* Puncturing patters as appears in SE 20 */
9559 { &hf_oran_puncPattern,
9560 { "puncPattern", "oran_fh_cus.puncPattern",
9561 FT_STRING, BASE_NONE,
9562 NULL((void*)0), 0x0,
9563 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9564 },
9565
9566 /* 7.7.20.2 numPuncPatterns */
9567 { &hf_oran_numPuncPatterns,
9568 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9569 FT_UINT8, BASE_DEC,
9570 NULL((void*)0), 0x0,
9571 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9572 },
9573 /* 7.7.20.3 symbolMask */
9574 { &hf_oran_symbolMask_ext20,
9575 { "symbolMask", "oran_fh_cus.symbolMask",
9576 FT_UINT16, BASE_HEX,
9577 NULL((void*)0), 0xfffc,
9578 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9579 },
9580 /* 7.7.20.4 startPuncPrb */
9581 { &hf_oran_startPuncPrb,
9582 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9583 FT_UINT16, BASE_DEC,
9584 NULL((void*)0), 0x03ff,
9585 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9586 },
9587 /* 7.7.20.5 numPuncPrb */
9588 { &hf_oran_numPuncPrb,
9589 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9590 FT_UINT8, BASE_DEC,
9591 NULL((void*)0), 0x0,
9592 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9593 },
9594 /* 7.7.20.6 puncReMask */
9595 { &hf_oran_puncReMask,
9596 { "puncReMask", "oran_fh_cus.puncReMask",
9597 FT_UINT16, BASE_DEC,
9598 NULL((void*)0), 0xffc0,
9599 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9600 },
9601 /* 7.7.20.12 multiSDScope */
9602 { &hf_oran_multiSDScope,
9603 { "multiSDScope", "oran_fh_cus.multiSDScope",
9604 FT_BOOLEAN, 8,
9605 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9606 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9607 },
9608 /* 7.7.20.4 rbgIncl */
9609 { &hf_oran_RbgIncl,
9610 { "rbgIncl", "oran_fh_cus.rbgIncl",
9611 FT_BOOLEAN, 8,
9612 NULL((void*)0), 0x01,
9613 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9614 },
9615
9616 /* 7.7.21.2 ciPrbGroupSize */
9617 { &hf_oran_ci_prb_group_size,
9618 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9619 FT_UINT8, BASE_DEC,
9620 NULL((void*)0), 0x0,
9621 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9622 },
9623 /* 7.21.3 */
9624 { &hf_oran_prg_size_st5,
9625 { "prgSize", "oran_fh_cus.prgSize",
9626 FT_UINT8, BASE_DEC,
9627 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9628 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9629 },
9630 { &hf_oran_prg_size_st6,
9631 { "prgSize", "oran_fh_cus.prgSize",
9632 FT_UINT8, BASE_DEC,
9633 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9634 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9635 },
9636
9637 /* 7.7.17.2 numUeID */
9638 { &hf_oran_num_ueid,
9639 { "numUeID", "oran_fh_cus.numUeID",
9640 FT_UINT8, BASE_DEC,
9641 NULL((void*)0), 0x0,
9642 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9643 },
9644
9645 /* 7.7.16.2 antMask */
9646 { &hf_oran_antMask,
9647 { "antMask", "oran_fh_cus.antMask",
9648 FT_UINT64, BASE_HEX,
9649 NULL((void*)0), 0xffffffffffffffff,
9650 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9651 },
9652
9653 /* 7.7.18.2 transmissionWindowOffset */
9654 { &hf_oran_transmissionWindowOffset,
9655 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9656 FT_UINT16, BASE_DEC,
9657 NULL((void*)0), 0x0,
9658 "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)}
9659 },
9660 /* 7.7.18.3 transmissionWindowSize */
9661 { &hf_oran_transmissionWindowSize,
9662 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9663 FT_UINT16, BASE_DEC,
9664 NULL((void*)0), 0x3fff,
9665 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9666 },
9667 /* 7.7.18.4 toT */
9668 { &hf_oran_toT,
9669 { "toT", "oran_fh_cus.toT",
9670 FT_UINT8, BASE_DEC,
9671 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9672 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9673 },
9674
9675 /* 7.7.2.2 bfaCompHdr */
9676 { &hf_oran_bfaCompHdr,
9677 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9678 FT_STRING, BASE_NONE,
9679 NULL((void*)0), 0x0,
9680 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9681 },
9682 /* 7.7.2.2-2: bfAzPtWidth */
9683 { &hf_oran_bfAzPtWidth,
9684 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9685 FT_UINT8, BASE_DEC,
9686 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9687 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9688 },
9689 /* 7.7.2.2-3: bfZePtWidth */
9690 { &hf_oran_bfZePtWidth,
9691 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9692 FT_UINT8, BASE_DEC,
9693 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9694 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9695 },
9696 /* 7.7.2.2-4: bfAz3ddWidth */
9697 { &hf_oran_bfAz3ddWidth,
9698 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9699 FT_UINT8, BASE_DEC,
9700 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9701 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9702 },
9703 /* 7.7.2.2-5: bfZe3ddWidth */
9704 { &hf_oran_bfZe3ddWidth,
9705 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9706 FT_UINT8, BASE_DEC,
9707 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9708 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9709 },
9710
9711 /* 7.7.2.3 bfAzPt */
9712 { &hf_oran_bfAzPt,
9713 { "bfAzPt", "oran_fh_cus.bfAzPt",
9714 FT_UINT8, BASE_DEC,
9715 NULL((void*)0), 0x0,
9716 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9717 },
9718 /* 7.7.2.4 bfZePt */
9719 { &hf_oran_bfZePt,
9720 { "bfZePt", "oran_fh_cus.bfZePt",
9721 FT_UINT8, BASE_DEC,
9722 NULL((void*)0), 0x0,
9723 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9724 },
9725 /* 7.7.2.5 bfAz3dd */
9726 { &hf_oran_bfAz3dd,
9727 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9728 FT_UINT8, BASE_DEC,
9729 NULL((void*)0), 0x0,
9730 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9731 },
9732 /* 7.7.2.6 bfZe3dd */
9733 { &hf_oran_bfZe3dd,
9734 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9735 FT_UINT8, BASE_DEC,
9736 NULL((void*)0), 0x0,
9737 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9738 },
9739
9740 /* 7.7.2.7 bfAzSl */
9741 { &hf_oran_bfAzSl,
9742 { "bfAzSl", "oran_fh_cus.bfAzSl",
9743 FT_UINT8, BASE_DEC,
9744 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9745 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9746 },
9747 /* 7.7.2.8 bfZeSl */
9748 { &hf_oran_bfZeSl,
9749 { "bfZeSl", "oran_fh_cus.bfZeSl",
9750 FT_UINT8, BASE_DEC,
9751 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9752 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9753 },
9754
9755 /* 7.5.2.17 */
9756 { &hf_oran_cmd_scope,
9757 { "cmdScope", "oran_fh_cus.cmdScope",
9758 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9759 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9760 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9761 },
9762 /* 7.5.2.18 */
9763 { &hf_oran_number_of_st4_cmds,
9764 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9765 FT_UINT8, BASE_DEC,
9766 NULL((void*)0), 0x0,
9767 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9768 },
9769
9770 { &hf_oran_st4_cmd_header,
9771 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9772 FT_STRING, BASE_NONE,
9773 NULL((void*)0), 0x0,
9774 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9775 },
9776
9777 /* 7.5.3.38 */
9778 { &hf_oran_st4_cmd_type,
9779 { "st4CmdType", "oran_fh_cus.st4CmdType",
9780 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9781 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9782 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9783 },
9784 /* 7.5.3.39 */
9785 { &hf_oran_st4_cmd_len,
9786 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9787 FT_UINT16, BASE_DEC,
9788 NULL((void*)0), 0x0,
9789 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9790 },
9791 /* 7.5.3.40 */
9792 { &hf_oran_st4_cmd_num_slots,
9793 { "numSlots", "oran_fh_cus.st4NumSlots",
9794 FT_UINT8, BASE_DEC,
9795 NULL((void*)0), 0x0,
9796 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9797 },
9798 /* 7.5.3.41 */
9799 { &hf_oran_st4_cmd_ack_nack_req_id,
9800 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9801 FT_UINT16, BASE_DEC,
9802 NULL((void*)0), 0x0,
9803 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9804 },
9805
9806 { &hf_oran_st4_cmd,
9807 { "Command", "oran_fh_cus.st4Cmd",
9808 FT_STRING, BASE_NONE,
9809 NULL((void*)0), 0x0,
9810 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9811 },
9812
9813 /* 7.5.3.52 */
9814 { &hf_oran_sleepmode_trx,
9815 { "sleepMode", "oran_fh_cus.sleepMode",
9816 FT_UINT8, BASE_HEX,
9817 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9818 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9819 },
9820 { &hf_oran_sleepmode_asm,
9821 { "sleepMode", "oran_fh_cus.sleepMode",
9822 FT_UINT8, BASE_HEX,
9823 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9824 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9825 },
9826
9827 /* 7.5.3.51 */
9828 { &hf_oran_log2maskbits,
9829 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9830 FT_UINT8, BASE_HEX,
9831 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9832 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9833 },
9834 /* 7.5.3.53 */
9835 { &hf_oran_num_slots_ext,
9836 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9837 FT_UINT24, BASE_HEX,
9838 NULL((void*)0), 0x0fffff,
9839 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9840 },
9841 /* 7.5.3.54 */
9842 { &hf_oran_antMask_trx_control,
9843 { "antMask", "oran_fh_cus.trxControl.antMask",
9844 FT_BYTES, BASE_NONE,
9845 NULL((void*)0), 0x0,
9846 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9847 },
9848 /* 7.5.3.55 */
9849 { &hf_oran_ready,
9850 { "ready", "oran_fh_cus.ready",
9851 FT_BOOLEAN, 8,
9852 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9853 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9854 },
9855 /* 7.5.3.34 */
9856 { &hf_oran_number_of_acks,
9857 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9858 FT_UINT8, BASE_DEC,
9859 NULL((void*)0), 0x0,
9860 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9861 },
9862 /* 7.5.3.35 */
9863 { &hf_oran_number_of_nacks,
9864 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9865 FT_UINT8, BASE_DEC,
9866 NULL((void*)0), 0x0,
9867 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9868 },
9869 /* 7.5.3.36 */
9870 { &hf_oran_ackid,
9871 { "ackId", "oran_fh_cus.ackId",
9872 FT_UINT16, BASE_DEC,
9873 NULL((void*)0), 0x0,
9874 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9875 },
9876 /* 7.5.3.37 */
9877 { &hf_oran_nackid,
9878 { "nackId", "oran_fh_cus.nackId",
9879 FT_UINT16, BASE_DEC,
9880 NULL((void*)0), 0x0,
9881 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9882 },
9883
9884 /* Links between acknack requests & responses */
9885 { &hf_oran_acknack_request_frame,
9886 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9887 FT_FRAMENUM, BASE_NONE,
9888 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9889 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9890 },
9891 { &hf_oran_acknack_request_time,
9892 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9893 FT_UINT32, BASE_DEC,
9894 NULL((void*)0), 0x0,
9895 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9896 },
9897 { &hf_oran_acknack_request_type,
9898 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9899 FT_UINT32, BASE_DEC,
9900 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9901 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9902 },
9903 { &hf_oran_acknack_response_frame,
9904 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9905 FT_FRAMENUM, BASE_NONE,
9906 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9907 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9908 },
9909 { &hf_oran_acknack_response_time,
9910 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9911 FT_UINT32, BASE_DEC,
9912 NULL((void*)0), 0x0,
9913 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9914 },
9915
9916 /* 7.5.3.43 */
9917 { &hf_oran_disable_tdbfns,
9918 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9919 FT_BOOLEAN, 8,
9920 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9921 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9922 },
9923
9924 /* 7.5.3.44 */
9925 { &hf_oran_td_beam_group,
9926 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9927 FT_UINT16, BASE_HEX,
9928 NULL((void*)0), 0x7fff,
9929 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9930 },
9931 /* 7.5.3.43 */
9932 { &hf_oran_disable_tdbfws,
9933 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9934 FT_BOOLEAN, 8,
9935 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9936 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9937 },
9938
9939 /* 7.5.3.56 */
9940 { &hf_oran_td_beam_num,
9941 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9942 FT_UINT16, BASE_HEX,
9943 NULL((void*)0), 0x7fff,
9944 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9945 },
9946
9947 /* 7.5.3.49 */
9948 { &hf_oran_dir_pattern,
9949 { "dirPattern", "oran_fh_cus.dirPattern",
9950 FT_BOOLEAN, 16,
9951 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9952 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9953 },
9954 /* 7.5.3.50 */
9955 { &hf_oran_guard_pattern,
9956 { "guardPattern", "oran_fh_cus.guardPattern",
9957 FT_BOOLEAN, 16,
9958 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9959 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9960 },
9961
9962 /* For convenient filtering */
9963 { &hf_oran_cplane,
9964 { "C-Plane", "oran_fh_cus.c-plane",
9965 FT_NONE, BASE_NONE,
9966 NULL((void*)0), 0x0,
9967 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9968 },
9969 { &hf_oran_uplane,
9970 { "U-Plane", "oran_fh_cus.u-plane",
9971 FT_NONE, BASE_NONE,
9972 NULL((void*)0), 0x0,
9973 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9974 },
9975 { &hf_oran_bf,
9976 { "BeamForming", "oran_fh_cus.bf",
9977 FT_NONE, BASE_NONE,
9978 NULL((void*)0), 0x0,
9979 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9980 },
9981 { &hf_oran_zero_prb,
9982 { "Zero PRB", "oran_fh_cus.zero-prb",
9983 FT_NONE, BASE_NONE,
9984 NULL((void*)0), 0x0,
9985 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9986 },
9987 { &hf_oran_nonzero_prb,
9988 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9989 FT_NONE, BASE_NONE,
9990 NULL((void*)0), 0x0,
9991 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9992 },
9993 { &hf_oran_bundle_weights_all_zero,
9994 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9995 FT_NONE, BASE_NONE,
9996 NULL((void*)0), 0x0,
9997 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9998 },
9999
10000
10001 /* 5.1.3.2.7 */
10002 { &hf_oran_ecpri_pcid,
10003 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
10004 FT_NONE, BASE_NONE,
10005 NULL((void*)0), 0x0,
10006 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10007 },
10008 { &hf_oran_ecpri_rtcid,
10009 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
10010 FT_NONE, BASE_NONE,
10011 NULL((void*)0), 0x0,
10012 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10013 },
10014 /* 5.1.3.2.8 */
10015 { &hf_oran_ecpri_seqid,
10016 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
10017 FT_NONE, BASE_NONE,
10018 NULL((void*)0), 0x0,
10019 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10020 },
10021
10022 /* 7.7.23.2 */
10023 { &hf_oran_num_sym_prb_pattern,
10024 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
10025 FT_UINT8, BASE_DEC,
10026 NULL((void*)0), 0xf0,
10027 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10028 },
10029 /* 7.7.23.9 */
10030 { &hf_oran_prb_mode,
10031 { "prbMode", "oran_fh_cus.prbMode",
10032 FT_BOOLEAN, 8,
10033 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
10034 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10035 },
10036 /* 7.7.23.4 */
10037 { &hf_oran_sym_prb_pattern,
10038 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
10039 FT_STRING, BASE_NONE,
10040 NULL((void*)0), 0x0,
10041 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10042 },
10043 /* 7.7.23.3 */
10044 { &hf_oran_sym_mask,
10045 { "symMask", "oran_fh_cus.symMask",
10046 FT_UINT16, BASE_HEX,
10047 NULL((void*)0), 0x3fff,
10048 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10049 },
10050 /* 7.7.23.5 */
10051 {&hf_oran_num_mc_scale_offset,
10052 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
10053 FT_UINT8, BASE_DEC,
10054 NULL((void*)0), 0xf0,
10055 "number of modulation compression scaling value per symPrbPattern",
10056 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10057 },
10058 /* 7.7.23.4 */
10059 { &hf_oran_prb_pattern,
10060 { "prbPattern", "oran_fh_cus.prbPattern",
10061 FT_UINT8, BASE_DEC,
10062 NULL((void*)0), 0x0f,
10063 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10064 },
10065 /* 7.7.23.10 */
10066 { &hf_oran_prb_blk_offset,
10067 { "prbBlkOffset", "oran_fh_cus.prbBlkOffset",
10068 FT_UINT16, BASE_DEC,
10069 NULL((void*)0), 0x0ff0,
10070 "offset to start of PRB block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10071 },
10072
10073 /* 7.7.23.11 */
10074 { &hf_oran_prb_blk_size,
10075 { "prbBlkSize", "oran_fh_cus.prbBlkSize",
10076 FT_UINT16, BASE_DEC,
10077 NULL((void*)0), 0x0ff0,
10078 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10079 },
10080
10081 /* 7.7.3.2 */
10082 { &hf_oran_codebook_index,
10083 { "codebookIndex", "oran_fh_cus.codebookIndex",
10084 FT_UINT8, BASE_DEC,
10085 NULL((void*)0), 0x0,
10086 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10087 },
10088 /* 7.7.3.3 */
10089 { &hf_oran_layerid,
10090 { "layerID", "oran_fh_cus.layerID",
10091 FT_UINT8, BASE_DEC,
10092 NULL((void*)0), 0xf0,
10093 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10094 },
10095 /* 7.7.3.5 */
10096 { &hf_oran_numlayers,
10097 { "numLayers", "oran_fh_cus.numLayers",
10098 FT_UINT8, BASE_DEC,
10099 NULL((void*)0), 0x0f,
10100 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10101 },
10102 /* 7.7.3.4 */
10103 { &hf_oran_txscheme,
10104 { "txScheme", "oran_fh_cus.txScheme",
10105 FT_UINT8, BASE_DEC,
10106 NULL((void*)0), 0xf0,
10107 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10108 },
10109 /* 7.7.3.6 */
10110 { &hf_oran_crs_remask,
10111 { "crsReMask", "oran_fh_cus.crsReMask",
10112 FT_UINT16, BASE_HEX,
10113 NULL((void*)0), 0x0fff,
10114 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10115 },
10116 /* 7.7.3.8 */
10117 { &hf_oran_crs_shift,
10118 { "crsShift", "oran_fh_cus.crsShift",
10119 FT_UINT8, BASE_HEX,
10120 NULL((void*)0), 0x80,
10121 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10122 },
10123 /* 7.7.3.7 */
10124 { &hf_oran_crs_symnum,
10125 { "crsSymNum", "oran_fh_cus.crsSymNum",
10126 FT_UINT8, BASE_DEC,
10127 NULL((void*)0), 0x0f,
10128 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10129 },
10130 /* 7.7.3.9 */
10131 { &hf_oran_beamid_ap1,
10132 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
10133 FT_UINT16, BASE_DEC,
10134 NULL((void*)0), 0x7f,
10135 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10136 },
10137 /* 7.7.3.10 */
10138 { &hf_oran_beamid_ap2,
10139 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
10140 FT_UINT16, BASE_DEC,
10141 NULL((void*)0), 0x7f,
10142 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10143 },
10144 /* 7.7.3.11 */
10145 { &hf_oran_beamid_ap3,
10146 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
10147 FT_UINT16, BASE_DEC,
10148 NULL((void*)0), 0x7f,
10149 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10150 },
10151
10152 /* 7.7.10.3a */
10153 { &hf_oran_port_list_index,
10154 { "portListIndex", "oran_fh_cus.portListIndex",
10155 FT_UINT8, BASE_DEC,
10156 NULL((void*)0), 0x0,
10157 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10158 },
10159
10160 { &hf_oran_alpn_per_sym,
10161 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
10162 FT_UINT8, BASE_HEX,
10163 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
10164 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10165 },
10166 { &hf_oran_ant_dmrs_snr,
10167 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
10168 FT_UINT8, BASE_HEX,
10169 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
10170 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10171 },
10172
10173 /* 7.7.24.6 */
10174 { &hf_oran_user_group_size,
10175 { "userGroupSize", "oran_fh_cus.userGroupSize",
10176 FT_UINT8, BASE_DEC,
10177 NULL((void*)0), 0x1f,
10178 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10179 },
10180 /* 7.7.24.7 */
10181 { &hf_oran_user_group_id,
10182 { "userGroupId", "oran_fh_cus.userGroupId",
10183 FT_UINT8, BASE_DEC,
10184 NULL((void*)0), 0x0,
10185 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10186 },
10187 /* 7.7.24.8 */
10188 { &hf_oran_entry_type,
10189 { "entryType", "oran_fh_cus.entryType",
10190 FT_UINT8, BASE_DEC,
10191 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
10192 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10193 },
10194 /* 7.7.24.9 */
10195 { &hf_oran_dmrs_port_number,
10196 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
10197 FT_UINT8, BASE_DEC,
10198 NULL((void*)0), 0x1f,
10199 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10200 },
10201 /* 7.7.24.10 */
10202 { &hf_oran_ueid_reset,
10203 { "ueidReset", "oran_fh_cus.ueidReset",
10204 FT_BOOLEAN, 8,
10205 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
10206 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10207 },
10208 /* 7.7.24.11 */
10209 { &hf_oran_dmrs_symbol_mask,
10210 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
10211 FT_UINT16, BASE_HEX,
10212 NULL((void*)0), 0x3fff,
10213 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10214 },
10215 { &hf_oran_dmrs_symbol_mask_s13,
10216 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
10217 FT_BOOLEAN, 16,
10218 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
10219 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10220 },
10221 { &hf_oran_dmrs_symbol_mask_s12,
10222 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
10223 FT_BOOLEAN, 16,
10224 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
10225 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10226 },
10227 { &hf_oran_dmrs_symbol_mask_s11,
10228 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
10229 FT_BOOLEAN, 16,
10230 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
10231 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10232 },
10233 { &hf_oran_dmrs_symbol_mask_s10,
10234 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
10235 FT_BOOLEAN, 16,
10236 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
10237 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10238 },
10239 { &hf_oran_dmrs_symbol_mask_s9,
10240 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
10241 FT_BOOLEAN, 16,
10242 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
10243 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10244 },
10245 { &hf_oran_dmrs_symbol_mask_s8,
10246 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
10247 FT_BOOLEAN, 16,
10248 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
10249 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10250 },
10251 { &hf_oran_dmrs_symbol_mask_s7,
10252 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
10253 FT_BOOLEAN, 16,
10254 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
10255 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10256 },
10257 { &hf_oran_dmrs_symbol_mask_s6,
10258 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
10259 FT_BOOLEAN, 16,
10260 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
10261 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10262 },
10263 { &hf_oran_dmrs_symbol_mask_s5,
10264 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10265 FT_BOOLEAN, 16,
10266 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10267 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10268 },
10269 { &hf_oran_dmrs_symbol_mask_s4,
10270 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10271 FT_BOOLEAN, 16,
10272 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10273 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10274 },
10275 { &hf_oran_dmrs_symbol_mask_s3,
10276 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10277 FT_BOOLEAN, 16,
10278 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10279 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10280 },
10281 { &hf_oran_dmrs_symbol_mask_s2,
10282 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10283 FT_BOOLEAN, 16,
10284 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10285 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10286 },
10287 { &hf_oran_dmrs_symbol_mask_s1,
10288 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10289 FT_BOOLEAN, 16,
10290 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10291 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10292 },
10293 { &hf_oran_dmrs_symbol_mask_s0,
10294 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10295 FT_BOOLEAN, 16,
10296 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10297 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10298 },
10299
10300 /* 7.7.24.12 */
10301 { &hf_oran_scrambling,
10302 { "scrambling", "oran_fh_cus.scrambling",
10303 FT_UINT16, BASE_HEX,
10304 NULL((void*)0), 0x0,
10305 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10306 },
10307 /* 7.7.24.13 */
10308 { &hf_oran_nscid,
10309 { "nscid", "oran_fh_cus.nscid",
10310 FT_UINT8, BASE_HEX,
10311 NULL((void*)0), 0x80,
10312 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10313 },
10314 /* 7.7.24.14 */
10315 { &hf_oran_dtype,
10316 { "dType", "oran_fh_cus.dType",
10317 FT_UINT8, BASE_HEX,
10318 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10319 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10320 },
10321 /* 7.7.24.15 */
10322 { &hf_oran_cmd_without_data,
10323 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10324 FT_UINT8, BASE_HEX,
10325 NULL((void*)0), 0x30,
10326 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10327 },
10328 /* 7.7.24.16 */
10329 { &hf_oran_lambda,
10330 { "lambda", "oran_fh_cus.lambda",
10331 FT_UINT8, BASE_HEX,
10332 NULL((void*)0), 0x0c,
10333 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10334 },
10335 /* 7.7.24.19 */
10336 { &hf_oran_first_prb,
10337 { "firstPrb", "oran_fh_cus.firstPrb",
10338 FT_UINT16, BASE_DEC,
10339 NULL((void*)0), 0x03fe,
10340 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10341 },
10342 /* 7.7.24.20 */
10343 { &hf_oran_last_prb,
10344 { "lastPrb", "oran_fh_cus.lastPrb",
10345 FT_UINT16, BASE_DEC,
10346 NULL((void*)0), 0x01ff,
10347 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10348 },
10349
10350 /* 7.7.24.17 */
10351 /* TODO: add value_string */
10352 { &hf_oran_low_papr_type,
10353 { "lowPaprType", "oran_fh_cus.lowPaprType",
10354 FT_UINT8, BASE_HEX,
10355 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10356 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10357 },
10358 /* 7.7.24.18 */
10359 { &hf_oran_hopping_mode,
10360 { "hoppingMode", "oran_fh_cus.hoppingMode",
10361 FT_UINT8, BASE_HEX,
10362 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10363 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10364 },
10365
10366 { &hf_oran_tx_win_for_on_air_symbol_l,
10367 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10368 FT_UINT8, BASE_DEC,
10369 NULL((void*)0), 0xf0,
10370 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10371 },
10372 { &hf_oran_tx_win_for_on_air_symbol_r,
10373 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10374 FT_UINT8, BASE_DEC,
10375 NULL((void*)0), 0x0f,
10376 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10377 },
10378 /* 7.7.26.2 */
10379 { &hf_oran_num_fo_fb,
10380 { "numFoFb", "oran_fh_cus.numFoFb",
10381 FT_UINT8, BASE_DEC,
10382 NULL((void*)0), 0x7f,
10383 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10384 },
10385 /* 7.7.26.3 */
10386 { &hf_oran_freq_offset_fb,
10387 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10388 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10389 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10390 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10391 },
10392
10393 /* 7.7.28.2 */
10394 { &hf_oran_num_ue_sinr_rpt,
10395 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10396 FT_UINT8, BASE_DEC,
10397 NULL((void*)0), 0x1f,
10398 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10399 },
10400
10401 /* 7.5.2.19 */
10402 { &hf_oran_num_sinr_per_prb,
10403 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10404 FT_UINT8, BASE_DEC,
10405 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10406 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10407 },
10408 { &hf_oran_num_sinr_per_prb_right,
10409 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10410 FT_UINT8, BASE_DEC,
10411 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10412 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10413 },
10414
10415 /* 7.5.3.68 */
10416 { &hf_oran_sinr_value,
10417 { "sinrValue", "oran_fh_cus.sinrValue",
10418 FT_FLOAT, BASE_NONE,
10419 NULL((void*)0), 0x0,
10420 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10421 },
10422
10423 { &hf_oran_measurement_report,
10424 { "Measurement Report", "oran_fh_cus.measurement-report",
10425 FT_STRING, BASE_NONE,
10426 NULL((void*)0), 0x0,
10427 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10428 },
10429 /* 7.5.3.57 */
10430 { &hf_oran_mf,
10431 { "mf", "oran_fh_cus.mf",
10432 FT_BOOLEAN, 8,
10433 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10434 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10435 },
10436 /* 7.5.3.59 */
10437 { &hf_oran_meas_data_size,
10438 { "measDataSize", "oran_fh_cus.measDataSize",
10439 FT_UINT16, BASE_DEC,
10440 NULL((void*)0), 0x0,
10441 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10442 },
10443
10444 /* 7.5.3.58 */
10445 { &hf_oran_meas_type_id,
10446 { "measTypeId", "oran_fh_cus.measTypeId",
10447 FT_UINT8, BASE_DEC,
10448 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10449 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10450 },
10451 /* 7.5.3.66 */
10452 { &hf_oran_num_elements,
10453 { "numElements", "oran_fh_cus.numElements",
10454 FT_UINT8, BASE_DEC,
10455 NULL((void*)0), 0x0,
10456 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10457 },
10458 /* 7.5.3.60 */
10459 { &hf_oran_ue_tae,
10460 { "ueTae", "oran_fh_cus.ueTae",
10461 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10462 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10463 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10464 },
10465 /* 7.5.3.61 */
10466 { &hf_oran_ue_layer_power,
10467 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10468 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10469 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10470 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10471 },
10472
10473 /* 7.5.3.62 */
10474 { &hf_oran_ue_freq_offset,
10475 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10476 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10477 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10478 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10479 },
10480 /* 7.5.3.63 */
10481 { &hf_oran_ipn_power,
10482 { "ipnPower", "oran_fh_cus.ipnPower",
10483 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10484 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10485 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10486 },
10487 /* 7.5.3.64 */
10488 { &hf_oran_ant_dmrs_snr_val,
10489 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10490 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10491 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10492 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10493 },
10494
10495 { &hf_oran_measurement_command,
10496 { "Measurement Command", "oran_fh_cus.measurement-command",
10497 FT_STRING, BASE_NONE,
10498 NULL((void*)0), 0x0,
10499 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10500 },
10501
10502 /* 7.5.27.2 */
10503 { &hf_oran_beam_type,
10504 {"beamType", "oran_fh_cus.beamType",
10505 FT_UINT16, BASE_DEC,
10506 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10507 NULL((void*)0),
10508 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10509 },
10510 /* 7.5.3.65 */
10511 { &hf_oran_meas_cmd_size,
10512 {"measCmdSize", "oran_fh_cus.measCmdSize",
10513 FT_UINT16, BASE_DEC,
10514 NULL((void*)0), 0x0,
10515 "measurement command size in words",
10516 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10517 },
10518
10519 { &hf_oran_symbol_reordering_layer,
10520 { "Layer", "oran_fh_cus.layer",
10521 FT_STRING, BASE_NONE,
10522 NULL((void*)0), 0x0,
10523 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10524 },
10525 { &hf_oran_dmrs_entry,
10526 { "Entry", "oran_fh_cus.dmrs-entry",
10527 FT_STRING, BASE_NONE,
10528 NULL((void*)0), 0x0,
10529 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10530 },
10531
10532 /* 7.7.29.3 */
10533 { &hf_oran_cd_scg_size,
10534 {"cdScgSize", "oran_fh_cus.cdScgSize",
10535 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10536 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10537 "Cyclic delay subcarrier group size",
10538 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10539 },
10540 /* 7.7.29.4 */
10541 { &hf_oran_cd_scg_phase_step,
10542 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10543 FT_INT8, BASE_DEC,
10544 NULL((void*)0), 0x0,
10545 "Cyclic delay subcarrier group phase step",
10546 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10547 },
10548
10549 { &hf_oran_sinr_prb,
10550 { "PRB", "oran_fh_cus.sinr.prb",
10551 FT_STRING, BASE_NONE,
10552 NULL((void*)0), 0x0,
10553 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10554 },
10555 /* 7.5.2.20 */
10556 { &hf_oran_oru_control_sinr_slot_mask_id,
10557 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10558 FT_UINT8, BASE_DEC,
10559 NULL((void*)0), 0x1f,
10560 "SINR time resolution",
10561 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10562 },
10563 /* 7.7.24.21 */
10564 { &hf_oran_pos_meas,
10565 {"posMeas", "oran_fh_cus.posMeas",
10566 FT_BOOLEAN, 8,
10567 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10568 "Positioning measurement report request",
10569 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10570 },
10571
10572 /* 7.5.3.69 */
10573 { &hf_oran_ue_radial_speed,
10574 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10575 FT_UINT16, BASE_DEC,
10576 NULL((void*)0), 0x0,
10577 "UE radial speed",
10578 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10579 },
10580 /* 7.5.3.70 */
10581 { &hf_oran_ue_az_aoa,
10582 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10583 FT_UINT16, BASE_DEC,
10584 NULL((void*)0), 0x0,
10585 "UE azimuth angle of arrival",
10586 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10587 },
10588 /* 7.5.3.71 */
10589 { &hf_oran_ue_ze_aoa,
10590 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10591 FT_UINT16, BASE_DEC,
10592 NULL((void*)0), 0x0,
10593 "UE zenith angle of arrival",
10594 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10595 },
10596 /* 7.5.3.72 */
10597 { &hf_oran_ue_pos_toa_offset,
10598 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10599 FT_UINT16, BASE_DEC,
10600 NULL((void*)0), 0x0,
10601 "UE positioning time of arrival offset",
10602 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10603 },
10604
10605 /* 7.7.30.2 */
10606 { &hf_oran_num_rep_ue,
10607 {"numRepUe", "oran_fh_cus.numRepUe",
10608 FT_UINT8, BASE_DEC,
10609 NULL((void*)0), 0x0f,
10610 "Number of UEs with PUSCH repetition",
10611 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10612 },
10613 /* 7.7.30.3 */
10614 { &hf_oran_rep_ueid,
10615 {"repUeId", "oran_fh_cus.repUeId",
10616 FT_UINT16, BASE_DEC,
10617 NULL((void*)0), 0x7fff,
10618 "UEId the PUSCH is part of",
10619 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10620 },
10621 /* 7.7.30.4 */
10622 { &hf_oran_is_last_rep,
10623 {"isLastRep", "oran_fh_cus.isLastRep",
10624 FT_BOOLEAN, 8,
10625 NULL((void*)0), 0x40,
10626 "Last transmission in the repetition",
10627 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10628 },
10629 /* 7.7.30.5 */
10630 { &hf_oran_rep_index,
10631 {"repIndex", "oran_fh_cus.repIndex",
10632 FT_UINT8, BASE_DEC,
10633 NULL((void*)0), 0x3f,
10634 "Repetition index of the PUSCH transmission",
10635 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10636 },
10637 /* 7.7.30.6 */
10638 { &hf_oran_num_reps,
10639 {"numReps", "oran_fh_cus.numReps",
10640 FT_UINT8, BASE_DEC,
10641 NULL((void*)0), 0x3f,
10642 "The number of total PUSCH repetitions",
10643 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10644 },
10645
10646 /* 7.7.31.2 */
10647 { &hf_oran_mcs_table,
10648 {"mcsTable", "oran_fh_cus.mcsTable",
10649 FT_UINT8, BASE_DEC,
10650 VALS(mcs_table_vals)((0 ? (const struct _value_string*)0 : ((mcs_table_vals)))), 0x0f,
10651 "MCS index table",
10652 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10653 },
10654 /* 7.7.31.3 */
10655 { &hf_oran_mcs_index,
10656 {"mcsIndex", "oran_fh_cus.mcsIndex",
10657 FT_UINT8, BASE_DEC,
10658 NULL((void*)0), 0x3f,
10659 "MCS index value",
10660 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10661 },
10662
10663 /* 7.7.33.3 */
10664 { &hf_oran_num_meas_req,
10665 {"numMeasReq", "oran_fh_cus.numMeasReq",
10666 FT_UINT8, BASE_DEC,
10667 NULL((void*)0), 0x1f,
10668 "Number of UEs for which meas is requested",
10669 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10670 },
10671 /* 7.7.32.5 */
10672 { &hf_oran_ue_rank,
10673 {"ueRank", "oran_fh_cus.ueRank",
10674 FT_UINT8, BASE_DEC,
10675 VALS(ue_rank_vals)((0 ? (const struct _value_string*)0 : ((ue_rank_vals)))), 0x0f,
10676 "Number of UE layers under evaluation",
10677 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10678 },
10679 /* 7.7.32.6 */
10680 { &hf_oran_num_of_ue_ant_ports,
10681 {"numOfUeAntPorts", "oran_fh_cus.numofUeAntPorts",
10682 FT_UINT8, BASE_DEC,
10683 VALS(num_of_ue_ant_ports_vals)((0 ? (const struct _value_string*)0 : ((num_of_ue_ant_ports_vals
))))
, 0xf0,
10684 "Used for the PUSCH tx under evaluation",
10685 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10686 },
10687 /* 7.7.32.8 */
10688 { &hf_oran_codebook_subset,
10689 {"codebookSubset", "oran_fh_cus.codebookSubset",
10690 FT_UINT8, BASE_DEC,
10691 VALS(codebook_subset_vals)((0 ? (const struct _value_string*)0 : ((codebook_subset_vals
))))
, 0xc0,
10692 "UE capability wrt ULTPMI sets",
10693 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10694 },
10695 /* 7.7.32.9 */
10696 { &hf_oran_full_pwr_mode,
10697 {"fullPwrMode", "oran_fh_cus.fullPwrMode",
10698 FT_UINT8, BASE_DEC,
10699 VALS(full_pwr_mode_vals)((0 ? (const struct _value_string*)0 : ((full_pwr_mode_vals))
))
, 0xc0,
10700 "Transmission mode",
10701 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10702 },
10703 /* 7.7.32.10 */
10704 { &hf_oran_full_pwr_mode_2_tpmi_group,
10705 {"fullPwrMode2TpmiGroup", "oran_fh_cus.fullPwrMode2TpmiGroup",
10706 FT_UINT16, BASE_HEX,
10707 NULL((void*)0), 0x3fff,
10708 "Capabilities",
10709 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10710 },
10711
10712 /* 7.5.3.75 */
10713 { &hf_oran_num_cand_ranks,
10714 {"numCandRanks", "oran_fh_cus.numCandRanks",
10715 FT_UINT8, BASE_DEC,
10716 NULL((void*)0), 0xf0,
10717 NULL((void*)0),
10718 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10719 },
10720 /* 7.5.3.76 */
10721 { &hf_oran_ue_pref_rank,
10722 {"uePrefRank", "oran_fh_cus.uePrefRank",
10723 FT_UINT8, BASE_DEC,
10724 NULL((void*)0), 0x0f,
10725 "Most optimal UL Tx rank for UE",
10726 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10727 },
10728 /* 7.5.3.77 */
10729 { &hf_oran_ue_tpmi_rank_y,
10730 {"ueTpmiRankY", "oran_fh_cus.ueTpmiRankY",
10731 FT_UINT8, BASE_DEC,
10732 NULL((void*)0), 0x0,
10733 "TPMI index for codebook-based PUSCH tx",
10734 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10735 },
10736 /* 7.5.3.78 */
10737 { &hf_oran_ue_tpmi_rank_y_sinr_lx,
10738 {"ueTpmiRankYSinrLX", "oran_fh_cus.ueTpmiRankYSinrLX",
10739 FT_UINT16, BASE_HEX | BASE_RANGE_STRING0x00000100,
10740 RVALS(ue_tmpi_rank_sinr_vals)((0 ? (const struct _range_string*)0 : ((ue_tmpi_rank_sinr_vals
))))
, 0x0,
10741 "Estimation of post-equalization SINR",
10742 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10743 },
10744 /* 7.5.3.79 */
10745 { &hf_oran_ue_layer_pre_eq_sinr,
10746 {"ueLayerPreEqSinr", "oran_fh_cus.ueLayerPreEqSinr",
10747 FT_UINT16, BASE_HEX,
10748 NULL((void*)0), 0x0,
10749 "Pre-equalization SINR of a UE layer",
10750 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10751 },
10752
10753 { &hf_oran_c_section_common,
10754 { "Common Section", "oran_fh_cus.c-plane.section.common",
10755 FT_STRING, BASE_NONE,
10756 NULL((void*)0), 0x0,
10757 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10758 },
10759 { &hf_oran_c_section,
10760 { "Section", "oran_fh_cus.c-plane.section",
10761 FT_STRING, BASE_NONE,
10762 NULL((void*)0), 0x0,
10763 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10764 },
10765 { &hf_oran_u_section,
10766 { "Section", "oran_fh_cus.u-plane.section",
10767 FT_STRING, BASE_NONE,
10768 NULL((void*)0), 0x0,
10769 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10770 },
10771
10772 /* Link back to UL C-plane where udCompHdr was recorded */
10773 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10774 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10775 FT_FRAMENUM, BASE_NONE,
10776 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10777 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10778 },
10779
10780 /* For ext11, where was a beamId (last) defined? */
10781 { &hf_oran_bfws_frame_defined,
10782 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10783 FT_FRAMENUM, BASE_NONE,
10784 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10785 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10786 },
10787 { &hf_oran_bfws_symbols_since_defined,
10788 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10789 FT_UINT32, BASE_DEC,
10790 NULL((void*)0), 0x0,
10791 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10792 },
10793
10794 /* Corresponding C-plane frame for DL U-plane */
10795 { &hf_oran_corresponding_cplane_frame,
10796 { "C-plane frame", "oran_fh_cus.cplane-frame",
10797 FT_FRAMENUM, BASE_NONE,
10798 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10799 },
10800 /* Time since corresponding C-plane frame for U-plane */
10801 { &hf_oran_corresponding_cplane_frame_time_delta,
10802 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10803 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10804 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10805 },
10806 /* Corresponding U-plane frame for C-plane */
10807 { &hf_oran_corresponding_uplane_frame,
10808 { "U-plane frame", "oran_fh_cus.uplane-frame",
10809 FT_FRAMENUM, BASE_NONE,
10810 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10811 },
10812 { &hf_oran_corresponding_uplane_frames_total,
10813 { "U-plane frames total", "oran_fh_cus.u-plane-frames-total",
10814 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10815 "Number of corresponding U-plane frames", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10816 },
10817
10818 /* Reassembly */
10819 { &hf_oran_fragment,
10820 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10821 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10822 { &hf_oran_fragments,
10823 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10824 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10825 { &hf_oran_fragment_overlap,
10826 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10827 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10828 { &hf_oran_fragment_overlap_conflict,
10829 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10830 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10831 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10832 { &hf_oran_fragment_multiple_tails,
10833 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10834 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10835 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10836 { &hf_oran_fragment_too_long_fragment,
10837 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10838 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10839 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10840 { &hf_oran_fragment_error,
10841 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10842 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10843 { &hf_oran_fragment_count,
10844 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10845 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10846 { &hf_oran_reassembled_in,
10847 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10848 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10849 { &hf_oran_reassembled_length,
10850 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10851 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10852 { &hf_oran_reassembled_data,
10853 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10854 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10855
10856 { &hf_oran_payload,
10857 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10858 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10859 };
10860
10861 /* Setup protocol subtree array */
10862 static int *ett[] = {
10863 &ett_oran,
10864 &ett_oran_ecpri_pcid,
10865 &ett_oran_ecpri_rtcid,
10866 &ett_oran_ecpri_seqid,
10867 &ett_oran_section_type,
10868 &ett_oran_u_timing,
10869 &ett_oran_u_section,
10870 &ett_oran_u_prb,
10871 &ett_oran_section,
10872 &ett_oran_iq,
10873 &ett_oran_bfw_bundle,
10874 &ett_oran_bfw,
10875 &ett_oran_frequency_range,
10876 &ett_oran_prb_cisamples,
10877 &ett_oran_cisample,
10878 &ett_oran_udcomphdr,
10879 &ett_oran_udcompparam,
10880 &ett_oran_cicomphdr,
10881 &ett_oran_cicompparam,
10882 &ett_oran_bfwcomphdr,
10883 &ett_oran_bfwcompparam,
10884 &ett_oran_ext19_port,
10885 &ett_oran_prb_allocation,
10886 &ett_oran_punc_pattern,
10887 &ett_oran_bfacomphdr,
10888 &ett_oran_modcomp_param_set,
10889 &ett_oran_st4_cmd_header,
10890 &ett_oran_st4_cmd,
10891 &ett_oran_sym_prb_pattern,
10892 &ett_oran_measurement_report,
10893 &ett_oran_measurement_command,
10894 &ett_oran_sresmask,
10895 &ett_oran_c_section_common,
10896 &ett_oran_c_section,
10897 &ett_oran_remask,
10898 &ett_oran_mc_scale_remask,
10899 &ett_oran_symbol_reordering_layer,
10900 &ett_oran_dmrs_entry,
10901 &ett_oran_dmrs_symbol_mask,
10902 &ett_oran_symbol_mask,
10903 &ett_oran_active_beamspace_coefficient_mask,
10904 &ett_oran_sinr_prb,
10905
10906 &ett_oran_fragment,
10907 &ett_oran_fragments
10908 };
10909
10910 /* Separate subtree array for extensions. Used with [ext-1] */
10911 static int *ext_ett[HIGHEST_EXTTYPE32];
10912 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10913 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10914 }
10915
10916 expert_module_t* expert_oran;
10917
10918 static ei_register_info ei[] = {
10919 { &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)}}
}},
10920 { &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)}}
}},
10921 { &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)}}
}},
10922 { &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)}}
}},
10923 { &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)}}
}},
10924 { &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)}}
}},
10925 { &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)}}
}},
10926 { &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)}}
}},
10927 { &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)}}
}},
10928 { &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)}}
}},
10929 { &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)}}
}},
10930 { &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)}}
}},
10931 { &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)}}
}},
10932 { &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)}}
}},
10933 { &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)}}
}},
10934 { &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)}}
}},
10935 { &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)}}
}},
10936 { &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)}}
}},
10937 { &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)}}
}},
10938 { &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)}}
}},
10939 { &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)}}
}},
10940 { &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)}}
}},
10941 { &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)}}
}},
10942 { &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)}}
}},
10943 { &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)}}
}},
10944 { &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)}}
}},
10945 { &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)}}
}},
10946 { &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)}}
}},
10947 { &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)}}
}},
10948 { &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)}}
}},
10949 { &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)}}
}},
10950 { &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)}}
}},
10951 { &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)}}
}},
10952 { &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)}}
}},
10953 { &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)}}
}},
10954 { &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)}}
}},
10955 { &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)}}
}},
10956 { &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)}}
}},
10957 { &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)}}
}},
10958 { &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)}}
}},
10959 { &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)}}
}},
10960 { &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)}}
}},
10961 { &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)}}
}},
10962 { &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)}}
}},
10963 { &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)}}
}},
10964 { &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)}}
}},
10965 { &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)}}
}},
10966 { &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)}}
}},
10967 { &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)}}
}},
10968 { &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)}}
}},
10969 { &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)}}
}},
10970 { &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)}}
}},
10971 { &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)}}
}},
10972 { &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)}}
}},
10973 { &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)}}
}},
10974 { &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)}}
}},
10975 { &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)}}
}},
10976 { &ei_oran_se12_rb_set, { "oran_fh_cus.se12_rb_set", PI_MALFORMED0x07000000, PI_WARN0x00600000, "rb should not be set when SE12 is present", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}}
10977 };
10978
10979
10980 /* Register the protocol name and description */
10981 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10982
10983 /* Allow dissector to find be found by name. */
10984 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10985
10986 /* Register the tap name. */
10987 oran_tap = register_tap("oran-fh-cus");
10988
10989 /* Required function calls to register the header fields and subtrees */
10990 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10991 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10992 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10993
10994 expert_oran = expert_register_protocol(proto_oran);
10995 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10996
10997
10998 /* Preferences */
10999 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
11000
11001 /* Register bit width/compression preferences separately by direction. */
11002 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
11003 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
11004 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
11005 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
11006 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
11007 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
11008 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
11009 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
11010
11011 /* Uplink userplane */
11012 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
11013 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
11014 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
11015 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
11016 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
11017 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
11018 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
11019 "configuration of the O-RU. This preference instructs the dissector to expect "
11020 "this field to be present in uplink messages",
11021 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
11022 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
11023 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
11024 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
11025 "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",
11026 10, &us_allowed_for_ul_in_symbol);
11027
11028 /* Downlink userplane */
11029 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
11030 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
11031 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
11032 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
11033 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
11034 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
11035 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
11036 "configuration of the O-RU. This preference instructs the dissector to expect "
11037 "this field to be present in downlink messages",
11038 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
11039
11040 /* SINR */
11041 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
11042 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
11043 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
11044 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
11045 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
11046
11047 /* BF-related */
11048 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
11049 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
11050 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
11051 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
11052 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
11053 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
11054 "Default is 1-byte alignment", &st6_4byte_alignment);
11055
11056 /* Misc (and will seldom need to be accessed) */
11057 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
11058 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
11059 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
11060 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
11061 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
11062 &pref_support_udcompLen, udcomplen_support_options, false0);
11063 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
11064 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
11065 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
11066 "", &show_unscaled_values);
11067 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
11068 "Attempt Radio Transport layer reassembly", "",
11069 &do_radio_transport_layer_reassembly);
11070 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
11071
11072 prefs_register_bool_preference(oran_module, "oran.link_planes",
11073 "Link C-plane and U-plane using sectionId", "",
11074 &link_planes_together);
11075
11076
11077 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11078 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11079 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11080
11081 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11082 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11083
11084 register_init_routine(&oran_init_protocol);
11085
11086 /* Register reassembly table. */
11087 reassembly_table_register(&oran_reassembly_table,
11088 &oran_reassembly_table_functions);
11089}
11090
11091/*
11092* Editor modelines - http://www.wireshark.org/tools/modelines.html
11093*
11094* Local Variables:
11095* c-basic-offset: 4
11096* tab-width: 8
11097* indent-tabs-mode: nil
11098* End:
11099*
11100* ex: set shiftwidth=4 tabstop=8 expandtab:
11101* :indentSize=4:tabSize=8:noTabs=true:
11102*/