Bug Summary

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

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-06-23-100357-3596-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-oran.c
1/* packet-oran.c
2 * Routines for O-RAN fronthaul UC-plane dissection
3 * Copyright 2020, Jan Schiefer, Keysight Technologies, Inc.
4 * Copyright 2020- Martin Mathieson
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <[email protected]>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /*
14 * Dissector for the O-RAN Fronthaul CUS protocol specification.
15 * See https://specifications.o-ran.org/specifications, WG4, Fronthaul Interfaces Workgroup
16 * The current implementation is based on the ORAN-WG4.CUS.0-v20.00 specification.
17 * Note that other eCPRI message types are handled in packet-ecpri.c
18 */
19
20#include <config.h>
21
22#include <math.h>
23
24#include <epan/packet.h>
25#include <epan/expert.h>
26#include <epan/prefs.h>
27#include <epan/tap.h>
28#include <epan/tfs.h>
29#include <epan/reassemble.h>
30
31#include <wsutil/ws_roundup.h>
32#include <wsutil/ws_padding_to.h>
33
34#include "epan/dissectors/packet-oran.h"
35
36/* N.B. dissector preferences are taking the place of (some) M-plane parameters, so unfortunately it can be
37 * fiddly to get the preferences into a good state to decode a given capture..
38 * TODO:
39 * - for U-Plane, track back to last C-Plane frame for that eAxC
40 * doing, but this matching can be tricky see 7.8.1 Coupling of C-Plane and U-Plane
41 * - Detect/indicate signs of application layer fragmentation?
42 * same eAxC in same symbol (same/different section ID?)
43 * - Not handling M-plane setting for "little endian byte order" as applied to IQ samples and beam weights
44 * does anyone use this?
45 * - for section extensions, check more constraints (which other extension types 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 * - attempt to show (at least when section Ids are used) which beamId is associated with each DL U-Plane section
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_block_offset;
402static int hf_oran_prb_block_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
508
509/* Computed fields */
510static int hf_oran_c_eAxC_ID;
511static int hf_oran_refa;
512
513static int hf_oran_bfws_frame_defined;
514static int hf_oran_bfws_symbols_since_defined;
515
516static int hf_oran_corresponding_cplane_frame;
517static int hf_oran_corresponding_cplane_frame_time_delta;
518
519
520/* Convenient fields for filtering, mostly shown as hidden */
521static int hf_oran_cplane;
522static int hf_oran_uplane;
523static int hf_oran_bf; /* to match frames that configure beamforming in any way */
524static int hf_oran_zero_prb;
525static int hf_oran_nonzero_prb;
526static int hf_oran_bundle_weights_all_zero;
527
528static int hf_oran_ul_cplane_ud_comp_hdr_frame;
529
530/* For reassembly */
531static int hf_oran_fragments;
532static int hf_oran_fragment;
533static int hf_oran_fragment_overlap;
534static int hf_oran_fragment_overlap_conflict;
535static int hf_oran_fragment_multiple_tails;
536static int hf_oran_fragment_too_long_fragment;
537static int hf_oran_fragment_error;
538static int hf_oran_fragment_count;
539static int hf_oran_reassembled_in;
540static int hf_oran_reassembled_length;
541static int hf_oran_reassembled_data;
542
543static int hf_oran_payload;
544
545
546/* Subtrees */
547static int ett_oran;
548static int ett_oran_ecpri_rtcid;
549static int ett_oran_ecpri_pcid;
550static int ett_oran_ecpri_seqid;
551static int ett_oran_section;
552static int ett_oran_section_type;
553static int ett_oran_u_timing;
554static int ett_oran_u_section;
555static int ett_oran_u_prb;
556static int ett_oran_iq;
557static int ett_oran_bfw_bundle;
558static int ett_oran_bfw;
559static int ett_oran_frequency_range;
560static int ett_oran_prb_cisamples;
561static int ett_oran_cisample;
562static int ett_oran_udcomphdr;
563static int ett_oran_udcompparam;
564static int ett_oran_cicomphdr;
565static int ett_oran_cicompparam;
566static int ett_oran_bfwcomphdr;
567static int ett_oran_bfwcompparam;
568static int ett_oran_ext19_port;
569static int ett_oran_prb_allocation;
570static int ett_oran_punc_pattern;
571static int ett_oran_bfacomphdr;
572static int ett_oran_modcomp_param_set;
573static int ett_oran_st4_cmd_header;
574static int ett_oran_st4_cmd;
575static int ett_oran_sym_prb_pattern;
576static int ett_oran_measurement_report;
577static int ett_oran_measurement_command;
578static int ett_oran_sresmask;
579static int ett_oran_c_section_common;
580static int ett_oran_c_section;
581static int ett_oran_remask;
582static int ett_oran_mc_scale_remask;
583static int ett_oran_symbol_reordering_layer;
584static int ett_oran_dmrs_entry;
585static int ett_oran_dmrs_symbol_mask;
586static int ett_oran_symbol_mask;
587static int ett_oran_active_beamspace_coefficient_mask;
588static int ett_oran_sinr_prb;
589
590static int ett_oran_fragment;
591static int ett_oran_fragments;
592
593/* Reassembly table. */
594static reassembly_table oran_reassembly_table;
595
596static void *oran_key(const packet_info *pinfo _U___attribute__((unused)), const uint32_t id _U___attribute__((unused)), const void *data)
597{
598 return (void *)data;
599}
600
601static void oran_free_key(void *ptr _U___attribute__((unused)))
602{
603}
604
605static reassembly_table_functions oran_reassembly_table_functions =
606{
607 g_direct_hash,
608 g_direct_equal,
609 oran_key,
610 oran_key,
611 oran_free_key,
612 oran_free_key
613};
614
615static const fragment_items oran_frag_items = {
616 &ett_oran_fragment,
617 &ett_oran_fragments,
618 &hf_oran_fragments,
619 &hf_oran_fragment,
620 &hf_oran_fragment_overlap,
621 &hf_oran_fragment_overlap_conflict,
622 &hf_oran_fragment_multiple_tails,
623 &hf_oran_fragment_too_long_fragment,
624 &hf_oran_fragment_error,
625 &hf_oran_fragment_count,
626 &hf_oran_reassembled_in,
627 &hf_oran_reassembled_length,
628 &hf_oran_reassembled_data,
629 "O-RAN FH CUS fragments"
630};
631
632
633
634/* Don't want all extensions to open and close together. Use [extType-1] entry */
635static int ett_oran_c_section_extension[HIGHEST_EXTTYPE30];
636
637/* Expert info */
638static expert_field ei_oran_unsupported_bfw_compression_method;
639static expert_field ei_oran_invalid_sample_bit_width;
640static expert_field ei_oran_reserved_numBundPrb;
641static expert_field ei_oran_extlen_wrong;
642static expert_field ei_oran_invalid_eaxc_bit_width;
643static expert_field ei_oran_extlen_zero;
644static expert_field ei_oran_rbg_size_reserved;
645static expert_field ei_oran_frame_length;
646static expert_field ei_oran_numprbc_ext21_zero;
647static expert_field ei_oran_ci_prb_group_size_reserved;
648static expert_field ei_oran_st8_nackid;
649static expert_field ei_oran_st4_no_cmds;
650static expert_field ei_oran_st4_zero_len_cmd;
651static expert_field ei_oran_st4_wrong_len_cmd;
652static expert_field ei_oran_st4_unknown_cmd;
653static expert_field ei_oran_mcot_out_of_range;
654static expert_field ei_oran_se10_unknown_beamgrouptype;
655static expert_field ei_oran_se10_not_allowed;
656static expert_field ei_oran_start_symbol_id_not_zero;
657static expert_field ei_oran_trx_control_cmd_scope;
658static expert_field ei_oran_unhandled_se;
659static expert_field ei_oran_bad_symbolmask;
660static expert_field ei_oran_numslots_not_zero;
661static expert_field ei_oran_version_unsupported;
662static expert_field ei_oran_laa_msg_type_unsupported;
663static expert_field ei_oran_se_on_unsupported_st;
664static expert_field ei_oran_cplane_unexpected_sequence_number_ul;
665static expert_field ei_oran_cplane_unexpected_sequence_number_dl;
666static expert_field ei_oran_uplane_unexpected_sequence_number_ul;
667static expert_field ei_oran_uplane_unexpected_sequence_number_dl;
668static expert_field ei_oran_acknack_no_request;
669static expert_field ei_oran_udpcomphdr_should_be_zero;
670static expert_field ei_oran_radio_fragmentation_c_plane;
671static expert_field ei_oran_lastRbdid_out_of_range;
672static expert_field ei_oran_rbgMask_beyond_last_rbdid;
673static expert_field ei_oran_unexpected_measTypeId;
674static expert_field ei_oran_unsupported_compression_method;
675static expert_field ei_oran_ud_comp_len_wrong_size;
676static expert_field ei_oran_sresmask2_not_zero_with_rb;
677static expert_field ei_oran_st6_rb_shall_be_0;
678static expert_field ei_oran_st9_not_ul;
679static expert_field ei_oran_st10_numsymbol_not_14;
680static expert_field ei_oran_st10_startsymbolid_not_0;
681static expert_field ei_oran_st10_not_ul;
682static expert_field ei_oran_se24_nothing_to_inherit;
683static expert_field ei_oran_num_sinr_per_prb_unknown;
684static expert_field ei_oran_start_symbol_id_bits_ignored;
685static expert_field ei_oran_user_group_id_reserved_value;
686static expert_field ei_oran_port_list_index_zero;
687static expert_field ei_oran_ul_uplane_symbol_too_long;
688static expert_field ei_oran_reserved_not_zero;
689static expert_field ei_oran_too_many_symbols;
690static expert_field ei_oran_se30_not_ul;
691static expert_field ei_oran_se30_unknown_ueid;
692static expert_field ei_oran_beamid_bfws_not_found;
693static expert_field ei_oran_syminc_set_for_uplane;
694
695
696
697/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
698#define ECPRI_MT_IQ_DATA0 0
699#define ECPRI_MT_RT_CTRL_DATA2 2
700
701
702/* Preference settings - try to set reasonable defaults */
703static unsigned pref_du_port_id_bits = 4;
704static unsigned pref_bandsector_id_bits = 4;
705static unsigned pref_cc_id_bits = 4;
706static unsigned pref_ru_port_id_bits = 4;
707
708/* TODO: ideally should be per-flow */
709static unsigned pref_sample_bit_width_uplink = 14;
710static unsigned pref_sample_bit_width_downlink = 14;
711static unsigned pref_sample_bit_width_sinr = 14;
712
713/* TODO: these ideally should be per-flow too */
714static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
715static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
716
717static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
718
719
720/* Is udCompHeader present (both directions) */
721static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
722static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
723
724/* Are we ignoring UL C-Plane udCompHdr? */
725static bool_Bool pref_override_ul_compression = false0;
726
727static unsigned pref_data_plane_section_total_rbs = 273;
728static unsigned pref_num_bf_antennas = 32;
729static bool_Bool pref_showIQSampleValues = true1;
730
731/* Based upon m-plane param, so will be system-wide */
732static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
733static bool_Bool udcomplen_heuristic_result_set = false0;
734static bool_Bool udcomplen_heuristic_result = false0;
735
736/* st6-4byte-alignment-required */
737static bool_Bool st6_4byte_alignment = false0;
738
739/* Requested, allows I/Q to be stored as integers.. */
740static bool_Bool show_unscaled_values = false0;
741
742/* Initialized off. Timing is in microseconds. */
743static unsigned us_allowed_for_ul_in_symbol = 0;
744
745/* Reassemble U-Plane (at Radio Transport layer) */
746static bool_Bool do_radio_transport_layer_reassembly = true1;
747
748/* Link U-plane back to C-plane using sectionIds */
749static bool_Bool link_planes_together = true1;
750
751static const enum_val_t dl_compression_options[] = {
752 { "COMP_NONE", "No Compression", COMP_NONE0 },
753 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
754 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
755 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
756 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
757 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
758 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
759 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
760 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
761 { NULL((void*)0), NULL((void*)0), 0 }
762};
763
764/* No Modulation compression in UL.. */
765static const enum_val_t ul_compression_options[] = {
766 { "COMP_NONE", "No Compression", COMP_NONE0 },
767 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
768 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
769 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
770 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
771 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
772 { NULL((void*)0), NULL((void*)0), 0 }
773};
774
775static const enum_val_t udcomplen_support_options[] = {
776 { "NOT_SUPPORTED", "Not Supported", 0 },
777 { "SUPPORTED", "Supported", 1 },
778 { "HEURISTIC", "Attempt Heuristic", 2 },
779 { NULL((void*)0), NULL((void*)0), 0 }
780};
781
782static const enum_val_t udcomphdr_present_options[] = {
783 { "NOT_PRESENT", "Not Present", 0 },
784 { "PRESENT", "Present", 1 },
785 { "HEURISTIC", "Attempt Heuristic", 2 },
786 { NULL((void*)0), NULL((void*)0), 0 }
787};
788
789
790
791static const value_string e_bit[] = {
792 { 0, "More fragments follow" },
793 { 1, "Last fragment" },
794 { 0, NULL((void*)0)}
795};
796
797#define DIR_UPLINK0 0
798#define DIR_DOWNLINK1 1
799
800
801static const value_string data_direction_vals[] = {
802 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
803 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
804 { 0, NULL((void*)0)}
805};
806
807static const value_string rb_vals[] = {
808 { 0, "Every RB used" },
809 { 1, "Every other RB used" },
810 { 0, NULL((void*)0)}
811};
812
813static const value_string sym_inc_vals[] = {
814 { 0, "Use the current symbol number" },
815 { 1, "Increment the current symbol number" },
816 { 0, NULL((void*)0)}
817};
818
819static const value_string lbtMode_vals[] = {
820 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
821 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
822 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
823 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
824 { 0, NULL((void*)0)}
825};
826
827static const range_string filter_indices[] = {
828 {0, 0, "standard channel filter"},
829 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
830 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
831 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
832 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
833 {5, 5, "UL filter for PRACH preamble formats"},
834 {8, 8, "UL filter NPUSCH"},
835 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
836 {9, 15, "Reserved"},
837 {0, 0, NULL((void*)0)}
838};
839
840/* 7.3.1-1 */
841static const range_string section_types[] = {
842 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
843 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
844 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
845 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
846 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
847 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
848 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
849 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
850 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
851 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
852 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
853 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
854 { 12, 255, "Reserved for future use" },
855 { 0, 0, NULL((void*)0)} };
856
857static const range_string section_types_short[] = {
858 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
859 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
860 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
861 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
862 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
863 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
864 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
865 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
866 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
867 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
868 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
869 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
870 { 12, 255, "Reserved for future use" },
871 { 0, 0, NULL((void*)0) }
872};
873
874static const range_string ud_comp_header_width[] = {
875 {0, 0, "I and Q are each 16 bits wide"},
876 {1, 15, "Bit width of I and Q"},
877 {0, 0, NULL((void*)0)} };
878
879/* Table 8.3.3.13-3 */
880static const range_string ud_comp_header_meth[] = {
881 {COMP_NONE0, COMP_NONE0, "No compression" },
882 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
883 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
884 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
885 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
886 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
887 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
888 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
889 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
890 {9, 15, "Reserved"},
891 {0, 0, NULL((void*)0)}
892};
893
894/* Table 7.5.2.13-2 */
895static const range_string frame_structure_fft[] = {
896 {0, 0, "Reserved (no FFT/iFFT processing)"},
897 {1, 3, "Reserved"},
898 {4, 4, "FFT size 16"},
899 {5, 5, "FFT size 32"},
900 {6, 6, "FFT size 64"},
901 {7, 7, "FFT size 128"},
902 {8, 8, "FFT size 256"},
903 {9, 9, "FFT size 512"},
904 {10, 10, "FFT size 1024"},
905 {11, 11, "FFT size 2048"},
906 {12, 12, "FFT size 4096"},
907 {13, 13, "FFT size 1536"},
908 {14, 14, "FFT size 3072"},
909 {15, 15, "Reserved"},
910 {0, 0, NULL((void*)0)}
911};
912
913/* Table 7.5.2.13-3 */
914static const range_string subcarrier_spacings[] = {
915 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
916 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
917 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
918 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
919 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
920 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
921 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
922 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
923 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
924 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
925 { 0, 0, NULL((void*)0) }
926};
927
928/* Table 7.5.3.14-1 laaMsgType definition */
929static const range_string laaMsgTypes[] = {
930 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
931 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
932 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
933 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
934 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
935 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
936 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
937 {7, 15, "reserved for future methods"},
938 {0, 0, NULL((void*)0)}
939};
940
941/* 7.7.26.3 */
942static const range_string freq_offset_fb_values[] = {
943 {0, 0, "no frequency offset"},
944 {8000, 8000, "value not provided"},
945 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
946 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
947 {0x0, 0xffff, "reserved"},
948 {0, 0, NULL((void*)0)}
949};
950
951/* Table 7.5.2.19-1 */
952static const value_string num_sinr_per_prb_vals[] = {
953 { 0, "1" },
954 { 1, "2" },
955 { 2, "3" },
956 { 3, "4" },
957 { 4, "6" },
958 { 5, "12" },
959 { 6, "1 SINR value per section for DFT-s-OFDM" },
960 { 7, "reserved" },
961 { 0, NULL((void*)0)}
962};
963
964static const value_string meas_type_id_vals[] = {
965 { 1, "UE Timing Advance Error" },
966 { 2, "UE Layer power" },
967 { 3, "UE frequency offset" },
968 { 4, "Interference plus Noise for allocated PRBs" },
969 { 5, "Interference plus Noise for unallocated PRBs" },
970 { 6, "DMRS-SNR per antenna" },
971 { 7, "UE positioning measurement report" },
972 { 8, "UE radial speed measurement report" },
973 { 0, NULL((void*)0)}
974};
975
976static const value_string beam_type_vals[] = {
977 { 0, "List of beamId values" },
978 { 1, "Range of beamId values" },
979 { 0, NULL((void*)0)}
980};
981
982/* 7.7.24.3 */
983static const value_string entry_type_vals[] = {
984 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
985 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
986 { 2, "related parameters if have transform precoding disabled " },
987 { 3, "related parameters if have transform precoding enabled " },
988 { 0, NULL((void*)0)}
989};
990
991/* Table 7.7.29.3-1 */
992static const range_string cd_scg_size_vals[] = {
993 { 0, 0, "1 subcarrier" },
994 { 1, 1, "1 RB x N subcarriers" },
995 { 2, 2, "2 RB x N subcarriers" },
996 { 3, 3, "4 RB x N subcarriers" },
997 { 4, 4, "8 RB x N subcarriers" },
998 { 5, 5, "16 RB x N subcarriers" },
999 { 6, 6, "32 RB x N subcarriers" },
1000 { 7, 15, "reserved"},
1001 { 0, 0, NULL((void*)0)}
1002};
1003
1004
1005/* Table 7.6.1-1 */
1006static const value_string exttype_vals[] = {
1007 {0, "Reserved"},
1008 {1, "Beamforming weights"},
1009 {2, "Beamforming attributes"},
1010 {3, "DL Precoding configuration parameters and indications"},
1011 {4, "Modulation compr. params"},
1012 {5, "Modulation compression additional scaling parameters"},
1013 {6, "Non-contiguous PRB allocation"},
1014 {7, "Multiple-eAxC designation"},
1015 {8, "Regularization factor"},
1016 {9, "Dynamic Spectrum Sharing parameters"},
1017 {10, "Multiple ports grouping"},
1018 {11, "Flexible BF weights"},
1019 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1020 {13, "PRB Allocation with Frequency Hopping"},
1021 {14, "Nulling-layer Info. for ueId-based beamforming"},
1022 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1023 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1024 {17, "Section description for indication of user port group"},
1025 {18, "Section description for Uplink Transmission Management"},
1026 {19, "Compact beamforming information for multiple port"},
1027 {20, "Puncturing extension"},
1028 {21, "Variable PRB group size for channel information"},
1029 {22, "ACK/NACK request"},
1030 {23, "Multiple symbol modulation compression parameters"},
1031 {24, "PUSCH DMRS configuration"},
1032 {25, "Symbol reordering for DMRS-BF"},
1033 {26, "Frequency offset feedback"},
1034 {27, "O-DU controlled dimensionality reduction"},
1035 {28, "O-DU controlled frequency resolution for SINR reporting"},
1036 {29, "Cyclic delay adjustment"},
1037 {30, "PUSCH repetition indication"},
1038 {0, NULL((void*)0)}
1039};
1040static 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) }
;
1041
1042
1043/**************************************************************************************/
1044/* Keep track for each Section Extension, which section types are allowed to carry it */
1045typedef struct {
1046 bool_Bool ST0;
1047 bool_Bool ST1;
1048 bool_Bool ST3;
1049 bool_Bool ST5;
1050 bool_Bool ST6;
1051 bool_Bool ST10;
1052 bool_Bool ST11;
1053} AllowedCTs_t;
1054
1055
1056static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE30] = {
1057 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1058 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1059 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1060 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1061 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1062 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1063 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1064 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1065 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1066 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1067 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1068 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1069 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1070 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1071 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1072 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1073 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1074 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1075 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1076 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1077 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1078 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1079 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1080 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1081 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1082 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1083 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1084 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1085 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1086 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1087 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1088};
1089
1090static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1091{
1092 if (se==0 || se>HIGHEST_EXTTYPE30) {
1093 /* Don't know about new SE, so don't complain.. */
1094 return true1;
1095 }
1096
1097 switch (st) {
1098 case 0:
1099 return ext_cts[se-1].ST0;
1100 case 1:
1101 return ext_cts[se-1].ST1;
1102 case 3:
1103 return ext_cts[se-1].ST3;
1104 case 5:
1105 return ext_cts[se-1].ST5;
1106 case 6:
1107 return ext_cts[se-1].ST6;
1108 case 10:
1109 return ext_cts[se-1].ST10;
1110 case 11:
1111 return ext_cts[se-1].ST11;
1112 default:
1113 /* New/unknown section type that includes 'ef'.. assume ok */
1114 return true1;
1115 }
1116}
1117
1118/************************************************************************************/
1119
1120/* Table 7.7.1.2-2 */
1121static const value_string bfw_comp_headers_iq_width[] = {
1122 {0, "I and Q are 16 bits wide"},
1123 {1, "I and Q are 1 bit wide"},
1124 {2, "I and Q are 2 bits wide"},
1125 {3, "I and Q are 3 bits wide"},
1126 {4, "I and Q are 4 bits wide"},
1127 {5, "I and Q are 5 bits wide"},
1128 {6, "I and Q are 6 bits wide"},
1129 {7, "I and Q are 7 bits wide"},
1130 {8, "I and Q are 8 bits wide"},
1131 {9, "I and Q are 9 bits wide"},
1132 {10, "I and Q are 10 bits wide"},
1133 {11, "I and Q are 11 bits wide"},
1134 {12, "I and Q are 12 bits wide"},
1135 {13, "I and Q are 13 bits wide"},
1136 {14, "I and Q are 14 bits wide"},
1137 {15, "I and Q are 15 bits wide"},
1138 {0, NULL((void*)0)}
1139};
1140
1141/* Table 7.7.1.2-3 */
1142static const value_string bfw_comp_headers_comp_meth[] = {
1143 {COMP_NONE0, "no compression"},
1144 {COMP_BLOCK_FP1, "block floating point"},
1145 {COMP_BLOCK_SCALE2, "block scaling"},
1146 {COMP_U_LAW3, "u-law"},
1147 {4, "beamspace compression type I"},
1148 {5, "beamspace compression type II"},
1149 {0, NULL((void*)0)}
1150};
1151
1152/* 7.7.6.2 rbgSize (resource block group size) */
1153static const value_string rbg_size_vals[] = {
1154 {0, "reserved"},
1155 {1, "1"},
1156 {2, "2"},
1157 {3, "3"},
1158 {4, "4"},
1159 {5, "6"},
1160 {6, "8"},
1161 {7, "16"},
1162 {0, NULL((void*)0)}
1163};
1164
1165/* 7.7.6.5 */
1166static const value_string priority_vals[] = {
1167 {0, "0"},
1168 {1, "+1"},
1169 {2, "-2 (reserved, should not be used)"},
1170 {3, "-1"},
1171 {0, NULL((void*)0)}
1172};
1173
1174/* 7.7.10.2 beamGroupType */
1175static const value_string beam_group_type_vals[] = {
1176 {0x0, "common beam"},
1177 {0x1, "beam matrix indication"},
1178 {0x2, "beam vector listing"},
1179 {0x3, "beamId/ueId listing with associated port-list index"},
1180 {0, NULL((void*)0)}
1181};
1182
1183/* 7.7.9.2 technology (interface name) */
1184static const value_string interface_name_vals[] = {
1185 {0x0, "LTE"},
1186 {0x1, "NR"},
1187 {0, NULL((void*)0)}
1188};
1189
1190/* 7.7.18.4 toT (type of transmission) */
1191static const value_string type_of_transmission_vals[] = {
1192 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1193 {0x1, "uniformly distributed over the transmission window"},
1194 {0x2, "Reserved"},
1195 {0x3, "Reserved"},
1196 {0, NULL((void*)0)}
1197};
1198
1199/* 7.7.2.2 (width of bfa parameters) */
1200static const value_string bfa_bw_vals[] = {
1201 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1202 {1, "2-bit bitwidth"},
1203 {2, "3-bit bitwidth"},
1204 {3, "4-bit bitwidth"},
1205 {4, "5-bit bitwidth"},
1206 {5, "6-bit bitwidth"},
1207 {6, "7-bit bitwidth"},
1208 {7, "8-bit bitwidth"},
1209 {0, NULL((void*)0)}
1210};
1211
1212/* 7.7.2.7 & 7.7.2.8 */
1213static const value_string sidelobe_suppression_vals[] = {
1214 {0, "10 dB"},
1215 {1, "15 dB"},
1216 {2, "20 dB"},
1217 {3, "25 dB"},
1218 {4, "30 dB"},
1219 {5, "35 dB"},
1220 {6, "40 dB"},
1221 {7, ">= 45 dB"},
1222 {0, NULL((void*)0)}
1223};
1224
1225static const value_string lbtTrafficClass_vals[] = {
1226 {1, "Priority 1"},
1227 {2, "Priority 2"},
1228 {3, "Priority 3"},
1229 {4, "Priority 4"},
1230 {0, NULL((void*)0)}
1231};
1232
1233/* 7.5.3.22 */
1234static const value_string lbtPdschRes_vals[] = {
1235 {0, "not sensing – indicates that the O-RU is transmitting data"},
1236 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1237 {2, "success – indicates that the channel was successfully acquired"},
1238 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1239 {0, NULL((void*)0)}
1240};
1241
1242/* Table 7.5.2.15-3 */
1243static const value_string ci_comp_opt_vals[] = {
1244 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1245 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1246 {0, NULL((void*)0)}
1247};
1248
1249/* 7.5.2.17 */
1250static const range_string cmd_scope_vals[] = {
1251 {0, 0, "ARRAY-COMMAND"},
1252 {1, 1, "CARRIER-COMMAND"},
1253 {2, 2, "O-RU-COMMAND"},
1254 {3, 15, "reserved"},
1255 {0, 0, NULL((void*)0)}
1256};
1257
1258/* N.B., table in 7.5.3.38 is truncated.. */
1259static const range_string st4_cmd_type_vals[] = {
1260 {0, 0, "reserved for future command types"},
1261 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1262 {2, 2, "TDD_CONFIG_PATTERN"},
1263 {3, 3, "TRX_CONTROL"},
1264 {4, 4, "ASM"},
1265 {5, 255, "reserved for future command types"},
1266 {0, 0, NULL((void*)0)}
1267};
1268
1269/* Table 7.5.3.51-1 */
1270static const value_string log2maskbits_vals[] = {
1271 {0, "reserved"},
1272 {1, "min antMask size is 16 bits.."},
1273 {2, "min antMask size is 16 bits.."},
1274 {3, "min antMask size is 16 bits.."},
1275 {4, "16 bits"},
1276 {5, "32 bits"},
1277 {6, "64 bits"},
1278 {7, "128 bits"},
1279 {8, "256 bits"},
1280 {9, "512 bits"},
1281 {10, "1024 bits"},
1282 {11, "2048 bits"},
1283 {12, "4096 bits"},
1284 {13, "8192 bits"},
1285 {14, "16384 bits"},
1286 {15, "reserved"},
1287 {0, NULL((void*)0)}
1288};
1289
1290/* Table 16.1-1 Sleep modes */
1291static const value_string sleep_mode_trx_vals[] = {
1292 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1293 { 1, "TRXC-mode1-wake-up-duration (L)"},
1294 { 2, "TRXC-mode2-wake-up-duration (M)"},
1295 { 3, "TRXC-mode3-wake-up-duration (N)"},
1296 { 0, NULL((void*)0)}
1297};
1298
1299static const value_string sleep_mode_asm_vals[] = {
1300 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1301 { 1, "ASM-mode1-wake-up-duration (L)"},
1302 { 2, "ASM-mode2-wake-up-duration (M)"},
1303 { 3, "ASM-mode3-wake-up-duration (N)"},
1304 { 0, NULL((void*)0)}
1305};
1306
1307/* 7.7.21.3.1 */
1308static const value_string prg_size_st5_vals[] = {
1309 { 0, "reserved"},
1310 { 1, "Precoding resource block group size as WIDEBAND"},
1311 { 2, "Precoding resource block group size 2"},
1312 { 3, "Precoding resource block group size 4"},
1313 { 0, NULL((void*)0)}
1314};
1315
1316/* 7.7.21.3.2 */
1317static const value_string prg_size_st6_vals[] = {
1318 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1319 { 1, "Precoding resource block group size as WIDEBAND"},
1320 { 2, "Precoding resource block group size 2"},
1321 { 3, "Precoding resource block group size 4"},
1322 { 0, NULL((void*)0)}
1323};
1324
1325/* 7.7.24.4 */
1326static const value_string alpn_per_sym_vals[] = {
1327 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1328 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1329 { 0, NULL((void*)0)}
1330};
1331
1332/* 7.7.24.5 */
1333static const value_string ant_dmrs_snr_vals[] = {
1334 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1335 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1336 { 0, NULL((void*)0)}
1337};
1338
1339/* 7.7.24.14 */
1340static const value_string dtype_vals[] = {
1341 { 0, "assume DMRS configuration type 1"},
1342 { 1, "assume DMRS configuration type 2"},
1343 { 0, NULL((void*)0)}
1344};
1345
1346/* 7.7.24.17 */
1347static const value_string papr_type_vals[] = {
1348 { 0, "sequence generator type 1 for short sequence lengths"},
1349 { 1, "sequence generator type 1 for long sequence lengths"},
1350 { 2, "sequence generator type 2 for short sequence lengths"},
1351 { 3, "sequence generator type 2 for long sequence lengths"},
1352 { 0, NULL((void*)0)}
1353};
1354
1355/* 7.7.24.18 */
1356static const value_string hopping_mode_vals[] = {
1357 { 0, "neither group, nor sequence hopping is enabled"},
1358 { 1, "group hopping is enabled and sequence hopping is disabled"},
1359 { 2, "sequence hopping is enabled and group hopping is disabled"},
1360 { 3, "reserved"},
1361 { 0, NULL((void*)0)}
1362};
1363
1364
1365static const true_false_string tfs_sfStatus =
1366{
1367 "subframe was transmitted",
1368 "subframe was dropped"
1369};
1370
1371static const true_false_string tfs_lbtBufErr =
1372{
1373 "buffer overflow – data received at O-RU is larger than the available buffer size",
1374 "reserved"
1375};
1376
1377static const true_false_string tfs_partial_full_sf = {
1378 "partial SF",
1379 "full SF"
1380};
1381
1382static const true_false_string disable_tdbfns_tfs = {
1383 "beam numbers excluded",
1384 "beam numbers included"
1385};
1386
1387static const true_false_string continuity_indication_tfs = {
1388 "continuity between current and next bundle",
1389 "discontinuity between current and next bundle"
1390};
1391
1392static const true_false_string prb_mode_tfs = {
1393 "PRB-BLOCK mode",
1394 "PRB-MASK mode"
1395};
1396
1397static const true_false_string symbol_direction_tfs = {
1398 "DL symbol",
1399 "UL symbol"
1400};
1401
1402static const true_false_string symbol_guard_tfs = {
1403 "guard symbol",
1404 "non-guard symbol"
1405};
1406
1407static const true_false_string beam_numbers_included_tfs = {
1408 "time-domain beam numbers excluded in this command",
1409 "time-domain beam numbers included in this command"
1410};
1411
1412static const true_false_string measurement_flag_tfs = {
1413 "at least one additional measurement report or command after the current one",
1414 "no additional measurement report or command"
1415};
1416
1417static const true_false_string repetition_se6_tfs = {
1418 "repeated highest priority data section in the C-Plane message",
1419 "no repetition"
1420};
1421
1422static const true_false_string repetition_se19_tfs = {
1423 "per port information not present in the extension",
1424 "per port info present in the extension"
1425};
1426
1427static const true_false_string tfs_report_no_report_pos_meas =
1428{
1429 "Report MEAS_UE_POS for UE",
1430 "Do not report UE_POS for UE"
1431};
1432
1433
1434/* Forward declaration */
1435static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1436 unsigned comp_meth,
1437 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1438
1439
1440static const true_false_string ready_tfs = {
1441 "message is a \"ready\" message",
1442 "message is a ACK message"
1443};
1444
1445static const true_false_string multi_sd_scope_tfs = {
1446 "Puncturing pattern applies to current and following sections",
1447 "Puncturing pattern applies to current section"
1448};
1449
1450static const true_false_string tfs_ueid_reset = {
1451 "cannot assume same UE as in preceding slot",
1452 "can assume same UE as in preceding slot"
1453};
1454
1455
1456/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1457typedef struct {
1458 /* Ext 6 config */
1459 bool_Bool ext6_set;
1460 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1461
1462 uint8_t ext6_num_bits_set;
1463 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1464 /* TODO: store an f value for each bit position? */
1465
1466 /* Ext 12 config */
1467 bool_Bool ext12_set;
1468 unsigned ext12_num_pairs;
1469#define MAX_BFW_EXT12_PAIRS128 128
1470 struct {
1471 uint8_t off_start_prb;
1472 uint8_t num_prb;
1473 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1474
1475 /* Ext 13 config */
1476 bool_Bool ext13_set;
1477 unsigned ext13_num_start_prbs;
1478#define MAX_BFW_EXT13_ALLOCATIONS128 128
1479 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1480 /* TODO: store nextSymbolId here too? */
1481
1482 /* Ext 21 config */
1483 bool_Bool ext21_set;
1484 uint8_t ext21_ci_prb_group_size;
1485
1486 /* Results/settings (after calling ext11_work_out_bundles()) */
1487 uint32_t num_bundles;
1488#define MAX_BFW_BUNDLES512 512
1489 struct {
1490 uint32_t start; /* first prb of bundle */
1491 uint32_t end; /* last prb of bundle*/
1492 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1493 } bundles[MAX_BFW_BUNDLES512];
1494} ext11_settings_t;
1495
1496
1497/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1498/* Won't be called with numBundPrb=0 */
1499static void ext11_work_out_bundles(unsigned startPrbc,
1500 unsigned numPrbc,
1501 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1502 ext11_settings_t *settings)
1503{
1504 /* Allocation configured by ext 6 */
1505 if (settings->ext6_set) {
1506 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1507
1508 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1509 rbg size. i.e. each bundle gets the correct number of PRBs until
1510 all rbg entries are consumed... */
1511
1512 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1513
1514 if (bundles_per_entry == 0) {
1515 bundles_per_entry = 1;
1516 }
1517
1518 /* Ext6 behaviour may also be affected by ext 21 */
1519 if (settings->ext21_set) {
1520 /* N.B., have already checked that numPrbc is not 0 */
1521
1522 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1523 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1524
1525 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1526 }
1527
1528 unsigned bundles_set = 0;
1529 bool_Bool reached_orphan = false0;
1530 /* For each bit set in ext6 rbg mask.. */
1531 for (unsigned n=0;
1532 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1533 n++) {
1534
1535 /* Watch out for array bound */
1536 if (n >= 28) {
1537 break;
1538 }
1539
1540 /* For each bundle... */
1541
1542 /* TODO: Work out where first PRB is */
1543 /* May not be the start of an rbg block... */
1544 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1545
1546 /* For each bundle within identified rbgSize block */
1547 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1548
1549 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1550
1551 /* Start already beyond end, so doesn't count. */
1552 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1553 settings->num_bundles = bundles_set;
1554 return;
1555 }
1556
1557 /* Bundle consists of numBundPrb bundles */
1558 /* TODO: may involve PRBs from >1 rbg blocks.. */
1559 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1560 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1561 /* Extends beyond end, so counts but is an orphan bundle */
1562 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1563 settings->bundles[bundles_set].is_orphan = true1;
1564 reached_orphan = true1;
1565 }
1566
1567 /* Get out if have reached array bound */
1568 if (++bundles_set == MAX_BFW_BUNDLES512) {
1569 return;
1570 }
1571 }
1572 }
1573 settings->num_bundles = bundles_set;
1574 }
1575
1576 /* Allocation configured by ext 12 */
1577 else if (settings->ext12_set) {
1578 /* First, allocate normally from startPrbc, numPrbc */
1579 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1580
1581 /* Don't overflow settings->bundles[] ! */
1582 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1583
1584 for (uint32_t n=0; n < settings->num_bundles; n++) {
1585 settings->bundles[n].start = startPrbc + n*numBundPrb;
1586 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1587 /* Does it go beyond the end? */
1588 if (settings->bundles[n].end > startPrbc+numPrbc) {
1589 settings->bundles[n].end = startPrbc+numPrbc;
1590 settings->bundles[n].is_orphan = true1;
1591 }
1592 }
1593 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1594 return;
1595 }
1596
1597 unsigned prb_offset = startPrbc + numPrbc;
1598
1599 /* Loop over pairs, adding bundles for each */
1600 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1601 prb_offset += settings->ext12_pairs[p].off_start_prb;
1602 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1603
1604 for (uint32_t n=0; n < pair_bundles; n++) {
1605 unsigned idx = settings->num_bundles;
1606
1607 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1608 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1609 /* Does it go beyond the end? */
1610 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1611 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1612 settings->bundles[idx].is_orphan = true1;
1613 }
1614 /* Range check / return */
1615 settings->num_bundles++;
1616 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1617 return;
1618 }
1619 }
1620
1621 prb_offset += settings->ext12_pairs[p].num_prb;
1622 }
1623 }
1624
1625 /* Allocation configured by ext 13 */
1626 else if (settings->ext13_set) {
1627 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1628 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1629
1630 /* Don't overflow settings->bundles[] ! */
1631 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1632
1633 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1634 unsigned alloc_start = alloc * alloc_size;
1635 for (uint32_t n=0; n < alloc_size; n++) {
1636 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1637 /* ERROR */
1638 return;
1639 }
1640 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1641 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1642 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1643 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1644 settings->bundles[alloc_start+n].is_orphan = true1;
1645 }
1646 }
1647 }
1648 }
1649
1650 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1651 else {
1652 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1653
1654 /* Don't overflow settings->bundles[] */
1655 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1656
1657 /* For each bundle.. */
1658 for (uint32_t n=0; n < settings->num_bundles; n++) {
1659 /* Allocate start and end */
1660 settings->bundles[n].start = startPrbc + n*numBundPrb;
1661 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1662 /* If would go beyond end of PRBs, limit and identify as orphan */
1663 if (settings->bundles[n].end > startPrbc+numPrbc) {
1664 settings->bundles[n].end = startPrbc+numPrbc;
1665 settings->bundles[n].is_orphan = true1;
1666 }
1667 }
1668 }
1669}
1670
1671
1672/* Modulation Compression configuration */
1673typedef struct {
1674 /* Application of each entry is filtered by RE.
1675 * TODO: should also be filtered by PRB + symbol... */
1676 uint16_t mod_compr_re_mask;
1677
1678 /* Settings to apply */
1679 bool_Bool mod_compr_csf;
1680 float mod_compr_scaler;
1681} mod_compr_config_t;
1682
1683/* Multiple configs with a section */
1684typedef struct {
1685 uint16_t section_id;
1686 uint32_t num_configs;
1687
1688 #define MAX_MOD_COMPR_CONFIGS12 12
1689 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1690} section_mod_compr_config_t;
1691
1692/* Flow has separate configs for each section */
1693typedef struct {
1694 uint16_t num_sections;
1695
1696 /* Separate config for each section */
1697 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1698} mod_compr_params_t;
1699
1700
1701typedef struct {
1702 uint32_t frame_number;
1703 nstime_t frame_time;
1704
1705 /* Timing to match */
1706 uint8_t frame;
1707 uint8_t subframe;
1708 uint8_t slot;
1709 uint8_t startSymbol;
1710
1711 bool_Bool in_use;
1712 uint16_t startPrb;
1713 uint16_t numPrb;
1714 uint16_t numSymbols;
1715 uint16_t beamIds[273];
1716} section_details_t;
1717
1718typedef struct {
1719 uint16_t sectionId;
1720 /* For the same sectionId, can have 2 currently active entries.. */
1721 section_details_t details[2];
1722} expected_section_data_t;
1723
1724typedef struct {
1725
1726 /* Need at least 2 entries with same sectionId.. */
1727 uint8_t num_data_sections;
1728 expected_section_data_t data_sections[MAX_SECTION_IDs32];
1729} expected_dl_data_t;
1730
1731
1732/*******************************************************/
1733/* Overall state of a flow (eAxC/plane) */
1734typedef struct {
1735 /* State for sequence analysis [each direction] */
1736 bool_Bool last_frame_seen[2];
1737 uint32_t last_frame[2];
1738 uint8_t next_expected_sequence_number[2];
1739
1740 /* DL expected frames. */
1741 expected_dl_data_t expected_dl_data;
1742
1743 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1744 Note that this assumes that the same ackNackId will not be reused within a state,
1745 which may well not be valid */
1746 wmem_tree_t *ack_nack_requests;
1747
1748 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1749 Note that this appears in the common section header parts of ST1, ST3, ST5,
1750 so can still be over-written per sectionId in the U-Plane */
1751 unsigned ul_ud_comp_hdr_frame;
1752 bool_Bool ul_ud_comp_hdr_set;
1753 unsigned ul_ud_comp_hdr_bit_width;
1754 int ul_ud_comp_hdr_compression;
1755
1756 bool_Bool udcomphdrDownlink_heuristic_result_set;
1757 bool_Bool udcomphdrDownlink_heuristic_result;
1758 bool_Bool udcomphdrUplink_heuristic_result_set;
1759 bool_Bool udcomphdrUplink_heuristic_result;
1760
1761 /* Modulation compression params */
1762 mod_compr_params_t mod_comp_params;
1763} flow_state_t;
1764
1765static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1766 unsigned sectionId)
1767{
1768 if (flow == NULL((void*)0)) {
1769 return NULL((void*)0);
1770 }
1771
1772 /* Look for this section among existing entries */
1773 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1774 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1775 return &flow->mod_comp_params.sections[s];
1776 }
1777 }
1778
1779 /* Not found, so try to add a new one */
1780 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1781 /* Can't allocate one! */
1782 return NULL((void*)0);
1783 }
1784 else {
1785 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1786 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1787 }
1788}
1789
1790static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1791 unsigned sectionId)
1792{
1793 if (flow == NULL((void*)0)) {
1794 return NULL((void*)0);
1795 }
1796
1797 /* Look for this section among existing entries */
1798 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1799 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1800 return &flow->mod_comp_params.sections[s];
1801 }
1802 }
1803
1804 /* Not found */
1805 return NULL((void*)0);
1806}
1807
1808
1809
1810typedef struct {
1811 uint32_t request_frame_number;
1812 nstime_t request_frame_time;
1813 enum {
1814 SE22,
1815 ST4Cmd1,
1816 ST4Cmd2,
1817 ST4Cmd3,
1818 ST4Cmd4
1819 } requestType;
1820
1821 uint32_t response_frame_number;
1822 nstime_t response_frame_time;
1823} ack_nack_request_t;
1824
1825static const value_string acknack_type_vals[] = {
1826 { SE22, "SE 22" },
1827 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1828 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1829 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1830 { ST4Cmd4, "ST4 (ASM)" },
1831 { 0, NULL((void*)0)}
1832};
1833
1834#define ORAN_C_PLANE0 0
1835#define ORAN_U_PLANE1 1
1836
1837/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1838static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1839{
1840 uint16_t eth_bits = 0;
1841 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1842 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1843 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1844 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1845 if (!opposite_dir) {
1846 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1847 }
1848 else {
1849 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1850 }
1851 }
1852 return eaxc_id | (plane << 16) | (eth_bits << 17);
1853}
1854
1855
1856/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1857static wmem_tree_t *flow_states_table;
1858
1859/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1860static wmem_tree_t *flow_results_table;
1861
1862typedef struct {
1863 /* Sequence analysis */
1864 bool_Bool unexpected_seq_number;
1865 uint8_t expected_sequence_number;
1866 uint32_t previous_frame;
1867
1868 expected_dl_data_t expected_dl_data;
1869
1870} flow_result_t;
1871
1872
1873/* Uplink timing */
1874/* For a given symbol, track first to last UL frame to find out first-last time */
1875/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1876/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1877static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1878{
1879 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1880}
1881
1882typedef struct {
1883 uint32_t first_frame;
1884 nstime_t first_frame_time;
1885 uint32_t frames_seen_in_symbol;
1886 uint32_t last_frame_in_symbol;
1887} ul_timing_for_slot;
1888
1889/* Set during first pass. timing_key -> ul_timing_for_slot* */
1890static wmem_tree_t *ul_symbol_timing;
1891
1892
1893/* Tracking lifetimes of DL beamIds */
1894typedef struct {
1895 uint32_t frame_defined;
1896 uint32_t symbol_when_defined;
1897} bfw_definition;
1898
1899/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1900static wmem_tree_t *dl_beam_ids_defined;
1901/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1902static wmem_tree_t *dl_beam_ids_results;
1903
1904
1905static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1906 ack_nack_request_t *response);
1907
1908
1909
1910
1911static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1912 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
1913
1914 /* Write the given formatted text to:
1915 - the info column (if pinfo != NULL)
1916 - 1 or 2 other labels (optional)
1917 */
1918static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1919 packet_info *pinfo, const char *format, ...)
1920{
1921#define MAX_INFO_BUFFER256 256
1922 char info_buffer[MAX_INFO_BUFFER256];
1923 va_list ap;
1924
1925 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
1926 return;
1927 }
1928
1929 va_start(ap, format)__builtin_va_start(ap, format);
1930 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
1931 va_end(ap)__builtin_va_end(ap);
1932
1933 /* Add to indicated places */
1934 if (pinfo != NULL((void*)0)) {
1935 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
1936 }
1937 if (ti1 != NULL((void*)0)) {
1938 proto_item_append_text(ti1, "%s", info_buffer);
1939 }
1940 if (ti2 != NULL((void*)0)) {
1941 proto_item_append_text(ti2, "%s", info_buffer);
1942 }
1943}
1944
1945/* Add section labels (type + PRB range) for C-Plane, U-Plane */
1946static void
1947write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
1948 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
1949{
1950 switch (num_prbx) {
1951 case 0:
1952 /* None -> all */
1953 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
1954 break;
1955 case 1:
1956 /* Single PRB */
1957 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
1958 break;
1959 default:
1960 /* Range */
1961 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
1962 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
1963 }
1964}
1965
1966static void
1967write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
1968 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
1969 uint32_t num_trx)
1970{
1971 switch (num_prbx) {
1972 case 0:
1973 /* TODO: ?? */
1974 break;
1975 case 1:
1976 /* Single PRB */
1977 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
1978 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
1979 section_id, ueId, start_prbx, num_trx);
1980 break;
1981 default:
1982 /* Range */
1983 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
1984 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
1985 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
1986 }
1987}
1988
1989/* Add a reserved field, and warn if value isn't 0 */
1990/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
1991static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
1992{
1993 uint32_t reserved;
1994 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
1995 if (reserved != 0) {
1996 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
1997 "reserved field saw value of 0x%x", reserved);
1998 }
1999}
2000
2001/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2002static void
2003addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2004{
2005 /* Subtree */
2006 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2007 tvb, *offset, 2, ENC_NA0x00000000);
2008 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2009
2010 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2011 int id_offset = *offset;
2012
2013 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2014 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2015 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2016 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2017 *eAxC = 0;
2018 *offset += 2;
2019 return;
2020 }
2021
2022 unsigned bit_offset = *offset * 8;
2023
2024 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2025 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2026
2027 /* DU Port ID */
2028 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);
2029 bit_offset += pref_du_port_id_bits;
2030 /* BandSector ID */
2031 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2032 bit_offset += pref_bandsector_id_bits;
2033 /* CC ID */
2034 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2035 bit_offset += pref_cc_id_bits;
2036 /* RU Port ID */
2037 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);
2038 *offset += 2;
2039
2040 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2041 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2042 char id[16];
2043 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2044 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2045 proto_item_set_generated(pi);
2046
2047 tap_info->eaxc = *eAxC;
2048 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2049 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2050 tap_info->eaxc_cc_id = (uint16_t)ccId;
2051 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2052}
2053
2054/* Uniquely identify the U-plane stream that may need to be reassembled */
2055static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2056 uint8_t frameid, uint8_t subframeid,
2057 uint8_t slotid, uint8_t symbolid)
2058{
2059 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2060 and hope for no collisions */
2061 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2062 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2063}
2064
2065/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2066/* Return out info that may be used for sequence number analysis and reassembly */
2067static int
2068addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2069 uint32_t *subseqid, uint32_t *e)
2070{
2071 /* Subtree */
2072 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2073 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2074
2075 /* Sequence ID (8 bits) */
2076 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2077 offset += 1;
2078
2079 /* Show link back to previous sequence ID, if set */
2080 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2081 if (result) {
2082 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2083 proto_item_set_generated(prev_ti);
2084 }
2085
2086 /* E bit */
2087 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2088 /* Subsequence ID (7 bits) */
2089 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2090 offset += 1;
2091
2092 /* radio-transport fragmentation not allowed for C-Plane messages */
2093 if (plane == ORAN_C_PLANE0) {
2094 if (*e !=1 || *subseqid != 0) {
2095 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2096 }
2097 }
2098
2099 /* Summary */
2100 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2101 return offset;
2102}
2103
2104static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2105{
2106 uint64_t temp_val;
2107
2108 static int * const symbol_mask_flags[] = {
2109 &hf_oran_symbol_mask_s13,
2110 &hf_oran_symbol_mask_s12,
2111 &hf_oran_symbol_mask_s11,
2112 &hf_oran_symbol_mask_s10,
2113 &hf_oran_symbol_mask_s9,
2114 &hf_oran_symbol_mask_s8,
2115 &hf_oran_symbol_mask_s7,
2116 &hf_oran_symbol_mask_s6,
2117 &hf_oran_symbol_mask_s5,
2118 &hf_oran_symbol_mask_s4,
2119 &hf_oran_symbol_mask_s3,
2120 &hf_oran_symbol_mask_s2,
2121 &hf_oran_symbol_mask_s1,
2122 &hf_oran_symbol_mask_s0,
2123 NULL((void*)0)
2124 };
2125
2126 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2127 hf_oran_symbol_mask,
2128 ett_oran_symbol_mask, symbol_mask_flags,
2129 ENC_BIG_ENDIAN0x00000000, &temp_val);
2130 /* Set out parameters */
2131 if (symbol_mask) {
2132 *symbol_mask = (uint32_t)temp_val;
2133 }
2134 if (ti) {
2135 *ti = temp_ti;
2136 }
2137 return offset+2;
2138}
2139
2140/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2141static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2142 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2143{
2144 /* Subtree */
2145 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2146 tvb, offset, 1, "",
2147 "bfwCompHdr");
2148 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2149
2150 /* Width and method */
2151 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2152 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2153 /* Special case: 0 -> 16 */
2154 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2155 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2156 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2157 offset++;
2158
2159 /* Summary */
2160 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2161 *iq_width,
2162 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2163
2164 return offset;
2165}
2166
2167/* Return offset */
2168/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2169 each BFW is actually for.. */
2170static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2171{
2172 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2173 /* K is the number of elements in uncompressed beamforming weight vector.
2174 * Calculated from parameters describing tx-array or tx-array */
2175 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2176
2177 static uint16_t trx_enabled[1024];
2178
2179 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2180 static int * const mask_bits[] = {
2181 &hf_oran_active_beamspace_coefficient_n1,
2182 &hf_oran_active_beamspace_coefficient_n2,
2183 &hf_oran_active_beamspace_coefficient_n3,
2184 &hf_oran_active_beamspace_coefficient_n4,
2185 &hf_oran_active_beamspace_coefficient_n5,
2186 &hf_oran_active_beamspace_coefficient_n6,
2187 &hf_oran_active_beamspace_coefficient_n7,
2188 &hf_oran_active_beamspace_coefficient_n8,
2189 NULL((void*)0)
2190 };
2191
2192 *num_trx_entries = 0;
2193 uint64_t val;
2194 for (unsigned n=0; n < k_octets; n++) {
2195 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2196 hf_oran_activeBeamspaceCoefficientMask,
2197 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2198 ENC_BIG_ENDIAN0x00000000, &val);
2199 offset++;
2200 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2201 for (unsigned b=0; b < 8; b++) {
2202 if ((1 << b) & (unsigned)val) {
2203 if (((n*8)+b) < pref_num_bf_antennas) {
2204 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2205 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2206 }
2207 }
2208 }
2209 }
2210 }
2211 /* Set pointer to static array */
2212 *trx_entries = trx_enabled;
2213
2214 /* Show how many bits set */
2215 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2216 offset-k_octets, k_octets, *num_trx_entries);
2217 proto_item_set_generated(ti);
2218
2219 return offset;
2220}
2221
2222static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2223{
2224 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2225 tap_info->beams[tap_info->num_beams++] = beam_id;
2226 }
2227}
2228
2229
2230/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2231 * Depends upon passed-in bfwCompMeth (field may be empty) */
2232static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2233 proto_item *meth_ti, uint32_t *bfw_comp_method,
2234 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2235{
2236 if (*bfw_comp_method == COMP_NONE0) {
2237 /* Absent! */
2238 *num_trx_entries = 0;
2239 *supported = true1;
2240 return offset;
2241 }
2242
2243 /* Subtree */
2244 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2245 tvb, offset, 1, "",
2246 "bfwCompParam");
2247 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2248
2249 proto_item_append_text(bfwcompparam_ti,
2250 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2251
2252 *num_trx_entries = 0;
2253 *supported = false0;
2254 switch (*bfw_comp_method) {
2255 case COMP_BLOCK_FP1: /* block floating point */
2256 /* 4 reserved bits + exponent */
2257 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2258 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2259 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2260 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2261 *supported = true1;
2262 offset++;
2263 break;
2264 case COMP_BLOCK_SCALE2: /* block scaling */
2265 /* Separate into integer and fractional bits? */
2266 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2267 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2268 offset++;
2269 break;
2270 case COMP_U_LAW3: /* u-law */
2271 /* compBitWidth, compShift */
2272 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2273 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2274 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2275 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2276 offset++;
2277 break;
2278 case 4: /* beamspace I (BLOCK SCALING) */
2279 /* activeBeamspaceCoefficientMask */
2280 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2281 *bfw_comp_method = COMP_BLOCK_SCALE2;
2282 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2283 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2284 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2285 offset++;
2286 break;
2287 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2288 /* activeBeamspaceCoefficientMask */
2289 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2290 /* reserved (4 bits) + exponent (4 bits) */
2291 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2292 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2293 offset += 1;
2294 *bfw_comp_method = COMP_BLOCK_FP1;
2295 *supported = true1;
2296 break;
2297
2298 default:
2299 /* Not handled */
2300 break;
2301 }
2302
2303 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2304
2305 /* Can't go on if compression scheme not supported */
2306 if (!(*supported) && meth_ti) {
2307 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2308 "BFW Compression method %u (%s) not decompressed by dissector",
2309 *bfw_comp_method,
2310 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2311 }
2312 return offset;
2313}
2314
2315
2316/* Special case for uncompressed/16-bit value */
2317static float uncompressed_to_float(uint32_t h)
2318{
2319 int16_t i16 = h & 0x0000ffff;
2320 if (show_unscaled_values) {
2321 return (float)i16;
2322 }
2323 return ((float)i16) / 0x7fff;
2324}
2325
2326/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2327static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2328 uint32_t exponent,
2329 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2330 section_mod_compr_config_t *m_c_p, uint8_t re)
2331{
2332 switch (comp_method) {
2333 case COMP_NONE0: /* no compression */
2334 return uncompressed_to_float(bits);
2335
2336 case COMP_BLOCK_FP1: /* block floating point */
2337 case BFP_AND_SELECTIVE_RE5:
2338 {
2339 /* A.1.3 Block Floating Point Decompression Algorithm */
2340 int32_t cPRB = bits;
2341 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2342
2343 /* Check last bit, in case we need to flip to -ve */
2344 if (cPRB >= (1<<(iq_width-1))) {
2345 cPRB -= (1<<iq_width);
2346 }
2347
2348 /* Unscale (8.1.3.1) */
2349 cPRB *= scaler;
2350 if (show_unscaled_values) {
2351 return (float)cPRB;
2352 }
2353
2354 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2355 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 */
2356
2357 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2358 return ret;
2359 }
2360
2361 case COMP_BLOCK_SCALE2:
2362 case COMP_U_LAW3:
2363 /* Not supported! But will be reported as expert info outside of this function! */
2364 return 0.0;
2365
2366 case COMP_MODULATION4:
2367 case MOD_COMPR_AND_SELECTIVE_RE6:
2368 {
2369 /* Described in A.5 (with pseudo code) */
2370 /* N.B., Applies to downlink data only - is not used for BFW */
2371
2372 /* Defaults if not overridden. TODO: what should these be? */
2373 bool_Bool csf = false0;
2374 float mcScaler = (float)(1 << 11);
2375
2376 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2377 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2378 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2379 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2380 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2381 /* Return first (should be only) found */
2382 csf = m_c_p->configs[c].mod_compr_csf;
2383 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2384 break;
2385 }
2386 }
2387 }
2388
2389 int32_t cPRB = bits;
2390
2391 /* 2) Map iqSample to iqSampleFx */
2392 /* Check last bit, in case we need to flip to -ve */
2393 if (cPRB >= (1<<(iq_width-1))) {
2394 cPRB -= (1<<iq_width);
2395 }
2396 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2397
2398
2399 /* 3) or 4) (b) - add unshifted value if csf set */
2400 float csf_to_add = 0.0;
2401 if (csf) {
2402 /* Unshift the constellation point */
2403 csf_to_add = (float)1.0 / (1 << (iq_width));
2404 }
2405 iqSampleFx += csf_to_add;
2406
2407 /* 3) or 4) (c) - unscaling */
2408 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2409 return iqSampleScaled;
2410 }
2411
2412 default:
2413 /* Not supported! But will be reported as expert info outside of this function! */
2414 return 0.0;
2415 }
2416}
2417
2418/* Out-of-range value used for special case */
2419#define ORPHAN_BUNDLE_NUMBER999 999
2420
2421/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2422static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2423 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2424 section_mod_compr_config_t *mod_compr_params,
2425 uint32_t num_weights_per_bundle,
2426 uint8_t iq_width,
2427 unsigned bundle_number,
2428 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2429 uint32_t symbol_count,
2430 section_details_t *section_details,
2431 oran_tap_info *tap_info)
2432{
2433 /* Set bundle name */
2434 char bundle_name[32];
2435 if (!is_orphan) {
2436 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2437 }
2438 else {
2439 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2440 }
2441
2442 /* Create Bundle root */
2443 proto_item *bundle_ti;
2444 if (first_prb != last_prb) {
2445 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2446 tvb, offset, 0, "",
2447 "%s: (PRBs %3u-%3u)",
2448 bundle_name,
2449 first_prb, last_prb);
2450 }
2451 else {
2452 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2453 tvb, offset, 0, "",
2454 "%s: (PRB %3u)",
2455 bundle_name,
2456 first_prb);
2457 }
2458 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2459
2460 /* Generated bundle id */
2461 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2462 bundle_number);
2463 proto_item_set_generated(bundleid_ti);
2464 proto_item_set_hidden(bundleid_ti);
2465
2466 /* bfwCompParam */
2467 bool_Bool compression_method_supported = false0;
2468 unsigned exponent = 0;
2469 unsigned num_trx_entries = 0;
2470 uint16_t *trx_entries;
2471 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2472 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2473 &num_trx_entries, &trx_entries);
2474
2475 /* Create Bundle subtree */
2476 int bit_offset = offset*8;
2477 int bfw_offset;
2478
2479 /* contInd */
2480 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2481 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2482 /* beamId */
2483 uint32_t beam_id;
2484 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2485 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2486 bit_offset += 16;
2487 add_beam_id_to_tap(tap_info, beam_id);
2488
2489 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2490 if (section_details) {
2491 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2492 if (prb < 273) {
2493 section_details->beamIds[prb] = beam_id;
2494 }
2495 }
2496 }
2497 }
2498
2499 /* On first pass, record that beamId was defined here */
2500 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2501 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2502 definition->frame_defined = pinfo->num;
2503 definition->symbol_when_defined = symbol_count;
2504 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2505 }
2506
2507
2508 /* Number of weights per bundle (from preference) */
2509 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2510 num_weights_per_bundle);
2511 proto_item_set_generated(wpb_ti);
2512
2513 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2514 if (num_trx_entries != 0) {
2515 num_weights_per_bundle = num_trx_entries;
2516 }
2517
2518 bool_Bool non_zero_weights_seen = false0;
2519 int bit_offset_before_weights = bit_offset;
2520 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2521
2522 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2523
2524 /* Create subtree */
2525 bfw_offset = bit_offset / 8;
2526 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2527 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2528 tvb, bfw_offset, bfw_extent,
2529 "", "TRX %3u: (", trx_index);
2530 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2531
2532 /* I */
2533 /* Get bits, and convert to float. */
2534 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2535 if (bits) {
2536 non_zero_weights_seen = true1;
2537 }
2538 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2539 exponent, mod_compr_params, 0 /* RE */);
2540 /* Add to tree. */
2541 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);
2542 bit_offset += iq_width;
2543 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2544
2545 /* Q */
2546 /* Get bits, and convert to float. */
2547 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2548 if (bits) {
2549 non_zero_weights_seen = true1;
2550 }
2551
2552 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2553 exponent, mod_compr_params, 0 /* RE */);
2554 /* Add to tree. */
2555 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);
2556 bit_offset += iq_width;
2557 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2558 }
2559
2560 if (!non_zero_weights_seen) {
2561 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2562 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2563 }
2564
2565 /* Set extent of bundle */
2566 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2567
2568 return (bit_offset+7)/8;
2569}
2570
2571/* Return new bit offset. in/out will always be byte-aligned.. */
2572static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2573 unsigned comp_meth, uint8_t *exponent)
2574{
2575 if (comp_meth == COMP_NONE0) {
2576 /* Nothing in frame so don't even create subtree */
2577 return bit_offset;
2578 }
2579
2580 /* Subtree */
2581 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2582 tvb, bit_offset/8, 1, "",
2583 "ciCompParam");
2584 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2585 uint32_t ci_exponent;
2586
2587 /* Contents differ by compression method */
2588 switch (comp_meth) {
2589 case COMP_BLOCK_FP1:
2590 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2591 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2592 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2593 *exponent = ci_exponent;
2594 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2595 bit_offset += 8; /* one byte */
2596 break;
2597 case COMP_BLOCK_SCALE2:
2598 /* Separate into integer (1) and fractional (7) bits? */
2599 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2600 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2601 bit_offset += 8;
2602 break;
2603 case COMP_U_LAW3:
2604 /* compBitWidth, compShift (4 bits each) */
2605 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2606 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2607 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2608 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2609 bit_offset += 8;
2610 break;
2611
2612 default:
2613 /* reserved, ? bytes of zeros.. */
2614 break;
2615 }
2616
2617 return bit_offset;
2618}
2619
2620/* frameStructure (7.5.2.13) */
2621static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2622 uint32_t subframeId, uint32_t slotId)
2623{
2624 uint32_t scs;
2625 /* FFT Size (4 bits) */
2626 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2627 /* Subcarrier spacing (SCS) */
2628 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2629
2630 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2631 uint32_t slots_per_subframe = 1;
2632 if (scs <= 4) {
2633 slots_per_subframe = 1 << scs;
2634 }
2635 if (scs <= 4 || scs >= 12) {
2636 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2637 (slots_per_subframe*subframeId) + slotId);
2638 proto_item_set_generated(ti);
2639 }
2640 return offset + 1;
2641}
2642
2643static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2644 unsigned iq_width, bool_Bool *p_csf)
2645{
2646 proto_item *csf_ti;
2647 uint64_t csf;
2648 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2649 if (csf) {
2650 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2651 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2652 if (iq_width >=1 && iq_width <= 5) {
2653 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2654 }
2655 }
2656
2657 /* Set out parameter */
2658 if (p_csf != NULL((void*)0)) {
2659 *p_csf = (csf!=0);
2660 }
2661 return bit_offset+1;
2662}
2663
2664
2665/* Section 7.
2666 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2667static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2668 flow_state_t* state,
2669 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2670 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2671 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2672 unsigned num_sinr_per_prb)
2673{
2674 unsigned offset = 0;
2675 proto_tree *c_section_tree = NULL((void*)0);
2676 proto_item *sectionHeading = NULL((void*)0);
2677
2678 /* Section subtree */
2679 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2680 tvb, offset, 0, "", "Section");
2681 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2682
2683 uint32_t sectionId = 0;
2684
2685 uint32_t startPrbc=0, startPrbu=0;
2686 uint32_t numPrbc=0, numPrbu=0;
2687 uint32_t ueId = 0;
2688 proto_item *ueId_ti = NULL((void*)0);
2689 uint32_t section_beamId = 0;
2690 proto_item *section_beamId_ti = NULL((void*)0);
2691 bool_Bool section_beamId_ignored = false0;
2692
2693 proto_item *numsymbol_ti = NULL((void*)0);
2694 bool_Bool numsymbol_ignored = false0;
2695
2696 proto_item *numprbc_ti = NULL((void*)0);
2697
2698 /* Config affecting ext11 bundles (initially unset) */
2699 ext11_settings_t ext11_settings;
2700 memset(&ext11_settings, 0, sizeof(ext11_settings));
2701
2702 /* Section Type 10 needs to keep track of PRB range that should be reported
2703 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2704 /* All PRBs start as false */
2705#define MAX_PRBS273 273
2706 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2707 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2708
2709 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2710#define MAX_UEIDS16 16
2711 uint32_t ueids[MAX_UEIDS16];
2712 uint32_t number_of_ueids = 0;
2713
2714
2715 bool_Bool extension_flag = false0;
2716
2717 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2718 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2719 (sectionType != SEC_C_SLOT_CONTROL)) {
2720
2721 /* sectionID */
2722 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2723 if (sectionId == 4095) {
2724 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2725 }
2726 offset++;
2727
2728 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2729 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2730 }
2731
2732 /* rb */
2733 uint32_t rb;
2734 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2735 /* symInc (1 bit) */
2736 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2737 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2738 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2739 unsigned int sym_inc;
2740 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2741 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2742 /* "0 shall be used" */
2743 proto_item_append_text(sym_inc_ti, " (should be 0)");
2744 }
2745 }
2746 else {
2747 /* reserved (1 bit) */
2748 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2749 }
2750
2751 /* startPrbx and numPrbx */
2752 if (sectionType == SEC_C_SINR_REPORTING) {
2753 /* startPrbu (10 bits) */
2754 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2755 offset += 2;
2756
2757 /* numPrbu */
2758 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2759 if (numPrbu == 0) {
2760 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2761 numPrbu = pref_data_plane_section_total_rbs;
2762 }
2763 offset += 1;
2764 }
2765 else {
2766 /* startPrbc (10 bits) */
2767 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2768 offset += 2;
2769
2770 /* numPrbc */
2771 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2772 if (numPrbc == 0) {
2773 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2774 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2775 numPrbc = MAX_PRBS273;
2776 }
2777 offset += 1;
2778 }
2779
2780 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2781 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2782 if (n < MAX_PRBS273) {
2783 prbs_for_st10_type5[n] = true1;
2784 }
2785 }
2786
2787 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2788 static int * const remask_flags[] = {
2789 &hf_oran_reMask_re1,
2790 &hf_oran_reMask_re2,
2791 &hf_oran_reMask_re3,
2792 &hf_oran_reMask_re4,
2793 &hf_oran_reMask_re5,
2794 &hf_oran_reMask_re6,
2795 &hf_oran_reMask_re7,
2796 &hf_oran_reMask_re8,
2797 &hf_oran_reMask_re9,
2798 &hf_oran_reMask_re10,
2799 &hf_oran_reMask_re11,
2800 &hf_oran_reMask_re12,
2801 NULL((void*)0)
2802 };
2803
2804 /* reMask */
2805 uint64_t remask;
2806 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2807 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2808 offset++;
2809 /* numSymbol */
2810 uint32_t numSymbol;
2811 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2812 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2813 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2814 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2815 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2816 }
2817 if ((startSymbolId + numSymbol) > 14) {
2818 /* Warn if startSymbol + numSymbol would be > 14 */
2819 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2820 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2821 startSymbolId, numSymbol);
2822 }
2823 offset++;
2824
2825 /* [ef] (extension flag) */
2826 switch (sectionType) {
2827 case SEC_C_UNUSED_RB: /* Section Type 0 */
2828 case SEC_C_NORMAL: /* Section Type 1 */
2829 case SEC_C_PRACH: /* Section Type 3 */
2830 case SEC_C_UE_SCHED: /* Section Type 5 */
2831 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2832 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2833 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2834 break;
2835 default:
2836 /* Other section types don't support extensions */
2837 break;
2838 }
2839
2840 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2841 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2842
2843 if (numPrbc == 0) {
2844 /* Special case for all PRBs */
2845 numPrbc = pref_data_plane_section_total_rbs;
2846 startPrbc = 0; /* may already be 0... */
2847 }
2848 }
2849 else {
2850 /* Section Type 9 */
2851 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2852 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2853 }
2854
2855 /* Section type specific fields (after 'numSymbol') */
2856 switch (sectionType) {
2857 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2858 /* reserved (15 bits) */
2859 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2860 offset += 2;
2861 break;
2862
2863 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2864 /* beamId */
2865 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2866 offset += 2;
2867
2868 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2869 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2870 break;
2871
2872 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2873 {
2874 /* beamId */
2875 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2876 offset += 2;
2877
2878 /* freqOffset */
2879 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2880 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);
2881 freqOffset |= 0xff000000; /* Must sign-extend */
2882 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2883 offset += 3;
2884
2885 /* reserved (8 bits) */
2886 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2887 offset += 1;
2888
2889 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2890 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2891 break;
2892 }
2893
2894 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2895 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2896 /* ueId */
2897 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2898 offset += 2;
2899 if (ueId == 0x7fff) {
2900 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2901 }
2902 else {
2903 ueids[number_of_ueids++] = ueId;
2904 }
2905
2906 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
2907 break;
2908
2909 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
2910 {
2911 /* Hidden filter for bf (DMFS-BF) */
2912 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
2913 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
2914
2915 unsigned bit_offset = offset*8;
2916
2917 /* sinr iqWidth */
2918 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
2919 proto_item_append_text(iq_width_item, " (from preferences)");
2920 proto_item_set_generated(iq_width_item);
2921
2922 /* sinr compMethod */
2923 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
2924 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
2925 proto_item_set_generated(sinr_comp_meth_item);
2926
2927 /* Add SINR entries for each PRB */
2928 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
2929 /* Create a subtree for each PRB */
2930 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
2931 tvb, offset, 0, "", "PRB %3u (", prb);
2932 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
2933
2934 /* Each prb starts byte-aligned */
2935 bit_offset = ((bit_offset+7)/8) * 8;
2936
2937 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
2938
2939 /* sinrCompParam (udCompParam format, may be empty) */
2940 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
2941 uint16_t sReSMask;
2942 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
2943 pref_iqCompressionSINR, &exponent, &sReSMask,
2944 true1) * 8; /* last param is for_sinr */
2945
2946 /* sinrValues for this PRB. */
2947 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
2948 for (unsigned n=0; n < num_sinr_per_prb; n++) {
2949 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
2950
2951 /* Using SINR compression settings from preferences */
2952 float value = decompress_value(sinr_bits,
2953 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
2954 exponent,
2955 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
2956 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
2957 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
2958 bit_offset/8, sample_len_in_bytes, value);
2959 proto_item_append_text(prb_ti, " %8f", value);
2960
2961 /* Show here which subcarriers share which values (they all divide 12..) */
2962 if (num_sinr_per_prb == 12) {
2963 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
2964 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
2965 }
2966 else {
2967 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
2968 startPrbu+((prb-startPrbu)*(rb+1)),
2969 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
2970 }
2971 bit_offset += pref_sample_bit_width_sinr;
2972 }
2973
2974 /* 1-byte alignment per PRB (7.2.11) */
2975 offset = (bit_offset+7)/8;
2976 bit_offset = offset*8;
2977
2978 proto_item_append_text(prb_ti, ")");
2979 proto_item_set_end(prb_ti, tvb, offset);
2980 }
2981 break;
2982 }
2983 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
2984 /* Reserved (15 bits) */
2985 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2986 offset += 2;
2987 break;
2988
2989 default:
2990 break;
2991 }
2992 }
2993 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
2994 /* ef */
2995 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2996 /* ueId */
2997 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2998 offset += 2;
2999 /* regularizationFactor */
3000 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3001 offset += 2;
3002 /* reserved (4 bits) */
3003 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3004 /* rb ("Value=0 shall be set") */
3005 uint32_t rb;
3006 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3007 if (rb != 0) {
3008 proto_item_append_text(rb_ti, " (should be set to 0)");
3009 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3010 }
3011 /* symInc */
3012 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3013 /* startPrbc */
3014 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3015 offset += 2;
3016 /* numPrbc */
3017 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3018 offset += 1;
3019
3020 /* Hidden filter for bf */
3021 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3022 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3023
3024 /* ciIsample,ciQsample pairs */
3025 unsigned m;
3026 unsigned prb;
3027 uint32_t bit_offset = offset*8;
3028
3029 /* Antenna count from preference */
3030 unsigned num_trx = pref_num_bf_antennas;
3031
3032 write_channel_section_info(sectionHeading, pinfo,
3033 sectionId, ueId, startPrbc, numPrbc, num_trx);
3034
3035 bool_Bool first_prb = true1;
3036 uint8_t exponent = 0;
3037 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3038
3039 /* PRB subtree */
3040 unsigned prb_start_offset = bit_offset;
3041 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3042 tvb, bit_offset/8, 0,
3043 "", "PRB=%u", prb);
3044 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3045
3046 /* There may be a ciCompParam here.. */
3047 if (first_prb || ci_comp_opt==1) {
3048 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3049 }
3050 first_prb = false0;
3051
3052 /* Antennas */
3053 for (m=0; m < num_trx; m++) {
3054
3055 unsigned sample_offset = bit_offset / 8;
3056 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3057
3058 /* Create subtree for antenna */
3059 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3060 tvb, sample_offset, sample_extent,
3061 "", "TRX=%2u: ", m);
3062 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3063
3064 /* I */
3065 /* Get bits, and convert to float. */
3066 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3067 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3068
3069 /* Add to tree. */
3070 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);
3071 bit_offset += ci_iq_width;
3072 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3073
3074 /* Q */
3075 /* Get bits, and convert to float. */
3076 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3077 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3078
3079 /* Add to tree. */
3080 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);
3081 bit_offset += ci_iq_width;
3082 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3083 }
3084 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3085 }
3086
3087 /* Pad out by 1 or 4 bytes, according to preference */
3088 if (!st6_4byte_alignment) {
3089 offset = (bit_offset + 7) / 8;
3090 }
3091 else {
3092 int mode = bit_offset % 32;
3093 if (mode != 0) {
3094 offset = (bit_offset + (32-mode))/8;
3095 }
3096 else {
3097 offset = bit_offset/8;
3098 }
3099 }
3100 proto_item_set_end(c_section_tree, tvb, offset);
3101 }
3102
3103
3104 expected_section_data_t *dl_data_section = NULL((void*)0);
3105 unsigned index_to_use = 0;
3106
3107 /* On first pass, allocate a section entry to use */
3108 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3109
3110 if (!tap_info->uplink) {
3111 /* Look for existing entry to overwrite first. */
3112 for (uint8_t s=0; s < state->expected_dl_data.num_data_sections; s++) {
3113 if (sectionId == state->expected_dl_data.data_sections[s].sectionId) {
3114 /* If 2nd entry not in use, use that one */
3115 if (!state->expected_dl_data.data_sections[s].details[1].in_use) {
3116 index_to_use = 1;
3117 }
3118 else {
3119 /* Both in use, so replace the older of the 2 entries */
3120 if (state->expected_dl_data.data_sections[s].details[1].frame_number < state->expected_dl_data.data_sections[s].details[0].frame_number) {
3121 index_to_use = 1;
3122 }
3123 }
3124 dl_data_section = &state->expected_dl_data.data_sections[s];
3125 break;
3126 }
3127 }
3128
3129 /* Else try to allocate a new DL expected data section */
3130 if (dl_data_section == NULL((void*)0) && state->expected_dl_data.num_data_sections < MAX_SECTION_IDs32-1) {
3131 dl_data_section = &state->expected_dl_data.data_sections[state->expected_dl_data.num_data_sections++];
3132 }
3133
3134 if (dl_data_section) {
3135 dl_data_section->details[index_to_use].in_use = true1;
3136 dl_data_section->details[index_to_use].frame = frameId;
3137 dl_data_section->details[index_to_use].subframe = subframeId;
3138 dl_data_section->details[index_to_use].slot = slotId;
3139 dl_data_section->details[index_to_use].startSymbol = startSymbolId;
3140
3141 dl_data_section->details[index_to_use].frame_number = pinfo->num;
3142 dl_data_section->details[index_to_use].frame_time = pinfo->abs_ts;
3143 dl_data_section->sectionId = sectionId;
3144 dl_data_section->details[index_to_use].startPrb = startPrbc;
3145 dl_data_section->details[index_to_use].numPrb = numPrbc;
3146 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3147 if (prb < 273) {
3148 dl_data_section->details[index_to_use].beamIds[prb] = section_beamId;
3149 }
3150 }
3151 }
3152 }
3153 }
3154
3155 bool_Bool seen_se10 = false0;
3156 uint32_t numPortc = 0;
3157 proto_item *bf_ti = NULL((void*)0);
3158
3159 /* Section extension commands */
3160 while (extension_flag) {
3161 int extension_start_offset = offset;
3162
3163 /* Prefetch extType so can use specific extension type ett */
3164 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3165 uint32_t exttype_ett_index = exttype;
3166 if (exttype == 0 || exttype > HIGHEST_EXTTYPE30) {
3167 /* Just use first one if out of range */
3168 exttype_ett_index = 1;
3169 }
3170
3171 /* Create subtree for each extension (with summary) */
3172 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3173 tvb, offset, 0, "", "Extension");
3174 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3175
3176 /* ef (i.e. another extension after this one?) */
3177 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3178
3179 /* extType */
3180 proto_item *exttype_ti;
3181 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3182 offset++;
3183 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3184
3185 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3186
3187 /* Don't tap if out of range. */
3188 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE30) {
3189 tap_info->extensions[exttype] = true1;
3190 }
3191
3192 /* Is this SE allowed for this section type? */
3193 if (!se_allowed_in_st(exttype, sectionType)) {
3194 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3195 "SE %u (%s) should not appear in ST %u (%s)!",
3196 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3197 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3198 }
3199
3200
3201 /* extLen (number of 32-bit words) */
3202 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3203 uint32_t extlen;
3204 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3205 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3206 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3207 offset += extlen_len;
3208 if (extlen == 0) {
3209 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3210 /* Break out to avoid infinitely looping! */
3211 break;
3212 }
3213
3214 bool_Bool ext_unhandled = false0;
3215
3216 switch (exttype) {
3217
3218 case 1: /* SE 1: Beamforming Weights */
3219 {
3220 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3221 proto_item *comp_meth_ti = NULL((void*)0);
3222
3223 /* Hidden filter for bf */
3224 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3225 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3226
3227 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3228 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3229 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3230
3231 /* bfwCompParam */
3232 uint32_t exponent = 0;
3233 bool_Bool compression_method_supported = false0;
3234 unsigned num_trx = 0;
3235 uint16_t *trx; /* ptr to array */
3236 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3237 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3238 &num_trx, &trx);
3239
3240 /* Can't show details of unsupported compression method */
3241 if (!compression_method_supported) {
3242 break;
3243 }
3244
3245 /* We know:
3246 - iq_width (above)
3247 - numBfWeights (taken from preference)
3248 - remaining bytes in extension
3249 We can therefore derive TRX (number of antennas).
3250 */
3251
3252 bool_Bool using_array = false0;
3253
3254 /* I & Q samples
3255 May know how many entries from activeBeamspaceCoefficientMask. */
3256 if (num_trx == 0) {
3257 /* Don't know how many there will be, so just fill available bytes... */
3258 unsigned weights_bytes = (extlen*4)-3;
3259 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3260 num_trx = num_weights_pairs;
3261 }
3262 else {
3263 using_array = true1;
3264 num_trx = pref_num_bf_antennas;
3265 }
3266
3267 int bit_offset = offset*8;
3268
3269 for (unsigned n=0; n < num_trx; n++) {
3270 /* Create antenna subtree */
3271 int bfw_offset = bit_offset / 8;
3272
3273 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3274
3275 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3276 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3277 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3278
3279 /* I value */
3280 /* Get bits, and convert to float. */
3281 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3282 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3283 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3284 /* Add to tree. */
3285 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3286 (bfwcomphdr_iq_width+7)/8, value);
3287 bit_offset += bfwcomphdr_iq_width;
3288 proto_item_append_text(bfw_ti, "I=%f ", value);
3289
3290 /* Leave a gap between I and Q values */
3291 proto_item_append_text(bfw_ti, " ");
3292
3293 /* Q value */
3294 /* Get bits, and convert to float. */
3295 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3296 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3297 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3298 /* Add to tree. */
3299 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3300 (bfwcomphdr_iq_width+7)/8, value);
3301 bit_offset += bfwcomphdr_iq_width;
3302 proto_item_append_text(bfw_ti, "Q=%f", value);
3303
3304 proto_item_append_text(bfw_ti, ")");
3305 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3306 }
3307 /* Need to round to next byte */
3308 offset = (bit_offset+7)/8;
3309
3310 break;
3311 }
3312
3313 case 2: /* SE 2: Beamforming attributes */
3314 {
3315 /* Hidden filter for bf */
3316 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3317 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3318
3319 /* bfaCompHdr (get widths of fields to follow) */
3320 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3321 /* subtree */
3322 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3323 tvb, offset, 2, "", "bfaCompHdr");
3324 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3325
3326 /* reserved (2 bits) */
3327 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3328 /* bfAzPtWidth (3 bits) */
3329 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3330 /* bfZePtWidth (3 bits) */
3331 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3332 offset += 1;
3333
3334 /* reserved (2 bits) */
3335 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3336 /* bfAz3ddWidth (3 bits) */
3337 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3338 /* bfZe3ddWidth (3 bits) */
3339 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3340 offset += 1;
3341
3342 unsigned bit_offset = offset*8;
3343
3344 /* bfAzPt */
3345 if (bfAzPtWidth > 0) {
3346 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3347 bit_offset += (bfAzPtWidth+1);
3348 }
3349 /* bfZePt */
3350 if (bfZePtWidth > 0) {
3351 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3352 bit_offset += (bfZePtWidth+1);
3353 }
3354 /* bfAz3dd */
3355 if (bfAz3ddWidth > 0) {
3356 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3357 bit_offset += (bfAz3ddWidth+1);
3358 }
3359 /* bfZe3dd */
3360 if (bfZe3ddWidth > 0) {
3361 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3362 bit_offset += (bfZe3ddWidth+1);
3363 }
3364
3365 /* Pad to next byte (unless last 2 fields already fit in this one) */
3366 if ((bit_offset % 8) > 2) {
3367 offset = (bit_offset+7) / 8;
3368 }
3369 else {
3370 offset = bit_offset / 8;
3371 }
3372
3373 /* bfAzSl (3 bits) */
3374 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3375 /* bfZeSl (3 bits) */
3376 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3377 offset += 1;
3378 break;
3379 }
3380
3381 case 3: /* SE 3: DL precoding parameters */
3382 {
3383 /* codebookindex (8 bits) */
3384 /* "This parameter is not used and shall be set to zero." */
3385 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3386 offset += 1;
3387 /* layerid */
3388 uint32_t layerid;
3389 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3390 /* numLayers */
3391 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3392 offset += 1;
3393
3394 /* Stop here for non-first data layer */
3395 if (layerid != 0 && layerid != 0xf) {
3396 break;
3397 }
3398
3399 /* First data layer case */
3400 /* txScheme */
3401 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3402 /* crsReMask */
3403 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3404 offset += 2;
3405
3406 /* crsShift (1 bit) */
3407 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3408 /* reserved (3 bits) */
3409 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3410 /* crsSymNum (4 bits) */
3411 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3412 offset += 1;
3413 /* reserved (8 bits) */
3414 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3415 offset += 1;
3416
3417 /* reserved (1 bit) */
3418 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3419 /* beamIdAP1 (15 bits) */
3420 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3421 offset += 2;
3422 /* reserved (1 bit) */
3423 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3424 /* beamIdAP2 (15 bits) */
3425 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3426 offset += 2;
3427 /* reserved (1 bit) */
3428 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3429 /* beamIdAP3 (15 bits) */
3430 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3431 offset += 2;
3432 break;
3433 }
3434
3435 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3436 {
3437 /* csf */
3438 bool_Bool csf;
3439 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3440
3441 /* modCompScaler */
3442 uint32_t modCompScaler;
3443 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3444 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3445 offset += 2;
3446
3447 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3448 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3449 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3450 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3451 proto_item_append_text(ti, " (%f)", value);
3452
3453 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3454
3455 /* Store these params in this flow's state */
3456 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3457 unsigned i = sect_config->num_configs;
3458 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3459 sect_config->configs[i].mod_compr_csf = csf;
3460 sect_config->configs[i].mod_compr_scaler = value;
3461 sect_config->num_configs++;
3462 }
3463 break;
3464 }
3465
3466 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3467 {
3468 /* Applies only to section types 1,3 and 5 */
3469 /* N.B. there may be multiple instances of this SE in the same frame */
3470
3471 /* There may be one or 2 entries, depending upon extlen */
3472 int sets = 1, reserved_bits = 0;
3473 switch (extlen) {
3474 case 2:
3475 sets = 1;
3476 reserved_bits = 20;
3477 break;
3478 case 3:
3479 sets = 2;
3480 reserved_bits = 24;
3481 break;
3482 case 4:
3483 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3484 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3485 sets = 3;
3486 reserved_bits = 28;
3487 }
3488 else {
3489 sets = 4;
3490 reserved_bits = 0;
3491 }
3492 break;
3493
3494 default:
3495 /* Malformed error!!! */
3496 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3497 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3498 extlen);
3499 break;
3500 }
3501
3502 unsigned bit_offset = offset*8;
3503 /* Dissect each set */
3504 for (int n=0; n < sets; n++) {
3505 /* Subtree for each set */
3506 unsigned set_start_offset = bit_offset/8;
3507 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3508 tvb, set_start_offset, 0, "");
3509 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3510
3511 uint64_t mcScaleReMask, mcScaleOffset;
3512 bool_Bool csf;
3513
3514 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3515 static int * const remask_flags[] = {
3516 &hf_oran_mc_scale_re_mask_re1,
3517 &hf_oran_mc_scale_re_mask_re2,
3518 &hf_oran_mc_scale_re_mask_re3,
3519 &hf_oran_mc_scale_re_mask_re4,
3520 &hf_oran_mc_scale_re_mask_re5,
3521 &hf_oran_mc_scale_re_mask_re6,
3522 &hf_oran_mc_scale_re_mask_re7,
3523 &hf_oran_mc_scale_re_mask_re8,
3524 &hf_oran_mc_scale_re_mask_re9,
3525 &hf_oran_mc_scale_re_mask_re10,
3526 &hf_oran_mc_scale_re_mask_re11,
3527 &hf_oran_mc_scale_re_mask_re12,
3528 NULL((void*)0)
3529 };
3530 /* Same as above, but offset by 4 bits */
3531 static int * const remask_flags_even[] = {
3532 &hf_oran_mc_scale_re_mask_re1_even,
3533 &hf_oran_mc_scale_re_mask_re2_even,
3534 &hf_oran_mc_scale_re_mask_re3_even,
3535 &hf_oran_mc_scale_re_mask_re4_even,
3536 &hf_oran_mc_scale_re_mask_re5_even,
3537 &hf_oran_mc_scale_re_mask_re6_even,
3538 &hf_oran_mc_scale_re_mask_re7_even,
3539 &hf_oran_mc_scale_re_mask_re8_even,
3540 &hf_oran_mc_scale_re_mask_re9_even,
3541 &hf_oran_mc_scale_re_mask_re10_even,
3542 &hf_oran_mc_scale_re_mask_re11_even,
3543 &hf_oran_mc_scale_re_mask_re12_even,
3544 NULL((void*)0)
3545 };
3546
3547 /* RE Mask (12 bits) */
3548 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3549 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3550 ett_oran_mc_scale_remask,
3551 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3552 bit_offset += 12;
3553
3554 /* csf (1 bit) */
3555 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3556 /* mcScaleOffset (15 bits) */
3557 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3558 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3559 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3560 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3561 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3562 bit_offset += 15;
3563
3564 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3565
3566 /* Record this config */
3567 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3568 unsigned i = sect_config->num_configs;
3569 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3570 sect_config->configs[i].mod_compr_csf = csf;
3571 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3572 sect_config->num_configs++;
3573 }
3574
3575 /* Summary */
3576 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3577 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3578 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3579 }
3580
3581 proto_item_append_text(extension_ti, " (%u sets)", sets);
3582
3583 /* Reserved (variable-length) */
3584 if (reserved_bits) {
3585 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3586 bit_offset += reserved_bits;
3587 }
3588
3589 offset = bit_offset/8;
3590 break;
3591 }
3592
3593 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3594 {
3595 /* numSymbol not used in this case */
3596 if (numsymbol_ti && !numsymbol_ignored) {
3597 proto_item_append_text(numsymbol_ti, " (ignored)");
3598 numsymbol_ignored = true1;
3599 }
3600
3601 /* Will update ext6 recorded info */
3602 ext11_settings.ext6_set = true1;
3603
3604 /* repetition */
3605 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3606 /* rbgSize (PRBs per bit set in rbgMask) */
3607 uint32_t rbgSize;
3608 proto_item *rbg_size_ti;
3609 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3610 if (rbgSize == 0) {
3611 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3612 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3613 }
3614 /* rbgMask (28 bits) */
3615 uint32_t rbgMask;
3616 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3617 if (rbgSize == 0) {
3618 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3619 }
3620
3621 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3622 offset += 4;
3623 /* priority */
3624 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3625 /* symbolMask */
3626 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3627
3628 /* Look up rbg_size enum -> value */
3629 switch (rbgSize) {
3630 case 0:
3631 /* N.B. reserved, but covered above with expert info (would remain 0) */
3632 break;
3633 case 1:
3634 ext11_settings.ext6_rbg_size = 1; break;
3635 case 2:
3636 ext11_settings.ext6_rbg_size = 2; break;
3637 case 3:
3638 ext11_settings.ext6_rbg_size = 3; break;
3639 case 4:
3640 ext11_settings.ext6_rbg_size = 4; break;
3641 case 5:
3642 ext11_settings.ext6_rbg_size = 6; break;
3643 case 6:
3644 ext11_settings.ext6_rbg_size = 8; break;
3645 case 7:
3646 ext11_settings.ext6_rbg_size = 16; break;
3647 /* N.B., encoded in 3 bits, so no other values are possible */
3648 }
3649
3650 /* Set to looked-up value */
3651 rbgSize = ext11_settings.ext6_rbg_size;
3652
3653 uint32_t lastRbgid = 0;
3654 if (rbgSize != 0) {
3655 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3656 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3657 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3658 if (lastRbgid > 27) {
3659 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3660 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3661 rbgSize, startPrbc, numPrbc);
3662 break;
3663 }
3664 }
3665
3666 /* Record (and count) which bits are set in rbgMask */
3667 bool_Bool first_seen = false0;
3668 unsigned first_seen_pos=0, last_seen_pos=0;
3669 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3670 if ((rbgMask >> n) & 0x01) {
3671 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3672 if (!first_seen) {
3673 first_seen = true1;
3674 first_seen_pos = n;
3675 }
3676 last_seen_pos = n;
3677 }
3678 }
3679
3680 /* Show how many bits were set in rbgMask */
3681 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3682 /* Also, that is the range of bits */
3683 if (first_seen) {
3684 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3685
3686 /* Complain if last set bit is beyond lastRbgid */
3687 if (last_seen_pos > lastRbgid) {
3688 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3689 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3690 rbgMask, last_seen_pos, lastRbgid);
3691 }
3692 }
3693
3694 /* Also update prbs_for_st10_type5[] */
3695 if (sectionType == 10 && rbgSize != 0) {
3696 /* Unset all entries */
3697 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3698
3699 /* Work out which PRB first bit corresponds to */
3700 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3701
3702 /* Add PRBs corresponding to each bit set */
3703 for (unsigned n=0; n < 28 ; n++) {
3704 if ((rbgMask >> n) & 0x01) {
3705 /* Lazy way to clip any values that lie outside of range for section */
3706 for (unsigned p=0; p < rbgSize; p++) {
3707 unsigned start = firstPrbStart + (n*rbgSize);
3708 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3709 prbs_for_st10_type5[start+p] = true1;
3710 }
3711 }
3712 }
3713 }
3714 }
3715
3716 break;
3717 }
3718
3719 case 7: /* SE 7: eAxC mask */
3720 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3721 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3722 offset += 2;
3723 break;
3724
3725 case 8: /* SE 8: Regularization factor */
3726 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3727 offset += 2;
3728 break;
3729
3730 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3731 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3732 offset += 1;
3733 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3734 offset += 1;
3735 break;
3736
3737 case 10: /* SE 10: Group configuration of multiple ports */
3738 {
3739 seen_se10 = true1;
3740
3741 /* beamGroupType */
3742 uint32_t beam_group_type = 0;
3743 proto_item *bgt_ti;
3744 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3745 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3746 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3747
3748 /* numPortc */
3749 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3750 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3751 offset++;
3752
3753 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3754 unsigned n;
3755
3756 switch (beam_group_type) {
3757 case 0x0: /* common beam */
3758 case 0x1: /* beam matrix indication */
3759 /* Reserved byte */
3760 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3761 offset++;
3762
3763 /* Explain how entries are allocated */
3764 if (beam_group_type == 0x0) {
3765 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3766 }
3767 else {
3768 /* 'numPortc' consecutive BeamIds from section header */
3769 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3770 }
3771
3772 if (sectionType == 5) {
3773 /* These types are not allowed */
3774 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3775 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3776 }
3777 break;
3778
3779 case 0x2: /* beam vector listing */
3780 {
3781 proto_item_append_text(extension_ti, " [ ");
3782
3783 /* Beam listing vector case */
3784 /* Work out how many port beam entries there is room for */
3785 /* Using numPortC as visible in issue 18116 */
3786 for (n=0; n < numPortc; n++) {
3787 /* 1 reserved bit */
3788 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3789
3790 /* port beam ID (or UEID) (15 bits) */
3791 uint32_t id;
3792 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3793 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3794 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3795 offset += 2;
3796
3797 if (id != 0x7fff) {
3798 if (number_of_ueids < MAX_UEIDS16) {
3799 ueids[number_of_ueids++] = id;
3800 }
3801 }
3802
3803 proto_item_append_text(extension_ti, "%u ", id);
3804 }
3805
3806 proto_item_append_text(extension_ti, "]");
3807 break;
3808 }
3809 case 0x3: /* beamId/ueId listing with associated port-list index */
3810 {
3811 proto_item_append_text(extension_ti, " [ ");
3812
3813 if (numPortc > 0) {
3814 /* first portListIndex is outside loop */
3815 uint32_t port_list_index;
3816 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3817 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3818 if (port_list_index == 0) {
3819 /* Value 0 is reserved */
3820 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3821 }
3822 offset += 1;
3823
3824 for (n=0; n < numPortc-1; n++) {
3825 /* 1 reserved bit */
3826 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3827
3828 /* port beam ID (or UEID) */
3829 uint32_t id;
3830 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3831 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3832 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3833 offset += 2;
3834
3835 if (id != 0x7fff) {
3836 if (number_of_ueids < MAX_UEIDS16) {
3837 ueids[number_of_ueids++] = id;
3838 }
3839 }
3840
3841 /* subsequent portListIndex */
3842 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3843 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3844 if (port_list_index == 0) {
3845 /* Value 0 is reserved */
3846 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3847 }
3848 offset += 1;
3849
3850 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3851 }
3852 }
3853
3854 proto_item_append_text(extension_ti, "]");
3855 break;
3856 }
3857
3858
3859 default:
3860 /* Warning for unsupported/reserved value */
3861 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3862 break;
3863 }
3864 break;
3865 }
3866
3867 case 11: /* SE 11: Flexible Weights Extension Type */
3868 {
3869 /* Hidden filter for bf */
3870 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3871 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3872
3873 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3874 if (section_beamId_ti && !section_beamId_ignored) {
3875 proto_item_append_text(section_beamId_ti, " (ignored)");
3876 section_beamId_ignored = true1;
3877 }
3878
3879 bool_Bool disableBFWs;
3880 uint32_t numBundPrb;
3881 bool_Bool rad;
3882
3883 /* disableBFWs */
3884 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3885 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3886 if (disableBFWs) {
3887 proto_item_append_text(extension_ti, " (disableBFWs)");
3888 }
3889
3890 /* RAD */
3891 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3892 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3893 /* bundleOffset (6 bits) */
3894 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3895 offset, 1, ENC_BIG_ENDIAN0x00000000);
3896 offset++;
3897
3898 /* numBundPrb (number of prbs in each bundle) */
3899 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3900 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3901 offset++;
3902 /* value zero is reserved.. */
3903 if (numBundPrb == 0) {
3904 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3905 }
3906
3907 uint32_t num_bundles;
3908 bool_Bool orphaned_prbs = false0;
3909
3910 /* N.B. glibly assuming that Mu=1 */
3911 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
3912
3913 if (!disableBFWs) {
3914 /********************************************/
3915 /* Table 7.7.1.1-1 */
3916 /********************************************/
3917
3918 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3919 proto_item *comp_meth_ti = NULL((void*)0);
3920
3921 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3922 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3923 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3924
3925 /* Work out number of bundles, but take care not to divide by zero. */
3926 if (numBundPrb == 0) {
3927 break;
3928 }
3929
3930 /* Work out bundles! */
3931 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
3932 num_bundles = ext11_settings.num_bundles;
3933
3934 /* Add (complete) bundles */
3935 for (unsigned b=0; b < num_bundles; b++) {
3936 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
3937 comp_meth_ti, bfwcomphdr_comp_meth,
3938 NULL((void*)0) /* no ModCompr */,
3939 (ext11_settings.ext21_set) ?
3940 numPrbc :
3941 pref_num_bf_antennas,
3942 bfwcomphdr_iq_width,
3943 b, /* bundle number */
3944 ext11_settings.bundles[b].start,
3945 ext11_settings.bundles[b].end,
3946 ext11_settings.bundles[b].is_orphan,
3947 symbol_count,
3948 (link_planes_together && dl_data_section) ? &dl_data_section->details[index_to_use] : NULL((void*)0),
3949 tap_info);
3950 if (!offset) {
3951 break;
3952 }
3953 }
3954 if (num_bundles > 0) {
3955 /* Set flag from last bundle entry */
3956 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
3957 }
3958 }
3959 else {
3960 /********************************************/
3961 /* Table 7.7.1.1-2 */
3962 /* No weights in this case */
3963 /********************************************/
3964
3965 /* Work out number of bundles, but take care not to divide by zero. */
3966 if (numBundPrb == 0) {
3967 break;
3968 }
3969
3970 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
3971 num_bundles = ext11_settings.num_bundles;
3972
3973 for (unsigned n=0; n < num_bundles; n++) {
3974 /* contInd */
3975 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
3976 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3977 /* beamId */
3978 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
3979 uint32_t beam_id;
3980 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
3981 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
3982 if (!ext11_settings.bundles[n].is_orphan) {
3983 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
3984 ext11_settings.bundles[n].start,
3985 ext11_settings.bundles[n].end,
3986 n);
3987 }
3988 else {
3989 orphaned_prbs = true1;
3990 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
3991 ext11_settings.bundles[n].start,
3992 ext11_settings.bundles[n].end);
3993 }
3994 offset += 2;
3995
3996 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3997 if (dl_data_section) {
3998 /* Set beamId only for range of PRBs */
3999 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4000 if (prb < 273) {
4001 dl_data_section->details[index_to_use].beamIds[prb] = beam_id;
4002 }
4003 }
4004 }
4005 }
4006
4007 /* Look for where BFWs were sent for this beamId */
4008 bfw_definition *definition;
4009
4010 wmem_tree_key_t key[3];
4011 key[0].length = 1;
4012 key[0].key = &pinfo->num;
4013 key[1].length = 1;
4014 key[1].key = &beam_id;
4015 key[2].length = 0;
4016 key[2].key = NULL((void*)0);
4017
4018 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4019 /* Look up current result */
4020 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4021 if (definition != NULL((void*)0)) {
4022 /* Add to results table for this frame */
4023 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4024 }
4025 }
4026 else {
4027 /* Look up from result table */
4028 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4029 }
4030
4031 /* Show link back to frame where/when beamId was defined */
4032 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4033 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4034 proto_item_set_generated(defined_ti);
4035 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4036 symbol_count - definition->symbol_when_defined);
4037 proto_item_set_generated(since_ti);
4038 }
4039 else {
4040 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4041 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4042 }
4043 }
4044
4045 }
4046
4047 /* Add summary to extension root */
4048 if (orphaned_prbs) {
4049 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4050 }
4051 else {
4052 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4053 }
4054 }
4055
4056 break;
4057
4058 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4059 {
4060 /* numSymbol not used in this case */
4061 if (numsymbol_ti && !numsymbol_ignored) {
4062 proto_item_append_text(numsymbol_ti, " (ignored)");
4063 numsymbol_ignored = true1;
4064 }
4065
4066 ext11_settings.ext12_set = true1;
4067
4068 /* priority */
4069 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4070
4071 /* symbolMask */
4072 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4073
4074 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4075 should be populated with 0s. */
4076 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4077 uint8_t prb_index;
4078
4079 /* This is for ST10/ST11. First pair starts after frames signalled there */
4080 uint16_t st10_st11_offset = startPrbc + numPrbc;
4081
4082 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4083 {
4084 /* Create a subtree for each pair */
4085 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4086 tvb, offset, 2, "");
4087 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4088
4089 /* offStartPrb */
4090 uint32_t off_start_prb;
4091 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4092 offset++;
4093
4094 /* numPrb */
4095 uint32_t num_prb;
4096 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4097 offset++;
4098
4099 extlen_remaining_bytes -= 2;
4100
4101 /* Last pair may be 0,0 if not used. Check for this */
4102 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4103 proto_item_append_text(pair_ti, " (not used)");
4104 }
4105 /* Add summary to pair root item, and configure details in ext11_settings */
4106 else {
4107 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4108 prb_index, off_start_prb, num_prb);
4109 proto_item_append_text(extension_ti, "[%u : %u]",
4110 off_start_prb, num_prb);
4111 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4112 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4113 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4114 }
4115
4116 /* Also update PRBs to be covered for ST10 type 5 */
4117 /* Original range from section is added to.. */
4118 /* TODO: I don't think this is quite right.. */
4119 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4120 if (prb < MAX_PRBS273) {
4121 prbs_for_st10_type5[prb] = true1;
4122 }
4123 }
4124
4125 /* Any next pair will begin after this one */
4126 st10_st11_offset += (off_start_prb + num_prb);
4127 }
4128 }
4129 break;
4130 }
4131
4132 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4133 {
4134 /* Will update settings for ext11 */
4135 ext11_settings.ext13_set = true1;
4136
4137 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4138 uint8_t allocation_index;
4139
4140 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4141
4142 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4143 {
4144 /* Subtree for allocation */
4145 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4146 tvb, offset, 2, "");
4147 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4148
4149 /* Reserved (2 bits) */
4150 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4151
4152 /* nextSymbolId (4 bits) */
4153 uint32_t next_symbol_id;
4154 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4155
4156 /* nextStartPrbc (10 bits) */
4157 uint32_t next_start_prbc;
4158 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4159 offset += 2;
4160
4161 /* Add summary to allocation root item */
4162 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4163 allocation_index, next_symbol_id, next_start_prbc);
4164
4165 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4166 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4167 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4168 }
4169 else {
4170 /* Add entry for configuring ext11. don't store out of range */
4171 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4172 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4173 }
4174 }
4175 prev_next_symbol_id = next_symbol_id;
4176 prev_next_start_prbc = next_start_prbc;
4177
4178 extlen_remaining_bytes -= 2;
4179 }
4180 break;
4181 }
4182
4183 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4184 /* Hidden filter for bf (DMRS BF) */
4185 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4186 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4187
4188 if (!seen_se10) {
4189 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4190 offset += 1;
4191 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4192 offset += 1;
4193 }
4194 else {
4195 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4196 for (unsigned port=0; port < numPortc+1; port++) {
4197 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4198 offset += 1;
4199 }
4200 }
4201 break;
4202
4203 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4204 {
4205 /* frameStructure */
4206 offset = dissect_frame_structure(extension_tree, tvb, offset,
4207 subframeId, slotId);
4208 /* freqOffset */
4209 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4210 offset += 3;
4211 /* cpLength */
4212 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4213 if (sectionType != 0 && sectionType != 3) {
4214 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4215 }
4216 offset += 2;
4217 break;
4218 }
4219
4220 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4221 {
4222 /* Just filling available bytes with antMask entries.
4223 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4224 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4225 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4226 for (unsigned n=0; n < num_ant_masks; n++) {
4227 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4228 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4229 offset += 8;
4230 }
4231 break;
4232 }
4233
4234 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4235 {
4236 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4237 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4238 uint32_t ueid_index = 1;
4239
4240 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4241 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4242 /* numUeId (Number of UE Ids per user) */
4243 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4244 /* TODO: show ueids[ueid_index] here too? */
4245 proto_item_append_text(ti, " (user #%u)", ueid_index);
4246 }
4247 break;
4248 }
4249
4250 case 18: /* SE 18: Uplink transmission management */
4251 /* transmissionWindowOffset */
4252 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4253 offset += 2;
4254 /* reserved (2 bits) */
4255 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4256 /* transmissionWindowSize (14 bits) */
4257 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4258 offset += 2;
4259
4260 /* reserved (6 bits) */
4261 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4262 /* toT (2 bits) */
4263 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4264 offset += 1;
4265 break;
4266
4267 case 19: /* SE 19: Compact beamforming information for multiple port */
4268 {
4269 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4270 if (section_beamId_ti && !section_beamId_ignored) {
4271 proto_item_append_text(section_beamId_ti, " (ignored)");
4272 section_beamId_ignored = true1;
4273 }
4274
4275 /* numSymbol not used in this case */
4276 if (numsymbol_ti && !numsymbol_ignored) {
4277 proto_item_append_text(numsymbol_ti, " (ignored)");
4278 numsymbol_ignored = true1;
4279 }
4280
4281 /* disableBFWs */
4282 bool_Bool disableBFWs;
4283 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4284 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4285 if (disableBFWs) {
4286 proto_item_append_text(extension_ti, " (disableBFWs)");
4287 }
4288 /* repetition (1 bit) */
4289 uint64_t repetition;
4290 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4291 /* numPortc (6 bits) */
4292 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4293 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4294 offset++;
4295
4296 /* priority (2 bits) */
4297 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4298 /* symbolMask (14 bits) */
4299 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4300
4301 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4302 proto_item *comp_meth_ti = NULL((void*)0);
4303
4304 if (!repetition) {
4305
4306 if (!disableBFWs) {
4307 /* bfwCompHdr */
4308 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4309 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4310 }
4311
4312 /* Add entries for each port */
4313 for (unsigned port=0; port < numPortc; port++) {
4314
4315 /* Create subtree for port entry*/
4316 int port_start_offset = offset;
4317 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4318 tvb, offset, 0,
4319 "", "Port %u: ", port);
4320 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4321
4322 /* Reserved (4 bits) */
4323 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4324 /* portReMask (12 bits) */
4325 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4326 offset += 2;
4327
4328 /* Reserved (2 bits) */
4329 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4330 /* portSymbolMask (14 bits) */
4331 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4332 offset += 2;
4333
4334 /* Reserved (1 bit) */
4335 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4336 /* beamID (15 bits) */
4337 uint16_t beamId;
4338 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4339 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4340 offset += 2;
4341
4342 /* No weights present */
4343 if (!disableBFWs) {
4344 /*******************************************************************/
4345 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4346 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4347 /*******************************************************************/
4348
4349 /* bfwCompParam */
4350 bool_Bool compression_method_supported = false0;
4351 uint32_t exponent = 0;
4352 unsigned num_trx_entries = 0;
4353 uint16_t *trx;
4354 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4355 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4356 &num_trx_entries, &trx);
4357
4358 int bit_offset = offset*8;
4359 int bfw_offset;
4360
4361 /* Add weights for each TRX */
4362 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4363 for (unsigned b=0; b < trx_to_add; b++) {
4364
4365 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4366
4367 /* Create BFW subtree */
4368 bfw_offset = bit_offset / 8;
4369 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4370 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4371 tvb, bfw_offset, bfw_extent,
4372 "", "TRX %u: (", trx_index);
4373 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4374
4375 /* I */
4376 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4377 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4378 /* Add to tree. */
4379 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4380 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4381 bit_offset += bfwcomphdr_iq_width;
4382 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4383
4384 /* Q */
4385 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4386 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4387 /* Add to tree. */
4388 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4389 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4390 bit_offset += bfwcomphdr_iq_width;
4391 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4392 }
4393
4394 offset = (bit_offset+7)/8;
4395 }
4396 else {
4397 /* No weights... */
4398 }
4399
4400 /* Set length of this port entry */
4401 proto_item_set_len(port_ti, offset-port_start_offset);
4402 }
4403 }
4404 break;
4405 }
4406
4407 case 20: /* SE 20: Puncturing extension */
4408 {
4409 /* numPuncPatterns */
4410 uint32_t numPuncPatterns;
4411 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4412 offset += 1;
4413
4414 /* Add each puncturing pattern */
4415 for (uint32_t n=0; n < numPuncPatterns; n++) {
4416 unsigned pattern_start_offset = offset;
4417
4418 /* Subtree for this puncturing pattern */
4419 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4420 tvb, offset, 0,
4421 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4422 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4423
4424 /* SymbolMask (14 bits) */
4425 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4426 offset += 1;
4427
4428 uint32_t startPuncPrb, numPuncPrb;
4429
4430 /* startPuncPrb (10 bits) */
4431 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4432 offset += 2;
4433 /* numPuncPrb (8 bits) */
4434 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4435 offset += 1;
4436
4437 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4438
4439 /* Make a hole in range of PRBs to report */
4440 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4441 if (p < MAX_PRBS273) {
4442 prbs_for_st10_type5[p] = false0;
4443 }
4444 }
4445
4446 /* puncReMask (12 bits) */
4447 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4448 offset += 1;
4449 /* rb (1 bit) */
4450 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4451 /* reserved (1 bit) */
4452 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4453 /* multiSDScope (1 bit) */
4454 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4455 /* rbgIncl (1 bit) */
4456 bool_Bool rbgIncl;
4457 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4458 offset += 1;
4459
4460 if (rbgIncl) {
4461 /* reserved (1 bit) */
4462 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4463 /* rbgSize(3 bits) */
4464 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4465 /* rbgMask (28 bits) */
4466 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4467 offset += 4;
4468
4469 proto_item_append_text(rb_ti, " (ignored)");
4470 }
4471
4472 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4473 }
4474
4475 break;
4476 }
4477 case 21: /* SE 21: Variable PRB group size for channel information */
4478 {
4479 /* ciPrbGroupSize */
4480 uint32_t ci_prb_group_size;
4481 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);
4482 offset += 1;
4483
4484 switch (ci_prb_group_size) {
4485 case 0:
4486 case 1:
4487 case 255:
4488 /* Reserved value */
4489 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4490 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4491 ci_prb_group_size);
4492 break;
4493 default:
4494 /* This value affects how SE 11 is interpreted */
4495 ext11_settings.ext21_set = true1;
4496 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4497
4498 if (numPrbc == 0) {
4499 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4500 }
4501 break;
4502 }
4503
4504 /* reserved (6 bits) */
4505 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4506
4507 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4508 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4509 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4510 }
4511 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4512 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4513 }
4514 offset += 1;
4515 break;
4516 }
4517
4518 case 22: /* SE 22: ACK/NACK request */
4519 {
4520 uint32_t ack_nack_req_id;
4521 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4522 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4523 offset += 2;
4524
4525 if (state) {
4526 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4527 /* Add this request into conversation state on first pass */
4528 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)))
;
4529 request_details->request_frame_number = pinfo->num;
4530 request_details->request_frame_time = pinfo->abs_ts;
4531 request_details->requestType = SE22;
4532 /* Insert into flow's tree */
4533 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4534 }
4535 else {
4536 /* Try to link forward to ST8 response */
4537 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4538 ack_nack_req_id);
4539 if (response) {
4540 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4541 }
4542 }
4543 }
4544 break;
4545 }
4546
4547 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4548 {
4549 /* Green common header */
4550
4551 /* numSymPrbPattern (4 bits) */
4552 uint32_t num_sym_prb_pattern;
4553 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4554 /* reserved (3 bits) */
4555 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4556 /* prbMode (1 bit) */
4557 bool_Bool prb_mode;
4558 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4559 offset += 1;
4560
4561 /* reserved (8 bits) */
4562 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4563 offset += 1;
4564
4565 /* Dissect each SymPrbPattern */
4566 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4567
4568 /* Subtree */
4569 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4570 tvb, offset, 1, "",
4571 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4572 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4573
4574
4575 /* Orange part */
4576
4577 /* Reserved (2 bits) */
4578 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4579 /* symMask (14 bits) */
4580 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4581 offset += 2;
4582 /* numMcScaleOffset (4 bits) */
4583 uint32_t numMcScaleOffset;
4584 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4585
4586 if (!prb_mode) { /* PRB-MASK */
4587 /* prbPattern (4 bits) */
4588 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4589 offset += 1;
4590 /* reserved (8 bits) */
4591 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4592 offset += 1;
4593 }
4594 else { /* PRB-BLOCK */
4595 /* prbBlkOffset (8 bits) */
4596 proto_tree_add_item(pattern_tree, hf_oran_prb_block_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4597 offset += 1;
4598 /* prbBlkSize (4 bits) */
4599 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4600 offset += 1;
4601 }
4602
4603 /* Yellowish part */
4604 if (prb_mode) { /* PRB-BLOCK */
4605 /* prbBlkSize (4 bits) */
4606 proto_tree_add_item(pattern_tree, hf_oran_prb_block_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4607 }
4608 else {
4609 /* reserved (4 bits) */
4610 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4611 }
4612
4613 for (unsigned c=0; c < numMcScaleOffset; c++) {
4614
4615 if (c > 0) {
4616 /* reserved (4 bits) */
4617 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4618 }
4619
4620 static int * const remask_flags_even[] = {
4621 &hf_oran_mc_scale_re_mask_re1_even,
4622 &hf_oran_mc_scale_re_mask_re2_even,
4623 &hf_oran_mc_scale_re_mask_re3_even,
4624 &hf_oran_mc_scale_re_mask_re4_even,
4625 &hf_oran_mc_scale_re_mask_re5_even,
4626 &hf_oran_mc_scale_re_mask_re6_even,
4627 &hf_oran_mc_scale_re_mask_re7_even,
4628 &hf_oran_mc_scale_re_mask_re8_even,
4629 &hf_oran_mc_scale_re_mask_re9_even,
4630 &hf_oran_mc_scale_re_mask_re10_even,
4631 &hf_oran_mc_scale_re_mask_re11_even,
4632 &hf_oran_mc_scale_re_mask_re12_even,
4633 NULL((void*)0)
4634 };
4635
4636 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4637 uint64_t mcScaleReMask, mcScaleOffset;
4638 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4639 hf_oran_mc_scale_re_mask_even,
4640 ett_oran_mc_scale_remask,
4641 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4642
4643 offset += 2;
4644 /* csf (1 bit) */
4645 bool_Bool csf;
4646 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4647 /* mcScaleOffset (15 bits) */
4648 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);
4649 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4650 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4651 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4652 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4653
4654 offset += 2;
4655
4656 /* Record this config. */
4657 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4658 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4659
4660 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4661 unsigned i = sect_config->num_configs;
4662 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4663 sect_config->configs[i].mod_compr_csf = csf;
4664 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4665 sect_config->num_configs++;
4666 }
4667 }
4668
4669 proto_item_set_end(pattern_ti, tvb, offset);
4670 }
4671 break;
4672 }
4673
4674 case 24: /* SE 24: PUSCH DMRS configuration */
4675 {
4676 /* Hidden filter for bf (DMRS BF) */
4677 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4678 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4679
4680 /* alpnPerSym (1 bit) */
4681 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4682 /* antDmrsSnr (1 bit) */
4683 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4684 /* reserved (1 bit) */
4685 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4686 /* userGroupSize (5 bits) */
4687 uint32_t user_group_size;
4688 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);
4689 if (user_group_size == 0) {
4690 proto_item_append_text(ugs_ti, " (not used)");
4691 }
4692 else if (user_group_size > 12) {
4693 proto_item_append_text(ugs_ti, " (reserved)");
4694 }
4695 offset += 1;
4696 /* userGroupId (8 bits)*/
4697 uint32_t user_group_id;
4698 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);
4699 if (user_group_id == 0) {
4700 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4701 }
4702 if (user_group_id == 255) {
4703 /* Value 255 is reserved */
4704 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4705 }
4706 offset += 1;
4707
4708 bool_Bool seen_value_to_inherit = false0;
4709 bool_Bool inherited_config_has_transform_precoding = false0;
4710 int dmrs_configs_seen = 0;
4711
4712 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4713 uint32_t ueid_index = 0;
4714 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4715 dmrs_configs_seen++;
4716
4717 /* Subtree */
4718 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4719 tvb, offset, 0, "",
4720 "Entry");
4721 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4722
4723 /* entryType (3 bits) */
4724 uint32_t entry_type;
4725 proto_item *entry_type_ti;
4726 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4727 if (entry_type > 3) {
4728 proto_item_append_text(entry_type_ti, " (reserved)");
4729 }
4730
4731 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4732 unsigned int dmrs_port_number;
4733 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);
4734 if (dmrs_port_number > 11) {
4735 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4736 }
4737 offset += 1;
4738
4739 /* What follows depends upon entryType */
4740 switch (entry_type) {
4741 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4742 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4743 /* No further fields for these */
4744 /* Error here if no previous values to inherit!! */
4745 if (!seen_value_to_inherit) {
4746 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4747 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4748
4749 }
4750 /* TODO: would be useful to repeat whole inherited config here? */
4751 break;
4752
4753 case 2: /* transform precoding disabled */
4754 case 3: /* transform precoding enabled */
4755 {
4756 /* Type 2/3 are very similar.. */
4757
4758 /* ueIdReset (1 bit) */
4759 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4760 /* posMeas (1 bit) */
4761 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4762
4763 /* dmrsSymbolMask (14 bits) */
4764 static int * const dmrs_symbol_mask_flags[] = {
4765 &hf_oran_dmrs_symbol_mask_s13,
4766 &hf_oran_dmrs_symbol_mask_s12,
4767 &hf_oran_dmrs_symbol_mask_s11,
4768 &hf_oran_dmrs_symbol_mask_s10,
4769 &hf_oran_dmrs_symbol_mask_s9,
4770 &hf_oran_dmrs_symbol_mask_s8,
4771 &hf_oran_dmrs_symbol_mask_s7,
4772 &hf_oran_dmrs_symbol_mask_s6,
4773 &hf_oran_dmrs_symbol_mask_s5,
4774 &hf_oran_dmrs_symbol_mask_s4,
4775 &hf_oran_dmrs_symbol_mask_s3,
4776 &hf_oran_dmrs_symbol_mask_s2,
4777 &hf_oran_dmrs_symbol_mask_s1,
4778 &hf_oran_dmrs_symbol_mask_s0,
4779 NULL((void*)0)
4780 };
4781 proto_tree_add_bitmask(entry_tree, tvb, offset,
4782 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4783 offset += 2;
4784
4785 /* scrambling */
4786 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4787 offset += 2;
4788
4789 /* nscid (1 bit) */
4790 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4791
4792 /* These 5 bits differ depending upon entry type */
4793 if (entry_type == 2) { /* type 2 */
4794 /* dType (1 bit) */
4795 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4796 /* cdmWithoutData (2 bits) */
4797 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4798 /* lambda (2 bits) */
4799 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4800 }
4801 else { /* type 3 */
4802 /* reserved (1 bit) */
4803 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4804 /* lowPaprType (2 bits) */
4805 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4806 /* hoppingMode (2 bits) */
4807 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4808 }
4809
4810 /* firstPrb (9 bits) */
4811 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4812 offset += 1;
4813 /* lastPrb (9 bits) */
4814 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4815 offset += 2;
4816 /* Reserved (16 bits) */
4817 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4818 offset += 2;
4819
4820 /* Could now see entry types 0 or 1 - they have these values to inherit */
4821 seen_value_to_inherit = true1;
4822 inherited_config_has_transform_precoding = (entry_type == 3);
4823 break;
4824 }
4825
4826 default:
4827 /* reserved - expert info */
4828 break;
4829 }
4830
4831 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4832 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4833 proto_item_set_end(entry_ti, tvb, offset);
4834
4835 if (entry_type <= 1) {
4836 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4837 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4838 }
4839 }
4840
4841 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4842 break;
4843 }
4844
4845 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4846 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4847 where each layer could be one or apply to all layers. */
4848 {
4849 /* TODO: should only appear in one section of a message - check? */
4850 unsigned layer = 0;
4851 proto_item *layer_ti;
4852 while (offset+7 <= (extension_start_offset + extlen*4)) {
4853 /* Layer subtree */
4854 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4855 tvb, offset, 7, "",
4856 "Layer");
4857 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4858
4859 /* All 14 symbols for a layer (or all layers) */
4860 for (unsigned s=0; s < 14; s++) {
4861 proto_item *sym_ti;
4862 /* txWinForOnAirSymbol */
4863 unsigned int tx_win_for_on_air_symbol;
4864 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4865 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4866 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4867 if (tx_win_for_on_air_symbol == 0x0F) {
4868 /* Ordering not affected */
4869 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4870 }
4871 else {
4872 proto_item_append_text(sym_ti, " (sym %u)", s);
4873 }
4874 if (s % 2) {
4875 offset += 1;
4876 }
4877 }
4878
4879 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4880 proto_item_append_text(extension_ti, " (layer %u)", layer);
4881 }
4882 /* Set layer subtree label */
4883 if (layer == 1) {
4884 proto_item_append_text(layer_ti, " (all)");
4885 proto_item_append_text(extension_ti, " (all)");
4886 }
4887 if (layer == 0) {
4888 /* TODO: are no layers valid? What does it mean? */
4889 proto_item_append_text(extension_ti, " (none)");
4890 }
4891 break;
4892 }
4893
4894 case 26: /* SE 26: Frequency offset feedback */
4895 /* Reserved (8 bits) */
4896 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4897 offset += 1;
4898 /* Reserved (1 bit) */
4899 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4900 /* numFoFb (7 bits) */
4901 unsigned num_fo_fb;
4902 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4903 offset += 1;
4904
4905 /* Add each freqOffsetFb value */
4906 for (unsigned n=0; n < num_fo_fb; n++) {
4907 unsigned freq_offset_fb;
4908 /* freqOffsetFb (16 bits) */
4909 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4910 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4911 /* Show if maps onto a -ve number */
4912 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4913 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4914 }
4915 proto_item_append_text(offset_ti, " [#%u]", n+1);
4916 offset += 2;
4917 }
4918 break;
4919
4920 case 27: /* SE 27: O-DU controlled dimensionality reduction */
4921 {
4922 /* Hidden filter for bf (DMRS BF) */
4923 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4924 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4925
4926 /* beamType (2 bits) */
4927 unsigned beam_type;
4928 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
4929 /* reserved (6 bits) */
4930 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
4931 offset += 1;
4932
4933 /* numElements */
4934 unsigned num_elements;
4935 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);
4936 if (num_elements == 0) {
4937 num_elements = 256;
4938 proto_item_append_text(num_elements_ti, " (256");
4939 }
4940
4941 offset += 1;
4942
4943 /* beamId value(s) */
4944 switch (beam_type) {
4945 case 0:
4946 for (unsigned n=0; n < num_elements; n++) {
4947 /* reserved (1 bit) + beamId */
4948 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4949 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4950 offset += 2;
4951 }
4952 break;
4953 case 1:
4954 /* reserved (1 bit) + beamId */
4955 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4956 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4957 offset += 2;
4958 break;
4959 default:
4960 /* Unknown type... */
4961 break;
4962 }
4963 break;
4964 }
4965
4966 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
4967 {
4968 /* reserved (3 bits) */
4969 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
4970 /* numUeSinrRpt (5 bits) */
4971 uint32_t num_ue_sinr_rpt;
4972 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
4973 offset += 1;
4974
4975 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
4976 /* reserved (1 bit) */
4977 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
4978 tvb, offset, 1);
4979
4980 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
4981 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
4982 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4983 if (n % 2) {
4984 offset += 1;
4985 }
4986 }
4987
4988 /* May need to skip beyond half-used byte */
4989 if (num_ue_sinr_rpt % 2) {
4990 offset += 1;
4991 }
4992 break;
4993 }
4994
4995 case 29: /* SE 29: Cyclic delay adjustment */
4996 /* reserved (4 bits) */
4997 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4998 /* cdScgSize (4 bits) */
4999 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5000 offset += 1;
5001
5002 /* cdScgPhaseStep */
5003 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5004 offset += 1;
5005 break;
5006
5007 case 30: /* SE 30: PUSCH repetition indication */
5008 {
5009 /* Only valid for UL */
5010 if (!tap_info->uplink) {
5011 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5012 }
5013
5014 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5015
5016 /* reserved (4 bits) */
5017 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5018 /* numRepUe (4 bits) */
5019 uint8_t num_rep_ue;
5020 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5021 offset ++;
5022 /* reserved (8 bits) */
5023 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5024 offset += 1;
5025
5026 if (num_rep_ue == 1) {
5027 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5028 /* reserved (1 bit) */
5029 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5030 /* isLastRep (1 bit). Value meaningless here? */
5031 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5032 /* repIndex (6 bits) */
5033 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5034 offset += 1;
5035
5036 /* reserved (2 bits) */
5037 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5038 /* numReps (6 bits) */
5039 uint8_t num_reps;
5040 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5041 /* TODO: should numReps be 0 here? */
5042 offset += 1;
5043
5044 /* reserved (2 bits) */
5045 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5046 offset += 2;
5047
5048 }
5049 else {
5050 /* SE10 present */
5051 bool_Bool is_last_rep = false0;
5052 /* TODO: should is_last_rep (also) cause loop exit? */
5053 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5054 /* reserved (1 bit) */
5055 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5056 /* isLastRep (1 bit) */
5057 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5058 /* repIndex (6 bits) */
5059 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5060 offset += 1;
5061
5062 /* reserved (2 bits) */
5063 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5064 /* numReps (6 bits) */
5065 uint8_t num_reps;
5066 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);
5067 /* TODO: values 33-63 are reserved */
5068 if (num_reps > 32) {
5069 proto_item_append_text(num_reps_ti, " (reserved)");
5070 }
5071 offset += 1;
5072
5073 for (uint8_t rep=0; rep < num_reps; rep++) {
5074 /* reserved (1 bit) */
5075 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5076 /* repUeId (15 bits) */
5077 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5078 uint16_t ueid;
5079 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5080
5081 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5082 bool_Bool matched = false0;
5083 for (unsigned u=0; u < number_of_ueids; u++) {
5084 if (ueid == ueids[u])
5085 matched = true1;
5086 }
5087 if (!matched) {
5088 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5089 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5090 }
5091 offset += 2;
5092 }
5093 }
5094 }
5095 break;
5096 }
5097
5098
5099 default:
5100 /* Other/unexpected extension types */
5101 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5102 "SE %u (%s) not supported by dissector",
5103 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5104 ext_unhandled = true1;
5105 break;
5106 }
5107
5108 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5109 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5110 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5111 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5112 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5113 extlen*4, offset-extension_start_offset);
5114 }
5115
5116 /* Move offset to beyond signalled length of extension */
5117 offset = extension_start_offset + (extlen*4);
5118
5119 /* Set length of extension header. */
5120 proto_item_set_len(extension_ti, extlen*4);
5121 }
5122 /* End of section extension handling */
5123
5124 /* Tap section beamId if not overwritten by SEs */
5125 if (!section_beamId_ignored && section_beamId != 0) {
5126 add_beam_id_to_tap(tap_info, section_beamId);
5127 }
5128
5129
5130 /* RRM measurement reports have measurement reports *after* extensions */
5131 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5132 {
5133 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5134 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5135 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5136
5137 bool_Bool mf;
5138 do {
5139 /* Measurement report subtree */
5140 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5141 tvb, offset, 1, "", "Measurement Report");
5142 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5143 unsigned report_start_offset = offset;
5144
5145 /* measurement flag (i.e., more reports after this one) (1 bit) */
5146 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5147
5148 /* measTypeId (7 bits) */
5149 uint32_t meas_type_id;
5150 proto_item *meas_type_id_ti;
5151 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);
5152 offset += 1;
5153
5154 /* Common to all measurement types */
5155 unsigned num_elements = 0;
5156 if (meas_type_id == 6) {
5157 /* numElements */
5158 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5159 }
5160 else {
5161 /* All other meas ids have a reserved byte */
5162 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5163 }
5164 offset += 1;
5165
5166 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5167 unsigned meas_data_size;
5168 proto_item *meas_data_size_ti;
5169 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);
5170 meas_data_size *= 4;
5171 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5172 offset += 2;
5173
5174 /* Summary for measurement report root */
5175 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5176 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5177 /* And section header */
5178 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5179 /* And Info column */
5180 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5181
5182 /* Handle specific message type fields */
5183 switch (meas_type_id) {
5184 case 1:
5185 {
5186 /* ueTae */
5187 unsigned ue_tae;
5188 proto_item *ue_tae_ti;
5189 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5190 /* Show if maps onto a -ve number */
5191 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5192 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5193 }
5194 offset += 2;
5195
5196 /* Reserved (16 bits) */
5197 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5198 offset += 2;
5199 break;
5200 }
5201 case 2:
5202 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5203 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5204 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5205 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5206 unsigned ue_layer_power;
5207 proto_item *ue_layer_power_ti;
5208 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);
5209 /* Show if maps onto a -ve number */
5210 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5211 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5212 }
5213 offset += 2;
5214 }
5215 /* padding out to 4 bytes */
5216 break;
5217 case 3:
5218 {
5219 /* ueFreqOffset */
5220 unsigned ue_freq_offset;
5221 proto_item *ue_freq_offset_ti;
5222 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);
5223 /* Show if maps onto a -ve number */
5224 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5225 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5226 }
5227 offset += 2;
5228
5229 /* Reserved (16 bits) */
5230 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5231 offset += 2;
5232 break;
5233 }
5234 case 4:
5235 case 5:
5236 /* reserved (2 bits) */
5237 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5238 /* symbolMask (14 bits) */
5239 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5240
5241 /* 2 bytes for each PRB ipnPower */
5242 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5243 /* Skip if should not be reported */
5244 if (!prbs_for_st10_type5[prb]) {
5245 continue;
5246 }
5247 unsigned ipn_power;
5248 proto_item *ipn_power_ti;
5249 /* ipnPower (2 bytes) */
5250 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5251 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5252 /* Show if maps onto a -ve number */
5253 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5254 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5255 }
5256 offset += 2;
5257 }
5258 /* padding out to 4 bytes */
5259 break;
5260 case 6:
5261 /* antDmrsSnrVal entries */
5262 for (unsigned n=0; n < num_elements; n++) {
5263 unsigned snr_value;
5264 proto_item *snr_value_ti;
5265 /* antDmrsSnrVal (2 bytes) */
5266 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);
5267 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5268 /* Show if maps onto a -ve number */
5269 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5270 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5271 }
5272 offset += 2;
5273 }
5274 break;
5275 case 7:
5276 {
5277 /* UE positioning measurement report */
5278 float start_value;
5279
5280 /* ueAzAoa (16 bits) */
5281 uint32_t ue_az_aoa;
5282 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);
5283 if (ue_az_aoa <= 0xE0F) {
5284 if (ue_az_aoa >= 0x0708) {
5285 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5286 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5287 }
5288 else {
5289 start_value = 180 + (ue_az_aoa * (float)0.1);
5290 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5291 }
5292 }
5293 else if (ue_az_aoa == 0xffff) {
5294 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5295 }
5296 else {
5297 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5298 }
5299 offset += 2;
5300
5301 /* Reserved (16 bits) */
5302 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5303 offset += 2;
5304
5305 /* ueZeAoa (16 bits) */
5306 uint32_t ue_ze_aoa;
5307 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);
5308 if (ue_ze_aoa <= 0x707) {
5309 start_value = ue_ze_aoa * (float)0.1;
5310 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5311 }
5312 else if (ue_az_aoa == 0xffff) {
5313 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5314 }
5315 else {
5316 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5317 }
5318 offset += 2;
5319
5320 /* Reserved (16 bits) */
5321 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5322 offset += 2;
5323
5324 /* uePosToaOffset (16 bits) */
5325 uint32_t ue_pos_toa_offset;
5326 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);
5327 if (ue_pos_toa_offset == 0) {
5328 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5329 }
5330 else if (ue_pos_toa_offset <= 0x7fff) {
5331 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5332 }
5333 else if (ue_pos_toa_offset == 0x8000) {
5334 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5335 }
5336 else {
5337 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5338 }
5339 offset += 2;
5340
5341 /* Reserved (16 bits) */
5342 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5343 offset += 2;
5344 break;
5345 }
5346 case 8:
5347 {
5348 /* UE radial speed measurement report */
5349
5350 /* ueRadialSpeed (16 bits) */
5351 uint32_t radial_speed;
5352 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);
5353 if (radial_speed <= 10000) {
5354 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5355 }
5356 else if (radial_speed == 0x8000) {
5357 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5358 }
5359 else {
5360 proto_item_append_text(radial_speed_ti, " (reserved value)");
5361 }
5362 offset += 2;
5363
5364 /* Reserved (16 bits) */
5365 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5366 offset += 2;
5367 break;
5368 }
5369
5370 default:
5371 /* Anything else is not expected */
5372 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5373 "measTypeId %u (%s) not supported - only 1-6 are expected",
5374 meas_type_id,
5375 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5376 break;
5377
5378 }
5379
5380 /* Pad out to next 4 bytes */
5381 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5382
5383 /* TODO: verify dissected size of report vs meas_data_size? */
5384
5385 /* End of measurement report tree */
5386 proto_item_set_end(mr_ti, tvb, offset);
5387 } while (mf);
5388 }
5389
5390 /* Request for RRM Measurements has measurement commands after extensions */
5391 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5392 {
5393 bool_Bool mf = true1;
5394 do {
5395 /* Measurement command subtree */
5396 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5397 tvb, offset, 8, "", "Measurement Command");
5398 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5399
5400 /* mf (1 bit). 1st measurement command is always preset */
5401 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5402
5403 /* measTypeId (7 bits) */
5404 uint32_t meas_type_id;
5405 proto_item *meas_type_id_ti;
5406 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);
5407 offset += 1;
5408
5409 proto_item *meas_command_ti;
5410 uint32_t meas_command_size;
5411
5412 switch (meas_type_id) {
5413 case 5: /* command for IpN for unallocated PRBs */
5414 /* reserved (1 byte) */
5415 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5416 offset += 1;
5417 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5418 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);
5419 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5420 offset += 2;
5421 /* reserved (2 bits) */
5422 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5423 /* symbolMask (14 bits) */
5424 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5425 /* reserved (16 bits) */
5426 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5427 offset += 2;
5428 break;
5429
5430 default:
5431 /* Anything else is not expected */
5432 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5433 "measTypeId %u (%s) not supported - only 5 is expected",
5434 meas_type_id,
5435 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5436 break;
5437 }
5438 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5439
5440 } while (mf);
5441 }
5442
5443 /* Set extent of overall section */
5444 proto_item_set_len(sectionHeading, offset);
5445
5446 return offset;
5447}
5448
5449/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5450/* bit_width and comp_meth are out params */
5451static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5452 bool_Bool cplane, bool_Bool ignore,
5453 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5454 oran_tap_info *tap_info)
5455{
5456 /* Subtree */
5457 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5458 tvb, offset, 1, "",
5459 "udCompHdr");
5460 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5461
5462 /* udIqWidth */
5463 uint32_t hdr_iq_width;
5464 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5465 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5466 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5467
5468 /* udCompMeth */
5469 uint32_t ud_comp_meth;
5470 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5471 if (comp_meth) {
5472 *comp_meth = ud_comp_meth;
5473 }
5474
5475 /* Populate tap header with compression settings */
5476 if (!ignore) {
5477 tap_info->compression_methods |= (1 << ud_comp_meth);
5478 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))
;
5479 /* Summary */
5480 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5481 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5482 }
5483 else {
5484 proto_item_append_text(udcomphdr_ti, " (ignored)");
5485 if (hdr_iq_width || ud_comp_meth) {
5486 if (cplane) {
5487 /* Only ignore DL for cplane */
5488 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5489 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5490 tvb_get_uint8(tvb, offset));
5491 }
5492 else {
5493 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5494 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5495 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5496 tvb_get_uint8(tvb, offset));
5497 */
5498 }
5499
5500 }
5501 }
5502 return offset+1;
5503}
5504
5505/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5506/* bit_width and comp_meth are out params */
5507static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5508 unsigned comp_meth,
5509 uint32_t *exponent, uint16_t *sReSMask,
5510 bool_Bool for_sinr)
5511{
5512 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5513 /* sinrCompParam only present when bfp is used */
5514 return offset;
5515 }
5516
5517 if (comp_meth == COMP_NONE0 ||
5518 comp_meth == COMP_MODULATION4 ||
5519 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5520
5521 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5522 return offset;
5523 }
5524
5525 /* Subtree */
5526 unsigned start_offset = offset;
5527 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5528 tvb, offset, 1, "",
5529 (for_sinr) ? "sinrCompParam" : "udCompParam");
5530 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5531
5532 /* Show comp_meth as a generated field */
5533 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5534 proto_item_set_generated(meth_ti);
5535
5536 uint32_t param_exponent;
5537 uint64_t param_sresmask;
5538
5539 static int * const sres_mask_flags[] = {
5540 &hf_oran_sReSMask_re12,
5541 &hf_oran_sReSMask_re11,
5542 &hf_oran_sReSMask_re10,
5543 &hf_oran_sReSMask_re9,
5544 &hf_oran_sReSMask_re8,
5545 &hf_oran_sReSMask_re7,
5546 &hf_oran_sReSMask_re6,
5547 &hf_oran_sReSMask_re5,
5548 &hf_oran_sReSMask_re4,
5549 &hf_oran_sReSMask_re3,
5550 &hf_oran_sReSMask_re2,
5551 &hf_oran_sReSMask_re1,
5552 NULL((void*)0)
5553 };
5554
5555 switch (comp_meth) {
5556 case COMP_BLOCK_FP1: /* 1 */
5557 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5558 /* reserved (4 bits) */
5559 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5560 /* exponent (4 bits) */
5561 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5562 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5563 *exponent = param_exponent;
5564 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5565 offset += 1;
5566 break;
5567
5568 case COMP_BLOCK_SCALE2: /* 2 */
5569 /* Separate into integer and fractional bits? */
5570 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5571 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5572 offset++;
5573 break;
5574
5575 case COMP_U_LAW3: /* 3 */
5576 /* compBitWidth, compShift */
5577 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5578 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5579 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5580 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5581 offset += 1;
5582 break;
5583
5584 case BFP_AND_SELECTIVE_RE5: /* 5 */
5585 {
5586 /* sReSMask (exponent in middle!) */
5587 proto_item *sresmask_ti;
5588 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5589 hf_oran_sReSMask,
5590 ett_oran_sresmask,
5591 sres_mask_flags,
5592 ENC_NA0x00000000,
5593 &param_sresmask);
5594
5595 /* Get rid of exponent-shaped gap */
5596 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5597 unsigned res = 0;
5598 for (unsigned n=0; n < 12; n++) {
5599 if ((param_sresmask >> n) & 0x1) {
5600 res++;
5601 }
5602 }
5603 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5604
5605 /* exponent */
5606 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5607 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5608 *sReSMask = (uint16_t)param_sresmask;
5609 *exponent = param_exponent;
5610
5611 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5612 offset += 2;
5613 break;
5614 }
5615
5616 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5617 {
5618 /* sReSMask (exponent in middle!) */
5619 proto_item *sresmask_ti;
5620
5621 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5622 hf_oran_sReSMask,
5623 ett_oran_sresmask,
5624 sres_mask_flags,
5625 ENC_NA0x00000000,
5626 &param_sresmask);
5627
5628 /* Get rid of reserved-shaped gap */
5629 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5630 unsigned res = 0;
5631 for (unsigned n=0; n < 12; n++) {
5632 if ((param_sresmask >> n) & 0x1) {
5633 res++;
5634 }
5635 }
5636 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5637
5638 /* reserved (4 bits) */
5639 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5640 *sReSMask = (uint16_t)param_sresmask;
5641
5642 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5643 offset += 2;
5644 break;
5645 }
5646
5647 default:
5648 /* reserved (set to all zeros), but how many bytes?? */
5649 break;
5650 }
5651
5652 proto_item_set_len(udcompparam_ti, offset-start_offset);
5653 return offset;
5654}
5655
5656
5657/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5658/* bit_width and comp_meth are out params */
5659static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5660 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5661{
5662 /* Subtree */
5663 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5664 tvb, offset, 1, "",
5665 "ciCompHdr");
5666 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5667
5668 /* ciIqWidth */
5669 uint32_t hdr_iq_width;
5670 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5671 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5672 if (bit_width) {
5673 *bit_width = hdr_iq_width;
5674 }
5675 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5676
5677 /* ciCompMeth */
5678 uint32_t ci_comp_meth;
5679 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5680 if (comp_meth) {
5681 *comp_meth = ci_comp_meth;
5682 }
5683
5684 /* ciCompOpt */
5685 uint32_t opt;
5686 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5687 *comp_opt = opt;
5688 offset += 1;
5689
5690 /* Summary */
5691 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5692 hdr_iq_width,
5693 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5694 (*comp_opt) ? "compression per PRB" : "compression per UE");
5695 return offset;
5696}
5697
5698static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5699{
5700 unsigned version;
5701 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5702 if (version != 1) {
5703 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5704 "PayloadVersion %u not supported by dissector (only 1 is known)",
5705 version);
5706 /* TODO: should throw an exception? */
5707 }
5708}
5709
5710static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5711 ack_nack_request_t *request)
5712{
5713 /* Request frame */
5714 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5715 tvb, 0, 0, request->request_frame_number);
5716 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5717
5718 /* Work out gap between frames (in ms) */
5719 int seconds_between_packets = (int)
5720 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5721 int nseconds_between_packets =
5722 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5723
5724 int total_gap = (seconds_between_packets*1000) +
5725 ((nseconds_between_packets+500000) / 1000000);
5726
5727 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5728 tvb, 0, 0, total_gap);
5729 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5730
5731 /* Type of request */
5732 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5733 tvb, 0, 0, request->requestType);
5734 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5735}
5736
5737static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5738 ack_nack_request_t *response)
5739{
5740 if (response->response_frame_number == 0) {
5741 /* Requests may not get a response, and can't always tell when to expect one */
5742 return;
5743 }
5744
5745 /* Response frame */
5746 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5747 tvb, 0, 0, response->response_frame_number);
5748 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5749
5750 /* Work out gap between frames (in ms) */
5751 int seconds_between_packets = (int)
5752 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5753 int nseconds_between_packets =
5754 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5755
5756 int total_gap = (seconds_between_packets*1000) +
5757 ((nseconds_between_packets+500000) / 1000000);
5758
5759 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5760 tvb, 0, 0, total_gap);
5761 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5762}
5763
5764
5765
5766/* Control plane dissector (section 7). */
5767static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5768 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5769{
5770 /* Hidden filter for plane */
5771 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5772 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5773
5774 /* Set up structures needed to add the protocol subtree and manage it */
5775 unsigned offset = 0;
5776
5777 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5778 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5779
5780 tap_info->userplane = false0;
5781
5782 /* Create display subtree for the protocol */
5783 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5784 proto_item_append_text(protocol_item, "-C");
5785 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5786
5787 /* ecpriRtcid (eAxC ID) */
5788 uint16_t eAxC;
5789 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5790 tap_info->eaxc = eAxC;
5791
5792 /* Look up any existing conversation state for eAxC+plane */
5793 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
5794 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
5795
5796 /* Message identifier */
5797 uint32_t seq_id, sub_seq_id, e;
5798 proto_item *seq_id_ti;
5799 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
5800
5801 /* Section common subtree */
5802 int section_tree_offset = offset;
5803 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
5804 tvb, offset, 0, "", "C-Plane Section Type ");
5805 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
5806
5807 /* Peek ahead at the section type */
5808 uint32_t sectionType = 0;
5809 sectionType = tvb_get_uint8(tvb, offset+5);
5810
5811 uint32_t scs = 0;
5812 proto_item *scs_ti = NULL((void*)0);
5813
5814 /* dataDirection */
5815 uint32_t direction = 0;
5816 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
5817 tap_info->uplink = (direction==0);
5818
5819 /* Update/report status of conversation */
5820 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
5821
5822 if (state == NULL((void*)0)) {
5823 /* Allocate new state */
5824 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
5825 state->ack_nack_requests = wmem_tree_new(wmem_epan_scope());
5826 wmem_tree_insert32(flow_states_table, key, state);
5827 }
5828
5829 /* Check sequence analysis status */
5830 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
5831 /* Store this result */
5832 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
5833 result->unexpected_seq_number = true1;
5834 result->expected_sequence_number = state->next_expected_sequence_number[direction];
5835 result->previous_frame = state->last_frame[direction];
5836 wmem_tree_insert32(flow_results_table, pinfo->num, result);
5837 }
5838 /* Update conversation info */
5839 state->last_frame[direction] = pinfo->num;
5840 state->last_frame_seen[direction] = true1;
5841 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
5842 }
5843
5844 /* Show any issues associated with this frame number */
5845 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
5846 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
5847 expert_add_info_format(pinfo, seq_id_ti,
5848 (direction == DIR_UPLINK0) ?
5849 &ei_oran_cplane_unexpected_sequence_number_ul :
5850 &ei_oran_cplane_unexpected_sequence_number_dl,
5851 "Sequence number %u expected, but got %u",
5852 result->expected_sequence_number, seq_id);
5853
5854 /* Update tap info */
5855 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
5856 /* Don't get confused by being slightly out of order.. */
5857 if (missing_sns < 128) {
5858 tap_info->missing_sns = missing_sns;
5859 }
5860 else {
5861 tap_info->missing_sns = 0;
5862 }
5863
5864 /* TODO: could add previous/next frames (in seqId tree?) ? */
5865 }
5866
5867 /* payloadVersion */
5868 dissect_payload_version(section_tree, tvb, pinfo, offset);
5869
5870 /* filterIndex */
5871 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
5872 /* scs (for ST4 and ST8) */
5873 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
5874 }
5875 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
5876 /* reserved (4 bits) */
5877 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5878 }
5879 else if (sectionType != SEC_C_LAA) {
5880 /* filterIndex (most common case) */
5881 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
5882 }
5883 offset += 1;
5884
5885 unsigned ref_a_offset = offset;
5886 /* frameId */
5887 uint32_t frameId = 0;
5888 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
5889 tap_info->frame = frameId;
5890 offset += 1;
5891
5892 /* subframeId */
5893 uint32_t subframeId = 0;
5894 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
5895 /* slotId */
5896 uint32_t slotId = 0;
5897 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
5898 tap_info->slot = slotId;
5899 offset++;
5900
5901 /* startSymbolId */
5902 uint32_t startSymbolId = 0;
5903 proto_item *ssid_ti = NULL((void*)0);
5904 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
5905 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
5906 /* symbolId */
5907 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
5908 }
5909 else if (sectionType != SEC_C_LAA) {
5910 /* startSymbolId is in most section types */
5911 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
5912 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
5913 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
5914 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
5915 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
5916 }
5917 }
5918 else {
5919 /* reserved (6 bits) */
5920 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5921 }
5922 offset++;
5923
5924
5925 char id[16];
5926 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
5927 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
5928 proto_item_set_generated(pi);
5929
5930 uint32_t cmd_scope = 0;
5931 bool_Bool st8_ready = false0;
5932
5933 /* numberOfSections (or whatever section has instead) */
5934 uint32_t nSections = 0;
5935 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
5936 /* Slot Control has these fields instead */
5937 /* reserved (4 bits) */
5938 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5939 /* cmdScope (4 bits) */
5940 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
5941 }
5942 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
5943 /* reserved (7 bits) */
5944 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
5945 /* ready (1 bit) */
5946 /* TODO: when set, ready in slotId+1.. */
5947 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
5948 if (!st8_ready) {
5949 /* SCS value is ignored, and may be set to any value by O-RU */
5950 proto_item_append_text(scs_ti, " (ignored)");
5951 }
5952 }
5953 else if (sectionType != SEC_C_LAA) {
5954 /* numberOfSections */
5955 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
5956 }
5957 else {
5958 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5959 }
5960 offset++;
5961
5962 /* sectionType */
5963 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
5964 offset += 1;
5965
5966 /* Check that dataDirection is consistent with section type */
5967 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
5968 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
5969 }
5970 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
5971 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
5972 }
5973
5974 /* Note this section type in stats */
5975 if (sectionType < SEC_C_MAX_INDEX) {
5976 tap_info->section_types[sectionType] = true1;
5977 }
5978
5979 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
5980 unsigned bit_width = 0;
5981 unsigned comp_meth = 0;
5982 proto_item *comp_meth_ti;
5983 unsigned ci_comp_method = 0;
5984 uint8_t ci_comp_opt = 0;
5985
5986 uint32_t num_ues = 0;
5987 uint32_t number_of_acks = 0, number_of_nacks = 0;
5988
5989 uint32_t num_sinr_per_prb = 0;
5990
5991 switch (sectionType) {
5992 case SEC_C_UNUSED_RB: /* Section Type 0 */
5993 /* timeOffset */
5994 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5995 offset += 2;
5996 /* frameStructure */
5997 offset = dissect_frame_structure(section_tree, tvb, offset,
5998 subframeId, slotId);
5999
6000 /* cpLength */
6001 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6002 offset += 2;
6003 /* reserved (8 bits) */
6004 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6005 offset += 1;
6006 break;
6007
6008 case SEC_C_NORMAL: /* Section Type 1 */
6009 case SEC_C_UE_SCHED: /* Section Type 5 */
6010 /* udCompHdr */
6011 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6012 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6013 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6014 /* reserved (8 bits) */
6015 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6016 offset += 1;
6017 break;
6018
6019 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6020 break;
6021
6022 case SEC_C_PRACH: /* Section Type 3 */
6023 /* timeOffset */
6024 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6025 offset += 2;
6026 /* frameStructure */
6027 offset = dissect_frame_structure(section_tree, tvb, offset,
6028 subframeId, slotId);
6029 /* cpLength */
6030 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6031 offset += 2;
6032 /* udCompHdr */
6033 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6034 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6035 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6036 break;
6037
6038 case SEC_C_CH_INFO: /* Section Type 6 */
6039 /* numberOfUEs */
6040 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6041 offset += 1;
6042 /* ciCompHdr (was reserved) */
6043 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6044
6045 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6046 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6047 if (nSections == 0 || num_ues > nSections) {
6048 nSections = num_ues;
6049 }
6050 break;
6051
6052 case SEC_C_RSVD2:
6053 break;
6054
6055 case SEC_C_LAA: /* Section Type 7 */
6056 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6057 offset += 2;
6058 break;
6059
6060 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6061 /* numberOfAcks (1 byte) */
6062 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6063 offset += 1;
6064 /* numberOfNacks (1 byte) */
6065 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6066 offset += 1;
6067
6068 /* Show ACKs and NACKs. For both, try to link back to request. */
6069 for (unsigned int n=1; n <= number_of_acks; n++) {
6070 uint32_t ackid;
6071 proto_item *ack_ti;
6072 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6073 offset += 2;
6074
6075 /* Look up request table in state (which really should be set by now, but test anyway). */
6076 if (state && state->ack_nack_requests) {
6077 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6078 if (request != NULL((void*)0)) {
6079 /* On first pass, update with this response */
6080 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6081 request->response_frame_number = pinfo->num;
6082 request->response_frame_time = pinfo->abs_ts;
6083 }
6084
6085 /* Show request details */
6086 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6087 }
6088 else {
6089 /* Request not found */
6090 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6091 "Response for ackId=%u received, but no request found",
6092 ackid);
6093 }
6094 }
6095 }
6096 for (unsigned int m=1; m <= number_of_nacks; m++) {
6097 uint32_t nackid;
6098 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6099 offset += 2;
6100
6101 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6102 "Received Nack for ackNackId=%u",
6103 nackid);
6104
6105 /* Look up request table in state. */
6106 if (state && state->ack_nack_requests) {
6107 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6108 if (request) {
6109 /* On first pass, update with this response */
6110 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6111 request->response_frame_number = pinfo->num;
6112 request->response_frame_time = pinfo->abs_ts;
6113 }
6114
6115 /* Show request details */
6116 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6117 }
6118 else {
6119 /* Request not found */
6120 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6121 "Response for nackId=%u received, but no request found",
6122 nackid);
6123 }
6124 }
6125 }
6126 break;
6127
6128 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6129 {
6130 /* numSinrPerPrb (3 bits) */
6131 proto_item *nspp_ti;
6132 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);
6133 switch (num_sinr_per_prb) {
6134 case 0:
6135 num_sinr_per_prb = 1; break;
6136 case 1:
6137 num_sinr_per_prb = 2; break;
6138 case 2:
6139 num_sinr_per_prb = 3; break;
6140 case 3:
6141 num_sinr_per_prb = 4; break;
6142 case 4:
6143 num_sinr_per_prb = 6; break;
6144 case 5:
6145 num_sinr_per_prb = 12; break;
6146
6147 default:
6148 proto_item_append_text(nspp_ti, " (invalid)");
6149 num_sinr_per_prb = 1;
6150 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6151 "Invalid numSinrPerPrb value (%u)",
6152 num_sinr_per_prb);
6153 }
6154
6155 /* oruControlSinrSlotMaskId (5 bits) */
6156 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6157 offset += 1;
6158 /* reserved (8 bits) */
6159 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6160 offset += 1;
6161 break;
6162 }
6163
6164 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6165 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6166 /* reserved (16 bits) */
6167 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6168 offset += 2;
6169 break;
6170 };
6171
6172 /* Update udCompHdr details in state for UL U-Plane */
6173 if (state && direction==0) {
6174 switch (sectionType) {
6175 case SEC_C_NORMAL: /* Section Type 1 */
6176 case SEC_C_PRACH: /* Section Type 3 */
6177 case SEC_C_UE_SCHED: /* Section Type 5 */
6178 state->ul_ud_comp_hdr_set = true1;
6179 state->ul_ud_comp_hdr_bit_width = bit_width;
6180 state->ul_ud_comp_hdr_compression = comp_meth;
6181 state->ul_ud_comp_hdr_frame = pinfo->num;
6182 break;
6183 default:
6184 break;
6185 }
6186 }
6187
6188
6189 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6190 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6191 frameId, subframeId, slotId, startSymbolId);
6192 if (nSections) {
6193 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6194 }
6195
6196 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6197 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6198
6199 /* Set actual length of C-Plane section header */
6200 proto_item_set_len(section_tree, offset - section_tree_offset);
6201
6202 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6203 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6204 (st8_ready) ? " (Ready)" : " (ACK)");
6205 }
6206
6207
6208 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6209 if (sectionType == SEC_C_SLOT_CONTROL) {
6210 /* numberOfST4Cmds */
6211 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6212 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6213 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6214 if (no_st4_cmds == 0) {
6215 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6216 }
6217 offset += 1;
6218
6219 /* reserved (1 byte) */
6220 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6221 offset += 1;
6222
6223 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6224 proto_item *len_ti;
6225 for (uint32_t n=0; n < no_st4_cmds; n++) {
6226 /* Table 7.4.6-2: Section Type 4 Command common header format */
6227 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6228 tvb, offset, 8, "",
6229 "Type 4 Command common header");
6230 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6231
6232 /* st4CmdType */
6233 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6234 offset += 1;
6235
6236 /* st4CmdLen */
6237 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6238 if (st4_cmd_len == 0) {
6239 /* Meaning of 0 not yet defined (v15.00) */
6240 proto_item_append_text(len_ti, " (reserved)");
6241 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6242 }
6243 else {
6244 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6245 }
6246 offset += 2;
6247
6248 /* numSlots */
6249 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);
6250 if (num_slots == 0) {
6251 proto_item_append_text(slots_ti, " (until changed)");
6252 }
6253 offset += 1;
6254
6255 /* ackNackReqId */
6256 proto_item *ack_nack_req_id_ti;
6257 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);
6258 offset += 2;
6259 if (ack_nack_req_id == 0) {
6260 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6261 }
6262
6263 /* reserved (16 bits) */
6264 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6265 offset += 2;
6266
6267 /* Set common header summary */
6268 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6269 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6270 st4_cmd_len, num_slots, ack_nack_req_id);
6271
6272 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6273 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6274
6275
6276 /* Subtree for this command body */
6277 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6278 tvb, offset, 0, "",
6279 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6280 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6281
6282 unsigned command_start_offset = offset;
6283
6284 /* Check fields compatible with chosen command. */
6285 if (st4_cmd_type==1) {
6286 if (num_slots != 0) {
6287 /* "the value of numSlots should be set to zero for this command type" */
6288 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6289 "numSlots should be zero for ST4 command 1 - found %u",
6290 num_slots);
6291 }
6292 }
6293
6294 if (st4_cmd_type==3 || st4_cmd_type==4) {
6295 if (startSymbolId != 0) {
6296 /* "expected reception window for the commands is the symbol zero reception window" */
6297 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6298 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6299 startSymbolId);
6300 }
6301 }
6302
6303 /* Add format for this command */
6304 switch (st4_cmd_type) {
6305 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6306 {
6307 bool_Bool disable_tdbfns;
6308 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6309
6310 /* Hidden filter for bf */
6311 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6312 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6313
6314 /* reserved (2 bits) */
6315 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6316 /* symbolMask (14 bits) */
6317 uint32_t symbol_mask;
6318 proto_item *symbol_mask_ti;
6319 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6320 /* 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 */
6321 /* lsb is symbol 0 */
6322 for (unsigned s=0; s < 14; s++) {
6323 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6324 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6325 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6326 break;
6327 }
6328 }
6329
6330 /* disableTDBFNs (1 bit) */
6331 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6332
6333 /* tdBeamNum (15 bits) */
6334 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6335 offset += 2;
6336
6337 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6338 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6339 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6340 /* reserved (3 bytes) */
6341 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6342 offset += 3;
6343
6344 if (disable_tdbfns) {
6345 /* No beamnum information to show so get out. */
6346 break;
6347 }
6348
6349 /* Read beam entries until reach end of command length */
6350 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6351
6352 /* disableTDBFWs (1 bit) */
6353 bool_Bool disable_tdbfws;
6354 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6355
6356 /* tdBeamNum (15 bits) */
6357 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6358 offset += 2;
6359
6360 /* Showing BFWs? */
6361 if (!disable_tdbfws) {
6362
6363 /* bfwCompParam */
6364 unsigned exponent = 0;
6365 bool_Bool supported = false0;
6366 unsigned num_trx_entries;
6367 uint16_t *trx_entries;
6368 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6369 &bfwcomphdr_comp_meth, &exponent, &supported,
6370 &num_trx_entries, &trx_entries);
6371
6372 /* Antenna count from preference */
6373 unsigned num_trx = pref_num_bf_antennas;
6374 int bit_offset = offset*8;
6375
6376 for (unsigned trx=0; trx < num_trx; trx++) {
6377 /* Create antenna subtree */
6378 int bfw_offset = bit_offset / 8;
6379 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6380 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6381 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6382
6383 /* I value */
6384 /* Get bits, and convert to float. */
6385 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6386 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6387 /* Add to tree. */
6388 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6389 (bfwcomphdr_iq_width+7)/8, value);
6390 bit_offset += bfwcomphdr_iq_width;
6391 proto_item_append_text(bfw_ti, "I=%f ", value);
6392
6393 /* Leave a gap between I and Q values */
6394 proto_item_append_text(bfw_ti, " ");
6395
6396 /* Q value */
6397 /* Get bits, and convert to float. */
6398 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6399 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6400 /* Add to tree. */
6401 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6402 (bfwcomphdr_iq_width+7)/8, value);
6403 bit_offset += bfwcomphdr_iq_width;
6404 proto_item_append_text(bfw_ti, "Q=%f", value);
6405
6406 proto_item_append_text(bfw_ti, ")");
6407 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6408 }
6409 /* Need to round to next byte */
6410 offset = (bit_offset+7)/8;
6411 }
6412 }
6413 break;
6414 }
6415 case 2: /* TDD_CONFIG_PATTERN */
6416 /* reserved (2 bits) */
6417 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6418 /* dirPattern (14 bits) */
6419 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6420 offset += 2;
6421
6422 /* reserved (2 bits) */
6423 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6424 /* guardPattern (14 bits) */
6425 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6426 offset += 2;
6427 break;
6428
6429 case 3: /* TRX_CONTROL */
6430 {
6431 /* Only allowed cmdScope is ARRAY-COMMAND */
6432 if (cmd_scope != 0) {
6433 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6434 }
6435
6436 /* reserved (2 bits) */
6437 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6438 /* log2MaskBits (4 bits) */
6439 unsigned log2maskbits;
6440 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6441 /* sleepMode (2 bits) */
6442 uint32_t sleep_mode;
6443 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6444 offset += 1;
6445
6446 /* reserved (4 bits) */
6447 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6448 /* numSlotsExt (20 bits) */
6449 uint32_t num_slots_ext;
6450 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);
6451 if (num_slots==0 && num_slots_ext==0) {
6452 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6453 }
6454 else {
6455 /* Time should be rounded up according to SCS */
6456 float total = (float)(num_slots + num_slots_ext);
6457 /* From table 7.5.2.13-3 */
6458 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6459 0, 0, 0, 0, 0, 0, /* reserved */
6460 1000, 1000, 1000, 1000 };
6461 float slot_length = slot_length_by_scs[scs];
6462 /* Only using valid SCS. TODO: is this test ok? */
6463 if (slot_length != 0) {
6464 /* Round up to next slot */
6465 total = ((int)(total / slot_length) + 1) * slot_length;
6466 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6467 }
6468 }
6469 offset += 3;
6470
6471 /* reserved (2 bits) */
6472 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6473
6474 /* symbolMask (14 bits) */
6475 uint32_t symbol_mask;
6476 proto_item *sm_ti;
6477 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6478 if (symbol_mask == 0x0) {
6479 proto_item_append_text(sm_ti, " (wake)");
6480 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6481 }
6482 else if (symbol_mask == 0x3fff) {
6483 proto_item_append_text(sm_ti, " (sleep)");
6484 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6485 }
6486 else {
6487 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6488 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6489 sleep_mode, symbol_mask);
6490 }
6491 offset += 2;
6492
6493 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6494 unsigned antmask_length = 2;
6495 if (log2maskbits >= 4) {
6496 antmask_length = (1 << log2maskbits) / 8;
6497 }
6498 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6499 /* show count */
6500 unsigned antenna_count = 0;
6501 for (unsigned b=0; b < antmask_length; b++) {
6502 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6503 for (unsigned bit=0; bit < 8; bit++) {
6504 if ((1 << bit) & byte) {
6505 antenna_count++;
6506 }
6507 }
6508 }
6509 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6510 offset += antmask_length;
6511
6512 /* Pad to next 4-byte boundary */
6513 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6514 break;
6515 }
6516
6517 case 4: /* ASM (advanced sleep mode) */
6518 /* reserved (2+4=6 bits) */
6519 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6520 /* sleepMode (2 bits) */
6521 uint32_t sleep_mode;
6522 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6523 offset += 1;
6524
6525 /* reserved (4 bits) */
6526 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6527 /* numSlotsExt (20 bits) */
6528 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6529 offset += 3;
6530
6531 /* reserved (2 bits) */
6532 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6533 /* symbolMask (14 bits) */
6534 uint32_t symbol_mask;
6535 proto_item *sm_ti;
6536 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6537 if (symbol_mask == 0x0) {
6538 proto_item_append_text(sm_ti, " (wake)");
6539 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6540 }
6541 else if (symbol_mask == 0x3fff) {
6542 proto_item_append_text(sm_ti, " (sleep)");
6543 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6544 }
6545 else {
6546 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6547 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6548 sleep_mode, symbol_mask);
6549 }
6550 offset += 2;
6551
6552 /* reserved (2 bytes) */
6553 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6554 offset += 2;
6555 break;
6556
6557 default:
6558 /* Error! */
6559 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6560 "Dissected ST4 command (%u) not recognised",
6561 st4_cmd_type);
6562 break;
6563 }
6564
6565 /* Check apparent size of padding (0-3 bytes ok) */
6566 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6567 if (padding_remaining > 3) {
6568 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6569 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6570 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6571 }
6572
6573 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6574 offset = command_start_offset + (st4_cmd_len * 4);
6575
6576 /* Set end of command tree */
6577 proto_item_set_end(command_ti, tvb, offset);
6578
6579 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6580 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6581 /* Add this request into conversation state on first pass */
6582 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)))
;
6583 request_details->request_frame_number = pinfo->num;
6584 request_details->request_frame_time = pinfo->abs_ts;
6585 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6586
6587 wmem_tree_insert32(state->ack_nack_requests,
6588 ack_nack_req_id,
6589 request_details);
6590 }
6591 else {
6592 /* On later passes, try to link forward to ST8 response */
6593 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6594 ack_nack_req_id);
6595 if (response) {
6596 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6597 }
6598 }
6599 }
6600 }
6601 }
6602 /* LAA doesn't have sections either.. */
6603 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6604 /* 7.2.5 Table 6.4-6 */
6605 unsigned mcot;
6606 proto_item *mcot_ti;
6607
6608 /* laaMsgType */
6609 uint32_t laa_msg_type;
6610 proto_item *laa_msg_type_ti;
6611 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6612 /* laaMsgLen */
6613 uint32_t laa_msg_len;
6614 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6615 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6616 if (laa_msg_len == 0) {
6617 proto_item_append_text(len_ti, " (reserved)");
6618 }
6619 offset += 1;
6620
6621 int payload_offset = offset;
6622
6623 /* Payload */
6624 switch (laa_msg_type) {
6625 case 0:
6626 /* LBT_PDSCH_REQ */
6627 /* lbtHandle (16 bits) */
6628 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6629 offset += 2;
6630 /* lbtOffset (10 bits) */
6631 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6632 offset += 1;
6633 /* lbtMode (2 bits) */
6634 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6635 /* reserved (1 bit) */
6636 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6637 /* lbtDeferFactor (3 bits) */
6638 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6639 offset += 1;
6640 /* lbtBackoffCounter (10 bits) */
6641 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6642 offset += 1;
6643 /* MCOT (4 bits) */
6644 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6645 if (mcot<1 || mcot>10) {
6646 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6647 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6648 "MCOT seen with value %u (must be 1-10)", mcot);
6649
6650 }
6651 /* reserved (10 bits) */
6652 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6653 break;
6654 case 1:
6655 /* LBT_DRS_REQ */
6656 /* lbtHandle (16 bits) */
6657 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6658 offset += 2;
6659 /* lbtOffset (10 bits) */
6660 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6661 offset += 1;
6662 /* lbtMode (2 bits) */
6663 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6664 /* reserved (28 bits) */
6665 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6666 break;
6667 case 2:
6668 /* LBT_PDSCH_RSP */
6669 /* lbtHandle (16 bits) */
6670 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6671 offset += 2;
6672 /* lbtPdschRes (2 bits) */
6673 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6674 /* inParSF (1 bit) */
6675 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6676 /* sfStatus (1 bit) */
6677 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6678 /* sfnSf (12 bits) */
6679 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6680 offset += 2;
6681 /* reserved (24 bits) */
6682 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6683 break;
6684 case 3:
6685 /* LBT_DRS_RSP */
6686 /* lbtHandle (16 bits) */
6687 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6688 offset += 2;
6689 /* lbtDrsRes (1 bit) */
6690 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6691 /* reserved (7 bits) */
6692 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6693 break;
6694 case 4:
6695 /* LBT_Buffer_Error */
6696 /* lbtHandle (16 bits) */
6697 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6698 offset += 2;
6699 /* lbtBufErr (1 bit) */
6700 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6701 /* reserved (7 bits) */
6702 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6703 break;
6704 case 5:
6705 /* LBT_CWCONFIG_REQ */
6706 /* lbtHandle (16 bits) */
6707 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6708 offset += 2;
6709 /* lbtCWConfig_H (8 bits) */
6710 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6711 offset += 1;
6712 /* lbtCWConfig_T (8 bits) */
6713 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6714 offset += 1;
6715 /* lbtMode (2 bits) */
6716 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6717 /* lbtTrafficClass (3 bits) */
6718 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6719 /* reserved (19 bits) */
6720 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6721 break;
6722 case 6:
6723 /* LBT_CWCONFIG_RSP */
6724 /* lbtHandle (16 bits) */
6725 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6726 offset += 2;
6727 /* lbtCWR_Rst (1 bit) */
6728 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6729 /* reserved (7 bits) */
6730 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6731 break;
6732
6733 default:
6734 /* Unhandled! */
6735 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6736 "laaMsgType %u not supported by dissector",
6737 laa_msg_type);
6738
6739 break;
6740 }
6741 /* For now just skip indicated length of bytes */
6742 offset = payload_offset + 4*(laa_msg_len+1);
6743 }
6744
6745
6746 /* Dissect each C section */
6747 for (uint32_t i = 0; i < nSections; ++i) {
6748 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6749 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6750 protocol_item,
6751 subframeId, frameId, slotId, startSymbolId,
6752 bit_width, ci_comp_method, ci_comp_opt,
6753 num_sinr_per_prb);
6754 }
6755
6756 /* Expert error if we are short of tvb by > 3 bytes */
6757 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6758 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6759 "%u bytes remain at end of frame - should be 0-3",
6760 tvb_reported_length_remaining(tvb, offset));
6761 }
6762
6763 return tvb_captured_length(tvb);
6764}
6765
6766static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6767 unsigned sample_number, int samples_offset,
6768 oran_tap_info *tap_info,
6769 unsigned sample_bit_width,
6770 int comp_meth,
6771 uint32_t exponent,
6772 section_mod_compr_config_t *mod_compr_params,
6773 uint8_t re)
6774{
6775 /* I */
6776 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6777 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6778 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6779 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
6780 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
6781 samples_offset += sample_bit_width;
6782 /* Q */
6783 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
6784 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
6785 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
6786 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
6787 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
6788 samples_offset += sample_bit_width;
6789
6790 /* Update RE stats */
6791 tap_info->num_res++;
6792 /* if (i_value == 0.0 && q_value == 0.0) { */
6793 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
6794 if (i_bits == 0 && q_bits == 0) {
6795 tap_info->num_res_zero++;
6796 }
6797 else {
6798 tap_info->non_zero_re_in_current_prb = true1;
6799 }
6800 return samples_offset;
6801}
6802
6803
6804static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
6805{
6806 if (!udcomplen_heuristic_result_set) {
6807 /* All sections will start the same way */
6808 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
6809
6810 /* Move offset back to the start of the section */
6811 offset -= section_bytes_before_field;
6812
6813 do {
6814 /* This field appears several bytes into the U-plane section */
6815 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
6816 /* Are there enough bytes to still read the length field? */
6817 if (section_bytes_before_field+2 > length_remaining) {
6818 udcomplen_heuristic_result = false0;
6819 udcomplen_heuristic_result_set = true1;
6820 break;
6821 }
6822
6823 /* Read the length field */
6824 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
6825
6826 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
6827 * Could take into account numPrbU, etc */
6828 if (udcomplen < section_bytes_before_field+2) {
6829 udcomplen_heuristic_result = false0;
6830 udcomplen_heuristic_result_set = true1;
6831 break;
6832 }
6833
6834 /* Does this section fit into the frame? */
6835 if (udcomplen > length_remaining) {
6836 udcomplen_heuristic_result = false0;
6837 udcomplen_heuristic_result_set = true1;
6838 break;
6839 }
6840
6841 /* Move past this section */
6842 offset += udcomplen;
6843
6844 /* Are we at the end of the frame? */
6845 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
6846 if (tvb_reported_length_remaining(tvb, offset) < 4) {
6847 udcomplen_heuristic_result = true1;
6848 udcomplen_heuristic_result_set = true1;
6849 }
6850 } while (!udcomplen_heuristic_result_set);
6851 }
6852 return udcomplen_heuristic_result;
6853}
6854
6855static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
6856{
6857 if (tvb_captured_length_remaining(tvb, offset) < 2) {
6858 return false0;
6859 }
6860 uint8_t first_byte = tvb_get_uint8(tvb, offset);
6861 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
6862
6863 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
6864 /* - meth should be 0-8 */
6865 /* - reserved byte should be 0 */
6866 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
6867}
6868
6869static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
6870{
6871 /* Should really not happen, but guard against this anyway. */
6872 if (flow == NULL((void*)0)) {
6873 /* No state to update. */
6874 return false0;
6875 }
6876
6877 if (direction == DIR_UPLINK0) {
6878 if (flow->udcomphdrUplink_heuristic_result_set) {
6879 /* Return cached value */
6880 return flow->udcomphdrUplink_heuristic_result;
6881 }
6882 else {
6883 /* Work it out, and save answer for next time */
6884 flow->udcomphdrUplink_heuristic_result_set = true1;
6885 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
6886 return flow->udcomphdrUplink_heuristic_result;
6887 }
6888 }
6889 else {
6890 /* Downlink */
6891 if (flow->udcomphdrDownlink_heuristic_result_set) {
6892 /* Return cached value */
6893 return flow->udcomphdrDownlink_heuristic_result;
6894 }
6895 else {
6896 /* Work it out, and save answer for next time */
6897 flow->udcomphdrDownlink_heuristic_result_set = true1;
6898 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
6899 return flow->udcomphdrDownlink_heuristic_result;
6900 }
6901 }
6902}
6903
6904/* User plane dissector (section 8) */
6905static int
6906dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6907 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
6908{
6909 /* Hidden filter for plane */
6910 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
6911 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
6912
6913 /* Set up structures needed to add the protocol subtree and manage it */
6914 unsigned offset = 0;
6915
6916 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
6917 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
6918
6919 tap_info->userplane = true1;
6920
6921 /* Create display subtree for the protocol */
6922 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
6923 proto_item_append_text(protocol_item, "-U");
6924 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
6925
6926 /* Transport header */
6927 /* Real-time control data / IQ data transfer message series identifier */
6928 uint16_t eAxC;
6929 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
6930 tap_info->eaxc = eAxC;
6931
6932 /* Update/report status of conversation */
6933 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
6934 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
6935
6936 flow_result_t *result = NULL((void*)0);
6937
6938 /* Message identifier */
6939 proto_item *seqIdItem;
6940 uint32_t seqId, subSeqId, e;
6941 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
6942
6943 /* Common header for time reference */
6944 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
6945 tvb, offset, 4, "", "Timing Header (");
6946 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
6947
6948 /* dataDirection */
6949 uint32_t direction;
6950 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6951 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
6952 /* payloadVersion */
6953 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
6954 /* filterIndex */
6955 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6956 offset += 1;
6957
6958 int ref_a_offset = offset;
6959
6960 /* frameId */
6961 uint32_t frameId = 0;
6962 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6963 tap_info->frame = frameId;
6964 offset += 1;
6965
6966 /* subframeId */
6967 uint32_t subframeId = 0;
6968 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6969 /* slotId */
6970 uint32_t slotId = 0;
6971 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6972 tap_info->slot = slotId;
6973 offset++;
6974 /* symbolId */
6975 uint32_t symbolId = 0;
6976 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
6977 offset++;
6978
6979 char id[16];
6980 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
6981 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6982 proto_item_set_generated(pi);
6983
6984 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
6985 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
6986
6987 unsigned sample_bit_width;
6988 unsigned compression;
6989 int includeUdCompHeader;
6990
6991 /* Also look up C-PLANE state (sent in opposite direction) so may check current compression settings */
6992 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, true1);
6993 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
6994 uint32_t cplane_samedir_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
6995 flow_state_t* cplane_samedir_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_samedir_key);
6996
6997
6998 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is not equal to 0
3
Taking false branch
6999 /* Create state/conversation if doesn't exist yet */
7000 if (!state) {
7001 /* Allocate new state */
7002 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7003 state->ack_nack_requests = wmem_tree_new(wmem_epan_scope());
7004 wmem_tree_insert32(flow_states_table, key, state);
7005 }
7006
7007 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7008 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7009
7010 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7011 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
7012 /* Store this result */
7013 result->unexpected_seq_number = true1;
7014 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7015 result->previous_frame = state->last_frame[direction];
7016 }
7017 /* Update sequence analysis state */
7018 state->last_frame[direction] = pinfo->num;
7019 state->last_frame_seen[direction] = true1;
7020 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7021 }
7022
7023 /* Show any issues associated with this frame number */
7024 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
4
Value assigned to 'result'
7025 if (result) {
5
Assuming 'result' is null
7026 if (result->unexpected_seq_number) {
7027 expert_add_info_format(pinfo, seqIdItem,
7028 (direction == DIR_UPLINK0) ?
7029 &ei_oran_uplane_unexpected_sequence_number_ul :
7030 &ei_oran_uplane_unexpected_sequence_number_dl,
7031 "Sequence number %u expected, but got %u",
7032 result->expected_sequence_number, seqId);
7033 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7034 /* TODO: could add previous/next frame (in seqId tree?) ? */
7035 }
7036 }
7037
7038 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7039 /* N.B., timing is relative to first seen frame,
7040 not some notion of the beginning of the slot from sync, offset by some timing.. */
7041 if (direction
5.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7042 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7043 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7044 /* Set state on first pass */
7045 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7046 if (!timing) {
7047 /* Allocate new state */
7048 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7049 timing->first_frame = pinfo->num;
7050 timing->first_frame_time = pinfo->abs_ts;
7051 timing->frames_seen_in_symbol = 1;
7052 timing->last_frame_in_symbol = pinfo->num;
7053 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7054 }
7055 else {
7056 /* Update existing state */
7057 timing->frames_seen_in_symbol++;
7058 timing->last_frame_in_symbol = pinfo->num;
7059 }
7060 }
7061 else {
7062 /* Subsequent passes - look up result */
7063 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7064 if (timing) { /* Really shouldn't fail! */
7065 if (timing->frames_seen_in_symbol > 1) {
7066 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7067 int seconds_between_packets = (int)
7068 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7069 int nseconds_between_packets =
7070 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7071
7072
7073 /* Round to nearest microsecond. */
7074 uint32_t total_gap = (seconds_between_packets*1000000) +
7075 ((nseconds_between_packets+500) / 1000);
7076
7077 /* Show how long it has been */
7078 proto_item *ti = NULL((void*)0);
7079 if (pinfo->num != timing->first_frame) {
7080 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7081 proto_item_set_generated(ti);
7082 }
7083
7084 if (total_gap > us_allowed_for_ul_in_symbol) {
7085 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7086 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7087 total_gap, us_allowed_for_ul_in_symbol);
7088 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7089 }
7090
7091 /* Show how many frames were received */
7092 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7093 proto_item_set_generated(ti);
7094
7095 /* Link to first frame for this symbol */
7096 if (pinfo->num != timing->first_frame) {
7097 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7098 proto_item_set_generated(ti);
7099 }
7100
7101 /* And also last frame */
7102 if (pinfo->num != timing->last_frame_in_symbol) {
7103 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7104 proto_item_set_generated(ti);
7105 }
7106
7107 tap_info->ul_delay_in_us = total_gap;
7108 }
7109 }
7110 }
7111 }
7112
7113
7114 /* Look up preferences for samples */
7115 if (direction
5.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
6
Taking false branch
7116 sample_bit_width = pref_sample_bit_width_uplink;
7117 compression = pref_iqCompressionUplink;
7118 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7119 } else {
7120 sample_bit_width = pref_sample_bit_width_downlink;
7121 compression = pref_iqCompressionDownlink;
7122 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7123 }
7124
7125 /* If uplink, load any udCompHdr settings written by C-Plane */
7126 bool_Bool ud_cmp_hdr_cplane = false0;
7127 if (cplane_state && direction == 0) {
7
Assuming 'cplane_state' is null
7128 /* Initialise settings from udpCompHdr from C-Plane */
7129 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7130 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7131 compression = cplane_state->ul_ud_comp_hdr_compression;
7132 ud_cmp_hdr_cplane = true1;
7133 }
7134 }
7135
7136 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7137 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7138 if (sample_bit_width == 0) {
8
Assuming 'sample_bit_width' is not equal to 0
9
Taking false branch
7139 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7140 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7141 (direction == DIR_UPLINK0) ? 'U' : 'D',
7142 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7143 sample_bit_width);
7144 return offset;
7145 }
7146
7147 unsigned bytesLeft;
7148 unsigned number_of_sections = 0;
7149 unsigned nBytesPerPrb =0;
7150
7151
7152 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_samedir_state) {
10
Assuming 'link_planes_together' is false
7153 /* Take a deep-copy of this state on first pass */
7154 result->expected_dl_data = cplane_samedir_state->expected_dl_data;
7155 }
7156
7157 /* Add each section (not from count, just keep parsing until payload used) */
7158 do {
7159 /* Section subtree */
7160 unsigned section_start_offset = offset;
7161 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7162 tvb, offset, 0, "", "Section");
7163 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7164
7165 /* Section Header fields (darker green part) */
7166
7167 /* sectionId */
7168 uint32_t sectionId = 0;
7169 proto_item *ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7170 if (sectionId == 4095) {
11
Assuming 'sectionId' is not equal to 4095
12
Taking false branch
7171 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
7172 }
7173 offset++;
7174
7175 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
13
Assuming field 'num_section_ids' is >= MAX_SECTION_IDs
14
Taking false branch
7176 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7177 }
7178
7179 section_details_t *section_details = NULL((void*)0);
7180
7181 /* For DL, lookup corresponding C-plane frame/info */
7182 if (link_planes_together && direction == 1) {
15
Assuming 'link_planes_together' is true
16
Assuming 'direction' is equal to 1
17
Taking true branch
7183 if (cplane_samedir_state != NULL((void*)0)) {
18
Assuming 'cplane_samedir_state' is not equal to NULL
19
Taking true branch
7184
7185 expected_dl_data_t *dl_data = &result->expected_dl_data;
20
'dl_data' initialized to a null pointer value
7186 for (uint8_t sectIdx=0; sectIdx<dl_data->num_data_sections; sectIdx++) {
21
Access to field 'num_data_sections' results in a dereference of a null pointer (loaded from variable 'dl_data')
7187 if (sectionId == dl_data->data_sections[sectIdx].sectionId) {
7188 /* Need to work out which of 2 entries is in use for this data frame */
7189 unsigned index_to_use = 0;
7190
7191 /* Does the first entry match the timing for this frame? */
7192 if (dl_data->data_sections[sectIdx].details[0].frame == frameId &&
7193 dl_data->data_sections[sectIdx].details[0].subframe == subframeId &&
7194 dl_data->data_sections[sectIdx].details[0].slot == slotId &&
7195 /* Check that symbolId is in range */
7196 dl_data->data_sections[sectIdx].details[0].startSymbol <= symbolId &&
7197 (unsigned)(dl_data->data_sections[sectIdx].details[0].startSymbol + dl_data->data_sections[sectIdx].details[0].numSymbols) <= (unsigned)symbolId) {
7198
7199 index_to_use = 0;
7200 }
7201 else if (dl_data->data_sections[sectIdx].details[1].frame == frameId &&
7202 dl_data->data_sections[sectIdx].details[1].subframe == subframeId &&
7203 dl_data->data_sections[sectIdx].details[1].slot == slotId &&
7204 /* Check that symbolId is in range */
7205 dl_data->data_sections[sectIdx].details[1].startSymbol <= symbolId &&
7206 (unsigned)(dl_data->data_sections[sectIdx].details[1].startSymbol + dl_data->data_sections[sectIdx].details[1].numSymbols) <= (unsigned)symbolId) {
7207
7208 index_to_use = 1;
7209 }
7210 else {
7211 /* TODO: expert info warning? */
7212 }
7213
7214 section_details = &dl_data->data_sections[sectIdx].details[index_to_use];
7215
7216 /* Cplane frame number */
7217 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7218 section_details->frame_number);
7219 proto_item_set_generated(cplane_frame_ti);
7220
7221 /* usecs since cplane frame */
7222 time_t total_gap = (pinfo->abs_ts.secs*1000000 + (pinfo->abs_ts.nsecs/1000)) -
7223 (section_details->frame_time.secs*1000000 + (section_details->frame_time.nsecs/1000));
7224
7225 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);
7226 proto_item_set_generated(cplane_delta_ti);
7227
7228 break;
7229 }
7230 }
7231 }
7232
7233 }
7234
7235 /* rb */
7236 uint32_t rb;
7237 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7238 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7239 uint8_t syminc;
7240 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7241 if (syminc) {
7242 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7243 }
7244 /* startPrbu */
7245 uint32_t startPrbu = 0;
7246 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7247 offset += 2;
7248
7249 /* numPrbu */
7250 uint32_t numPrbu = 0;
7251 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7252 offset += 1;
7253
7254 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7255 uint32_t ud_comp_len = 0;
7256
7257 /* udCompHdr (if preferences indicate will be present) */
7258 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7259 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7260 if (included) {
7261 /* 7.5.2.10 */
7262 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7263 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7264 &compression, &ud_comp_meth_item, tap_info);
7265
7266 /* Not part of udCompHdr */
7267 uint32_t reserved;
7268 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7269 offset += 1;
7270 if (reserved != 0) {
7271 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7272 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7273 reserved);
7274 }
7275 }
7276 else {
7277 /* No fields to dissect - just showing comp values from prefs */
7278 /* iqWidth */
7279 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7280 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7281 proto_item_set_generated(iq_width_item);
7282
7283 /* udCompMethod */
7284 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7285 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7286 proto_item_set_generated(ud_comp_meth_item);
7287
7288 /* Point back to C-Plane, if used */
7289 /* TODO: doesn't work with multiple port mappings using SE10.. */
7290 if (ud_cmp_hdr_cplane) {
7291 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);
7292 proto_item_set_generated(cplane_ti);
7293 }
7294
7295 tap_info->compression_methods |= (1 << compression);
7296 tap_info->compression_width = sample_bit_width;
7297 }
7298
7299 /* Consider fragmentation after first section header */
7300 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7301
7302 /* Set fragmented flag. */
7303 bool_Bool save_fragmented = pinfo->fragmented;
7304 pinfo->fragmented = true1;
7305 fragment_head *fh;
7306 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7307
7308 /* Add this fragment into reassembly table */
7309 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7310 frameId, subframeId, slotId, symbolId);
7311 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7312 reassembly_id, /* id */
7313 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7314 subSeqId, /* frag_number */
7315 frag_data_len, /* frag_data_len */
7316 !e, /* more_frags */
7317 0);
7318
7319 bool_Bool update_col_info = true1;
7320
7321 /* See if this completes an SDU */
7322 tvbuff_t *original_tvb = tvb;
7323 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7324 fh, &oran_frag_items,
7325 &update_col_info, oran_tree);
7326 if (next_tvb) {
7327 /* Have reassembled data */
7328 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7329 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7330 /* Dissection should resume at start of reassembled tvb */
7331 offset = 0;
7332 }
7333 /* Will continue with either reassembled tvb or NULL */
7334 tvb = next_tvb;
7335
7336 /* Restore fragmented flag */
7337 pinfo->fragmented = save_fragmented;
7338
7339 /* Don't dissect any more if not complete yet.. */
7340 if (tvb == NULL((void*)0)) {
7341 return tvb_captured_length(original_tvb);
7342 }
7343 }
7344
7345
7346 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7347 switch (compression) {
7348 case COMP_NONE0:
7349 case COMP_BLOCK_FP1:
7350 case BFP_AND_SELECTIVE_RE5:
7351 case COMP_MODULATION4:
7352 case MOD_COMPR_AND_SELECTIVE_RE6:
7353 break;
7354 default:
7355 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7356 "Compression method %u (%s) not supported by dissector",
7357 compression,
7358 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7359 }
7360
7361 /* udCompLen (when supported, methods 5,6,7,8) */
7362 if (compression >= BFP_AND_SELECTIVE_RE5) {
7363 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7364 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7365
7366 if (supported) {
7367 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7368 if (ud_comp_len <= 1) {
7369 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7370 }
7371 /* TODO: report if less than a viable section in frame? */
7372 /* Check that there is this much length left in the frame */
7373 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7374 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7375 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7376 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7377 }
7378 /* Actual length of section will be checked below, at the end of the section */
7379 offset += 2;
7380 }
7381 }
7382
7383 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7384 uint64_t sresmask1=0, sresmask2=0;
7385 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7386 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7387 {
7388 static int * const sres_mask1_2_flags[] = {
7389 &hf_oran_sReSMask1_2_re12,
7390 &hf_oran_sReSMask1_2_re11,
7391 &hf_oran_sReSMask1_2_re10,
7392 &hf_oran_sReSMask1_2_re9,
7393 &hf_oran_sReSMask_re8,
7394 &hf_oran_sReSMask_re7,
7395 &hf_oran_sReSMask_re6,
7396 &hf_oran_sReSMask_re5,
7397 &hf_oran_sReSMask_re4,
7398 &hf_oran_sReSMask_re3,
7399 &hf_oran_sReSMask_re2,
7400 &hf_oran_sReSMask_re1,
7401 NULL((void*)0)
7402 };
7403
7404 /* reserved (4 bits) */
7405 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7406 /* sReSMask1 (12 bits) */
7407 proto_item *sresmask_ti;
7408 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7409 hf_oran_sReSMask1,
7410 ett_oran_sresmask,
7411 sres_mask1_2_flags,
7412 ENC_NA0x00000000,
7413 &sresmask1);
7414 offset += 2;
7415 /* Count REs present */
7416 unsigned res = 0;
7417 for (unsigned n=0; n < 12; n++) {
7418 if ((sresmask1 >> n) & 0x1) {
7419 res++;
7420 }
7421 }
7422 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7423
7424
7425 /* reserved (4 bits) */
7426 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7427 /* sReSMask2 (12 bits) */
7428 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7429 hf_oran_sReSMask2,
7430 ett_oran_sresmask,
7431 sres_mask1_2_flags,
7432 ENC_NA0x00000000,
7433 &sresmask2);
7434 offset += 2;
7435
7436 if (rb == 1) {
7437 proto_item_append_text(sresmask_ti, " (ignored)");
7438 if (sresmask2 != 0) {
7439 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7440 }
7441 }
7442 else {
7443 /* Count REs present */
7444 res = 0;
7445 for (unsigned n=0; n < 12; n++) {
7446 if ((sresmask2 >> n) & 0x1) {
7447 res++;
7448 }
7449 }
7450 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7451 }
7452 }
7453
7454 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7455
7456 /* TODO: should this use the same pref as c-plane? */
7457 if (numPrbu == 0) {
7458 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7459 numPrbu = pref_data_plane_section_total_rbs;
7460 startPrbu = 0; /* may already be 0... */
7461 }
7462
7463 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_samedir_state, sectionId);
7464
7465 /* Add each PRB */
7466 for (unsigned i = 0; i < numPrbu; i++) {
7467 /* Create subtree */
7468 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7469 tvb, offset, 0,
7470 "", "PRB");
7471 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7472 uint32_t exponent = 0;
7473 uint16_t sresmask = 0;
7474
7475 /* udCompParam (depends upon compression method) */
7476 int before = offset;
7477 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7478 int udcompparam_len = offset-before;
7479
7480 /* Show PRB number in root */
7481 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7482
7483 /* Work out how many REs / PRB */
7484 unsigned res_per_prb = 12;
7485 uint16_t sresmask_to_use = 0x0fff;
7486
7487 if (compression >= BFP_AND_SELECTIVE_RE5) {
7488 /* Work out which mask should be used */
7489 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7490 /* Selective RE cases, use value from compModParam */
7491 sresmask_to_use = (uint16_t)sresmask;
7492 }
7493 else {
7494 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7495 if (rb==1 || (i%2)==0) {
7496 /* Even values */
7497 sresmask_to_use = (uint16_t)sresmask1;
7498 }
7499 else {
7500 /* Odd values */
7501 sresmask_to_use = (uint16_t)sresmask2;
7502 }
7503 }
7504
7505 /* Count REs present using sresmask */
7506 res_per_prb = 0;
7507 /* Use sresmask to pick out which REs are present */
7508 for (unsigned n=0; n<12; n++) {
7509 if (sresmask_to_use & (1<<n)) {
7510 res_per_prb++;
7511 }
7512 }
7513 }
7514
7515 /* N.B. bytes for samples need to be padded out to next byte
7516 (certainly where there aren't 12 REs in PRB..) */
7517 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7518 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7519
7520 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7521
7522 if (section_details) {
7523 if ((startPrbu + i*(1+rb)) < 273) {
7524 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7525 section_details->beamIds[startPrbu + i*(1+rb)]);
7526 proto_item_set_generated(beamid_ti);
7527 }
7528 }
7529
7530
7531 tap_info->non_zero_re_in_current_prb = false0;
7532
7533 /* Optionally trying to show I/Q RE values */
7534 if (pref_showIQSampleValues) {
7535 /* Individual values */
7536 unsigned samples_offset = offset*8;
7537 unsigned samples_start = offset;
7538 unsigned samples = 0;
7539
7540 if (compression >= BFP_AND_SELECTIVE_RE5) {
7541 /* Use sresmask to pick out which REs are present */
7542 for (unsigned n=1; n<=12; n++) {
7543 if (sresmask_to_use & (1<<(n-1))) {
7544 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7545 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7546 samples++;
7547 }
7548 }
7549 }
7550 else {
7551 /* All 12 REs are present */
7552 for (unsigned n=1; n<=12; n++) {
7553 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7554 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7555 samples++;
7556 }
7557 }
7558 proto_item_append_text(prbHeading, " (%u REs)", samples);
7559 if (section_details) {
7560 if ((startPrbu + i*(1+rb)) < 273) {
7561 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7562 }
7563 }
7564
7565 /* Was this PRB all zeros? */
7566 if (!tap_info->non_zero_re_in_current_prb) {
7567 tap_info->num_prbs_zero++;
7568 /* Add a filter to make zero-valued PRBs more findable */
7569 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7570 samples_start, nBytesForSamples, ENC_NA0x00000000);
7571 proto_item_set_hidden(zero_ti);
7572 proto_item_append_text(prbHeading, " (all zeros)");
7573 }
7574 else {
7575 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7576 proto_item_set_hidden(nonzero_ti);
7577 }
7578 }
7579
7580 tap_info->num_prbs++;
7581
7582
7583 /* Advance past samples */
7584 offset += nBytesForSamples;
7585
7586 /* Set end of prb subtree */
7587 proto_item_set_end(prbHeading, tvb, offset);
7588 }
7589
7590 /* Set extent of section */
7591 proto_item_set_len(sectionHeading, offset-section_start_offset);
7592 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7593 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7594 "udCompLen indicates %u bytes in section, but dissected %u instead",
7595 ud_comp_len, offset-section_start_offset);
7596 }
7597
7598 bytesLeft = tvb_captured_length(tvb) - offset;
7599 number_of_sections++;
7600 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7601
7602 /* Show number of sections found */
7603 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7604 proto_item_set_generated(ti);
7605
7606 /* Expert error if we are short of tvb by > 3 bytes */
7607 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7608 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7609 "%u bytes remain at end of frame - should be 0-3",
7610 tvb_reported_length_remaining(tvb, offset));
7611 }
7612
7613 return tvb_captured_length(tvb);
7614}
7615
7616
7617/**********************************************************************/
7618/* Main dissection function. */
7619/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7620static int
7621dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7622{
7623 uint32_t ecpri_message_type = *(uint32_t *)data;
7624 unsigned offset = 0;
7625
7626 /* Allocate and zero tap struct */
7627 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
)))
;
7628 tap_info->pdu_size = pinfo->fd->pkt_len;
7629 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7630
7631 switch (ecpri_message_type) {
7632 case ECPRI_MT_IQ_DATA0:
7633 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7634 break;
7635 case ECPRI_MT_RT_CTRL_DATA2:
7636 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7637 break;
7638 default:
7639 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7640 return 0;
7641 }
7642
7643 tap_queue_packet(oran_tap, pinfo, tap_info);
7644
7645 return offset;
7646}
7647
7648static void oran_init_protocol(void)
7649{
7650 udcomplen_heuristic_result_set = false0;
7651 udcomplen_heuristic_result = false0;
7652}
7653
7654
7655/* Register the protocol with Wireshark. */
7656void
7657proto_register_oran(void)
7658{
7659 static hf_register_info hf[] = {
7660
7661 /* Section 5.1.3.2.7 */
7662 { &hf_oran_du_port_id,
7663 { "DU Port ID", "oran_fh_cus.du_port_id",
7664 FT_UINT16, BASE_DEC,
7665 NULL((void*)0), 0x0,
7666 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7667 },
7668
7669 /* Section 5.1.3.2.7 */
7670 { &hf_oran_bandsector_id,
7671 { "BandSector ID", "oran_fh_cus.bandsector_id",
7672 FT_UINT16, BASE_DEC,
7673 NULL((void*)0), 0x0,
7674 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7675 },
7676
7677 /* Section 5.1.3.2.7 */
7678 { &hf_oran_cc_id,
7679 { "CC ID", "oran_fh_cus.cc_id",
7680 FT_UINT16, BASE_DEC,
7681 NULL((void*)0), 0x0,
7682 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7683 },
7684
7685 /* Section 5.1.3.2.7 */
7686 { &hf_oran_ru_port_id,
7687 { "RU Port ID", "oran_fh_cus.ru_port_id",
7688 FT_UINT16, BASE_DEC,
7689 NULL((void*)0), 0x0,
7690 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7691 },
7692
7693 /* Section 5.1.3.2.8 */
7694 { &hf_oran_sequence_id,
7695 { "Sequence ID", "oran_fh_cus.sequence_id",
7696 FT_UINT8, BASE_DEC,
7697 NULL((void*)0), 0x0,
7698 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7699 },
7700
7701 /* Section 5.1.3.2.8 */
7702 { &hf_oran_e_bit,
7703 { "E Bit", "oran_fh_cus.e_bit",
7704 FT_UINT8, BASE_DEC,
7705 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7706 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7707 },
7708
7709 /* Section 5.1.3.2.8 */
7710 { &hf_oran_subsequence_id,
7711 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7712 FT_UINT8, BASE_DEC,
7713 NULL((void*)0), 0x7f,
7714 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7715 },
7716
7717 { &hf_oran_previous_frame,
7718 { "Previous frame in stream", "oran_fh_cus.previous-frame",
7719 FT_FRAMENUM, BASE_NONE,
7720 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
7721 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7722 },
7723
7724 /* Section 7.5.2.1 */
7725 { &hf_oran_data_direction,
7726 { "Data Direction", "oran_fh_cus.data_direction",
7727 FT_UINT8, BASE_DEC,
7728 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
7729 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7730 },
7731
7732 /* Section 7.5.2.2 */
7733 { &hf_oran_payload_version,
7734 { "Payload Version", "oran_fh_cus.payloadVersion",
7735 FT_UINT8, BASE_DEC,
7736 NULL((void*)0), 0x70,
7737 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7738 },
7739
7740 /* Section 7.5.2.3 */
7741 { &hf_oran_filter_index,
7742 { "Filter Index", "oran_fh_cus.filterIndex",
7743 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7744 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
7745 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7746 },
7747
7748 /* Section 7.5.2.4 */
7749 { &hf_oran_frame_id,
7750 { "Frame ID", "oran_fh_cus.frameId",
7751 FT_UINT8, BASE_DEC,
7752 NULL((void*)0), 0x0,
7753 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7754 },
7755
7756 /* Section 7.5.2.5 */
7757 { &hf_oran_subframe_id,
7758 { "Subframe ID", "oran_fh_cus.subframe_id",
7759 FT_UINT8, BASE_DEC,
7760 NULL((void*)0), 0xf0,
7761 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7762 },
7763
7764 /* Section 7.5.2.6 */
7765 { &hf_oran_slot_id,
7766 { "Slot ID", "oran_fh_cus.slotId",
7767 FT_UINT16, BASE_DEC,
7768 NULL((void*)0), 0x0fc0,
7769 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7770 },
7771
7772 /* Generated for convenience */
7773 { &hf_oran_slot_within_frame,
7774 { "Slot within frame", "oran_fh_cus.slot-within-frame",
7775 FT_UINT16, BASE_DEC,
7776 NULL((void*)0), 0x0,
7777 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7778 },
7779
7780 /* Section 7.5.2.7 */
7781 { &hf_oran_start_symbol_id,
7782 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
7783 FT_UINT8, BASE_DEC,
7784 NULL((void*)0), 0x3f,
7785 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7786 },
7787
7788 /* Section 7.5.2.8 */
7789 { &hf_oran_numberOfSections,
7790 { "Number of Sections", "oran_fh_cus.numberOfSections",
7791 FT_UINT8, BASE_DEC,
7792 NULL((void*)0), 0x0,
7793 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7794 },
7795
7796 /* Section 7.5.2.9 */
7797 { &hf_oran_sectionType,
7798 { "Section Type", "oran_fh_cus.sectionType",
7799 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
7800 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
7801 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7802 },
7803
7804 /* Section 7.5.2.10 */
7805 { &hf_oran_udCompHdr,
7806 { "udCompHdr", "oran_fh_cus.udCompHdr",
7807 FT_STRING, BASE_NONE,
7808 NULL((void*)0), 0x0,
7809 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7810 },
7811
7812 /* Section 7.5.2.11 */
7813 { &hf_oran_numberOfUEs,
7814 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
7815 FT_UINT8, BASE_DEC,
7816 NULL((void*)0), 0x0,
7817 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7818 },
7819
7820 /* Section 7.5.2.12 */
7821 { &hf_oran_timeOffset,
7822 { "Time Offset", "oran_fh_cus.timeOffset",
7823 FT_UINT16, BASE_DEC,
7824 NULL((void*)0), 0x0,
7825 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7826 },
7827
7828 /* Section 7.5.2.13 */
7829 { &hf_oran_frameStructure_fft,
7830 { "FFT Size", "oran_fh_cus.frameStructure.fft",
7831 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
7832 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
7833 "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) }
7834 },
7835
7836 /* Section 7.5.2.13 */
7837 { &hf_oran_frameStructure_subcarrier_spacing,
7838 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
7839 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
7840 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
7841 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
7842 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7843 },
7844
7845 /* Section 7.5.2.14 */
7846 { &hf_oran_cpLength,
7847 { "cpLength", "oran_fh_cus.cpLength",
7848 FT_UINT16, BASE_DEC,
7849 NULL((void*)0), 0x0,
7850 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7851 },
7852
7853 { &hf_oran_timing_header,
7854 { "Timing Header", "oran_fh_cus.timingHeader",
7855 FT_STRING, BASE_NONE,
7856 NULL((void*)0), 0x0,
7857 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7858 },
7859
7860 /* Section 7.5.3.1 */
7861 { &hf_oran_section_id,
7862 { "sectionId", "oran_fh_cus.sectionId",
7863 FT_UINT16, BASE_DEC,
7864 NULL((void*)0), 0xfff0,
7865 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7866 },
7867
7868 /* Section 7.5.3.2 */
7869 { &hf_oran_rb,
7870 { "rb", "oran_fh_cus.rb",
7871 FT_UINT8, BASE_DEC,
7872 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
7873 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7874 },
7875
7876 /* Section 7.5.5.3 */
7877 { &hf_oran_symInc,
7878 { "symInc", "oran_fh_cus.symInc",
7879 FT_UINT8, BASE_DEC,
7880 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
7881 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7882 },
7883
7884 /* Section 7.5.3.4 */
7885 { &hf_oran_startPrbc,
7886 { "startPrbc", "oran_fh_cus.startPrbc",
7887 FT_UINT16, BASE_DEC,
7888 NULL((void*)0), 0x03ff,
7889 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7890 },
7891
7892 /* Section 7.5.3.5 */
7893 { &hf_oran_reMask_re1,
7894 { "RE 1", "oran_fh_cus.reMask-RE1",
7895 FT_BOOLEAN, 16,
7896 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
7897 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7898 },
7899 { &hf_oran_reMask_re2,
7900 { "RE 2", "oran_fh_cus.reMask-RE2",
7901 FT_BOOLEAN, 16,
7902 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
7903 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7904 },
7905 { &hf_oran_reMask_re3,
7906 { "RE 3", "oran_fh_cus.reMask-RE3",
7907 FT_BOOLEAN, 16,
7908 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
7909 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7910 },
7911 { &hf_oran_reMask_re4,
7912 { "RE 4", "oran_fh_cus.reMask-RE4",
7913 FT_BOOLEAN, 16,
7914 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
7915 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7916 },
7917 { &hf_oran_reMask_re5,
7918 { "RE 5", "oran_fh_cus.reMask-RE5",
7919 FT_BOOLEAN, 16,
7920 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
7921 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7922 },
7923 { &hf_oran_reMask_re6,
7924 { "RE 6", "oran_fh_cus.reMask-RE6",
7925 FT_BOOLEAN, 16,
7926 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
7927 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7928 },
7929 { &hf_oran_reMask_re7,
7930 { "RE 7", "oran_fh_cus.reMask-RE7",
7931 FT_BOOLEAN, 16,
7932 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
7933 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7934 },
7935 { &hf_oran_reMask_re8,
7936 { "RE 8", "oran_fh_cus.reMask-RE8",
7937 FT_BOOLEAN, 16,
7938 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
7939 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7940 },
7941 { &hf_oran_reMask_re9,
7942 { "RE 9", "oran_fh_cus.reMask-RE9",
7943 FT_BOOLEAN, 16,
7944 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
7945 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7946 },
7947 { &hf_oran_reMask_re10,
7948 { "RE 10", "oran_fh_cus.reMask-RE10",
7949 FT_BOOLEAN, 16,
7950 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
7951 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7952 },
7953 { &hf_oran_reMask_re11,
7954 { "RE 11", "oran_fh_cus.reMask-RE11",
7955 FT_BOOLEAN, 16,
7956 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
7957 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7958 },
7959 { &hf_oran_reMask_re12,
7960 { "RE 12", "oran_fh_cus.reMask-RE12",
7961 FT_BOOLEAN, 16,
7962 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
7963 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7964 },
7965 { &hf_oran_reMask,
7966 { "RE Mask", "oran_fh_cus.reMask",
7967 FT_UINT16, BASE_HEX,
7968 NULL((void*)0), 0xfff0,
7969 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7970 },
7971
7972 /* Section 7.5.3.6 */
7973 { &hf_oran_numPrbc,
7974 { "numPrbc", "oran_fh_cus.numPrbc",
7975 FT_UINT8, BASE_DEC,
7976 NULL((void*)0), 0x0,
7977 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7978 },
7979 /* Section 7.5.3.7 */
7980 { &hf_oran_numSymbol,
7981 { "Number of Symbols", "oran_fh_cus.numSymbol",
7982 FT_UINT8, BASE_DEC,
7983 NULL((void*)0), 0x0f,
7984 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7985 },
7986 /* Section 7.5.3.8 */
7987 { &hf_oran_ef,
7988 { "Extension Flag", "oran_fh_cus.ef",
7989 FT_BOOLEAN, 8,
7990 NULL((void*)0), 0x80,
7991 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7992 },
7993 /* Section 7.5.3.9 */
7994 { &hf_oran_beamId,
7995 { "Beam ID", "oran_fh_cus.beamId",
7996 FT_UINT16, BASE_DEC,
7997 NULL((void*)0), 0x7fff,
7998 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
7999 },
8000
8001 { &hf_oran_extension,
8002 { "Extension", "oran_fh_cus.extension",
8003 FT_STRING, BASE_NONE,
8004 NULL((void*)0), 0x0,
8005 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8006 },
8007
8008 /* Section 7.6.2.1 */
8009 { &hf_oran_exttype,
8010 { "extType", "oran_fh_cus.extType",
8011 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8012 &exttype_vals_ext, 0x7f,
8013 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8014 },
8015
8016 /* Section 7.6.2.3 */
8017 { &hf_oran_extlen,
8018 { "extLen", "oran_fh_cus.extLen",
8019 FT_UINT16, BASE_DEC,
8020 NULL((void*)0), 0x0,
8021 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8022 },
8023
8024 /* Section 7.7.1 */
8025 { &hf_oran_bfw,
8026 { "bfw", "oran_fh_cus.bfw",
8027 FT_STRING, BASE_NONE,
8028 NULL((void*)0), 0x0,
8029 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8030 },
8031 { &hf_oran_bfw_bundle,
8032 { "Bundle", "oran_fh_cus.bfw.bundle",
8033 FT_STRING, BASE_NONE,
8034 NULL((void*)0), 0x0,
8035 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8036 },
8037 { &hf_oran_bfw_bundle_id,
8038 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8039 FT_UINT32, BASE_DEC,
8040 NULL((void*)0), 0x0,
8041 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8042 },
8043 /* Section 7.7.1.4 */
8044 { &hf_oran_bfw_i,
8045 { "bfwI", "oran_fh_cus.bfwI",
8046 FT_FLOAT, BASE_NONE,
8047 NULL((void*)0), 0x0,
8048 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8049 },
8050 /* Section 7.7.1.5 */
8051 { &hf_oran_bfw_q,
8052 { "bfwQ", "oran_fh_cus.bfwQ",
8053 FT_FLOAT, BASE_NONE,
8054 NULL((void*)0), 0x0,
8055 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8056 },
8057
8058 /* Section 7.5.3.10 */
8059 { &hf_oran_ueId,
8060 { "UE ID", "oran_fh_cus.ueId",
8061 FT_UINT16, BASE_DEC,
8062 NULL((void*)0), 0x7fff,
8063 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8064 },
8065 /* Section 7.5.3.11 */
8066 { &hf_oran_freqOffset,
8067 { "Frequency Offset", "oran_fh_cus.freqOffset",
8068 FT_UINT24, BASE_DEC,
8069 NULL((void*)0), 0x0,
8070 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8071 },
8072
8073 /* Section 7.5.3.12 */
8074 { &hf_oran_regularizationFactor,
8075 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8076 FT_INT16, BASE_DEC,
8077 NULL((void*)0), 0x0,
8078 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8079 },
8080 /* Section 7.5.3.14 */
8081 { &hf_oran_laaMsgType,
8082 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8083 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8084 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8085 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8086 },
8087 /* Section 7.5.3.15 */
8088 { &hf_oran_laaMsgLen,
8089 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8090 FT_UINT8, BASE_DEC,
8091 NULL((void*)0), 0x0f,
8092 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8093 },
8094 /* Section 7.5.3.16 */
8095 { &hf_oran_lbtHandle,
8096 { "LBT Handle", "oran_fh_cus.lbtHandle",
8097 FT_UINT16, BASE_HEX,
8098 NULL((void*)0), 0x0,
8099 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8100 },
8101 /* Section 7.5.3.17 */
8102 { &hf_oran_lbtDeferFactor,
8103 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8104 FT_UINT8, BASE_DEC,
8105 NULL((void*)0), 0x07,
8106 "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)}
8107 },
8108 /* Section 7.5.3.18 */
8109 { &hf_oran_lbtBackoffCounter,
8110 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8111 FT_UINT16, BASE_DEC,
8112 NULL((void*)0), 0xffc0,
8113 "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)}
8114 },
8115 /* Section 7.5.3.19 */
8116 { &hf_oran_lbtOffset,
8117 { "LBT Offset", "oran_fh_cus.lbtOffset",
8118 FT_UINT16, BASE_DEC,
8119 NULL((void*)0), 0xffc0,
8120 "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)}
8121 },
8122 /* Section 7.5.3.20 */
8123 { &hf_oran_MCOT,
8124 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8125 FT_UINT8, BASE_DEC,
8126 NULL((void*)0), 0x3c,
8127 "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)}
8128 },
8129 /* Section 7.5.3.21 */
8130 { &hf_oran_lbtMode,
8131 { "LBT Mode", "oran_fh_cus.lbtMode",
8132 FT_UINT8, BASE_DEC,
8133 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8134 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8135 },
8136 /* Section 7.5.3.22 */
8137 { &hf_oran_lbtPdschRes,
8138 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8139 FT_UINT8, BASE_DEC,
8140 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8141 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8142 },
8143 /* Section 7.5.3.23 */
8144 { &hf_oran_sfStatus,
8145 { "sfStatus", "oran_fh_cus.sfStatus",
8146 FT_BOOLEAN, 8,
8147 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8148 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8149 },
8150 /* Section 7.5.3.24 */
8151 { &hf_oran_lbtDrsRes,
8152 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8153 FT_BOOLEAN, 8,
8154 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8155 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8156 },
8157 /* Section 7.5.3.25 */
8158 { &hf_oran_initialPartialSF,
8159 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8160 FT_BOOLEAN, 8,
8161 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8162 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8163 },
8164 /* Section 7.5.3.26. */
8165 { &hf_oran_lbtBufErr,
8166 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8167 FT_BOOLEAN, 8,
8168 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8169 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8170 },
8171 /* Section 7.5.3.27 */
8172 { &hf_oran_sfnSfEnd,
8173 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8174 FT_UINT16, BASE_DEC,
8175 NULL((void*)0), 0x0fff,
8176 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8177 },
8178 /* Section 7.5.3.28 */
8179 { &hf_oran_lbtCWConfig_H,
8180 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8181 FT_UINT8, BASE_DEC,
8182 NULL((void*)0), 0x0,
8183 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8184 },
8185 /* Section 7.5.3.29 */
8186 { &hf_oran_lbtCWConfig_T,
8187 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8188 FT_UINT8, BASE_DEC,
8189 NULL((void*)0), 0x0,
8190 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8191 },
8192 /* Section 7.5.3.30 */
8193 { &hf_oran_lbtTrafficClass,
8194 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8195 FT_UINT8, BASE_DEC,
8196 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8197 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8198 },
8199 /* Section 7.5.3.31 */
8200 { &hf_oran_lbtCWR_Rst,
8201 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8202 FT_BOOLEAN, 8,
8203 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8204 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8205 },
8206
8207 /* Reserved fields */
8208 { &hf_oran_reserved,
8209 { "reserved", "oran_fh_cus.reserved",
8210 FT_UINT64, BASE_HEX,
8211 NULL((void*)0), 0x0,
8212 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8213 },
8214 { &hf_oran_reserved_1bit,
8215 { "reserved", "oran_fh_cus.reserved",
8216 FT_UINT8, BASE_HEX,
8217 NULL((void*)0), 0x80,
8218 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8219 },
8220 { &hf_oran_reserved_2bits,
8221 { "reserved", "oran_fh_cus.reserved",
8222 FT_UINT8, BASE_HEX,
8223 NULL((void*)0), 0xc0,
8224 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8225 },
8226 { &hf_oran_reserved_3bits,
8227 { "reserved", "oran_fh_cus.reserved",
8228 FT_UINT8, BASE_HEX,
8229 NULL((void*)0), 0xe0,
8230 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8231 },
8232 { &hf_oran_reserved_4bits,
8233 { "reserved", "oran_fh_cus.reserved",
8234 FT_UINT8, BASE_HEX,
8235 NULL((void*)0), 0xf0,
8236 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8237 },
8238 { &hf_oran_reserved_last_4bits,
8239 { "reserved", "oran_fh_cus.reserved",
8240 FT_UINT8, BASE_HEX,
8241 NULL((void*)0), 0x0f,
8242 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8243 },
8244 { &hf_oran_reserved_last_5bits,
8245 { "reserved", "oran_fh_cus.reserved",
8246 FT_UINT8, BASE_HEX,
8247 NULL((void*)0), 0x1f,
8248 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8249 },
8250 { &hf_oran_reserved_6bits,
8251 { "reserved", "oran_fh_cus.reserved",
8252 FT_UINT8, BASE_HEX,
8253 NULL((void*)0), 0xfc,
8254 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8255 },
8256 { &hf_oran_reserved_last_6bits,
8257 { "reserved", "oran_fh_cus.reserved",
8258 FT_UINT8, BASE_HEX,
8259 NULL((void*)0), 0x3f,
8260 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8261 },
8262 { &hf_oran_reserved_7bits,
8263 { "reserved", "oran_fh_cus.reserved",
8264 FT_UINT8, BASE_HEX,
8265 NULL((void*)0), 0xfe,
8266 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8267 },
8268 { &hf_oran_reserved_last_7bits,
8269 { "reserved", "oran_fh_cus.reserved",
8270 FT_UINT8, BASE_HEX,
8271 NULL((void*)0), 0x7f,
8272 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8273 },
8274 { &hf_oran_reserved_8bits,
8275 { "reserved", "oran_fh_cus.reserved",
8276 FT_UINT8, BASE_HEX,
8277 NULL((void*)0), 0x0,
8278 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8279 },
8280 { &hf_oran_reserved_16bits,
8281 { "reserved", "oran_fh_cus.reserved",
8282 FT_UINT16, BASE_HEX,
8283 NULL((void*)0), 0x0,
8284 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8285 },
8286 { &hf_oran_reserved_15bits,
8287 { "reserved", "oran_fh_cus.reserved",
8288 FT_UINT16, BASE_HEX,
8289 NULL((void*)0), 0x7fff,
8290 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8291 },
8292 { &hf_oran_reserved_bit1,
8293 { "reserved", "oran_fh_cus.reserved",
8294 FT_UINT8, BASE_HEX,
8295 NULL((void*)0), 0x40,
8296 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8297 },
8298 { &hf_oran_reserved_bit2,
8299 { "reserved", "oran_fh_cus.reserved",
8300 FT_UINT8, BASE_HEX,
8301 NULL((void*)0), 0x20,
8302 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8303 },
8304 { &hf_oran_reserved_bit4,
8305 { "reserved", "oran_fh_cus.reserved",
8306 FT_UINT8, BASE_HEX,
8307 NULL((void*)0), 0x08,
8308 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8309 },
8310 { &hf_oran_reserved_bit5,
8311 { "reserved", "oran_fh_cus.reserved",
8312 FT_UINT8, BASE_HEX,
8313 NULL((void*)0), 0x04,
8314 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8315 },
8316 { &hf_oran_reserved_bits123,
8317 { "reserved", "oran_fh_cus.reserved",
8318 FT_UINT8, BASE_HEX,
8319 NULL((void*)0), 0x70,
8320 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8321 },
8322 { &hf_oran_reserved_bits456,
8323 { "reserved", "oran_fh_cus.reserved",
8324 FT_UINT8, BASE_HEX,
8325 NULL((void*)0), 0x0e,
8326 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8327 },
8328
8329 /* 7.7.11.9 */
8330 { &hf_oran_cont_ind,
8331 { "contInd", "oran_fh_cus.contInd",
8332 FT_BOOLEAN, 8,
8333 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8334 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8335 },
8336 /* 7.7.11.10 */
8337 { &hf_oran_bundle_offset,
8338 { "BundleOffset", "oran_fh_cus.bundleOffset",
8339 FT_UINT8, BASE_DEC,
8340 NULL((void*)0), 0x3f,
8341 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8342 },
8343
8344 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8345 { &hf_oran_bfwCompHdr,
8346 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8347 FT_STRING, BASE_NONE,
8348 NULL((void*)0), 0x0,
8349 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8350 },
8351 { &hf_oran_bfwCompHdr_iqWidth,
8352 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8353 FT_UINT8, BASE_HEX,
8354 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8355 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8356 },
8357 { &hf_oran_bfwCompHdr_compMeth,
8358 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8359 FT_UINT8, BASE_HEX,
8360 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8361 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8362 },
8363
8364 /* 7.5.3.32 */
8365 { &hf_oran_ciCompParam,
8366 { "ciCompParam", "oran_fh_cus.ciCompParam",
8367 FT_STRING, BASE_NONE,
8368 NULL((void*)0), 0x0,
8369 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8370 },
8371
8372 /* Table 7.5.3.32-1 */
8373 { &hf_oran_blockScaler,
8374 { "blockScaler", "oran_fh_cus.blockScaler",
8375 FT_UINT8, BASE_HEX,
8376 NULL((void*)0), 0x0,
8377 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8378 },
8379 { &hf_oran_compBitWidth,
8380 { "compBitWidth", "oran_fh_cus.compBitWidth",
8381 FT_UINT8, BASE_DEC,
8382 NULL((void*)0), 0xf0,
8383 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8384 },
8385 { &hf_oran_compShift,
8386 { "compShift", "oran_fh_cus.compShift",
8387 FT_UINT8, BASE_DEC,
8388 NULL((void*)0), 0x0f,
8389 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8390 },
8391
8392 { &hf_oran_active_beamspace_coefficient_n1,
8393 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8394 FT_BOOLEAN, 8,
8395 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8396 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8397 },
8398 { &hf_oran_active_beamspace_coefficient_n2,
8399 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8400 FT_BOOLEAN, 8,
8401 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8402 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8403 },
8404 { &hf_oran_active_beamspace_coefficient_n3,
8405 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8406 FT_BOOLEAN, 8,
8407 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8408 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8409 },
8410 { &hf_oran_active_beamspace_coefficient_n4,
8411 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8412 FT_BOOLEAN, 8,
8413 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8414 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8415 },
8416 { &hf_oran_active_beamspace_coefficient_n5,
8417 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8418 FT_BOOLEAN, 8,
8419 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8420 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8421 },
8422 { &hf_oran_active_beamspace_coefficient_n6,
8423 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8424 FT_BOOLEAN, 8,
8425 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8426 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8427 },
8428 { &hf_oran_active_beamspace_coefficient_n7,
8429 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8430 FT_BOOLEAN, 8,
8431 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8432 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8433 },
8434 { &hf_oran_active_beamspace_coefficient_n8,
8435 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8436 FT_BOOLEAN, 8,
8437 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8438 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8439 },
8440
8441 { &hf_oran_activeBeamspaceCoefficientMask,
8442 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8443 FT_UINT8, BASE_HEX,
8444 NULL((void*)0), 0xff,
8445 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8446 },
8447 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8448 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8449 FT_UINT32, BASE_DEC,
8450 NULL((void*)0), 0x0,
8451 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8452 },
8453
8454 /* Section 7.7.6.6 */
8455 { &hf_oran_se6_repetition,
8456 { "repetition", "oran_fh_cus.repetition",
8457 FT_BOOLEAN, BASE_NONE,
8458 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8459 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8460 },
8461 /* 7.7.20.9 */
8462 { &hf_oran_rbgSize,
8463 { "rbgSize", "oran_fh_cus.rbgSize",
8464 FT_UINT8, BASE_HEX,
8465 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8466 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8467 },
8468 /* 7.7.20.10 */
8469 { &hf_oran_rbgMask,
8470 { "rbgMask", "oran_fh_cus.rbgMask",
8471 FT_UINT32, BASE_HEX,
8472 NULL((void*)0), 0x0fffffff,
8473 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8474 },
8475 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8476 { &hf_oran_noncontig_priority,
8477 { "priority", "oran_fh_cus.priority",
8478 FT_UINT8, BASE_HEX,
8479 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8480 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8481 },
8482
8483 /* 7.7.6.4 */
8484 { &hf_oran_symbol_mask,
8485 { "symbolMask", "oran_fh_cus.symbolMask",
8486 FT_UINT16, BASE_HEX,
8487 NULL((void*)0), 0x3fff,
8488 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8489 },
8490 { &hf_oran_symbol_mask_s13,
8491 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8492 FT_BOOLEAN, 16,
8493 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8494 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8495 },
8496 { &hf_oran_symbol_mask_s12,
8497 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8498 FT_BOOLEAN, 16,
8499 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8500 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8501 },
8502 { &hf_oran_symbol_mask_s11,
8503 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8504 FT_BOOLEAN, 16,
8505 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8506 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8507 },
8508 { &hf_oran_symbol_mask_s10,
8509 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8510 FT_BOOLEAN, 16,
8511 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8512 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8513 },
8514 { &hf_oran_symbol_mask_s9,
8515 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8516 FT_BOOLEAN, 16,
8517 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8518 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8519 },
8520 { &hf_oran_symbol_mask_s8,
8521 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8522 FT_BOOLEAN, 16,
8523 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8524 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8525 },
8526 { &hf_oran_symbol_mask_s7,
8527 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8528 FT_BOOLEAN, 16,
8529 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8530 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8531 },
8532 { &hf_oran_symbol_mask_s6,
8533 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8534 FT_BOOLEAN, 16,
8535 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8536 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8537 },
8538 { &hf_oran_symbol_mask_s5,
8539 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8540 FT_BOOLEAN, 16,
8541 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8542 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8543 },
8544 { &hf_oran_symbol_mask_s4,
8545 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8546 FT_BOOLEAN, 16,
8547 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8548 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8549 },
8550 { &hf_oran_symbol_mask_s3,
8551 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8552 FT_BOOLEAN, 16,
8553 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8554 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8555 },
8556 { &hf_oran_symbol_mask_s2,
8557 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8558 FT_BOOLEAN, 16,
8559 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8560 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8561 },
8562 { &hf_oran_symbol_mask_s1,
8563 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8564 FT_BOOLEAN, 16,
8565 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8566 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8567 },
8568 { &hf_oran_symbol_mask_s0,
8569 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8570 FT_BOOLEAN, 16,
8571 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8572 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8573 },
8574
8575
8576 /* 7.7.22.2 */
8577 { &hf_oran_ack_nack_req_id,
8578 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8579 FT_UINT16, BASE_HEX,
8580 NULL((void*)0), 0x0,
8581 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8582 },
8583
8584 /* Subtree for next 2 items */
8585 { &hf_oran_frequency_range,
8586 { "Frequency Range", "oran_fh_cus.frequencyRange",
8587 FT_STRING, BASE_NONE,
8588 NULL((void*)0), 0x0,
8589 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8590 },
8591
8592 /* 7.7.12.4 */
8593 { &hf_oran_off_start_prb,
8594 { "offStartPrb", "oran_fh_cus.offStartPrb",
8595 FT_UINT8, BASE_DEC,
8596 NULL((void*)0), 0x0,
8597 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8598 },
8599 /* 7.7.12.5 */
8600 { &hf_oran_num_prb,
8601 { "numPrb", "oran_fh_cus.numPrb",
8602 FT_UINT8, BASE_DEC,
8603 NULL((void*)0), 0x0,
8604 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8605 },
8606
8607 /* symbolId 8.3.3.7 */
8608 { &hf_oran_symbolId,
8609 { "Symbol Identifier", "oran_fh_cus.symbolId",
8610 FT_UINT8, BASE_DEC,
8611 NULL((void*)0), 0x3f,
8612 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8613 },
8614
8615 /* startPrbu 8.3.3.11 */
8616 { &hf_oran_startPrbu,
8617 { "startPrbu", "oran_fh_cus.startPrbu",
8618 FT_UINT16, BASE_DEC,
8619 NULL((void*)0), 0x03ff,
8620 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8621 },
8622
8623 /* numPrbu 8.3.3.12 */
8624 { &hf_oran_numPrbu,
8625 { "numPrbu", "oran_fh_cus.numPrbu",
8626 FT_UINT8, BASE_DEC,
8627 NULL((void*)0), 0x0,
8628 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8629 },
8630
8631 /* 7.7.1.3 */
8632 { &hf_oran_bfwCompParam,
8633 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8634 FT_STRING, BASE_NONE,
8635 NULL((void*)0), 0x0,
8636 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8637 },
8638
8639 /* 6.3.3.13 */
8640 { &hf_oran_udCompHdrMeth,
8641 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8642 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8643 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8644 "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)}
8645 },
8646 { &hf_oran_udCompHdrMeth_pref,
8647 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8648 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8649 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8650 "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)}
8651 },
8652 /* 8.3.3.18 */
8653 { &hf_oran_udCompLen,
8654 { "udCompLen", "oran_fh_cus.udCompLen",
8655 FT_UINT16, BASE_DEC,
8656 NULL((void*)0), 0x0,
8657 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8658 },
8659
8660 /* 7.5.2.10 */
8661 { &hf_oran_udCompHdrIqWidth,
8662 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8663 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8664 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8665 "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)}
8666 },
8667 { &hf_oran_udCompHdrIqWidth_pref,
8668 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8669 FT_UINT8, BASE_DEC,
8670 NULL((void*)0), 0x0,
8671 "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)}
8672 },
8673
8674 { &hf_oran_sinrCompHdrIqWidth_pref,
8675 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8676 FT_UINT8, BASE_DEC,
8677 NULL((void*)0), 0x0,
8678 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8679 },
8680 { &hf_oran_sinrCompHdrMeth_pref,
8681 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8682 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8683 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8684 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8685 },
8686
8687 /* Section 8.3.3.15 (not always present - depends upon meth) */
8688 { &hf_oran_udCompParam,
8689 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8690 FT_STRING, BASE_NONE,
8691 NULL((void*)0), 0x0,
8692 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8693 },
8694 /* 8.3.3.18 */
8695 { &hf_oran_sReSMask,
8696 { "sReSMask", "oran_fh_cus.sReSMask",
8697 FT_UINT16, BASE_HEX,
8698 NULL((void*)0), 0xf0ff,
8699 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8700 },
8701
8702 { &hf_oran_sReSMask_re12,
8703 { "RE-12", "oran_fh_cus.sReSMask-re12",
8704 FT_BOOLEAN, 16,
8705 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8706 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8707 },
8708 { &hf_oran_sReSMask_re11,
8709 { "RE-11", "oran_fh_cus.sReSMask-re11",
8710 FT_BOOLEAN, 16,
8711 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8712 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8713 },
8714 { &hf_oran_sReSMask_re10,
8715 { "RE-10", "oran_fh_cus.sReSMask-re10",
8716 FT_BOOLEAN, 16,
8717 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8718 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8719 },
8720 { &hf_oran_sReSMask_re9,
8721 { "RE-9", "oran_fh_cus.sReSMask-re9",
8722 FT_BOOLEAN, 16,
8723 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8724 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8725 },
8726 { &hf_oran_sReSMask_re8,
8727 { "RE-8", "oran_fh_cus.sReSMask-re8",
8728 FT_BOOLEAN, 16,
8729 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8730 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8731 },
8732 { &hf_oran_sReSMask_re7,
8733 { "RE-7", "oran_fh_cus.sReSMask-re7",
8734 FT_BOOLEAN, 16,
8735 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8736 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8737 },
8738 { &hf_oran_sReSMask_re6,
8739 { "RE-6", "oran_fh_cus.sReSMask-re6",
8740 FT_BOOLEAN, 16,
8741 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8742 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8743 },
8744 { &hf_oran_sReSMask_re5,
8745 { "RE-5", "oran_fh_cus.sReSMask-re5",
8746 FT_BOOLEAN, 16,
8747 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8748 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8749 },
8750 { &hf_oran_sReSMask_re4,
8751 { "RE-4", "oran_fh_cus.sReSMask-re4",
8752 FT_BOOLEAN, 16,
8753 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8754 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8755 },
8756 { &hf_oran_sReSMask_re3,
8757 { "RE-3", "oran_fh_cus.sReSMask-re3",
8758 FT_BOOLEAN, 16,
8759 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8760 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8761 },
8762 { &hf_oran_sReSMask_re2,
8763 { "RE-2", "oran_fh_cus.sReSMask-re2",
8764 FT_BOOLEAN, 16,
8765 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8766 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8767 },
8768 { &hf_oran_sReSMask_re1,
8769 { "RE-1", "oran_fh_cus.sReSMask-re1",
8770 FT_BOOLEAN, 16,
8771 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8772 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8773 },
8774
8775 /* 8.3.3.20 */
8776 { &hf_oran_sReSMask1,
8777 { "sReSMask1", "oran_fh_cus.sReSMask1",
8778 FT_UINT16, BASE_HEX,
8779 NULL((void*)0), 0x0fff,
8780 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8781 },
8782 /* 8.3.3.21 */
8783 { &hf_oran_sReSMask2,
8784 { "sReSMask2", "oran_fh_cus.sReSMask2",
8785 FT_UINT16, BASE_HEX,
8786 NULL((void*)0), 0x0fff,
8787 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8788 },
8789
8790 { &hf_oran_sReSMask1_2_re12,
8791 { "RE-12", "oran_fh_cus.sReSMask-re12",
8792 FT_BOOLEAN, 16,
8793 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8794 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8795 },
8796 { &hf_oran_sReSMask1_2_re11,
8797 { "RE-11", "oran_fh_cus.sReSMask-re11",
8798 FT_BOOLEAN, 16,
8799 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8800 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8801 },
8802 { &hf_oran_sReSMask1_2_re10,
8803 { "RE-10", "oran_fh_cus.sReSMask-re10",
8804 FT_BOOLEAN, 16,
8805 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8806 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8807 },
8808 { &hf_oran_sReSMask1_2_re9,
8809 { "RE-9", "oran_fh_cus.sReSMask-re9",
8810 FT_BOOLEAN, 16,
8811 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8812 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8813 },
8814
8815 /* Section 6.3.3.15 */
8816 { &hf_oran_iSample,
8817 { "iSample", "oran_fh_cus.iSample",
8818 FT_FLOAT, BASE_NONE,
8819 NULL((void*)0), 0x0,
8820 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8821 },
8822
8823 /* Section 6.3.3.16 */
8824 { &hf_oran_qSample,
8825 { "qSample", "oran_fh_cus.qSample",
8826 FT_FLOAT, BASE_NONE,
8827 NULL((void*)0), 0x0,
8828 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8829 },
8830
8831 { &hf_oran_exponent,
8832 { "Exponent", "oran_fh_cus.exponent",
8833 FT_UINT8, BASE_DEC,
8834 NULL((void*)0), 0x0f,
8835 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8836 },
8837
8838 { &hf_oran_iq_user_data,
8839 { "IQ User Data", "oran_fh_cus.iq_user_data",
8840 FT_BYTES, BASE_NONE,
8841 NULL((void*)0), 0x0,
8842 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8843 },
8844
8845
8846 { &hf_oran_u_section_ul_symbol_time,
8847 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
8848 FT_UINT32, BASE_DEC,
8849 NULL((void*)0), 0x0,
8850 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8851 },
8852 { &hf_oran_u_section_ul_symbol_frames,
8853 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
8854 FT_UINT32, BASE_DEC,
8855 NULL((void*)0), 0x0,
8856 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8857 },
8858 { &hf_oran_u_section_ul_symbol_first_frame,
8859 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
8860 FT_FRAMENUM, BASE_NONE,
8861 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8862 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8863 },
8864 { &hf_oran_u_section_ul_symbol_last_frame,
8865 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
8866 FT_FRAMENUM, BASE_NONE,
8867 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8868 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8869 },
8870
8871 { &hf_oran_c_eAxC_ID,
8872 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
8873 FT_STRING, BASE_NONE,
8874 NULL((void*)0), 0x0,
8875 "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) }
8876 },
8877
8878 { &hf_oran_refa,
8879 { "RefA", "oran_fh_cus.refa",
8880 FT_STRING, BASE_NONE,
8881 NULL((void*)0), 0x0,
8882 "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) }
8883 },
8884
8885
8886 /* Section 7.5.2.15 */
8887 { &hf_oran_ciCompHdr,
8888 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
8889 FT_STRING, BASE_NONE,
8890 NULL((void*)0), 0x0,
8891 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8892 },
8893 { &hf_oran_ciCompHdrMeth,
8894 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
8895 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8896 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
8897 "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)}
8898 },
8899 { &hf_oran_ciCompHdrIqWidth,
8900 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8901 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8902 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8903 "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)}
8904 },
8905 { &hf_oran_ciCompOpt,
8906 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
8907 FT_UINT8, BASE_DEC,
8908 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
8909 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8910 },
8911
8912 /* 7.7.11.7 */
8913 { &hf_oran_disable_bfws,
8914 { "disableBFWs", "oran_fh_cus.disableBFWs",
8915 FT_BOOLEAN, 8,
8916 NULL((void*)0), 0x80,
8917 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8918 },
8919 /* 7.7.11.8 */
8920 { &hf_oran_rad,
8921 { "RAD", "oran_fh_cus.rad",
8922 FT_BOOLEAN, 8,
8923 NULL((void*)0), 0x40,
8924 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8925 },
8926 /* 7.7.11.4 */
8927 { &hf_oran_num_bund_prbs,
8928 { "numBundPrb", "oran_fh_cus.numBundPrb",
8929 FT_UINT8, BASE_DEC,
8930 NULL((void*)0), 0x0,
8931 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8932 },
8933 { &hf_oran_beam_id,
8934 { "beamId", "oran_fh_cus.beamId",
8935 FT_UINT16, BASE_DEC,
8936 NULL((void*)0), 0x7fff,
8937 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8938 },
8939 { &hf_oran_num_weights_per_bundle,
8940 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
8941 FT_UINT16, BASE_DEC,
8942 NULL((void*)0), 0x0,
8943 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8944 },
8945
8946 { &hf_oran_samples_prb,
8947 {"PRB", "oran_fh_cus.prb",
8948 FT_STRING, BASE_NONE,
8949 NULL((void*)0), 0x0,
8950 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8951 },
8952
8953 /* 7.5.3.13 */
8954 { &hf_oran_ciSample,
8955 { "ciSample", "oran_fh_cus.ciSample",
8956 FT_STRING, BASE_NONE,
8957 NULL((void*)0), 0x0,
8958 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8959 },
8960 { &hf_oran_ciIsample,
8961 { "ciIsample", "oran_fh_cus.ciISample",
8962 FT_FLOAT, BASE_NONE,
8963 NULL((void*)0), 0x0,
8964 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8965 },
8966 { &hf_oran_ciQsample,
8967 { "ciQsample", "oran_fh_cus.ciQSample",
8968 FT_FLOAT, BASE_NONE,
8969 NULL((void*)0), 0x0,
8970 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8971 },
8972
8973 /* 7.7.10.2 */
8974 { &hf_oran_beamGroupType,
8975 { "beamGroupType", "oran_fh_cus.beamGroupType",
8976 FT_UINT8, BASE_DEC,
8977 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
8978 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8979 },
8980 /* 7.7.10.3 */
8981 { &hf_oran_numPortc,
8982 { "numPortc", "oran_fh_cus.numPortc",
8983 FT_UINT8, BASE_DEC,
8984 NULL((void*)0), 0x3f,
8985 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8986 },
8987
8988 /* 7.7.4.2 (1 bit) */
8989 { &hf_oran_csf,
8990 { "csf", "oran_fh_cus.csf",
8991 FT_BOOLEAN, BASE_NONE,
8992 NULL((void*)0), 0x0,
8993 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8994 },
8995 /* 7.7.4.3 */
8996 { &hf_oran_modcompscaler,
8997 { "modCompScaler", "oran_fh_cus.modcompscaler",
8998 FT_UINT16, BASE_DEC,
8999 NULL((void*)0), 0x7fff,
9000 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9001 },
9002
9003 /* 7.7.5.1 */
9004 { &hf_oran_modcomp_param_set,
9005 { "Set", "oran_fh_cus.modcomp-param-set",
9006 FT_STRING, BASE_NONE,
9007 NULL((void*)0), 0x0,
9008 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9009 },
9010
9011
9012
9013 /* mcScaleReMask 7.7.5.2 (12 bits) */
9014
9015 /* First entry (starts with msb within byte) */
9016 { &hf_oran_mc_scale_re_mask_re1,
9017 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9018 FT_BOOLEAN, 16,
9019 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9020 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9021 },
9022 { &hf_oran_mc_scale_re_mask_re2,
9023 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9024 FT_BOOLEAN, 16,
9025 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9026 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9027 },
9028 { &hf_oran_mc_scale_re_mask_re3,
9029 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9030 FT_BOOLEAN, 16,
9031 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9033 },
9034 { &hf_oran_mc_scale_re_mask_re4,
9035 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9036 FT_BOOLEAN, 16,
9037 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9038 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9039 },
9040 { &hf_oran_mc_scale_re_mask_re5,
9041 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9042 FT_BOOLEAN, 16,
9043 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9044 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9045 },
9046 { &hf_oran_mc_scale_re_mask_re6,
9047 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9048 FT_BOOLEAN, 16,
9049 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9050 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9051 },
9052 { &hf_oran_mc_scale_re_mask_re7,
9053 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9054 FT_BOOLEAN, 16,
9055 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9056 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9057 },
9058 { &hf_oran_mc_scale_re_mask_re8,
9059 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9060 FT_BOOLEAN, 16,
9061 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9062 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9063 },
9064 { &hf_oran_mc_scale_re_mask_re9,
9065 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9066 FT_BOOLEAN, 16,
9067 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9068 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9069 },
9070 { &hf_oran_mc_scale_re_mask_re10,
9071 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9072 FT_BOOLEAN, 16,
9073 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9074 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9075 },
9076 { &hf_oran_mc_scale_re_mask_re11,
9077 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9078 FT_BOOLEAN, 16,
9079 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9080 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9081 },
9082 { &hf_oran_mc_scale_re_mask_re12,
9083 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9084 FT_BOOLEAN, 16,
9085 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9086 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9087 },
9088
9089 /* Even tries entry (starts with 5th bit within byte) */
9090 { &hf_oran_mc_scale_re_mask_re1_even,
9091 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9092 FT_BOOLEAN, 16,
9093 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9094 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9095 },
9096 { &hf_oran_mc_scale_re_mask_re2_even,
9097 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9098 FT_BOOLEAN, 16,
9099 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9100 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9101 },
9102 { &hf_oran_mc_scale_re_mask_re3_even,
9103 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9104 FT_BOOLEAN, 16,
9105 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9106 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9107 },
9108 { &hf_oran_mc_scale_re_mask_re4_even,
9109 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9110 FT_BOOLEAN, 16,
9111 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9112 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9113 },
9114 { &hf_oran_mc_scale_re_mask_re5_even,
9115 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9116 FT_BOOLEAN, 16,
9117 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9118 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9119 },
9120 { &hf_oran_mc_scale_re_mask_re6_even,
9121 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9122 FT_BOOLEAN, 16,
9123 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9124 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9125 },
9126 { &hf_oran_mc_scale_re_mask_re7_even,
9127 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9128 FT_BOOLEAN, 16,
9129 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9130 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9131 },
9132 { &hf_oran_mc_scale_re_mask_re8_even,
9133 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9134 FT_BOOLEAN, 16,
9135 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9136 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9137 },
9138 { &hf_oran_mc_scale_re_mask_re9_even,
9139 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9140 FT_BOOLEAN, 16,
9141 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9142 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9143 },
9144 { &hf_oran_mc_scale_re_mask_re10_even,
9145 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9146 FT_BOOLEAN, 16,
9147 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9148 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9149 },
9150 { &hf_oran_mc_scale_re_mask_re11_even,
9151 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9152 FT_BOOLEAN, 16,
9153 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9154 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9155 },
9156 { &hf_oran_mc_scale_re_mask_re12_even,
9157 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9158 FT_BOOLEAN, 16,
9159 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9160 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9161 },
9162
9163 { &hf_oran_mc_scale_re_mask,
9164 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9165 FT_UINT16, BASE_HEX,
9166 NULL((void*)0), 0xfff0,
9167 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9168 },
9169 { &hf_oran_mc_scale_re_mask_even,
9170 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9171 FT_UINT16, BASE_HEX,
9172 NULL((void*)0), 0x0fff,
9173 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9174 },
9175
9176 /* mcScaleOffset 7.7.5.4 (15 bits) */
9177 { &hf_oran_mc_scale_offset,
9178 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9179 FT_UINT24, BASE_DEC,
9180 NULL((void*)0), 0x0,
9181 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9182 },
9183 /* eAxCmask (7.7.7.2) */
9184 { &hf_oran_eAxC_mask,
9185 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9186 FT_UINT16, BASE_HEX,
9187 NULL((void*)0), 0xffff,
9188 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9189 },
9190 /* technology (interface name) 7.7.9.2 */
9191 { &hf_oran_technology,
9192 { "Technology", "oran_fh_cus.technology",
9193 FT_UINT8, BASE_DEC,
9194 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9195 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9196 },
9197 /* Exttype 14 (7.7.14.2) */
9198 { &hf_oran_nullLayerInd,
9199 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9200 FT_BOOLEAN, BASE_NONE,
9201 NULL((void*)0), 0x0,
9202 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9203 },
9204
9205 /* Exttype 19 */
9206 /* 7.7.19.3 */
9207 { &hf_oran_se19_repetition,
9208 { "repetition", "oran_fh_cus.repetition",
9209 FT_BOOLEAN, BASE_NONE,
9210 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9211 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9212 },
9213 /* 7.7.19.8 */
9214 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9215 { &hf_oran_portReMask,
9216 { "portReMask", "oran_fh_cus.portReMask",
9217 FT_BOOLEAN, 16,
9218 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9219 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9220 },
9221 /* 7.7.19.9 */
9222 { &hf_oran_portSymbolMask,
9223 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9224 FT_BOOLEAN, 16,
9225 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9226 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9227 },
9228
9229 { &hf_oran_ext19_port,
9230 {"Port", "oran_fh_cus.ext19.port",
9231 FT_STRING, BASE_NONE,
9232 NULL((void*)0), 0x0,
9233 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9234 },
9235
9236 /* Ext 13 */
9237 { &hf_oran_prb_allocation,
9238 {"PRB allocation", "oran_fh_cus.prb-allocation",
9239 FT_STRING, BASE_NONE,
9240 NULL((void*)0), 0x0,
9241 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9242 },
9243 /* 7.7.13.2 */
9244 { &hf_oran_nextSymbolId,
9245 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9246 FT_UINT8, BASE_DEC,
9247 NULL((void*)0), 0x3c,
9248 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9249 },
9250 /* 7.7.13.3 */
9251 { &hf_oran_nextStartPrbc,
9252 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9253 FT_UINT16, BASE_DEC,
9254 NULL((void*)0), 0x03ff,
9255 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9256 },
9257
9258 /* Puncturing patters as appears in SE 20 */
9259 { &hf_oran_puncPattern,
9260 { "puncPattern", "oran_fh_cus.puncPattern",
9261 FT_STRING, BASE_NONE,
9262 NULL((void*)0), 0x0,
9263 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9264 },
9265
9266 /* 7.7.20.2 numPuncPatterns */
9267 { &hf_oran_numPuncPatterns,
9268 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9269 FT_UINT8, BASE_DEC,
9270 NULL((void*)0), 0x0,
9271 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9272 },
9273 /* 7.7.20.3 symbolMask */
9274 { &hf_oran_symbolMask_ext20,
9275 { "symbolMask", "oran_fh_cus.symbolMask",
9276 FT_UINT16, BASE_HEX,
9277 NULL((void*)0), 0xfffc,
9278 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9279 },
9280 /* 7.7.20.4 startPuncPrb */
9281 { &hf_oran_startPuncPrb,
9282 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9283 FT_UINT16, BASE_DEC,
9284 NULL((void*)0), 0x03ff,
9285 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9286 },
9287 /* 7.7.20.5 numPuncPrb */
9288 { &hf_oran_numPuncPrb,
9289 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9290 FT_UINT8, BASE_DEC,
9291 NULL((void*)0), 0x0,
9292 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9293 },
9294 /* 7.7.20.6 puncReMask */
9295 { &hf_oran_puncReMask,
9296 { "puncReMask", "oran_fh_cus.puncReMask",
9297 FT_UINT16, BASE_DEC,
9298 NULL((void*)0), 0xffc0,
9299 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9300 },
9301 /* 7.7.20.12 multiSDScope */
9302 { &hf_oran_multiSDScope,
9303 { "multiSDScope", "oran_fh_cus.multiSDScope",
9304 FT_BOOLEAN, 8,
9305 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9306 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9307 },
9308 /* 7.7.20.4 rbgIncl */
9309 { &hf_oran_RbgIncl,
9310 { "rbgIncl", "oran_fh_cus.rbgIncl",
9311 FT_BOOLEAN, 8,
9312 NULL((void*)0), 0x01,
9313 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9314 },
9315
9316 /* 7.7.21.2 ciPrbGroupSize */
9317 { &hf_oran_ci_prb_group_size,
9318 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9319 FT_UINT8, BASE_DEC,
9320 NULL((void*)0), 0x0,
9321 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9322 },
9323 /* 7.21.3 */
9324 { &hf_oran_prg_size_st5,
9325 { "prgSize", "oran_fh_cus.prgSize",
9326 FT_UINT8, BASE_DEC,
9327 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9328 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9329 },
9330 { &hf_oran_prg_size_st6,
9331 { "prgSize", "oran_fh_cus.prgSize",
9332 FT_UINT8, BASE_DEC,
9333 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9334 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9335 },
9336
9337 /* 7.7.17.2 numUeID */
9338 { &hf_oran_num_ueid,
9339 { "numUeID", "oran_fh_cus.numUeID",
9340 FT_UINT8, BASE_DEC,
9341 NULL((void*)0), 0x0,
9342 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9343 },
9344
9345 /* 7.7.16.2 antMask */
9346 { &hf_oran_antMask,
9347 { "antMask", "oran_fh_cus.antMask",
9348 FT_UINT64, BASE_HEX,
9349 NULL((void*)0), 0xffffffffffffffff,
9350 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9351 },
9352
9353 /* 7.7.18.2 transmissionWindowOffset */
9354 { &hf_oran_transmissionWindowOffset,
9355 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9356 FT_UINT16, BASE_DEC,
9357 NULL((void*)0), 0x0,
9358 "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)}
9359 },
9360 /* 7.7.18.3 transmissionWindowSize */
9361 { &hf_oran_transmissionWindowSize,
9362 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9363 FT_UINT16, BASE_DEC,
9364 NULL((void*)0), 0x3fff,
9365 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9366 },
9367 /* 7.7.18.4 toT */
9368 { &hf_oran_toT,
9369 { "toT", "oran_fh_cus.toT",
9370 FT_UINT8, BASE_DEC,
9371 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9372 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9373 },
9374
9375 /* 7.7.2.2 bfaCompHdr */
9376 { &hf_oran_bfaCompHdr,
9377 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9378 FT_STRING, BASE_NONE,
9379 NULL((void*)0), 0x0,
9380 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9381 },
9382 /* 7.7.2.2-2: bfAzPtWidth */
9383 { &hf_oran_bfAzPtWidth,
9384 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9385 FT_UINT8, BASE_DEC,
9386 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9387 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9388 },
9389 /* 7.7.2.2-3: bfZePtWidth */
9390 { &hf_oran_bfZePtWidth,
9391 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9392 FT_UINT8, BASE_DEC,
9393 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9394 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9395 },
9396 /* 7.7.2.2-4: bfAz3ddWidth */
9397 { &hf_oran_bfAz3ddWidth,
9398 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9399 FT_UINT8, BASE_DEC,
9400 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9401 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9402 },
9403 /* 7.7.2.2-5: bfZe3ddWidth */
9404 { &hf_oran_bfZe3ddWidth,
9405 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9406 FT_UINT8, BASE_DEC,
9407 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9408 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9409 },
9410
9411 /* 7.7.2.3 bfAzPt */
9412 { &hf_oran_bfAzPt,
9413 { "bfAzPt", "oran_fh_cus.bfAzPt",
9414 FT_UINT8, BASE_DEC,
9415 NULL((void*)0), 0x0,
9416 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9417 },
9418 /* 7.7.2.4 bfZePt */
9419 { &hf_oran_bfZePt,
9420 { "bfZePt", "oran_fh_cus.bfZePt",
9421 FT_UINT8, BASE_DEC,
9422 NULL((void*)0), 0x0,
9423 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9424 },
9425 /* 7.7.2.5 bfAz3dd */
9426 { &hf_oran_bfAz3dd,
9427 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9428 FT_UINT8, BASE_DEC,
9429 NULL((void*)0), 0x0,
9430 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9431 },
9432 /* 7.7.2.6 bfZe3dd */
9433 { &hf_oran_bfZe3dd,
9434 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9435 FT_UINT8, BASE_DEC,
9436 NULL((void*)0), 0x0,
9437 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9438 },
9439
9440 /* 7.7.2.7 bfAzSl */
9441 { &hf_oran_bfAzSl,
9442 { "bfAzSl", "oran_fh_cus.bfAzSl",
9443 FT_UINT8, BASE_DEC,
9444 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9445 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9446 },
9447 /* 7.7.2.8 bfZeSl */
9448 { &hf_oran_bfZeSl,
9449 { "bfZeSl", "oran_fh_cus.bfZeSl",
9450 FT_UINT8, BASE_DEC,
9451 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9452 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9453 },
9454
9455 /* 7.5.2.17 */
9456 { &hf_oran_cmd_scope,
9457 { "cmdScope", "oran_fh_cus.cmdScope",
9458 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9459 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9460 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9461 },
9462 /* 7.5.2.18 */
9463 { &hf_oran_number_of_st4_cmds,
9464 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9465 FT_UINT8, BASE_DEC,
9466 NULL((void*)0), 0x0,
9467 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9468 },
9469
9470 { &hf_oran_st4_cmd_header,
9471 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9472 FT_STRING, BASE_NONE,
9473 NULL((void*)0), 0x0,
9474 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9475 },
9476
9477 /* 7.5.3.38 */
9478 { &hf_oran_st4_cmd_type,
9479 { "st4CmdType", "oran_fh_cus.st4CmdType",
9480 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9481 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9482 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9483 },
9484 /* 7.5.3.39 */
9485 { &hf_oran_st4_cmd_len,
9486 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9487 FT_UINT16, BASE_DEC,
9488 NULL((void*)0), 0x0,
9489 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9490 },
9491 /* 7.5.3.40 */
9492 { &hf_oran_st4_cmd_num_slots,
9493 { "numSlots", "oran_fh_cus.st4NumSlots",
9494 FT_UINT8, BASE_DEC,
9495 NULL((void*)0), 0x0,
9496 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9497 },
9498 /* 7.5.3.41 */
9499 { &hf_oran_st4_cmd_ack_nack_req_id,
9500 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9501 FT_UINT16, BASE_DEC,
9502 NULL((void*)0), 0x0,
9503 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9504 },
9505
9506 { &hf_oran_st4_cmd,
9507 { "Command", "oran_fh_cus.st4Cmd",
9508 FT_STRING, BASE_NONE,
9509 NULL((void*)0), 0x0,
9510 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9511 },
9512
9513 /* 7.5.3.52 */
9514 { &hf_oran_sleepmode_trx,
9515 { "sleepMode", "oran_fh_cus.sleepMode",
9516 FT_UINT8, BASE_HEX,
9517 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9518 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9519 },
9520 { &hf_oran_sleepmode_asm,
9521 { "sleepMode", "oran_fh_cus.sleepMode",
9522 FT_UINT8, BASE_HEX,
9523 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9524 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9525 },
9526
9527 /* 7.5.3.51 */
9528 { &hf_oran_log2maskbits,
9529 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9530 FT_UINT8, BASE_HEX,
9531 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9532 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9533 },
9534 /* 7.5.3.53 */
9535 { &hf_oran_num_slots_ext,
9536 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9537 FT_UINT24, BASE_HEX,
9538 NULL((void*)0), 0x0fffff,
9539 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9540 },
9541 /* 7.5.3.54 */
9542 { &hf_oran_antMask_trx_control,
9543 { "antMask", "oran_fh_cus.trxControl.antMask",
9544 FT_BYTES, BASE_NONE,
9545 NULL((void*)0), 0x0,
9546 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9547 },
9548 /* 7.5.3.55 */
9549 { &hf_oran_ready,
9550 { "ready", "oran_fh_cus.ready",
9551 FT_BOOLEAN, 8,
9552 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9553 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9554 },
9555 /* 7.5.3.34 */
9556 { &hf_oran_number_of_acks,
9557 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9558 FT_UINT8, BASE_DEC,
9559 NULL((void*)0), 0x0,
9560 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9561 },
9562 /* 7.5.3.35 */
9563 { &hf_oran_number_of_nacks,
9564 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9565 FT_UINT8, BASE_DEC,
9566 NULL((void*)0), 0x0,
9567 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9568 },
9569 /* 7.5.3.36 */
9570 { &hf_oran_ackid,
9571 { "ackId", "oran_fh_cus.ackId",
9572 FT_UINT16, BASE_DEC,
9573 NULL((void*)0), 0x0,
9574 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9575 },
9576 /* 7.5.3.37 */
9577 { &hf_oran_nackid,
9578 { "nackId", "oran_fh_cus.nackId",
9579 FT_UINT16, BASE_DEC,
9580 NULL((void*)0), 0x0,
9581 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9582 },
9583
9584 /* Links between acknack requests & responses */
9585 { &hf_oran_acknack_request_frame,
9586 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9587 FT_FRAMENUM, BASE_NONE,
9588 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9589 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9590 },
9591 { &hf_oran_acknack_request_time,
9592 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9593 FT_UINT32, BASE_DEC,
9594 NULL((void*)0), 0x0,
9595 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9596 },
9597 { &hf_oran_acknack_request_type,
9598 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9599 FT_UINT32, BASE_DEC,
9600 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9601 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9602 },
9603 { &hf_oran_acknack_response_frame,
9604 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9605 FT_FRAMENUM, BASE_NONE,
9606 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9607 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9608 },
9609 { &hf_oran_acknack_response_time,
9610 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9611 FT_UINT32, BASE_DEC,
9612 NULL((void*)0), 0x0,
9613 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9614 },
9615
9616 /* 7.5.3.43 */
9617 { &hf_oran_disable_tdbfns,
9618 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9619 FT_BOOLEAN, 8,
9620 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9621 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9622 },
9623
9624 /* 7.5.3.44 */
9625 { &hf_oran_td_beam_group,
9626 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9627 FT_UINT16, BASE_HEX,
9628 NULL((void*)0), 0x7fff,
9629 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9630 },
9631 /* 7.5.3.43 */
9632 { &hf_oran_disable_tdbfws,
9633 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9634 FT_BOOLEAN, 8,
9635 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9636 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9637 },
9638
9639 /* 7.5.3.56 */
9640 { &hf_oran_td_beam_num,
9641 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9642 FT_UINT16, BASE_HEX,
9643 NULL((void*)0), 0x7fff,
9644 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9645 },
9646
9647 /* 7.5.3.49 */
9648 { &hf_oran_dir_pattern,
9649 { "dirPattern", "oran_fh_cus.dirPattern",
9650 FT_BOOLEAN, 16,
9651 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9652 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9653 },
9654 /* 7.5.3.50 */
9655 { &hf_oran_guard_pattern,
9656 { "guardPattern", "oran_fh_cus.guardPattern",
9657 FT_BOOLEAN, 16,
9658 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9659 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9660 },
9661
9662 /* For convenient filtering */
9663 { &hf_oran_cplane,
9664 { "C-Plane", "oran_fh_cus.c-plane",
9665 FT_NONE, BASE_NONE,
9666 NULL((void*)0), 0x0,
9667 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9668 },
9669 { &hf_oran_uplane,
9670 { "U-Plane", "oran_fh_cus.u-plane",
9671 FT_NONE, BASE_NONE,
9672 NULL((void*)0), 0x0,
9673 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9674 },
9675 { &hf_oran_bf,
9676 { "BeamForming", "oran_fh_cus.bf",
9677 FT_NONE, BASE_NONE,
9678 NULL((void*)0), 0x0,
9679 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9680 },
9681 { &hf_oran_zero_prb,
9682 { "Zero PRB", "oran_fh_cus.zero-prb",
9683 FT_NONE, BASE_NONE,
9684 NULL((void*)0), 0x0,
9685 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9686 },
9687 { &hf_oran_nonzero_prb,
9688 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9689 FT_NONE, BASE_NONE,
9690 NULL((void*)0), 0x0,
9691 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9692 },
9693 { &hf_oran_bundle_weights_all_zero,
9694 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9695 FT_NONE, BASE_NONE,
9696 NULL((void*)0), 0x0,
9697 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9698 },
9699
9700
9701 /* 5.1.3.2.7 */
9702 { &hf_oran_ecpri_pcid,
9703 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9704 FT_NONE, BASE_NONE,
9705 NULL((void*)0), 0x0,
9706 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9707 },
9708 { &hf_oran_ecpri_rtcid,
9709 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9710 FT_NONE, BASE_NONE,
9711 NULL((void*)0), 0x0,
9712 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9713 },
9714 /* 5.1.3.2.8 */
9715 { &hf_oran_ecpri_seqid,
9716 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
9717 FT_NONE, BASE_NONE,
9718 NULL((void*)0), 0x0,
9719 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9720 },
9721
9722 /* 7.7.23.2 */
9723 { &hf_oran_num_sym_prb_pattern,
9724 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
9725 FT_UINT8, BASE_DEC,
9726 NULL((void*)0), 0xf0,
9727 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9728 },
9729 /* 7.7.23.11 */
9730 { &hf_oran_prb_mode,
9731 { "prbMode", "oran_fh_cus.prbMode",
9732 FT_BOOLEAN, 8,
9733 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
9734 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9735 },
9736
9737 { &hf_oran_sym_prb_pattern,
9738 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
9739 FT_STRING, BASE_NONE,
9740 NULL((void*)0), 0x0,
9741 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9742 },
9743
9744 /* 7.7.23.3 */
9745 { &hf_oran_sym_mask,
9746 { "symMask", "oran_fh_cus.symMask",
9747 FT_UINT16, BASE_HEX,
9748 NULL((void*)0), 0x3fff,
9749 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9750 },
9751 /* 7.7.23.5 */
9752 {&hf_oran_num_mc_scale_offset,
9753 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
9754 FT_UINT8, BASE_DEC,
9755 NULL((void*)0), 0xf0,
9756 "number of modulation compression scaling value per symPrbPattern",
9757 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9758 },
9759 /* 7.7.23.4 */
9760 { &hf_oran_prb_pattern,
9761 { "prbPattern", "oran_fh_cus.prbPattern",
9762 FT_UINT8, BASE_DEC,
9763 NULL((void*)0), 0x0f,
9764 "resource block pattern part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9765 },
9766
9767 /* 7.7.3.2 */
9768 { &hf_oran_codebook_index,
9769 { "codebookIndex", "oran_fh_cus.codebookIndex",
9770 FT_UINT8, BASE_DEC,
9771 NULL((void*)0), 0x0,
9772 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9773 },
9774 /* 7.7.3.3 */
9775 { &hf_oran_layerid,
9776 { "layerID", "oran_fh_cus.layerID",
9777 FT_UINT8, BASE_DEC,
9778 NULL((void*)0), 0xf0,
9779 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9780 },
9781 /* 7.7.3.5 */
9782 { &hf_oran_numlayers,
9783 { "numLayers", "oran_fh_cus.numLayers",
9784 FT_UINT8, BASE_DEC,
9785 NULL((void*)0), 0x0f,
9786 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9787 },
9788 /* 7.7.3.4 */
9789 { &hf_oran_txscheme,
9790 { "txScheme", "oran_fh_cus.txScheme",
9791 FT_UINT8, BASE_DEC,
9792 NULL((void*)0), 0xf0,
9793 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9794 },
9795 /* 7.7.3.6 */
9796 { &hf_oran_crs_remask,
9797 { "crsReMask", "oran_fh_cus.crsReMask",
9798 FT_UINT16, BASE_HEX,
9799 NULL((void*)0), 0x0fff,
9800 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9801 },
9802 /* 7.7.3.8 */
9803 { &hf_oran_crs_shift,
9804 { "crsShift", "oran_fh_cus.crsShift",
9805 FT_UINT8, BASE_HEX,
9806 NULL((void*)0), 0x80,
9807 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9808 },
9809 /* 7.7.3.7 */
9810 { &hf_oran_crs_symnum,
9811 { "crsSymNum", "oran_fh_cus.crsSymNum",
9812 FT_UINT8, BASE_DEC,
9813 NULL((void*)0), 0x0f,
9814 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9815 },
9816 /* 7.7.3.9 */
9817 { &hf_oran_beamid_ap1,
9818 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
9819 FT_UINT16, BASE_DEC,
9820 NULL((void*)0), 0x7f,
9821 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9822 },
9823 /* 7.7.3.10 */
9824 { &hf_oran_beamid_ap2,
9825 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
9826 FT_UINT16, BASE_DEC,
9827 NULL((void*)0), 0x7f,
9828 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9829 },
9830 /* 7.7.3.11 */
9831 { &hf_oran_beamid_ap3,
9832 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
9833 FT_UINT16, BASE_DEC,
9834 NULL((void*)0), 0x7f,
9835 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9836 },
9837
9838 /* 7.7.10.3a */
9839 { &hf_oran_port_list_index,
9840 { "portListIndex", "oran_fh_cus.portListIndex",
9841 FT_UINT8, BASE_DEC,
9842 NULL((void*)0), 0x0,
9843 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9844 },
9845
9846 { &hf_oran_alpn_per_sym,
9847 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
9848 FT_UINT8, BASE_HEX,
9849 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
9850 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9851 },
9852 { &hf_oran_ant_dmrs_snr,
9853 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
9854 FT_UINT8, BASE_HEX,
9855 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
9856 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9857 },
9858
9859 /* 7.7.24.6 */
9860 { &hf_oran_user_group_size,
9861 { "userGroupSize", "oran_fh_cus.userGroupSize",
9862 FT_UINT8, BASE_DEC,
9863 NULL((void*)0), 0x1f,
9864 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9865 },
9866 /* 7.7.24.7 */
9867 { &hf_oran_user_group_id,
9868 { "userGroupId", "oran_fh_cus.userGroupId",
9869 FT_UINT8, BASE_DEC,
9870 NULL((void*)0), 0x0,
9871 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9872 },
9873 /* 7.7.24.8 */
9874 { &hf_oran_entry_type,
9875 { "entryType", "oran_fh_cus.entryType",
9876 FT_UINT8, BASE_DEC,
9877 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
9878 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9879 },
9880 /* 7.7.24.9 */
9881 { &hf_oran_dmrs_port_number,
9882 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
9883 FT_UINT8, BASE_DEC,
9884 NULL((void*)0), 0x1f,
9885 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9886 },
9887 /* 7.7.24.10 */
9888 { &hf_oran_ueid_reset,
9889 { "ueidReset", "oran_fh_cus.ueidReset",
9890 FT_BOOLEAN, 8,
9891 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
9892 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9893 },
9894 /* 7.7.24.11 */
9895 { &hf_oran_dmrs_symbol_mask,
9896 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
9897 FT_UINT16, BASE_HEX,
9898 NULL((void*)0), 0x3fff,
9899 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9900 },
9901 { &hf_oran_dmrs_symbol_mask_s13,
9902 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
9903 FT_BOOLEAN, 16,
9904 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
9905 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9906 },
9907 { &hf_oran_dmrs_symbol_mask_s12,
9908 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
9909 FT_BOOLEAN, 16,
9910 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
9911 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9912 },
9913 { &hf_oran_dmrs_symbol_mask_s11,
9914 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
9915 FT_BOOLEAN, 16,
9916 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9917 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9918 },
9919 { &hf_oran_dmrs_symbol_mask_s10,
9920 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
9921 FT_BOOLEAN, 16,
9922 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9923 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9924 },
9925 { &hf_oran_dmrs_symbol_mask_s9,
9926 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
9927 FT_BOOLEAN, 16,
9928 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9929 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9930 },
9931 { &hf_oran_dmrs_symbol_mask_s8,
9932 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
9933 FT_BOOLEAN, 16,
9934 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9935 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9936 },
9937 { &hf_oran_dmrs_symbol_mask_s7,
9938 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
9939 FT_BOOLEAN, 16,
9940 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9941 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9942 },
9943 { &hf_oran_dmrs_symbol_mask_s6,
9944 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
9945 FT_BOOLEAN, 16,
9946 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9947 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9948 },
9949 { &hf_oran_dmrs_symbol_mask_s5,
9950 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
9951 FT_BOOLEAN, 16,
9952 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
9953 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9954 },
9955 { &hf_oran_dmrs_symbol_mask_s4,
9956 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
9957 FT_BOOLEAN, 16,
9958 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
9959 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9960 },
9961 { &hf_oran_dmrs_symbol_mask_s3,
9962 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
9963 FT_BOOLEAN, 16,
9964 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
9965 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9966 },
9967 { &hf_oran_dmrs_symbol_mask_s2,
9968 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
9969 FT_BOOLEAN, 16,
9970 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
9971 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9972 },
9973 { &hf_oran_dmrs_symbol_mask_s1,
9974 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
9975 FT_BOOLEAN, 16,
9976 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
9977 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9978 },
9979 { &hf_oran_dmrs_symbol_mask_s0,
9980 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
9981 FT_BOOLEAN, 16,
9982 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
9983 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9984 },
9985
9986 /* 7.7.24.12 */
9987 { &hf_oran_scrambling,
9988 { "scrambling", "oran_fh_cus.scrambling",
9989 FT_UINT16, BASE_HEX,
9990 NULL((void*)0), 0x0,
9991 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9992 },
9993 /* 7.7.24.13 */
9994 { &hf_oran_nscid,
9995 { "nscid", "oran_fh_cus.nscid",
9996 FT_UINT8, BASE_HEX,
9997 NULL((void*)0), 0x80,
9998 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9999 },
10000 /* 7.7.24.14 */
10001 { &hf_oran_dtype,
10002 { "dType", "oran_fh_cus.dType",
10003 FT_UINT8, BASE_HEX,
10004 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10005 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10006 },
10007 /* 7.7.24.15 */
10008 { &hf_oran_cmd_without_data,
10009 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10010 FT_UINT8, BASE_HEX,
10011 NULL((void*)0), 0x30,
10012 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10013 },
10014 /* 7.7.24.16 */
10015 { &hf_oran_lambda,
10016 { "lambda", "oran_fh_cus.lambda",
10017 FT_UINT8, BASE_HEX,
10018 NULL((void*)0), 0x0c,
10019 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10020 },
10021 /* 7.7.24.19 */
10022 { &hf_oran_first_prb,
10023 { "firstPrb", "oran_fh_cus.firstPrb",
10024 FT_UINT16, BASE_DEC,
10025 NULL((void*)0), 0x03fe,
10026 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10027 },
10028 /* 7.7.24.20 */
10029 { &hf_oran_last_prb,
10030 { "lastPrb", "oran_fh_cus.lastPrb",
10031 FT_UINT16, BASE_DEC,
10032 NULL((void*)0), 0x01ff,
10033 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10034 },
10035
10036 /* 7.7.24.17 */
10037 /* TODO: add value_string */
10038 { &hf_oran_low_papr_type,
10039 { "lowPaprType", "oran_fh_cus.lowPaprType",
10040 FT_UINT8, BASE_HEX,
10041 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10042 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10043 },
10044 /* 7.7.24.18 */
10045 { &hf_oran_hopping_mode,
10046 { "hoppingMode", "oran_fh_cus.hoppingMode",
10047 FT_UINT8, BASE_HEX,
10048 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10049 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10050 },
10051
10052 { &hf_oran_tx_win_for_on_air_symbol_l,
10053 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10054 FT_UINT8, BASE_DEC,
10055 NULL((void*)0), 0xf0,
10056 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10057 },
10058 { &hf_oran_tx_win_for_on_air_symbol_r,
10059 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10060 FT_UINT8, BASE_DEC,
10061 NULL((void*)0), 0x0f,
10062 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10063 },
10064 /* 7.7.26.2 */
10065 { &hf_oran_num_fo_fb,
10066 { "numFoFb", "oran_fh_cus.numFoFb",
10067 FT_UINT8, BASE_DEC,
10068 NULL((void*)0), 0x7f,
10069 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10070 },
10071 /* 7.7.26.3 */
10072 { &hf_oran_freq_offset_fb,
10073 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10074 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10075 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10076 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10077 },
10078
10079 /* 7.7.28.2 */
10080 { &hf_oran_num_ue_sinr_rpt,
10081 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10082 FT_UINT8, BASE_DEC,
10083 NULL((void*)0), 0x1f,
10084 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10085 },
10086
10087 /* 7.5.2.19 */
10088 { &hf_oran_num_sinr_per_prb,
10089 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10090 FT_UINT8, BASE_DEC,
10091 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10092 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10093 },
10094 { &hf_oran_num_sinr_per_prb_right,
10095 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10096 FT_UINT8, BASE_DEC,
10097 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10098 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10099 },
10100
10101 /* 7.5.3.68 */
10102 { &hf_oran_sinr_value,
10103 { "sinrValue", "oran_fh_cus.sinrValue",
10104 FT_FLOAT, BASE_NONE,
10105 NULL((void*)0), 0x0,
10106 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10107 },
10108
10109 { &hf_oran_measurement_report,
10110 { "Measurement Report", "oran_fh_cus.measurement-report",
10111 FT_STRING, BASE_NONE,
10112 NULL((void*)0), 0x0,
10113 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10114 },
10115 /* 7.5.3.57 */
10116 { &hf_oran_mf,
10117 { "mf", "oran_fh_cus.mf",
10118 FT_BOOLEAN, 8,
10119 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10120 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10121 },
10122 /* 7.5.3.59 */
10123 { &hf_oran_meas_data_size,
10124 { "measDataSize", "oran_fh_cus.measDataSize",
10125 FT_UINT16, BASE_DEC,
10126 NULL((void*)0), 0x0,
10127 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10128 },
10129
10130 /* 7.5.3.58 */
10131 { &hf_oran_meas_type_id,
10132 { "measTypeId", "oran_fh_cus.measTypeId",
10133 FT_UINT8, BASE_DEC,
10134 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10135 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10136 },
10137 /* 7.5.3.66 */
10138 { &hf_oran_num_elements,
10139 { "numElements", "oran_fh_cus.numElements",
10140 FT_UINT8, BASE_DEC,
10141 NULL((void*)0), 0x0,
10142 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10143 },
10144 /* 7.5.3.60 */
10145 { &hf_oran_ue_tae,
10146 { "ueTae", "oran_fh_cus.ueTae",
10147 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10148 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10149 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10150 },
10151 /* 7.5.3.61 */
10152 { &hf_oran_ue_layer_power,
10153 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10154 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10155 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10156 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10157 },
10158
10159 /* 7.5.3.62 */
10160 { &hf_oran_ue_freq_offset,
10161 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10162 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10163 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10164 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10165 },
10166 /* 7.5.3.63 */
10167 { &hf_oran_ipn_power,
10168 { "ipnPower", "oran_fh_cus.ipnPower",
10169 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10170 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10171 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10172 },
10173 /* 7.5.3.64 */
10174 { &hf_oran_ant_dmrs_snr_val,
10175 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10176 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10177 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10178 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10179 },
10180
10181 { &hf_oran_measurement_command,
10182 { "Measurement Command", "oran_fh_cus.measurement-command",
10183 FT_STRING, BASE_NONE,
10184 NULL((void*)0), 0x0,
10185 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10186 },
10187
10188 /* 7.5.27.2 */
10189 { &hf_oran_beam_type,
10190 {"beamType", "oran_fh_cus.beamType",
10191 FT_UINT16, BASE_DEC,
10192 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10193 NULL((void*)0),
10194 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10195 },
10196 /* 7.5.3.65 */
10197 { &hf_oran_meas_cmd_size,
10198 {"measCmdSize", "oran_fh_cus.measCmdSize",
10199 FT_UINT16, BASE_DEC,
10200 NULL((void*)0), 0x0,
10201 "measurement command size in words",
10202 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10203 },
10204
10205 { &hf_oran_symbol_reordering_layer,
10206 { "Layer", "oran_fh_cus.layer",
10207 FT_STRING, BASE_NONE,
10208 NULL((void*)0), 0x0,
10209 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10210 },
10211 { &hf_oran_dmrs_entry,
10212 { "Entry", "oran_fh_cus.dmrs-entry",
10213 FT_STRING, BASE_NONE,
10214 NULL((void*)0), 0x0,
10215 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10216 },
10217
10218 /* 7.7.29.3 */
10219 { &hf_oran_cd_scg_size,
10220 {"cdScgSize", "oran_fh_cus.cdScgSize",
10221 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10222 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10223 "Cyclic delay subcarrier group size",
10224 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10225 },
10226 /* 7.7.29.4 */
10227 { &hf_oran_cd_scg_phase_step,
10228 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10229 FT_INT8, BASE_DEC,
10230 NULL((void*)0), 0x0,
10231 "Cyclic delay subcarrier group phase step",
10232 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10233 },
10234
10235 { &hf_oran_sinr_prb,
10236 { "PRB", "oran_fh_cus.sinr.prb",
10237 FT_STRING, BASE_NONE,
10238 NULL((void*)0), 0x0,
10239 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10240 },
10241 /* 7.5.2.20 */
10242 { &hf_oran_oru_control_sinr_slot_mask_id,
10243 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10244 FT_UINT8, BASE_DEC,
10245 NULL((void*)0), 0x1f,
10246 "SINR time resolution",
10247 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10248 },
10249 /* 7.7.24.21 */
10250 { &hf_oran_pos_meas,
10251 {"posMeas", "oran_fh_cus.posMeas",
10252 FT_BOOLEAN, 8,
10253 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10254 "Positioning measurement report request",
10255 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10256 },
10257
10258 /* 7.5.3.69 */
10259 { &hf_oran_ue_radial_speed,
10260 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10261 FT_UINT16, BASE_DEC,
10262 NULL((void*)0), 0x0,
10263 "UE radial speed",
10264 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10265 },
10266 /* 7.5.3.70 */
10267 { &hf_oran_ue_az_aoa,
10268 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10269 FT_UINT16, BASE_DEC,
10270 NULL((void*)0), 0x0,
10271 "UE azimuth angle of arrival",
10272 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10273 },
10274 /* 7.5.3.71 */
10275 { &hf_oran_ue_ze_aoa,
10276 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10277 FT_UINT16, BASE_DEC,
10278 NULL((void*)0), 0x0,
10279 "UE zenith angle of arrival",
10280 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10281 },
10282 /* 7.5.3.72 */
10283 { &hf_oran_ue_pos_toa_offset,
10284 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10285 FT_UINT16, BASE_DEC,
10286 NULL((void*)0), 0x0,
10287 "UE positioning time of arrival offset",
10288 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10289 },
10290
10291 /* 7.7.30.2 */
10292 { &hf_oran_num_rep_ue,
10293 {"numRepUe", "oran_fh_cus.numRepUe",
10294 FT_UINT8, BASE_DEC,
10295 NULL((void*)0), 0x0f,
10296 "Number of UEs with PUSCH repetition",
10297 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10298 },
10299 /* 7.7.30.3 */
10300 { &hf_oran_rep_ueid,
10301 {"repUeId", "oran_fh_cus.repUeId",
10302 FT_UINT16, BASE_DEC,
10303 NULL((void*)0), 0x7fff,
10304 "UEId the PUSCH is part of",
10305 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10306 },
10307 /* 7.7.30.4 */
10308 { &hf_oran_is_last_rep,
10309 {"isLastRep", "oran_fh_cus.isLastRep",
10310 FT_BOOLEAN, 8,
10311 NULL((void*)0), 0x40,
10312 "Last transmission in the repetition",
10313 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10314 },
10315 /* 7.7.30.5 */
10316 { &hf_oran_rep_index,
10317 {"repIndex", "oran_fh_cus.repIndex",
10318 FT_UINT8, BASE_DEC,
10319 NULL((void*)0), 0x3f,
10320 "Repetition index of the PUSCH transmission",
10321 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10322 },
10323 /* 7.7.30.6 */
10324 { &hf_oran_num_reps,
10325 {"numReps", "oran_fh_cus.numReps",
10326 FT_UINT8, BASE_DEC,
10327 NULL((void*)0), 0x3f,
10328 "The number of total PUSCH repetitions",
10329 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10330 },
10331
10332
10333 { &hf_oran_c_section_common,
10334 { "Common Section", "oran_fh_cus.c-plane.section.common",
10335 FT_STRING, BASE_NONE,
10336 NULL((void*)0), 0x0,
10337 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10338 },
10339 { &hf_oran_c_section,
10340 { "Section", "oran_fh_cus.c-plane.section",
10341 FT_STRING, BASE_NONE,
10342 NULL((void*)0), 0x0,
10343 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10344 },
10345 { &hf_oran_u_section,
10346 { "Section", "oran_fh_cus.u-plane.section",
10347 FT_STRING, BASE_NONE,
10348 NULL((void*)0), 0x0,
10349 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10350 },
10351
10352 /* Link back to UL C-plane where udCompHdr was recorded */
10353 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10354 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10355 FT_FRAMENUM, BASE_NONE,
10356 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10357 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10358 },
10359
10360 /* For ext11, where was a beamId (last) defined? */
10361 { &hf_oran_bfws_frame_defined,
10362 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10363 FT_FRAMENUM, BASE_NONE,
10364 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10365 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10366 },
10367 { &hf_oran_bfws_symbols_since_defined,
10368 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10369 FT_UINT32, BASE_DEC,
10370 NULL((void*)0), 0x0,
10371 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10372 },
10373
10374 /* Corresponding C-plane frame for DL U-plane */
10375 { &hf_oran_corresponding_cplane_frame,
10376 { "C-plane frame", "oran_fh_cus.cplane-frame",
10377 FT_FRAMENUM, BASE_NONE,
10378 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10379 },
10380 /* Time since corresponding C-plane frame for DL U-plane */
10381 { &hf_oran_corresponding_cplane_frame_time_delta,
10382 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10383 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10384 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10385 },
10386
10387 /* Reassembly */
10388 { &hf_oran_fragment,
10389 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10390 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10391 { &hf_oran_fragments,
10392 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10393 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10394 { &hf_oran_fragment_overlap,
10395 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10396 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10397 { &hf_oran_fragment_overlap_conflict,
10398 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10399 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10400 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10401 { &hf_oran_fragment_multiple_tails,
10402 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10403 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10404 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10405 { &hf_oran_fragment_too_long_fragment,
10406 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10407 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10408 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10409 { &hf_oran_fragment_error,
10410 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10411 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10412 { &hf_oran_fragment_count,
10413 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10414 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10415 { &hf_oran_reassembled_in,
10416 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10417 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10418 { &hf_oran_reassembled_length,
10419 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10420 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10421 { &hf_oran_reassembled_data,
10422 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10423 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10424
10425 { &hf_oran_payload,
10426 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10427 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10428 };
10429
10430 /* Setup protocol subtree array */
10431 static int *ett[] = {
10432 &ett_oran,
10433 &ett_oran_ecpri_pcid,
10434 &ett_oran_ecpri_rtcid,
10435 &ett_oran_ecpri_seqid,
10436 &ett_oran_section_type,
10437 &ett_oran_u_timing,
10438 &ett_oran_u_section,
10439 &ett_oran_u_prb,
10440 &ett_oran_section,
10441 &ett_oran_iq,
10442 &ett_oran_bfw_bundle,
10443 &ett_oran_bfw,
10444 &ett_oran_frequency_range,
10445 &ett_oran_prb_cisamples,
10446 &ett_oran_cisample,
10447 &ett_oran_udcomphdr,
10448 &ett_oran_udcompparam,
10449 &ett_oran_cicomphdr,
10450 &ett_oran_cicompparam,
10451 &ett_oran_bfwcomphdr,
10452 &ett_oran_bfwcompparam,
10453 &ett_oran_ext19_port,
10454 &ett_oran_prb_allocation,
10455 &ett_oran_punc_pattern,
10456 &ett_oran_bfacomphdr,
10457 &ett_oran_modcomp_param_set,
10458 &ett_oran_st4_cmd_header,
10459 &ett_oran_st4_cmd,
10460 &ett_oran_sym_prb_pattern,
10461 &ett_oran_measurement_report,
10462 &ett_oran_measurement_command,
10463 &ett_oran_sresmask,
10464 &ett_oran_c_section_common,
10465 &ett_oran_c_section,
10466 &ett_oran_remask,
10467 &ett_oran_mc_scale_remask,
10468 &ett_oran_symbol_reordering_layer,
10469 &ett_oran_dmrs_entry,
10470 &ett_oran_dmrs_symbol_mask,
10471 &ett_oran_symbol_mask,
10472 &ett_oran_active_beamspace_coefficient_mask,
10473 &ett_oran_sinr_prb,
10474
10475 &ett_oran_fragment,
10476 &ett_oran_fragments
10477 };
10478
10479 /* Separate subtree array for extensions. Used with [ext-1] */
10480 static int *ext_ett[HIGHEST_EXTTYPE30];
10481 for (unsigned extno=0; extno<HIGHEST_EXTTYPE30; extno++) {
10482 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10483 }
10484
10485 expert_module_t* expert_oran;
10486
10487 static ei_register_info ei[] = {
10488 { &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)}}
}},
10489 { &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)}}
}},
10490 { &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)}}
}},
10491 { &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)}}
}},
10492 { &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)}}
}},
10493 { &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)}}
}},
10494 { &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)}}
}},
10495 { &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)}}
}},
10496 { &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)}}
}},
10497 { &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)}}
}},
10498 { &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)}}
}},
10499 { &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)}}
}},
10500 { &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)}}
}},
10501 { &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)}}
}},
10502 { &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)}}
}},
10503 { &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)}}
}},
10504 { &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)}}
}},
10505 { &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)}}
}},
10506 { &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)}}
}},
10507 { &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)}}
}},
10508 { &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)}}
}},
10509 { &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)}}
}},
10510 { &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)}}
}},
10511 { &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)}}
}},
10512 { &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)}}
}},
10513 { &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)}}
}},
10514 { &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)}}
}},
10515 { &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)}}
}},
10516 { &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)}}
}},
10517 { &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)}}
}},
10518 { &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)}}
}},
10519 { &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)}}
}},
10520 { &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)}}
}},
10521 { &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)}}
}},
10522 { &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)}}
}},
10523 { &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)}}
}},
10524 { &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)}}
}},
10525 { &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)}}
}},
10526 { &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)}}
}},
10527 { &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)}}
}},
10528 { &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)}}
}},
10529 { &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)}}
}},
10530 { &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)}}
}},
10531 { &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)}}
}},
10532 { &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)}}
}},
10533 { &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)}}
}},
10534 { &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)}}
}},
10535 { &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)}}
}},
10536 { &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)}}
}},
10537 { &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)}}
}},
10538 { &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)}}
}},
10539 { &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)}}
}},
10540 { &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)}}
}},
10541 { &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)}}
}},
10542 { &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)}}
}},
10543 { &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)}}
}}
10544 };
10545
10546 /* Register the protocol name and description */
10547 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10548
10549 /* Allow dissector to find be found by name. */
10550 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10551
10552 /* Register the tap name. */
10553 oran_tap = register_tap("oran-fh-cus");
10554
10555 /* Required function calls to register the header fields and subtrees */
10556 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10557 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10558 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10559
10560 expert_oran = expert_register_protocol(proto_oran);
10561 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10562
10563
10564 /* Preferences */
10565 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10566
10567 /* Register bit width/compression preferences separately by direction. */
10568 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10569 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10570 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10571 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10572 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10573 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10574 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10575 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10576
10577 /* Uplink userplane */
10578 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10579 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10580 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10581 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10582 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
10583 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
10584 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10585 "configuration of the O-RU. This preference instructs the dissector to expect "
10586 "this field to be present in uplink messages",
10587 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
10588 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
10589 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
10590 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
10591 "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",
10592 10, &us_allowed_for_ul_in_symbol);
10593
10594 /* Downlink userplane */
10595 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
10596 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
10597 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
10598 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
10599 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
10600 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
10601 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
10602 "configuration of the O-RU. This preference instructs the dissector to expect "
10603 "this field to be present in downlink messages",
10604 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
10605
10606 /* SINR */
10607 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
10608 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
10609 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
10610 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
10611 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
10612
10613 /* BF-related */
10614 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
10615 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
10616 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
10617 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
10618 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
10619 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
10620 "Default is 1-byte alignment", &st6_4byte_alignment);
10621
10622 /* Misc (and will seldom need to be accessed) */
10623 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
10624 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
10625 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
10626 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
10627 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
10628 &pref_support_udcompLen, udcomplen_support_options, false0);
10629 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
10630 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
10631 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
10632 "", &show_unscaled_values);
10633 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
10634 "Attempt Radio Transport layer reassembly", "",
10635 &do_radio_transport_layer_reassembly);
10636 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
10637
10638 prefs_register_bool_preference(oran_module, "oran.link_planes",
10639 "Link C-plane and U-plane using sectionId", "",
10640 &link_planes_together);
10641
10642
10643 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10644 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10645 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10646
10647 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10648 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
10649
10650 register_init_routine(&oran_init_protocol);
10651
10652 /* Register reassembly table. */
10653 reassembly_table_register(&oran_reassembly_table,
10654 &oran_reassembly_table_functions);
10655}
10656
10657/*
10658* Editor modelines - http://www.wireshark.org/tools/modelines.html
10659*
10660* Local Variables:
10661* c-basic-offset: 4
10662* tab-width: 8
10663* indent-tabs-mode: nil
10664* End:
10665*
10666* ex: set shiftwidth=4 tabstop=8 expandtab:
10667* :indentSize=4:tabSize=8:noTabs=true:
10668*/