Bug Summary

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