Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-oran.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-14-100348-3642-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,
37 * so unfortunately it can be fiddly to get the preferences into a good state to
38 * decode a given capture..
39 * TODO:
40 * - Detect/indicate signs of application layer fragmentation?
41 * same eAxC in same symbol (same/different section ID?)
42 * - Not handling M-plane setting for "little endian byte order" as applied to
43 * IQ samples and beam weights does anyone use this?
44 * - for section extensions, check more constraints (which other extension types
45 * appear with them, order, repeated)
46 * - re-order items (decl and hf definitions) to match spec order?
47 * - track energy-saving status, and identify TRX or ASM commands as 'Sleep extension'
48 * - when tracking between C-plane and U-plane, indicated in C-plane any missing sectionIds/PRBs/REs
49 */
50
51/* Prototypes */
52void proto_register_oran(void);
53
54/* Initialize the protocol and registered fields */
55static int proto_oran;
56
57static int oran_tap = -1;
58
59static int hf_oran_du_port_id;
60static int hf_oran_bandsector_id;
61static int hf_oran_cc_id;
62static int hf_oran_ru_port_id;
63static int hf_oran_sequence_id;
64static int hf_oran_e_bit;
65static int hf_oran_subsequence_id;
66static int hf_oran_previous_frame;
67
68static int hf_oran_data_direction;
69static int hf_oran_payload_version;
70static int hf_oran_filter_index;
71static int hf_oran_frame_id;
72static int hf_oran_subframe_id;
73static int hf_oran_slot_id;
74static int hf_oran_slot_within_frame;
75static int hf_oran_start_symbol_id;
76static int hf_oran_numberOfSections;
77static int hf_oran_sectionType;
78
79static int hf_oran_udCompHdr;
80static int hf_oran_udCompHdrIqWidth;
81static int hf_oran_udCompHdrIqWidth_pref;
82static int hf_oran_udCompHdrMeth;
83static int hf_oran_udCompHdrMeth_pref;
84static int hf_oran_udCompLen;
85static int hf_oran_numberOfUEs;
86static int hf_oran_timeOffset;
87static int hf_oran_frameStructure_fft;
88static int hf_oran_frameStructure_subcarrier_spacing;
89static int hf_oran_cpLength;
90static int hf_oran_timing_header;
91static int hf_oran_section_id;
92static int hf_oran_rb;
93static int hf_oran_symInc;
94static int hf_oran_startPrbc;
95static int hf_oran_reMask_re1;
96static int hf_oran_reMask_re2;
97static int hf_oran_reMask_re3;
98static int hf_oran_reMask_re4;
99static int hf_oran_reMask_re5;
100static int hf_oran_reMask_re6;
101static int hf_oran_reMask_re7;
102static int hf_oran_reMask_re8;
103static int hf_oran_reMask_re9;
104static int hf_oran_reMask_re10;
105static int hf_oran_reMask_re11;
106static int hf_oran_reMask_re12;
107static int hf_oran_reMask;
108static int hf_oran_numPrbc;
109static int hf_oran_numSymbol;
110static int hf_oran_ef;
111static int hf_oran_beamId;
112
113static int hf_oran_sinrCompHdrIqWidth_pref;
114static int hf_oran_sinrCompHdrMeth_pref;
115
116static int hf_oran_ciCompHdr;
117static int hf_oran_ciCompHdrIqWidth;
118static int hf_oran_ciCompHdrMeth;
119static int hf_oran_ciCompOpt;
120
121static int hf_oran_extension;
122static int hf_oran_exttype;
123static int hf_oran_extlen;
124
125static int hf_oran_bfw_bundle;
126static int hf_oran_bfw_bundle_id;
127static int hf_oran_bfw;
128static int hf_oran_bfw_i;
129static int hf_oran_bfw_q;
130
131static int hf_oran_ueId;
132static int hf_oran_freqOffset;
133static int hf_oran_regularizationFactor;
134static int hf_oran_laaMsgType;
135static int hf_oran_laaMsgLen;
136static int hf_oran_lbtHandle;
137static int hf_oran_lbtDeferFactor;
138static int hf_oran_lbtBackoffCounter;
139static int hf_oran_lbtOffset;
140static int hf_oran_MCOT;
141static int hf_oran_lbtMode;
142static int hf_oran_sfnSfEnd;
143static int hf_oran_lbtPdschRes;
144static int hf_oran_sfStatus;
145static int hf_oran_initialPartialSF;
146static int hf_oran_lbtDrsRes;
147static int hf_oran_lbtBufErr;
148static int hf_oran_lbtTrafficClass;
149static int hf_oran_lbtCWConfig_H;
150static int hf_oran_lbtCWConfig_T;
151static int hf_oran_lbtCWR_Rst;
152
153static int hf_oran_reserved;
154static int hf_oran_reserved_1bit;
155static int hf_oran_reserved_2bits;
156static int hf_oran_reserved_3bits;
157static int hf_oran_reserved_4bits;
158static int hf_oran_reserved_last_4bits;
159static int hf_oran_reserved_last_5bits;
160static int hf_oran_reserved_6bits;
161static int hf_oran_reserved_last_6bits;
162static int hf_oran_reserved_7bits;
163static int hf_oran_reserved_last_7bits;
164static int hf_oran_reserved_8bits;
165static int hf_oran_reserved_16bits;
166static int hf_oran_reserved_15bits;
167static int hf_oran_reserved_bit1;
168static int hf_oran_reserved_bit2;
169static int hf_oran_reserved_bit4;
170static int hf_oran_reserved_bit5;
171static int hf_oran_reserved_bits123;
172static int hf_oran_reserved_bits456;
173
174static int hf_oran_bundle_offset;
175static int hf_oran_cont_ind;
176
177static int hf_oran_bfwCompHdr;
178static int hf_oran_bfwCompHdr_iqWidth;
179static int hf_oran_bfwCompHdr_compMeth;
180static int hf_oran_symbolId;
181static int hf_oran_startPrbu;
182static int hf_oran_numPrbu;
183
184static int hf_oran_udCompParam;
185static int hf_oran_sReSMask;
186static int hf_oran_sReSMask_re12;
187static int hf_oran_sReSMask_re11;
188static int hf_oran_sReSMask_re10;
189static int hf_oran_sReSMask_re9;
190static int hf_oran_sReSMask_re8;
191static int hf_oran_sReSMask_re7;
192static int hf_oran_sReSMask_re6;
193static int hf_oran_sReSMask_re5;
194static int hf_oran_sReSMask_re4;
195static int hf_oran_sReSMask_re3;
196static int hf_oran_sReSMask_re2;
197static int hf_oran_sReSMask_re1;
198
199static int hf_oran_sReSMask1;
200static int hf_oran_sReSMask2;
201static int hf_oran_sReSMask1_2_re12;
202static int hf_oran_sReSMask1_2_re11;
203static int hf_oran_sReSMask1_2_re10;
204static int hf_oran_sReSMask1_2_re9;
205
206static int hf_oran_bfwCompParam;
207
208static int hf_oran_iSample;
209static int hf_oran_qSample;
210
211static int hf_oran_ciCompParam;
212
213static int hf_oran_blockScaler;
214static int hf_oran_compBitWidth;
215static int hf_oran_compShift;
216
217static int hf_oran_active_beamspace_coefficient_n1;
218static int hf_oran_active_beamspace_coefficient_n2;
219static int hf_oran_active_beamspace_coefficient_n3;
220static int hf_oran_active_beamspace_coefficient_n4;
221static int hf_oran_active_beamspace_coefficient_n5;
222static int hf_oran_active_beamspace_coefficient_n6;
223static int hf_oran_active_beamspace_coefficient_n7;
224static int hf_oran_active_beamspace_coefficient_n8;
225static int hf_oran_activeBeamspaceCoefficientMask;
226static int hf_oran_activeBeamspaceCoefficientMask_bits_set;
227
228static int hf_oran_se6_repetition;
229
230static int hf_oran_rbgSize;
231static int hf_oran_rbgMask;
232static int hf_oran_noncontig_priority;
233
234static int hf_oran_symbol_mask;
235static int hf_oran_symbol_mask_s13;
236static int hf_oran_symbol_mask_s12;
237static int hf_oran_symbol_mask_s11;
238static int hf_oran_symbol_mask_s10;
239static int hf_oran_symbol_mask_s9;
240static int hf_oran_symbol_mask_s8;
241static int hf_oran_symbol_mask_s7;
242static int hf_oran_symbol_mask_s6;
243static int hf_oran_symbol_mask_s5;
244static int hf_oran_symbol_mask_s4;
245static int hf_oran_symbol_mask_s3;
246static int hf_oran_symbol_mask_s2;
247static int hf_oran_symbol_mask_s1;
248static int hf_oran_symbol_mask_s0;
249
250static int hf_oran_exponent;
251static int hf_oran_iq_user_data;
252
253static int hf_oran_disable_bfws;
254static int hf_oran_rad;
255static int hf_oran_num_bund_prbs;
256static int hf_oran_beam_id;
257static int hf_oran_num_weights_per_bundle;
258
259static int hf_oran_ack_nack_req_id;
260
261static int hf_oran_frequency_range;
262static int hf_oran_off_start_prb;
263static int hf_oran_num_prb;
264
265static int hf_oran_samples_prb;
266static int hf_oran_ciSample;
267static int hf_oran_ciIsample;
268static int hf_oran_ciQsample;
269
270static int hf_oran_beamGroupType;
271static int hf_oran_numPortc;
272
273static int hf_oran_csf;
274static int hf_oran_modcompscaler;
275
276static int hf_oran_modcomp_param_set;
277static int hf_oran_mc_scale_re_mask_re1;
278static int hf_oran_mc_scale_re_mask_re2;
279static int hf_oran_mc_scale_re_mask_re3;
280static int hf_oran_mc_scale_re_mask_re4;
281static int hf_oran_mc_scale_re_mask_re5;
282static int hf_oran_mc_scale_re_mask_re6;
283static int hf_oran_mc_scale_re_mask_re7;
284static int hf_oran_mc_scale_re_mask_re8;
285static int hf_oran_mc_scale_re_mask_re9;
286static int hf_oran_mc_scale_re_mask_re10;
287static int hf_oran_mc_scale_re_mask_re11;
288static int hf_oran_mc_scale_re_mask_re12;
289static int hf_oran_mc_scale_re_mask_re1_even;
290static int hf_oran_mc_scale_re_mask_re2_even;
291static int hf_oran_mc_scale_re_mask_re3_even;
292static int hf_oran_mc_scale_re_mask_re4_even;
293static int hf_oran_mc_scale_re_mask_re5_even;
294static int hf_oran_mc_scale_re_mask_re6_even;
295static int hf_oran_mc_scale_re_mask_re7_even;
296static int hf_oran_mc_scale_re_mask_re8_even;
297static int hf_oran_mc_scale_re_mask_re9_even;
298static int hf_oran_mc_scale_re_mask_re10_even;
299static int hf_oran_mc_scale_re_mask_re11_even;
300static int hf_oran_mc_scale_re_mask_re12_even;
301
302static int hf_oran_mc_scale_re_mask;
303static int hf_oran_mc_scale_re_mask_even;
304
305static int hf_oran_mc_scale_offset;
306
307static int hf_oran_eAxC_mask;
308static int hf_oran_technology;
309static int hf_oran_nullLayerInd;
310
311static int hf_oran_se19_repetition;
312static int hf_oran_portReMask;
313static int hf_oran_portSymbolMask;
314
315static int hf_oran_ext19_port;
316
317static int hf_oran_prb_allocation;
318static int hf_oran_nextSymbolId;
319static int hf_oran_nextStartPrbc;
320
321static int hf_oran_puncPattern;
322static int hf_oran_numPuncPatterns;
323static int hf_oran_symbolMask_ext20;
324static int hf_oran_startPuncPrb;
325static int hf_oran_numPuncPrb;
326static int hf_oran_puncReMask;
327static int hf_oran_multiSDScope;
328static int hf_oran_RbgIncl;
329
330static int hf_oran_ci_prb_group_size;
331static int hf_oran_prg_size_st5;
332static int hf_oran_prg_size_st6;
333
334static int hf_oran_num_ueid;
335
336static int hf_oran_antMask;
337
338static int hf_oran_transmissionWindowOffset;
339static int hf_oran_transmissionWindowSize;
340static int hf_oran_toT;
341
342static int hf_oran_bfaCompHdr;
343static int hf_oran_bfAzPtWidth;
344static int hf_oran_bfZePtWidth;
345static int hf_oran_bfAz3ddWidth;
346static int hf_oran_bfZe3ddWidth;
347static int hf_oran_bfAzPt;
348static int hf_oran_bfZePt;
349static int hf_oran_bfAz3dd;
350static int hf_oran_bfZe3dd;
351static int hf_oran_bfAzSl;
352static int hf_oran_bfZeSl;
353
354static int hf_oran_cmd_scope;
355static int hf_oran_number_of_st4_cmds;
356
357static int hf_oran_st4_cmd_header;
358static int hf_oran_st4_cmd_type;
359static int hf_oran_st4_cmd_len;
360static int hf_oran_st4_cmd_num_slots;
361static int hf_oran_st4_cmd_ack_nack_req_id;
362
363static int hf_oran_st4_cmd;
364
365static int hf_oran_sleepmode_trx;
366static int hf_oran_sleepmode_asm;
367static int hf_oran_log2maskbits;
368static int hf_oran_num_slots_ext;
369static int hf_oran_antMask_trx_control;
370
371static int hf_oran_ready;
372static int hf_oran_number_of_acks;
373static int hf_oran_number_of_nacks;
374static int hf_oran_ackid;
375static int hf_oran_nackid;
376
377static int hf_oran_acknack_request_frame;
378static int hf_oran_acknack_request_time;
379static int hf_oran_acknack_request_type;
380static int hf_oran_acknack_response_frame;
381static int hf_oran_acknack_response_time;
382
383static int hf_oran_disable_tdbfns;
384static int hf_oran_td_beam_group;
385static int hf_oran_disable_tdbfws;
386static int hf_oran_td_beam_num;
387
388static int hf_oran_dir_pattern;
389static int hf_oran_guard_pattern;
390
391static int hf_oran_ecpri_pcid;
392static int hf_oran_ecpri_rtcid;
393static int hf_oran_ecpri_seqid;
394
395static int hf_oran_num_sym_prb_pattern;
396static int hf_oran_prb_mode;
397static int hf_oran_sym_prb_pattern;
398static int hf_oran_sym_mask;
399static int hf_oran_num_mc_scale_offset;
400static int hf_oran_prb_pattern;
401static int hf_oran_prb_blk_offset;
402static int hf_oran_prb_blk_size;
403
404static int hf_oran_codebook_index;
405static int hf_oran_layerid;
406static int hf_oran_numlayers;
407static int hf_oran_txscheme;
408static int hf_oran_crs_remask;
409static int hf_oran_crs_shift;
410static int hf_oran_crs_symnum;
411static int hf_oran_beamid_ap1;
412static int hf_oran_beamid_ap2;
413static int hf_oran_beamid_ap3;
414
415static int hf_oran_port_list_index;
416static int hf_oran_alpn_per_sym;
417static int hf_oran_ant_dmrs_snr;
418static int hf_oran_user_group_size;
419static int hf_oran_user_group_id;
420static int hf_oran_entry_type;
421static int hf_oran_dmrs_port_number;
422static int hf_oran_ueid_reset;
423
424static int hf_oran_dmrs_symbol_mask;
425static int hf_oran_dmrs_symbol_mask_s13;
426static int hf_oran_dmrs_symbol_mask_s12;
427static int hf_oran_dmrs_symbol_mask_s11;
428static int hf_oran_dmrs_symbol_mask_s10;
429static int hf_oran_dmrs_symbol_mask_s9;
430static int hf_oran_dmrs_symbol_mask_s8;
431static int hf_oran_dmrs_symbol_mask_s7;
432static int hf_oran_dmrs_symbol_mask_s6;
433static int hf_oran_dmrs_symbol_mask_s5;
434static int hf_oran_dmrs_symbol_mask_s4;
435static int hf_oran_dmrs_symbol_mask_s3;
436static int hf_oran_dmrs_symbol_mask_s2;
437static int hf_oran_dmrs_symbol_mask_s1;
438static int hf_oran_dmrs_symbol_mask_s0;
439
440static int hf_oran_scrambling;
441static int hf_oran_nscid;
442static int hf_oran_dtype;
443static int hf_oran_cmd_without_data;
444static int hf_oran_lambda;
445static int hf_oran_first_prb;
446static int hf_oran_last_prb;
447static int hf_oran_low_papr_type;
448static int hf_oran_hopping_mode;
449
450static int hf_oran_tx_win_for_on_air_symbol_l;
451static int hf_oran_tx_win_for_on_air_symbol_r;
452
453static int hf_oran_num_fo_fb;
454static int hf_oran_freq_offset_fb;
455
456static int hf_oran_num_ue_sinr_rpt;
457static int hf_oran_num_sinr_per_prb;
458static int hf_oran_num_sinr_per_prb_right;
459
460static int hf_oran_sinr_value;
461
462static int hf_oran_measurement_report;
463static int hf_oran_mf;
464static int hf_oran_meas_data_size;
465static int hf_oran_meas_type_id;
466static int hf_oran_ipn_power;
467static int hf_oran_ue_tae;
468static int hf_oran_ue_layer_power;
469static int hf_oran_num_elements;
470static int hf_oran_ant_dmrs_snr_val;
471static int hf_oran_ue_freq_offset;
472
473static int hf_oran_measurement_command;
474
475static int hf_oran_beam_type;
476static int hf_oran_meas_cmd_size;
477
478static int hf_oran_symbol_reordering_layer;
479static int hf_oran_dmrs_entry;
480
481static int hf_oran_c_section_common;
482static int hf_oran_c_section;
483static int hf_oran_u_section;
484
485static int hf_oran_u_section_ul_symbol_time;
486static int hf_oran_u_section_ul_symbol_frames;
487static int hf_oran_u_section_ul_symbol_first_frame;
488static int hf_oran_u_section_ul_symbol_last_frame;
489
490static int hf_oran_cd_scg_size;
491static int hf_oran_cd_scg_phase_step;
492
493static int hf_oran_sinr_prb;
494static int hf_oran_oru_control_sinr_slot_mask_id;
495static int hf_oran_pos_meas;
496
497static int hf_oran_ue_radial_speed;
498static int hf_oran_ue_az_aoa;
499static int hf_oran_ue_ze_aoa;
500static int hf_oran_ue_pos_toa_offset;
501
502static int hf_oran_num_rep_ue;
503static int hf_oran_rep_ueid;
504static int hf_oran_is_last_rep;
505static int hf_oran_rep_index;
506static int hf_oran_num_reps;
507
508static int hf_oran_mcs_table;
509static int hf_oran_mcs_index;
510
511static int hf_oran_num_meas_req;
512static int hf_oran_num_of_ue_ant_ports;
513static int hf_oran_ue_rank;
514static int hf_oran_codebook_subset;
515static int hf_oran_full_pwr_mode;
516static int hf_oran_full_pwr_mode_2_tpmi_group;
517
518static int hf_oran_num_cand_ranks;
519static int hf_oran_ue_pref_rank;
520static int hf_oran_ue_tpmi_rank_y;
521static int hf_oran_ue_tpmi_rank_y_sinr_lx;
522static int hf_oran_ue_layer_pre_eq_sinr;
523
524
525/* Computed fields */
526static int hf_oran_c_eAxC_ID;
527static int hf_oran_refa;
528
529static int hf_oran_bfws_frame_defined;
530static int hf_oran_bfws_symbols_since_defined;
531
532static int hf_oran_corresponding_cplane_frame;
533static int hf_oran_corresponding_cplane_frame_time_delta;
534static int hf_oran_corresponding_uplane_frame;
535static int hf_oran_corresponding_uplane_frames_total;
536
537
538/* Convenient fields for filtering, mostly shown as hidden */
539static int hf_oran_cplane;
540static int hf_oran_uplane;
541static int hf_oran_bf; /* to match frames that configure beamforming in any way */
542static int hf_oran_zero_prb;
543static int hf_oran_nonzero_prb;
544static int hf_oran_bundle_weights_all_zero;
545
546static int hf_oran_ul_cplane_ud_comp_hdr_frame;
547
548/* For reassembly */
549static int hf_oran_fragments;
550static int hf_oran_fragment;
551static int hf_oran_fragment_overlap;
552static int hf_oran_fragment_overlap_conflict;
553static int hf_oran_fragment_multiple_tails;
554static int hf_oran_fragment_too_long_fragment;
555static int hf_oran_fragment_error;
556static int hf_oran_fragment_count;
557static int hf_oran_reassembled_in;
558static int hf_oran_reassembled_length;
559static int hf_oran_reassembled_data;
560
561static int hf_oran_payload;
562
563
564/* Subtrees */
565static int ett_oran;
566static int ett_oran_ecpri_rtcid;
567static int ett_oran_ecpri_pcid;
568static int ett_oran_ecpri_seqid;
569static int ett_oran_section;
570static int ett_oran_section_type;
571static int ett_oran_u_timing;
572static int ett_oran_u_section;
573static int ett_oran_u_prb;
574static int ett_oran_iq;
575static int ett_oran_bfw_bundle;
576static int ett_oran_bfw;
577static int ett_oran_frequency_range;
578static int ett_oran_prb_cisamples;
579static int ett_oran_cisample;
580static int ett_oran_udcomphdr;
581static int ett_oran_udcompparam;
582static int ett_oran_cicomphdr;
583static int ett_oran_cicompparam;
584static int ett_oran_bfwcomphdr;
585static int ett_oran_bfwcompparam;
586static int ett_oran_ext19_port;
587static int ett_oran_prb_allocation;
588static int ett_oran_punc_pattern;
589static int ett_oran_bfacomphdr;
590static int ett_oran_modcomp_param_set;
591static int ett_oran_st4_cmd_header;
592static int ett_oran_st4_cmd;
593static int ett_oran_sym_prb_pattern;
594static int ett_oran_measurement_report;
595static int ett_oran_measurement_command;
596static int ett_oran_sresmask;
597static int ett_oran_c_section_common;
598static int ett_oran_c_section;
599static int ett_oran_remask;
600static int ett_oran_mc_scale_remask;
601static int ett_oran_symbol_reordering_layer;
602static int ett_oran_dmrs_entry;
603static int ett_oran_dmrs_symbol_mask;
604static int ett_oran_symbol_mask;
605static int ett_oran_active_beamspace_coefficient_mask;
606static int ett_oran_sinr_prb;
607
608static int ett_oran_fragment;
609static int ett_oran_fragments;
610
611/* Reassembly table. */
612static reassembly_table oran_reassembly_table;
613
614static void *oran_key(const packet_info *pinfo _U___attribute__((unused)), const uint32_t id _U___attribute__((unused)), const void *data)
615{
616 return (void *)data;
617}
618
619static void oran_free_key(void *ptr _U___attribute__((unused)))
620{
621}
622
623static reassembly_table_functions oran_reassembly_table_functions =
624{
625 g_direct_hash,
626 g_direct_equal,
627 oran_key,
628 oran_key,
629 oran_free_key,
630 oran_free_key
631};
632
633static const fragment_items oran_frag_items = {
634 &ett_oran_fragment,
635 &ett_oran_fragments,
636 &hf_oran_fragments,
637 &hf_oran_fragment,
638 &hf_oran_fragment_overlap,
639 &hf_oran_fragment_overlap_conflict,
640 &hf_oran_fragment_multiple_tails,
641 &hf_oran_fragment_too_long_fragment,
642 &hf_oran_fragment_error,
643 &hf_oran_fragment_count,
644 &hf_oran_reassembled_in,
645 &hf_oran_reassembled_length,
646 &hf_oran_reassembled_data,
647 "O-RAN FH CUS fragments"
648};
649
650
651
652/* Don't want all extensions to open and close together. Use [extType-1] entry */
653static int ett_oran_c_section_extension[HIGHEST_EXTTYPE32];
654
655/* Expert info */
656static expert_field ei_oran_unsupported_bfw_compression_method;
657static expert_field ei_oran_invalid_sample_bit_width;
658static expert_field ei_oran_reserved_numBundPrb;
659static expert_field ei_oran_extlen_wrong;
660static expert_field ei_oran_invalid_eaxc_bit_width;
661static expert_field ei_oran_extlen_zero;
662static expert_field ei_oran_rbg_size_reserved;
663static expert_field ei_oran_frame_length;
664static expert_field ei_oran_numprbc_ext21_zero;
665static expert_field ei_oran_ci_prb_group_size_reserved;
666static expert_field ei_oran_st8_nackid;
667static expert_field ei_oran_st4_no_cmds;
668static expert_field ei_oran_st4_zero_len_cmd;
669static expert_field ei_oran_st4_wrong_len_cmd;
670static expert_field ei_oran_st4_unknown_cmd;
671static expert_field ei_oran_mcot_out_of_range;
672static expert_field ei_oran_se10_unknown_beamgrouptype;
673static expert_field ei_oran_se10_not_allowed;
674static expert_field ei_oran_start_symbol_id_not_zero;
675static expert_field ei_oran_trx_control_cmd_scope;
676static expert_field ei_oran_unhandled_se;
677static expert_field ei_oran_bad_symbolmask;
678static expert_field ei_oran_numslots_not_zero;
679static expert_field ei_oran_version_unsupported;
680static expert_field ei_oran_laa_msg_type_unsupported;
681static expert_field ei_oran_se_on_unsupported_st;
682static expert_field ei_oran_cplane_unexpected_sequence_number_ul;
683static expert_field ei_oran_cplane_unexpected_sequence_number_dl;
684static expert_field ei_oran_uplane_unexpected_sequence_number_ul;
685static expert_field ei_oran_uplane_unexpected_sequence_number_dl;
686static expert_field ei_oran_acknack_no_request;
687static expert_field ei_oran_udpcomphdr_should_be_zero;
688static expert_field ei_oran_radio_fragmentation_c_plane;
689static expert_field ei_oran_lastRbdid_out_of_range;
690static expert_field ei_oran_rbgMask_beyond_last_rbdid;
691static expert_field ei_oran_unexpected_measTypeId;
692static expert_field ei_oran_unsupported_compression_method;
693static expert_field ei_oran_ud_comp_len_wrong_size;
694static expert_field ei_oran_sresmask2_not_zero_with_rb;
695static expert_field ei_oran_st6_rb_shall_be_0;
696static expert_field ei_oran_st9_not_ul;
697static expert_field ei_oran_st10_numsymbol_not_14;
698static expert_field ei_oran_st10_startsymbolid_not_0;
699static expert_field ei_oran_st10_not_ul;
700static expert_field ei_oran_se24_nothing_to_inherit;
701static expert_field ei_oran_num_sinr_per_prb_unknown;
702static expert_field ei_oran_start_symbol_id_bits_ignored;
703static expert_field ei_oran_user_group_id_reserved_value;
704static expert_field ei_oran_port_list_index_zero;
705static expert_field ei_oran_ul_uplane_symbol_too_long;
706static expert_field ei_oran_reserved_not_zero;
707static expert_field ei_oran_too_many_symbols;
708static expert_field ei_oran_se30_not_ul;
709static expert_field ei_oran_se30_unknown_ueid;
710static expert_field ei_oran_beamid_bfws_not_found;
711static expert_field ei_oran_syminc_set_for_uplane;
712static expert_field ei_oran_cplane_entry_not_found;
713
714
715/* These are the message types handled by this dissector. Others have handling in packet-ecpri.c */
716#define ECPRI_MT_IQ_DATA0 0
717#define ECPRI_MT_RT_CTRL_DATA2 2
718
719
720/* Preference settings - try to set reasonable defaults */
721static unsigned pref_du_port_id_bits = 4;
722static unsigned pref_bandsector_id_bits = 4;
723static unsigned pref_cc_id_bits = 4;
724static unsigned pref_ru_port_id_bits = 4;
725
726/* TODO: ideally should be per-flow */
727static unsigned pref_sample_bit_width_uplink = 14;
728static unsigned pref_sample_bit_width_downlink = 14;
729static unsigned pref_sample_bit_width_sinr = 14;
730
731/* TODO: these ideally should be per-flow too */
732static int pref_iqCompressionUplink = COMP_BLOCK_FP1;
733static int pref_iqCompressionDownlink = COMP_BLOCK_FP1;
734
735static int pref_iqCompressionSINR = COMP_BLOCK_FP1;
736
737
738/* Is udCompHeader present (both directions) */
739static int pref_includeUdCompHeaderUplink = 2; /* start using heuristic */
740static int pref_includeUdCompHeaderDownlink = 2; /* start using heuristic */
741
742/* Are we ignoring UL C-Plane udCompHdr? */
743static bool_Bool pref_override_ul_compression = false0;
744
745static unsigned pref_data_plane_section_total_rbs = 273;
746static unsigned pref_num_bf_antennas = 32;
747static bool_Bool pref_showIQSampleValues = true1;
748
749/* Based upon m-plane param, so will be system-wide */
750static int pref_support_udcompLen = 2; /* start heuristic, can force other settings if necessary */
751static bool_Bool udcomplen_heuristic_result_set = false0;
752static bool_Bool udcomplen_heuristic_result = false0;
753
754/* st6-4byte-alignment-required */
755static bool_Bool st6_4byte_alignment = false0;
756
757/* Requested, allows I/Q to be stored as integers.. */
758static bool_Bool show_unscaled_values = false0;
759
760/* Initialized off. Timing is in microseconds. */
761static unsigned us_allowed_for_ul_in_symbol = 0;
762
763/* Reassemble U-Plane (at Radio Transport layer) */
764static bool_Bool do_radio_transport_layer_reassembly = true1;
765
766/* Link U-plane back to C-plane using sectionIds */
767static bool_Bool link_planes_together = true1;
768
769static const enum_val_t dl_compression_options[] = {
770 { "COMP_NONE", "No Compression", COMP_NONE0 },
771 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
772 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
773 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
774 { "COMP_MODULATION", "Modulation Compression", COMP_MODULATION4 },
775 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
776 { "MOD_COMPR_AND_SELECTIVE_RE", "Modulation Compression + selective RE sending", MOD_COMPR_AND_SELECTIVE_RE6 },
777 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
778 { "MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS", "Modulation Compression + selective RE sending with masks in section header", MOD_COMPR_AND_SELECTIVE_RE6 },
779 { NULL((void*)0), NULL((void*)0), 0 }
780};
781
782/* No Modulation compression in UL.. */
783static const enum_val_t ul_compression_options[] = {
784 { "COMP_NONE", "No Compression", COMP_NONE0 },
785 { "COMP_BLOCK_FP", "Block Floating Point Compression", COMP_BLOCK_FP1 },
786 { "COMP_BLOCK_SCALE", "Block Scaling Compression", COMP_BLOCK_SCALE2 },
787 { "COMP_U_LAW", "u-Law Compression", COMP_U_LAW3 },
788 { "BFP_AND_SELECTIVE_RE", "Block Floating Point + selective RE sending", BFP_AND_SELECTIVE_RE5 },
789 { "BFP_AND_SELECTIVE_RE_WITH_MASKS", "Block Floating Point + selective RE sending with masks in section header", BFP_AND_SELECTIVE_RE_WITH_MASKS7 },
790 { NULL((void*)0), NULL((void*)0), 0 }
791};
792
793static const enum_val_t udcomplen_support_options[] = {
794 { "NOT_SUPPORTED", "Not Supported", 0 },
795 { "SUPPORTED", "Supported", 1 },
796 { "HEURISTIC", "Attempt Heuristic", 2 },
797 { NULL((void*)0), NULL((void*)0), 0 }
798};
799
800static const enum_val_t udcomphdr_present_options[] = {
801 { "NOT_PRESENT", "Not Present", 0 },
802 { "PRESENT", "Present", 1 },
803 { "HEURISTIC", "Attempt Heuristic", 2 },
804 { NULL((void*)0), NULL((void*)0), 0 }
805};
806
807
808
809static const value_string e_bit[] = {
810 { 0, "More fragments follow" },
811 { 1, "Last fragment" },
812 { 0, NULL((void*)0)}
813};
814
815#define DIR_UPLINK0 0
816#define DIR_DOWNLINK1 1
817
818
819static const value_string data_direction_vals[] = {
820 { DIR_UPLINK0, "Uplink" }, /* gNB Rx */
821 { DIR_DOWNLINK1, "Downlink" }, /* gNB Tx */
822 { 0, NULL((void*)0)}
823};
824
825static const value_string rb_vals[] = {
826 { 0, "Every RB used" },
827 { 1, "Every other RB used" },
828 { 0, NULL((void*)0)}
829};
830
831static const value_string sym_inc_vals[] = {
832 { 0, "Use the current symbol number" },
833 { 1, "Increment the current symbol number" },
834 { 0, NULL((void*)0)}
835};
836
837static const value_string lbtMode_vals[] = {
838 { 0, "Full LBT (regular LBT, sending reservation signal until the beginning of the SF/slot)" },
839 { 1, "Partial LBT (looking back 25 usec prior to transmission" },
840 { 2, "Partial LBT (looking back 34 usec prior to transmission" },
841 { 3, "Full LBT and stop (regular LBT, without sending reservation signal" },
842 { 0, NULL((void*)0)}
843};
844
845static const value_string ue_rank_vals[] = {
846 { 1, "1" },
847 { 2, "2" },
848 { 3, "3" },
849 { 4, "4" },
850 { 0, NULL((void*)0)}
851};
852
853static const value_string num_of_ue_ant_ports_vals[] = {
854 { 2, "2" },
855 { 4, "4" },
856 { 0, NULL((void*)0)}
857};
858
859static const value_string codebook_subset_vals[] = {
860 { 0, "nonCoherent" },
861 { 1, "partialAndNonCoherent" },
862 { 2, "fullyAndPartialAndNonCoherent" },
863 { 3, "reserved" },
864 { 0, NULL((void*)0)}
865};
866
867
868static const range_string filter_indices[] = {
869 {0, 0, "standard channel filter"},
870 {1, 1, "UL filter for PRACH preamble formats 0, 1, 2; min. passband 839 x 1.25kHz = 1048.75 kHz"},
871 {2, 2, "UL filter for PRACH preamble format 3, min. passband 839 x 5 kHz = 4195 kHz"},
872 {3, 3, "UL filter for PRACH preamble formats A1, A2, A3, B1, B2, B3, B4, C0, C2; min. passband 139 x \u0394fRA"},
873 {4, 4, "UL filter for NPRACH 0, 1; min. passband 48 x 3.75KHz = 180 KHz"},
874 {5, 5, "UL filter for PRACH preamble formats"},
875 {8, 8, "UL filter NPUSCH"},
876 {9, 9, "Mixed numerology and other channels except PRACH and NB-IoT"},
877 {9, 15, "Reserved"},
878 {0, 0, NULL((void*)0)}
879};
880
881/* 7.3.1-1 */
882static const range_string section_types[] = {
883 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "Unused Resource Blocks or symbols in Downlink or Uplink" },
884 { SEC_C_NORMAL, SEC_C_NORMAL, "Most DL/UL radio channels" },
885 { SEC_C_RSVD2, SEC_C_RSVD2, "Reserved for future use" },
886 { SEC_C_PRACH, SEC_C_PRACH, "PRACH and mixed-numerology channels" },
887 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "Slot Configuration Control" },
888 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "UE scheduling information (UE-ID assignment to section)" },
889 { SEC_C_CH_INFO, SEC_C_CH_INFO, "Channel information" },
890 { SEC_C_LAA, SEC_C_LAA, "LAA (License Assisted Access)" },
891 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "ACK/NACK Feedback" },
892 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "SINR Reporting" },
893 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "RRM Measurement Reports" },
894 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "Request RRM Measurements" },
895 { 12, 255, "Reserved for future use" },
896 { 0, 0, NULL((void*)0)} };
897
898static const range_string section_types_short[] = {
899 { SEC_C_UNUSED_RB, SEC_C_UNUSED_RB, "(Unused RBs) " },
900 { SEC_C_NORMAL, SEC_C_NORMAL, "(Most channels) " },
901 { SEC_C_RSVD2, SEC_C_RSVD2, "(reserved) " },
902 { SEC_C_PRACH, SEC_C_PRACH, "(PRACH/mixed-\u03bc)" },
903 { SEC_C_SLOT_CONTROL, SEC_C_SLOT_CONTROL, "(Slot info) " },
904 { SEC_C_UE_SCHED, SEC_C_UE_SCHED, "(UE scheduling info)" },
905 { SEC_C_CH_INFO, SEC_C_CH_INFO, "(Channel info) " },
906 { SEC_C_LAA, SEC_C_LAA, "(LAA) " },
907 { SEC_C_ACK_NACK_FEEDBACK, SEC_C_ACK_NACK_FEEDBACK, "(ACK/NACK) " },
908 { SEC_C_SINR_REPORTING, SEC_C_SINR_REPORTING, "(SINR Reporting) " },
909 { SEC_C_RRM_MEAS_REPORTS, SEC_C_RRM_MEAS_REPORTS, "(RRM Meas Reports) " },
910 { SEC_C_REQUEST_RRM_MEAS, SEC_C_REQUEST_RRM_MEAS, "(Req RRM Meas) " },
911 { 12, 255, "Reserved for future use" },
912 { 0, 0, NULL((void*)0) }
913};
914
915static const range_string ud_comp_header_width[] = {
916 {0, 0, "I and Q are each 16 bits wide"},
917 {1, 15, "Bit width of I and Q"},
918 {0, 0, NULL((void*)0)} };
919
920/* Table 8.3.3.13-3 */
921static const range_string ud_comp_header_meth[] = {
922 {COMP_NONE0, COMP_NONE0, "No compression" },
923 {COMP_BLOCK_FP1, COMP_BLOCK_FP1, "Block floating point compression" },
924 {COMP_BLOCK_SCALE2, COMP_BLOCK_SCALE2, "Block scaling" },
925 {COMP_U_LAW3, COMP_U_LAW3, "Mu - law" },
926 {COMP_MODULATION4, COMP_MODULATION4, "Modulation compression" },
927 {BFP_AND_SELECTIVE_RE5, BFP_AND_SELECTIVE_RE5, "BFP + selective RE sending" },
928 {MOD_COMPR_AND_SELECTIVE_RE6, MOD_COMPR_AND_SELECTIVE_RE6, "mod-compr + selective RE sending" },
929 {BFP_AND_SELECTIVE_RE_WITH_MASKS7, BFP_AND_SELECTIVE_RE_WITH_MASKS7, "BFP + selective RE sending with masks in section header" },
930 {MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8, "mod-compr + selective RE sending with masks in section header"},
931 {9, 15, "Reserved"},
932 {0, 0, NULL((void*)0)}
933};
934
935/* Table 7.5.2.13-2 */
936static const range_string frame_structure_fft[] = {
937 {0, 0, "Reserved (no FFT/iFFT processing)"},
938 {1, 3, "Reserved"},
939 {4, 4, "FFT size 16"},
940 {5, 5, "FFT size 32"},
941 {6, 6, "FFT size 64"},
942 {7, 7, "FFT size 128"},
943 {8, 8, "FFT size 256"},
944 {9, 9, "FFT size 512"},
945 {10, 10, "FFT size 1024"},
946 {11, 11, "FFT size 2048"},
947 {12, 12, "FFT size 4096"},
948 {13, 13, "FFT size 1536"},
949 {14, 14, "FFT size 3072"},
950 {15, 15, "Reserved"},
951 {0, 0, NULL((void*)0)}
952};
953
954/* Table 7.5.2.13-3 */
955static const range_string subcarrier_spacings[] = {
956 { 0, 0, "SCS 15 kHz, 1 slot/subframe, slot length 1 ms" },
957 { 1, 1, "SCS 30 kHz, 2 slots/subframe, slot length 500 \u03bcs" },
958 { 2, 2, "SCS 60 kHz, 4 slots/subframe, slot length 250 \u03bcs" },
959 { 3, 3, "SCS 120 kHz, 8 slots/subframe, slot length 125 \u03bcs" },
960 { 4, 4, "SCS 240 kHz, 16 slots/subframe, slot length 62.5 \u03bcs" },
961 { 5, 11, "Reserved" }, /* N.B., 5 was 480kHz in early spec versions */
962 { 12, 12, "SCS 1.25 kHz, 1 slot/subframe, slot length 1 ms" },
963 { 13, 13, "SCS 3.75 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
964 { 14, 14, "SCS 5 kHz, 1 slot/subframe, slot length 1 ms" },
965 { 15, 15, "SCS 7.5 kHz(LTE - specific), 1 slot/subframe, slot length 1 ms" },
966 { 0, 0, NULL((void*)0) }
967};
968
969/* Table 7.5.3.14-1 laaMsgType definition */
970static const range_string laaMsgTypes[] = {
971 {0, 0, "LBT_PDSCH_REQ - lls - O-DU to O-RU request to obtain a PDSCH channel"},
972 {1, 1, "LBT_DRS_REQ - lls - O-DU to O-RU request to obtain the channel and send DRS"},
973 {2, 2, "LBT_PDSCH_RSP - O-RU to O-DU response, channel acq success or failure"},
974 {3, 3, "LBT_DRS_RSP - O-RU to O-DU response, DRS sending success or failure"},
975 {4, 4, "LBT_Buffer_Error - O-RU to O-DU response, reporting buffer overflow"},
976 {5, 5, "LBT_CWCONFIG_REQ - O-DU to O-RU request, congestion window configuration"},
977 {6, 6, "LBT_CWCONFIG_RST - O-RU to O-DU request, congestion window config, response"},
978 {7, 15, "reserved for future methods"},
979 {0, 0, NULL((void*)0)}
980};
981
982/* 7.7.26.3 */
983static const range_string freq_offset_fb_values[] = {
984 {0, 0, "no frequency offset"},
985 {8000, 8000, "value not provided"},
986 {1, 30000, "positive frequency offset, (0, +0.5] subcarrier"},
987 {0x8ad0, 0xffff, "negative frequency offset, [-0.5, 0) subcarrier"},
988 {0x0, 0xffff, "reserved"},
989 {0, 0, NULL((void*)0)}
990};
991
992/* 7.5.3.78 */
993static const range_string ue_tmpi_rank_sinr_vals[] = {
994 {0, 0, "0 dB SINR"},
995 {0x0001, 0x07ff, "positive SINR"},
996 {0xf800, 0xffff, "-ve SINR"},
997 {0x8000, 0x8000, "invalid measurement result"},
998 {0x0, 0xffff, "reserved"},
999 {0, 0, NULL((void*)0)}
1000};
1001
1002
1003
1004/* Table 7.5.2.19-1 */
1005static const value_string num_sinr_per_prb_vals[] = {
1006 { 0, "1" },
1007 { 1, "2" },
1008 { 2, "3" },
1009 { 3, "4" },
1010 { 4, "6" },
1011 { 5, "12" },
1012 { 6, "1 SINR value per section for DFT-s-OFDM" },
1013 { 7, "reserved" },
1014 { 0, NULL((void*)0)}
1015};
1016
1017static const value_string meas_type_id_vals[] = {
1018 { 1, "UE Timing Advance Error" },
1019 { 2, "UE Layer power" },
1020 { 3, "UE frequency offset" },
1021 { 4, "Interference plus Noise for allocated PRBs" },
1022 { 5, "Interference plus Noise for unallocated PRBs" },
1023 { 6, "DMRS-SNR per antenna" },
1024 { 7, "UE positioning measurement report" },
1025 { 8, "UE radial speed measurement report" },
1026 { 9, "UE post-equalization MU inteference measurement" },
1027 { 10, "UE TPMI and rank recommendation measurement" },
1028 { 11, "UE layer pre-equalization SINR report" },
1029 { 0, NULL((void*)0)}
1030};
1031
1032static const value_string beam_type_vals[] = {
1033 { 0, "List of beamId values" },
1034 { 1, "Range of beamId values" },
1035 { 0, NULL((void*)0)}
1036};
1037
1038/* 7.7.24.3 */
1039static const value_string entry_type_vals[] = {
1040 { 0, "inherit config from preceding entry (2 or 3) ueIdReset=0" },
1041 { 1, "inherit config from preceding entry (2 or 3) ueIdReset=1" },
1042 { 2, "related parameters if have transform precoding disabled " },
1043 { 3, "related parameters if have transform precoding enabled " },
1044 { 0, NULL((void*)0)}
1045};
1046
1047/* Table 7.7.29.3-1 */
1048static const range_string cd_scg_size_vals[] = {
1049 { 0, 0, "1 subcarrier" },
1050 { 1, 1, "1 RB x N subcarriers" },
1051 { 2, 2, "2 RB x N subcarriers" },
1052 { 3, 3, "4 RB x N subcarriers" },
1053 { 4, 4, "8 RB x N subcarriers" },
1054 { 5, 5, "16 RB x N subcarriers" },
1055 { 6, 6, "32 RB x N subcarriers" },
1056 { 7, 15, "reserved"},
1057 { 0, 0, NULL((void*)0)}
1058};
1059
1060
1061/* Table 7.6.1-1 */
1062static const value_string exttype_vals[] = {
1063 {0, "Reserved"},
1064 {1, "Beamforming weights"},
1065 {2, "Beamforming attributes"},
1066 {3, "DL Precoding configuration parameters and indications"},
1067 {4, "Modulation compr. params"},
1068 {5, "Modulation compression additional scaling parameters"},
1069 {6, "Non-contiguous PRB allocation"},
1070 {7, "Multiple-eAxC designation"},
1071 {8, "Regularization factor"},
1072 {9, "Dynamic Spectrum Sharing parameters"},
1073 {10, "Multiple ports grouping"},
1074 {11, "Flexible BF weights"},
1075 {12, "Non-Contiguous PRB Allocation with Frequency Ranges"},
1076 {13, "PRB Allocation with Frequency Hopping"},
1077 {14, "Nulling-layer Info. for ueId-based beamforming"},
1078 {15, "Mixed-numerology Info. for ueId-based beamforming"},
1079 {16, "Section description for antenna mapping in UE channel information based UL beamforming"},
1080 {17, "Section description for indication of user port group"},
1081 {18, "Section description for Uplink Transmission Management"},
1082 {19, "Compact beamforming information for multiple port"},
1083 {20, "Puncturing extension"},
1084 {21, "Variable PRB group size for channel information"},
1085 {22, "ACK/NACK request"},
1086 {23, "Multiple symbol modulation compression parameters"},
1087 {24, "PUSCH DMRS configuration"},
1088 {25, "Symbol reordering for DMRS-BF"},
1089 {26, "Frequency offset feedback"},
1090 {27, "O-DU controlled dimensionality reduction"},
1091 {28, "O-DU controlled frequency resolution for SINR reporting"},
1092 {29, "Cyclic delay adjustment"},
1093 {30, "PUSCH repetition indication"},
1094 {31, "MCS Information"},
1095 {32, "Rank and TPMI measurement request"},
1096 {0, NULL((void*)0)}
1097};
1098static value_string_ext exttype_vals_ext = VALUE_STRING_EXT_INIT(exttype_vals){ _try_val_to_str_ext_init, 0, (sizeof (exttype_vals) / sizeof
((exttype_vals)[0]))-1, exttype_vals, "exttype_vals", ((void
*)0) }
;
1099
1100
1101/**************************************************************************************/
1102/* Keep track for each Section Extension, which section types are allowed to carry it */
1103typedef struct {
1104 bool_Bool ST0;
1105 bool_Bool ST1;
1106 bool_Bool ST3;
1107 bool_Bool ST5;
1108 bool_Bool ST6;
1109 bool_Bool ST10;
1110 bool_Bool ST11;
1111} AllowedCTs_t;
1112
1113
1114static const AllowedCTs_t ext_cts[HIGHEST_EXTTYPE32] = {
1115 /* ST0 ST1 ST3 ST5 ST6 ST10 ST11 */
1116 { false0, true1, true1, false0, false0, false0, false0}, // SE 1 (1,3)
1117 { false0, true1, true1, false0, false0, false0, false0}, // SE 2 (1,3)
1118 { false0, true1, true1, false0, false0, false0, false0}, // SE 3 (1,3)
1119 { false0, true1, true1, true1, false0, false0, false0}, // SE 4 (1,3,5)
1120 { false0, true1, true1, true1, false0, false0, false0}, // SE 5 (1,3,5)
1121 { false0, true1, true1, true1, false0, true1, true1 }, // SE 6 (1,3,5,10,11)
1122 { true1, false0, false0, false0, false0, false0, false0}, // SE 7 (0)
1123 { false0, false0, false0, true1, false0, false0, false0}, // SE 8 (5)
1124 { true1, true1, true1, true1, true1, true1, true1 }, // SE 9 (all)
1125 { false0, true1, true1, true1, false0, false0, false0}, // SE 10 (1,3,5)
1126 { false0, true1, true1, false0, false0, false0, false0}, // SE 11 (1,3)
1127 { false0, true1, true1, true1, false0, true1, true1 }, // SE 12 (1,3,5,10,11)
1128 { false0, true1, true1, true1, false0, false0, false0}, // SE 13 (1,3,5)
1129 { false0, false0, false0, true1, false0, false0, false0}, // SE 14 (5)
1130 { false0, false0, false0, true1, true1, false0, false0}, // SE 15 (5,6)
1131 { false0, false0, false0, true1, false0, false0, false0}, // SE 16 (5)
1132 { false0, false0, false0, true1, false0, false0, false0}, // SE 17 (5)
1133 { false0, true1, true1, true1, false0, false0, false0}, // SE 18 (1,3,5)
1134 { false0, true1, true1, false0, false0, false0, false0}, // SE 19 (1,3)
1135 { true1, true1, true1, true1, true1, true1, true1 }, // SE 20 (0,1,3,5,10,11)
1136 { false0, false0, false0, true1, true1, false0, false0}, // SE 21 (5,6)
1137 { true1, true1, true1, true1, true1, true1, true1 }, // SE 22 (all)
1138 { false0, true1, true1, true1, false0, false0, false0}, // SE 23 (1,3,5)
1139 { false0, false0, false0, true1, false0, false0, false0}, // SE 24 (5)
1140 { false0, false0, false0, true1, false0, false0, false0}, // SE 25 (5)
1141 { false0, false0, false0, true1, false0, false0, false0}, // SE 26 (5)
1142 { false0, false0, false0, true1, false0, false0, false0}, // SE 27 (5)
1143 { false0, false0, false0, true1, false0, false0, false0}, // SE 28 (5)
1144 { false0, true1, true1, true1, false0, false0, false0}, // SE 29 (1,3,5)
1145 { false0, false0, false0, true1, false0, false0, false0}, // SE 30 (5)
1146 { false0, true1, true1, true1, false0, false0, false0}, // SE 31 (1,3,5)
1147 { false0, false0, false0, true1, false0, false0, false0}, // SE 32 (5)
1148};
1149
1150static bool_Bool se_allowed_in_st(unsigned se, unsigned st)
1151{
1152 if (se==0 || se>HIGHEST_EXTTYPE32) {
1153 /* Don't know about new SE, so don't complain.. */
1154 return true1;
1155 }
1156
1157 switch (st) {
1158 case 0:
1159 return ext_cts[se-1].ST0;
1160 case 1:
1161 return ext_cts[se-1].ST1;
1162 case 3:
1163 return ext_cts[se-1].ST3;
1164 case 5:
1165 return ext_cts[se-1].ST5;
1166 case 6:
1167 return ext_cts[se-1].ST6;
1168 case 10:
1169 return ext_cts[se-1].ST10;
1170 case 11:
1171 return ext_cts[se-1].ST11;
1172 default:
1173 /* New/unknown section type that includes 'ef'.. assume ok */
1174 return true1;
1175 }
1176}
1177
1178/************************************************************************************/
1179
1180/* Table 7.7.1.2-2 */
1181static const value_string bfw_comp_headers_iq_width[] = {
1182 {0, "I and Q are 16 bits wide"},
1183 {1, "I and Q are 1 bit wide"},
1184 {2, "I and Q are 2 bits wide"},
1185 {3, "I and Q are 3 bits wide"},
1186 {4, "I and Q are 4 bits wide"},
1187 {5, "I and Q are 5 bits wide"},
1188 {6, "I and Q are 6 bits wide"},
1189 {7, "I and Q are 7 bits wide"},
1190 {8, "I and Q are 8 bits wide"},
1191 {9, "I and Q are 9 bits wide"},
1192 {10, "I and Q are 10 bits wide"},
1193 {11, "I and Q are 11 bits wide"},
1194 {12, "I and Q are 12 bits wide"},
1195 {13, "I and Q are 13 bits wide"},
1196 {14, "I and Q are 14 bits wide"},
1197 {15, "I and Q are 15 bits wide"},
1198 {0, NULL((void*)0)}
1199};
1200
1201/* Table 7.7.1.2-3 */
1202static const value_string bfw_comp_headers_comp_meth[] = {
1203 {COMP_NONE0, "no compression"},
1204 {COMP_BLOCK_FP1, "block floating point"},
1205 {COMP_BLOCK_SCALE2, "block scaling"},
1206 {COMP_U_LAW3, "u-law"},
1207 {4, "beamspace compression type I"},
1208 {5, "beamspace compression type II"},
1209 {0, NULL((void*)0)}
1210};
1211
1212/* 7.7.6.2 rbgSize (resource block group size) */
1213static const value_string rbg_size_vals[] = {
1214 {0, "reserved"},
1215 {1, "1"},
1216 {2, "2"},
1217 {3, "3"},
1218 {4, "4"},
1219 {5, "6"},
1220 {6, "8"},
1221 {7, "16"},
1222 {0, NULL((void*)0)}
1223};
1224
1225/* 7.7.6.5 */
1226static const value_string priority_vals[] = {
1227 {0, "0"},
1228 {1, "+1"},
1229 {2, "-2 (reserved, should not be used)"},
1230 {3, "-1"},
1231 {0, NULL((void*)0)}
1232};
1233
1234/* 7.7.10.2 beamGroupType */
1235static const value_string beam_group_type_vals[] = {
1236 {0x0, "common beam"},
1237 {0x1, "beam matrix indication"},
1238 {0x2, "beam vector listing"},
1239 {0x3, "beamId/ueId listing with associated port-list index"},
1240 {0, NULL((void*)0)}
1241};
1242
1243/* 7.7.9.2 technology (interface name) */
1244static const value_string interface_name_vals[] = {
1245 {0x0, "LTE"},
1246 {0x1, "NR"},
1247 {0, NULL((void*)0)}
1248};
1249
1250/* 7.7.18.4 toT (type of transmission) */
1251static const value_string type_of_transmission_vals[] = {
1252 {0x0, "normal transmission mode, data can be distributed in any way the O-RU is implemented to transmit data"},
1253 {0x1, "uniformly distributed over the transmission window"},
1254 {0x2, "Reserved"},
1255 {0x3, "Reserved"},
1256 {0, NULL((void*)0)}
1257};
1258
1259/* 7.7.2.2 (width of bfa parameters) */
1260static const value_string bfa_bw_vals[] = {
1261 {0, "no bits, the field is not applicable (e.g., O-RU does not support it) or the default value shall be used"},
1262 {1, "2-bit bitwidth"},
1263 {2, "3-bit bitwidth"},
1264 {3, "4-bit bitwidth"},
1265 {4, "5-bit bitwidth"},
1266 {5, "6-bit bitwidth"},
1267 {6, "7-bit bitwidth"},
1268 {7, "8-bit bitwidth"},
1269 {0, NULL((void*)0)}
1270};
1271
1272/* 7.7.2.7 & 7.7.2.8 */
1273static const value_string sidelobe_suppression_vals[] = {
1274 {0, "10 dB"},
1275 {1, "15 dB"},
1276 {2, "20 dB"},
1277 {3, "25 dB"},
1278 {4, "30 dB"},
1279 {5, "35 dB"},
1280 {6, "40 dB"},
1281 {7, ">= 45 dB"},
1282 {0, NULL((void*)0)}
1283};
1284
1285static const value_string lbtTrafficClass_vals[] = {
1286 {1, "Priority 1"},
1287 {2, "Priority 2"},
1288 {3, "Priority 3"},
1289 {4, "Priority 4"},
1290 {0, NULL((void*)0)}
1291};
1292
1293/* 7.5.3.22 */
1294static const value_string lbtPdschRes_vals[] = {
1295 {0, "not sensing – indicates that the O-RU is transmitting data"},
1296 {1, "currently sensing – indicates the O-RU has not yet acquired the channel"},
1297 {2, "success – indicates that the channel was successfully acquired"},
1298 {3, "Failure – indicates expiration of the LBT timer. The LBT process should be reset"},
1299 {0, NULL((void*)0)}
1300};
1301
1302/* Table 7.5.2.15-3 */
1303static const value_string ci_comp_opt_vals[] = {
1304 {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"},
1305 {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"},
1306 {0, NULL((void*)0)}
1307};
1308
1309/* 7.5.2.17 */
1310static const range_string cmd_scope_vals[] = {
1311 {0, 0, "ARRAY-COMMAND"},
1312 {1, 1, "CARRIER-COMMAND"},
1313 {2, 2, "O-RU-COMMAND"},
1314 {3, 15, "reserved"},
1315 {0, 0, NULL((void*)0)}
1316};
1317
1318/* N.B., table in 7.5.3.38 is truncated.. */
1319static const range_string st4_cmd_type_vals[] = {
1320 {0, 0, "reserved for future command types"},
1321 {1, 1, "TIME_DOMAIN_BEAM_CONFIG"},
1322 {2, 2, "TDD_CONFIG_PATTERN"},
1323 {3, 3, "TRX_CONTROL"},
1324 {4, 4, "ASM"},
1325 {5, 5, "TRX_CONTROL_BIDIR"},
1326 {6, 255, "reserved for future command types"},
1327 {0, 0, NULL((void*)0)}
1328};
1329
1330/* Table 7.5.3.51-1 */
1331static const value_string log2maskbits_vals[] = {
1332 {0, "reserved"},
1333 {1, "min antMask size is 16 bits.."},
1334 {2, "min antMask size is 16 bits.."},
1335 {3, "min antMask size is 16 bits.."},
1336 {4, "16 bits"},
1337 {5, "32 bits"},
1338 {6, "64 bits"},
1339 {7, "128 bits"},
1340 {8, "256 bits"},
1341 {9, "512 bits"},
1342 {10, "1024 bits"},
1343 {11, "2048 bits"},
1344 {12, "4096 bits"},
1345 {13, "8192 bits"},
1346 {14, "16384 bits"},
1347 {15, "reserved"},
1348 {0, NULL((void*)0)}
1349};
1350
1351/* Table 16.1-1 Sleep modes */
1352static const value_string sleep_mode_trx_vals[] = {
1353 { 0, "TRXC-mode0-wake-up-duration (symbol)"},
1354 { 1, "TRXC-mode1-wake-up-duration (L)"},
1355 { 2, "TRXC-mode2-wake-up-duration (M)"},
1356 { 3, "TRXC-mode3-wake-up-duration (N)"},
1357 { 0, NULL((void*)0)}
1358};
1359
1360static const value_string sleep_mode_asm_vals[] = {
1361 { 0, "ASM-mode0-wake-up-duration (symbol)"},
1362 { 1, "ASM-mode1-wake-up-duration (L)"},
1363 { 2, "ASM-mode2-wake-up-duration (M)"},
1364 { 3, "ASM-mode3-wake-up-duration (N)"},
1365 { 0, NULL((void*)0)}
1366};
1367
1368/* 7.7.21.3.1 */
1369static const value_string prg_size_st5_vals[] = {
1370 { 0, "reserved"},
1371 { 1, "Precoding resource block group size as WIDEBAND"},
1372 { 2, "Precoding resource block group size 2"},
1373 { 3, "Precoding resource block group size 4"},
1374 { 0, NULL((void*)0)}
1375};
1376
1377/* 7.7.21.3.2 */
1378static const value_string prg_size_st6_vals[] = {
1379 { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"},
1380 { 1, "Precoding resource block group size as WIDEBAND"},
1381 { 2, "Precoding resource block group size 2"},
1382 { 3, "Precoding resource block group size 4"},
1383 { 0, NULL((void*)0)}
1384};
1385
1386/* 7.7.24.4 */
1387static const value_string alpn_per_sym_vals[] = {
1388 { 0, "report one allocated IPN value per all allocated symbols with DMRS"},
1389 { 1, "report one allocated IPN value per group of consecutive DMRS symbols"},
1390 { 0, NULL((void*)0)}
1391};
1392
1393/* 7.7.24.5 */
1394static const value_string ant_dmrs_snr_vals[] = {
1395 { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"},
1396 { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"},
1397 { 0, NULL((void*)0)}
1398};
1399
1400/* 7.7.24.14 */
1401static const value_string dtype_vals[] = {
1402 { 0, "assume DMRS configuration type 1"},
1403 { 1, "assume DMRS configuration type 2"},
1404 { 0, NULL((void*)0)}
1405};
1406
1407/* 7.7.24.17 */
1408static const value_string papr_type_vals[] = {
1409 { 0, "sequence generator type 1 for short sequence lengths"},
1410 { 1, "sequence generator type 1 for long sequence lengths"},
1411 { 2, "sequence generator type 2 for short sequence lengths"},
1412 { 3, "sequence generator type 2 for long sequence lengths"},
1413 { 0, NULL((void*)0)}
1414};
1415
1416/* 7.7.24.18 */
1417static const value_string hopping_mode_vals[] = {
1418 { 0, "neither group, nor sequence hopping is enabled"},
1419 { 1, "group hopping is enabled and sequence hopping is disabled"},
1420 { 2, "sequence hopping is enabled and group hopping is disabled"},
1421 { 3, "reserved"},
1422 { 0, NULL((void*)0)}
1423};
1424
1425/* Table 7.7.31.2-1 */
1426static const value_string mcs_table_vals[] = {
1427 { 0, "MCS index table 1 for PDSCH and PUSCH without transform precoding" },
1428 { 1, "MCS index table 2 for PDSCH and PUSCH without transform precoding" },
1429 { 2, "MCS index table 3 for PDSCH and PUSCH without transform precoding" },
1430 { 3, "MCS index table 4 for PDSCH" },
1431 { 4, "MCS index table for PUSCH with transform precoding and 64QAM" },
1432 { 5, "MCS index table 2 for PUSCH with transform precoding and 64QAM" },
1433 { 0, NULL((void*)0)}
1434};
1435
1436/* 7.7.32.9 */
1437static const value_string full_pwr_mode_vals[] = {
1438 { 0, "not configured"},
1439 { 1, "full power mode 0"},
1440 { 2, "full power mode 1"},
1441 { 3, "full power mode 2"},
1442 { 0, NULL((void*)0)}
1443};
1444
1445
1446static const true_false_string tfs_sfStatus =
1447{
1448 "subframe was transmitted",
1449 "subframe was dropped"
1450};
1451
1452static const true_false_string tfs_lbtBufErr =
1453{
1454 "buffer overflow – data received at O-RU is larger than the available buffer size",
1455 "reserved"
1456};
1457
1458static const true_false_string tfs_partial_full_sf = {
1459 "partial SF",
1460 "full SF"
1461};
1462
1463static const true_false_string disable_tdbfns_tfs = {
1464 "beam numbers excluded",
1465 "beam numbers included"
1466};
1467
1468static const true_false_string continuity_indication_tfs = {
1469 "continuity between current and next bundle",
1470 "discontinuity between current and next bundle"
1471};
1472
1473static const true_false_string prb_mode_tfs = {
1474 "PRB-BLOCK mode",
1475 "PRB-MASK mode"
1476};
1477
1478static const true_false_string symbol_direction_tfs = {
1479 "DL symbol",
1480 "UL symbol"
1481};
1482
1483static const true_false_string symbol_guard_tfs = {
1484 "guard symbol",
1485 "non-guard symbol"
1486};
1487
1488static const true_false_string beam_numbers_included_tfs = {
1489 "time-domain beam numbers excluded in this command",
1490 "time-domain beam numbers included in this command"
1491};
1492
1493static const true_false_string measurement_flag_tfs = {
1494 "at least one additional measurement report or command after the current one",
1495 "no additional measurement report or command"
1496};
1497
1498static const true_false_string repetition_se6_tfs = {
1499 "repeated highest priority data section in the C-Plane message",
1500 "no repetition"
1501};
1502
1503static const true_false_string repetition_se19_tfs = {
1504 "per port information not present in the extension",
1505 "per port info present in the extension"
1506};
1507
1508static const true_false_string tfs_report_no_report_pos_meas =
1509{
1510 "Report MEAS_UE_POS for UE",
1511 "Do not report UE_POS for UE"
1512};
1513
1514
1515/* Forward declaration */
1516static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
1517 unsigned comp_meth,
1518 uint32_t *exponent, uint16_t *sReSMask, bool_Bool for_sinr);
1519
1520
1521static const true_false_string ready_tfs = {
1522 "message is a \"ready\" message",
1523 "message is a ACK message"
1524};
1525
1526static const true_false_string multi_sd_scope_tfs = {
1527 "Puncturing pattern applies to current and following sections",
1528 "Puncturing pattern applies to current section"
1529};
1530
1531static const true_false_string tfs_ueid_reset = {
1532 "cannot assume same UE as in preceding slot",
1533 "can assume same UE as in preceding slot"
1534};
1535
1536
1537/* Config for (and later, worked-out allocations) bundles for ext11 (dynamic BFW) */
1538typedef struct {
1539 /* Ext 6 config */
1540 bool_Bool ext6_set;
1541 uint8_t ext6_rbg_size; /* number of PRBs allocated by bitmask */
1542
1543 uint8_t ext6_num_bits_set;
1544 uint8_t ext6_bits_set[28]; /* Which bit position this entry has */
1545 /* TODO: store an f value for each bit position? */
1546
1547 /* Ext 12 config */
1548 bool_Bool ext12_set;
1549 unsigned ext12_num_pairs;
1550#define MAX_BFW_EXT12_PAIRS128 128
1551 struct {
1552 uint8_t off_start_prb;
1553 uint8_t num_prb;
1554 } ext12_pairs[MAX_BFW_EXT12_PAIRS128];
1555
1556 /* Ext 13 config */
1557 bool_Bool ext13_set;
1558 unsigned ext13_num_start_prbs;
1559#define MAX_BFW_EXT13_ALLOCATIONS128 128
1560 unsigned ext13_start_prbs[MAX_BFW_EXT13_ALLOCATIONS128];
1561 /* TODO: store nextSymbolId here too? */
1562
1563 /* Ext 21 config */
1564 bool_Bool ext21_set;
1565 uint8_t ext21_ci_prb_group_size;
1566
1567 /* Results/settings (after calling ext11_work_out_bundles()) */
1568 uint32_t num_bundles;
1569#define MAX_BFW_BUNDLES512 512
1570 struct {
1571 uint32_t start; /* first prb of bundle */
1572 uint32_t end; /* last prb of bundle*/
1573 bool_Bool is_orphan; /* true if not complete (i.e., end-start < numBundPrb) */
1574 } bundles[MAX_BFW_BUNDLES512];
1575} ext11_settings_t;
1576
1577
1578/* Work out bundle allocation for ext 11. Take into account ext6/ext21, ext12 or ext13 in this section before ext 11. */
1579/* Won't be called with numBundPrb=0 */
1580static void ext11_work_out_bundles(unsigned startPrbc,
1581 unsigned numPrbc,
1582 unsigned numBundPrb, /* number of PRBs per (full) bundle */
1583 ext11_settings_t *settings)
1584{
1585 /* Allocation configured by ext 6 */
1586 if (settings->ext6_set) {
1587 unsigned bundles_per_entry = (settings->ext6_rbg_size / numBundPrb);
1588
1589 /* Need to cope with these not dividing exactly, or even having more PRbs in a bundle that
1590 rbg size. i.e. each bundle gets the correct number of PRBs until
1591 all rbg entries are consumed... */
1592
1593 /* TODO: need to check 7.9.4.2. Different cases depending upon value of RAD */
1594
1595 if (bundles_per_entry == 0) {
1596 bundles_per_entry = 1;
1597 }
1598
1599 /* Ext6 behaviour may also be affected by ext 21 */
1600 if (settings->ext21_set) {
1601 /* N.B., have already checked that numPrbc is not 0 */
1602
1603 /* ciPrbGroupSize overrides number of contiguous PRBs in group */
1604 bundles_per_entry = (settings->ext6_rbg_size / settings->ext21_ci_prb_group_size);
1605
1606 /* numPrbc is the number of PRB groups per antenna - handled in call to dissect_bfw_bundle() */
1607 }
1608
1609 unsigned bundles_set = 0;
1610 bool_Bool reached_orphan = false0;
1611 /* For each bit set in ext6 rbg mask.. */
1612 for (unsigned n=0;
1613 !reached_orphan && n < (settings->ext6_num_bits_set * settings->ext6_rbg_size) / numBundPrb;
1614 n++) {
1615
1616 /* Watch out for array bound */
1617 if (n >= 28) {
1618 break;
1619 }
1620
1621 /* For each bundle... */
1622
1623 /* TODO: Work out where first PRB is */
1624 /* May not be the start of an rbg block... */
1625 uint32_t prb_start = (settings->ext6_bits_set[n] * settings->ext6_rbg_size);
1626
1627 /* For each bundle within identified rbgSize block */
1628 for (unsigned m=0; !reached_orphan && m < bundles_per_entry; m++) {
1629
1630 settings->bundles[bundles_set].start = startPrbc+prb_start+(m*numBundPrb);
1631
1632 /* Start already beyond end, so doesn't count. */
1633 if (settings->bundles[bundles_set].start > (startPrbc+numPrbc-1)) {
1634 settings->num_bundles = bundles_set;
1635 return;
1636 }
1637
1638 /* Bundle consists of numBundPrb bundles */
1639 /* TODO: may involve PRBs from >1 rbg blocks.. */
1640 settings->bundles[bundles_set].end = startPrbc+prb_start+((m+1)*numBundPrb)-1;
1641 if (settings->bundles[bundles_set].end > (startPrbc+numPrbc-1)) {
1642 /* Extends beyond end, so counts but is an orphan bundle */
1643 settings->bundles[bundles_set].end = startPrbc+numPrbc-1;
1644 settings->bundles[bundles_set].is_orphan = true1;
1645 reached_orphan = true1;
1646 }
1647
1648 /* Get out if have reached array bound */
1649 if (++bundles_set == MAX_BFW_BUNDLES512) {
1650 return;
1651 }
1652 }
1653 }
1654 settings->num_bundles = bundles_set;
1655 }
1656
1657 /* Allocation configured by ext 12 */
1658 else if (settings->ext12_set) {
1659 /* First, allocate normally from startPrbc, numPrbc */
1660 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb;
1661
1662 /* Don't overflow settings->bundles[] ! */
1663 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1664
1665 for (uint32_t n=0; n < settings->num_bundles; n++) {
1666 settings->bundles[n].start = startPrbc + n*numBundPrb;
1667 settings->bundles[n].end = settings->bundles[n].start + numBundPrb-1;
1668 /* Does it go beyond the end? */
1669 if (settings->bundles[n].end > startPrbc+numPrbc) {
1670 settings->bundles[n].end = startPrbc+numPrbc;
1671 settings->bundles[n].is_orphan = true1;
1672 }
1673 }
1674 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1675 return;
1676 }
1677
1678 unsigned prb_offset = startPrbc + numPrbc;
1679
1680 /* Loop over pairs, adding bundles for each */
1681 for (unsigned p=0; p < settings->ext12_num_pairs; p++) {
1682 prb_offset += settings->ext12_pairs[p].off_start_prb;
1683 unsigned pair_bundles = (settings->ext12_pairs[p].num_prb+numBundPrb-1) / numBundPrb;
1684
1685 for (uint32_t n=0; n < pair_bundles; n++) {
1686 unsigned idx = settings->num_bundles;
1687
1688 settings->bundles[idx].start = prb_offset + n*numBundPrb;
1689 settings->bundles[idx].end = settings->bundles[idx].start + numBundPrb-1;
1690 /* Does it go beyond the end? */
1691 if (settings->bundles[idx].end > prb_offset + settings->ext12_pairs[p].num_prb) {
1692 settings->bundles[idx].end = prb_offset + settings->ext12_pairs[p].num_prb;
1693 settings->bundles[idx].is_orphan = true1;
1694 }
1695 /* Range check / return */
1696 settings->num_bundles++;
1697 if (settings->num_bundles == MAX_BFW_BUNDLES512) {
1698 return;
1699 }
1700 }
1701
1702 prb_offset += settings->ext12_pairs[p].num_prb;
1703 }
1704 }
1705
1706 /* Allocation configured by ext 13 */
1707 else if (settings->ext13_set) {
1708 unsigned alloc_size = (numPrbc+numBundPrb-1) / numBundPrb;
1709 settings->num_bundles = alloc_size * settings->ext13_num_start_prbs;
1710
1711 /* Don't overflow settings->bundles[] ! */
1712 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1713
1714 for (unsigned alloc=0; alloc < settings->ext13_num_start_prbs; alloc++) {
1715 unsigned alloc_start = alloc * alloc_size;
1716 for (uint32_t n=0; n < alloc_size; n++) {
1717 if ((alloc_start+n) >= MAX_BFW_BUNDLES512) {
1718 /* ERROR */
1719 return;
1720 }
1721 settings->bundles[alloc_start+n].start = settings->ext13_start_prbs[alloc] + startPrbc + n*numBundPrb;
1722 settings->bundles[alloc_start+n].end = settings->bundles[alloc_start+n].start + numBundPrb-1;
1723 if (settings->bundles[alloc_start+n].end > settings->ext13_start_prbs[alloc] + numPrbc) {
1724 settings->bundles[alloc_start+n].end = settings->ext13_start_prbs[alloc] + numPrbc;
1725 settings->bundles[alloc_start+n].is_orphan = true1;
1726 }
1727 }
1728 }
1729 }
1730
1731 /* Case where bundles are not controlled by other extensions - just divide up range into bundles we have */
1732 else {
1733 settings->num_bundles = (numPrbc+numBundPrb-1) / numBundPrb; /* rounded up */
1734
1735 /* Don't overflow settings->bundles[] */
1736 settings->num_bundles = MIN(MAX_BFW_BUNDLES, settings->num_bundles)(((512) < (settings->num_bundles)) ? (512) : (settings->
num_bundles))
;
1737
1738 /* For each bundle.. */
1739 for (uint32_t n=0; n < settings->num_bundles; n++) {
1740 /* Allocate start and end */
1741 settings->bundles[n].start = startPrbc + n*numBundPrb;
1742 settings->bundles[n].end = settings->bundles[n].start + numBundPrb - 1;
1743 /* If would go beyond end of PRBs, limit and identify as orphan */
1744 if (settings->bundles[n].end > startPrbc+numPrbc) {
1745 settings->bundles[n].end = startPrbc+numPrbc;
1746 settings->bundles[n].is_orphan = true1;
1747 }
1748 }
1749 }
1750}
1751
1752
1753/* Modulation Compression configuration */
1754typedef struct {
1755 /* Application of each entry is filtered by RE.
1756 * TODO: should also be filtered by PRB + symbol... */
1757 uint16_t mod_compr_re_mask;
1758
1759 /* Settings to apply */
1760 bool_Bool mod_compr_csf;
1761 float mod_compr_scaler;
1762} mod_compr_config_t;
1763
1764/* Multiple configs with a section */
1765typedef struct {
1766 uint16_t section_id;
1767 uint32_t num_configs;
1768
1769 #define MAX_MOD_COMPR_CONFIGS12 12
1770 mod_compr_config_t configs[MAX_MOD_COMPR_CONFIGS12];
1771} section_mod_compr_config_t;
1772
1773/* Flow has separate configs for each section */
1774typedef struct {
1775 uint16_t num_sections;
1776
1777 /* Separate config for each section */
1778 section_mod_compr_config_t sections[MAX_SECTION_IDs32];
1779} mod_compr_params_t;
1780
1781
1782typedef struct {
1783 uint32_t frame_number;
1784 nstime_t frame_time;
1785
1786 /* Timing to match */
1787 uint8_t frame;
1788 uint8_t subframe;
1789 uint8_t slot;
1790 uint8_t startSymbol;
1791
1792 bool_Bool in_use;
1793 uint16_t startPrb;
1794 uint16_t numPrb;
1795 uint16_t numSymbols;
1796 uint16_t beamIds[273];
1797} section_details_t;
1798
1799typedef struct {
1800 uint16_t sectionId;
1801 /* For the same sectionId, can have 2 currently active entries.. */
1802 section_details_t details[2];
1803} expected_section_data_t;
1804
1805
1806/*******************************************************/
1807/* Overall state of a flow (eAxC/plane) */
1808typedef struct {
1809 /* State for sequence analysis [each direction] */
1810 bool_Bool last_frame_seen[2];
1811 uint32_t last_frame[2];
1812 uint8_t next_expected_sequence_number[2];
1813
1814 /* expected frames. sectionId -> expected_section_data_t* */
1815 wmem_tree_t *expected_sections[2]; /* [direction] */
1816
1817 /* Table recording ackNack requests (ackNackId -> ack_nack_request_t*)
1818 Note that this assumes that the same ackNackId will not be reused within a state,
1819 which may well not be valid */
1820 wmem_tree_t *ack_nack_requests;
1821
1822 /* Store udCompHdr seen in C-Plane for UL - can be looked up and used by U-PLane.
1823 Note that this appears in the common section header parts of ST1, ST3, ST5,
1824 so can still be over-written per sectionId in the U-Plane */
1825 unsigned ul_ud_comp_hdr_frame;
1826 bool_Bool ul_ud_comp_hdr_set;
1827 unsigned ul_ud_comp_hdr_bit_width;
1828 int ul_ud_comp_hdr_compression;
1829
1830 bool_Bool udcomphdrDownlink_heuristic_result_set;
1831 bool_Bool udcomphdrDownlink_heuristic_result;
1832 bool_Bool udcomphdrUplink_heuristic_result_set;
1833 bool_Bool udcomphdrUplink_heuristic_result;
1834
1835 /* Modulation compression params */
1836 mod_compr_params_t mod_comp_params;
1837} flow_state_t;
1838
1839static section_mod_compr_config_t* get_mod_compr_section_to_write(flow_state_t *flow,
1840 unsigned sectionId)
1841{
1842 if (flow == NULL((void*)0)) {
1843 return NULL((void*)0);
1844 }
1845
1846 /* Look for this section among existing entries */
1847 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1848 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1849 return &flow->mod_comp_params.sections[s];
1850 }
1851 }
1852
1853 /* Not found, so try to add a new one */
1854 if (flow->mod_comp_params.num_sections >= MAX_SECTION_IDs32) {
1855 /* Can't allocate one! */
1856 return NULL((void*)0);
1857 }
1858 else {
1859 flow->mod_comp_params.sections[flow->mod_comp_params.num_sections].section_id = sectionId;
1860 return &flow->mod_comp_params.sections[flow->mod_comp_params.num_sections++];
1861 }
1862}
1863
1864static section_mod_compr_config_t* get_mod_compr_section_to_read(flow_state_t *flow,
1865 unsigned sectionId)
1866{
1867 if (flow == NULL((void*)0)) {
1868 return NULL((void*)0);
1869 }
1870
1871 /* Look for this section among existing entries */
1872 for (unsigned s=0; s < flow->mod_comp_params.num_sections; s++) {
1873 if (flow->mod_comp_params.sections[s].section_id == sectionId) {
1874 return &flow->mod_comp_params.sections[s];
1875 }
1876 }
1877
1878 /* Not found */
1879 return NULL((void*)0);
1880}
1881
1882
1883
1884typedef struct {
1885 uint32_t request_frame_number;
1886 nstime_t request_frame_time;
1887 enum {
1888 SE22,
1889 ST4Cmd1,
1890 ST4Cmd2,
1891 ST4Cmd3,
1892 ST4Cmd4
1893 } requestType;
1894
1895 uint32_t response_frame_number;
1896 nstime_t response_frame_time;
1897} ack_nack_request_t;
1898
1899static const value_string acknack_type_vals[] = {
1900 { SE22, "SE 22" },
1901 { ST4Cmd1, "ST4 (TIME_DOMAIN_BEAM_CONFIG)" },
1902 { ST4Cmd2, "ST4 (TDD_CONFIG_PATTERN)" },
1903 { ST4Cmd3, "ST4 (TRX_CONTROL)" },
1904 { ST4Cmd4, "ST4 (ASM)" },
1905 { 0, NULL((void*)0)}
1906};
1907
1908#define ORAN_C_PLANE0 0
1909#define ORAN_U_PLANE1 1
1910
1911/* Using parts of src/dst MAC address, so don't confuse UL messages with DL messages configuring UL.. */
1912static uint32_t make_flow_key(packet_info *pinfo, uint16_t eaxc_id, uint8_t plane, bool_Bool opposite_dir)
1913{
1914 uint16_t eth_bits = 0;
1915 if (pinfo->dl_src.len == 6 && pinfo->dl_dst.len == 6) {
1916 /* Only using (most of) 2 bytes from addresses for now, but reluctant to make key longer.. */
1917 const uint8_t *src_eth = (uint8_t*)pinfo->dl_src.data;
1918 const uint8_t *dst_eth = (uint8_t*)pinfo->dl_dst.data;
1919 if (!opposite_dir) {
1920 eth_bits = (src_eth[0]<<8) | dst_eth[5];
1921 }
1922 else {
1923 eth_bits = (dst_eth[0]<<8) | src_eth[5];
1924 }
1925 }
1926 return eaxc_id | (plane << 16) | (eth_bits << 17);
1927}
1928
1929
1930/* Table maintained on first pass from flow_key(uint32_t) -> flow_state_t* */
1931static wmem_tree_t *flow_states_table;
1932
1933typedef struct {
1934 uint32_t frame_number;
1935 uint16_t sectionId;
1936 uint32_t gap_in_usecs;
1937 uint8_t symbol;
1938 uint16_t startPrbu;
1939 uint16_t numPrbu;
1940} corresponding_uplane_frame;
1941
1942/* Table consulted on subsequent passes: frame_num -> flow_result_t* */
1943static wmem_tree_t *flow_results_table;
1944
1945typedef struct {
1946 /* Sequence analysis */
1947 bool_Bool unexpected_seq_number;
1948 uint8_t expected_sequence_number;
1949 uint32_t previous_frame;
1950
1951 /* sectionId -> expected_section_data_t* */
1952 /* Frame only covers one direction */
1953 wmem_tree_t *expected_sections;
1954
1955 /* List of u-plane frames (corresponding_uplane_frame*) corresponding to a c-plane frame */
1956 wmem_list_t *u_plane_frames;
1957} flow_result_t;
1958
1959
1960/* Uplink timing */
1961/* For a given symbol, track first to last UL frame to find out first-last time */
1962/* frameId (8) + subframeId (4) + slotId (6) + symbolId (6) = 24 bits */
1963/* N.B. if a capture lasts > 2.5s, may see same timing come around again... */
1964static uint32_t get_timing_key(uint8_t frameId, uint8_t subframeId, uint8_t slotId, uint8_t symbolId)
1965{
1966 return symbolId + (slotId<<8) + (subframeId<<14) + (frameId<<18);
1967}
1968
1969typedef struct {
1970 uint32_t first_frame;
1971 nstime_t first_frame_time;
1972 uint32_t frames_seen_in_symbol;
1973 uint32_t last_frame_in_symbol;
1974} ul_timing_for_slot;
1975
1976/* Set during first pass. timing_key -> ul_timing_for_slot* */
1977static wmem_tree_t *ul_symbol_timing;
1978
1979
1980/* Tracking lifetimes of DL beamIds */
1981typedef struct {
1982 uint32_t frame_defined;
1983 uint32_t symbol_when_defined;
1984} bfw_definition;
1985
1986/* Maintained during first pass: beamId (from ext11) -> bfw_definition */
1987static wmem_tree_t *dl_beam_ids_defined;
1988/* Lookup where/when beamIds were defined (frameid:beamid) -> bfw_definition */
1989static wmem_tree_t *dl_beam_ids_results;
1990
1991
1992static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1993 ack_nack_request_t *response);
1994
1995
1996
1997
1998static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1999 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)));
2000
2001 /* Write the given formatted text to:
2002 - the info column (if pinfo != NULL)
2003 - 1 or 2 other labels (optional)
2004 */
2005static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2006 packet_info *pinfo, const char *format, ...)
2007{
2008#define MAX_INFO_BUFFER256 256
2009 char info_buffer[MAX_INFO_BUFFER256];
2010 va_list ap;
2011
2012 if ((ti1 == NULL((void*)0)) && (ti2 == NULL((void*)0)) && (pinfo == NULL((void*)0))) {
2013 return;
2014 }
2015
2016 va_start(ap, format)__builtin_va_start(ap, format);
2017 vsnprintf(info_buffer, MAX_INFO_BUFFER256, format, ap);
2018 va_end(ap)__builtin_va_end(ap);
2019
2020 /* Add to indicated places */
2021 if (pinfo != NULL((void*)0)) {
2022 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2023 }
2024 if (ti1 != NULL((void*)0)) {
2025 proto_item_append_text(ti1, "%s", info_buffer);
2026 }
2027 if (ti2 != NULL((void*)0)) {
2028 proto_item_append_text(ti2, "%s", info_buffer);
2029 }
2030}
2031
2032/* Add section labels (type + PRB range) for C-Plane, U-Plane */
2033static void
2034write_section_info(proto_item *section_heading, packet_info *pinfo, proto_item *protocol_item,
2035 uint32_t section_id, uint32_t start_prbx, uint32_t num_prbx, uint32_t rb)
2036{
2037 switch (num_prbx) {
2038 case 0:
2039 /* None -> all */
2040 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (all PRBs)", section_id);
2041 break;
2042 case 1:
2043 /* Single PRB */
2044 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %7u)", section_id, start_prbx);
2045 break;
2046 default:
2047 /* Range */
2048 write_pdu_label_and_info(section_heading, protocol_item, pinfo, ", Id: %4d (PRB: %3u-%3u%s)", section_id, start_prbx,
2049 start_prbx + (num_prbx-1)*(1+rb), rb ? " (every-other)" : "");
2050 }
2051}
2052
2053static void
2054write_channel_section_info(proto_item *section_heading, packet_info *pinfo,
2055 uint32_t section_id, uint32_t ueId, uint32_t start_prbx, uint32_t num_prbx,
2056 uint32_t num_trx)
2057{
2058 switch (num_prbx) {
2059 case 0:
2060 /* TODO: ?? */
2061 break;
2062 case 1:
2063 /* Single PRB */
2064 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2065 ", Id: %4d (UEId=%5u PRB %7u, %2u antennas)",
2066 section_id, ueId, start_prbx, num_trx);
2067 break;
2068 default:
2069 /* Range */
2070 write_pdu_label_and_info(section_heading, NULL((void*)0), pinfo,
2071 ", Id: %4d (UEId=%5u PRBs %3u-%3u, %2u antennas)",
2072 section_id, ueId, start_prbx, start_prbx+num_prbx-1, num_trx);
2073 }
2074}
2075
2076/* Add a reserved field, and warn if value isn't 0 */
2077/* TODO: maybe add a pref not to output expert warning if becomes too annoying? */
2078static void add_reserved_field(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int len)
2079{
2080 uint32_t reserved;
2081 proto_item *res_ti = proto_tree_add_item_ret_uint(tree, hf, tvb, offset, len, ENC_NA0x00000000, &reserved);
2082 if (reserved != 0) {
2083 expert_add_info_format(NULL((void*)0), res_ti, &ei_oran_reserved_not_zero,
2084 "reserved field saw value of 0x%x", reserved);
2085 }
2086}
2087
2088/* 5.1.3.2.7 (real time control data / IQ data transfer message series identifier) */
2089static void
2090addPcOrRtcid(tvbuff_t *tvb, proto_tree *tree, unsigned *offset, int hf, uint16_t *eAxC, oran_tap_info *tap_info)
2091{
2092 /* Subtree */
2093 proto_item *oran_pcid_ti = proto_tree_add_item(tree, hf,
2094 tvb, *offset, 2, ENC_NA0x00000000);
2095 proto_tree *oran_pcid_tree = proto_item_add_subtree(oran_pcid_ti, ett_oran_ecpri_pcid);
2096
2097 uint64_t duPortId, bandSectorId, ccId, ruPortId = 0;
2098 int id_offset = *offset;
2099
2100 /* All parts of eAxC should be above 0, and should total 16 bits (breakdown controlled by preferences) */
2101 if (!((pref_du_port_id_bits > 0) && (pref_bandsector_id_bits > 0) && (pref_cc_id_bits > 0) && (pref_ru_port_id_bits > 0) &&
2102 ((pref_du_port_id_bits + pref_bandsector_id_bits + pref_cc_id_bits + pref_ru_port_id_bits) == 16))) {
2103 expert_add_info(NULL((void*)0), tree, &ei_oran_invalid_eaxc_bit_width);
2104 *eAxC = 0;
2105 *offset += 2;
2106 return;
2107 }
2108
2109 unsigned bit_offset = *offset * 8;
2110
2111 /* N.B. For sequence analysis / tapping, just interpret these 2 bytes as eAxC ID... */
2112 *eAxC = tvb_get_uint16(tvb, *offset, ENC_BIG_ENDIAN0x00000000);
2113
2114 /* DU Port ID */
2115 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_du_port_id, tvb, bit_offset, pref_du_port_id_bits, &duPortId, ENC_BIG_ENDIAN0x00000000);
2116 bit_offset += pref_du_port_id_bits;
2117 /* BandSector ID */
2118 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_bandsector_id, tvb, bit_offset, pref_bandsector_id_bits, &bandSectorId, ENC_BIG_ENDIAN0x00000000);
2119 bit_offset += pref_bandsector_id_bits;
2120 /* CC ID */
2121 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_cc_id, tvb, bit_offset, pref_cc_id_bits, &ccId, ENC_BIG_ENDIAN0x00000000);
2122 bit_offset += pref_cc_id_bits;
2123 /* RU Port ID */
2124 proto_tree_add_bits_ret_val(oran_pcid_tree, hf_oran_ru_port_id, tvb, bit_offset, pref_ru_port_id_bits, &ruPortId, ENC_BIG_ENDIAN0x00000000);
2125 *offset += 2;
2126
2127 proto_item_append_text(oran_pcid_ti, " (DU_Port_ID: %d, BandSector_ID: %d, CC_ID: %d, RU_Port_ID: %d)",
2128 (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2129 char id[16];
2130 snprintf(id, 16, "%x:%x:%x:%x", (int)duPortId, (int)bandSectorId, (int)ccId, (int)ruPortId);
2131 proto_item *pi = proto_tree_add_string(oran_pcid_tree, hf_oran_c_eAxC_ID, tvb, id_offset, 2, id);
2132 proto_item_set_generated(pi);
2133
2134 tap_info->eaxc = *eAxC;
2135 tap_info->eaxc_du_port_id = (uint16_t)duPortId;
2136 tap_info->eaxc_bandsector_id = (uint16_t)bandSectorId;
2137 tap_info->eaxc_cc_id = (uint16_t)ccId;
2138 tap_info->eaxc_ru_port_id = (uint16_t)ruPortId;
2139}
2140
2141/* Uniquely identify the U-plane stream that may need to be reassembled */
2142static uint32_t make_reassembly_id(uint32_t seqid, uint32_t direction, uint16_t eAxC,
2143 uint8_t frameid, uint8_t subframeid,
2144 uint8_t slotid, uint8_t symbolid)
2145{
2146 /* N.B., no room in 32-bits for all of this info, so cut down some of the fields
2147 and hope for no collisions */
2148 return (seqid << 24) | (direction << 23) | (slotid << 22) | (subframeid << 18) |
2149 (frameid << 9) | (symbolid << 6) | (eAxC & 0x3f);
2150}
2151
2152/* 5.1.3.2.8 ecpriSeqid (message identifier) */
2153/* Return out info that may be used for sequence number analysis and reassembly */
2154static int
2155addSeqid(tvbuff_t *tvb, proto_tree *oran_tree, int offset, int plane, uint32_t *seq_id, proto_item **seq_id_ti, packet_info *pinfo,
2156 uint32_t *subseqid, uint32_t *e)
2157{
2158 /* Subtree */
2159 proto_item *seqIdItem = proto_tree_add_item(oran_tree, hf_oran_ecpri_seqid, tvb, offset, 2, ENC_NA0x00000000);
2160 proto_tree *oran_seqid_tree = proto_item_add_subtree(seqIdItem, ett_oran_ecpri_seqid);
2161
2162 /* Sequence ID (8 bits) */
2163 *seq_id_ti = proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_sequence_id, tvb, offset, 1, ENC_NA0x00000000, seq_id);
2164 offset += 1;
2165
2166 /* Show link back to previous sequence ID, if set */
2167 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
2168 if (result) {
2169 proto_item *prev_ti = proto_tree_add_uint(oran_seqid_tree, hf_oran_previous_frame, tvb, 0, 0, result->previous_frame);
2170 proto_item_set_generated(prev_ti);
2171 }
2172
2173 /* E bit */
2174 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_e_bit, tvb, offset, 1, ENC_NA0x00000000, e);
2175 /* Subsequence ID (7 bits) */
2176 proto_tree_add_item_ret_uint(oran_seqid_tree, hf_oran_subsequence_id, tvb, offset, 1, ENC_NA0x00000000, subseqid);
2177 offset += 1;
2178
2179 /* radio-transport fragmentation not allowed for C-Plane messages */
2180 if (plane == ORAN_C_PLANE0) {
2181 if (*e !=1 || *subseqid != 0) {
2182 expert_add_info(NULL((void*)0), seqIdItem, &ei_oran_radio_fragmentation_c_plane);
2183 }
2184 }
2185
2186 /* Summary */
2187 proto_item_append_text(seqIdItem, " (SeqId: %3d, E: %d, SubSeqId: %d)", *seq_id, *e, *subseqid);
2188 return offset;
2189}
2190
2191static int dissect_symbolmask(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t *symbol_mask, proto_item **ti)
2192{
2193 uint64_t temp_val;
2194
2195 static int * const symbol_mask_flags[] = {
2196 &hf_oran_symbol_mask_s13,
2197 &hf_oran_symbol_mask_s12,
2198 &hf_oran_symbol_mask_s11,
2199 &hf_oran_symbol_mask_s10,
2200 &hf_oran_symbol_mask_s9,
2201 &hf_oran_symbol_mask_s8,
2202 &hf_oran_symbol_mask_s7,
2203 &hf_oran_symbol_mask_s6,
2204 &hf_oran_symbol_mask_s5,
2205 &hf_oran_symbol_mask_s4,
2206 &hf_oran_symbol_mask_s3,
2207 &hf_oran_symbol_mask_s2,
2208 &hf_oran_symbol_mask_s1,
2209 &hf_oran_symbol_mask_s0,
2210 NULL((void*)0)
2211 };
2212
2213 proto_item *temp_ti = proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2214 hf_oran_symbol_mask,
2215 ett_oran_symbol_mask, symbol_mask_flags,
2216 ENC_BIG_ENDIAN0x00000000, &temp_val);
2217 /* Set out parameters */
2218 if (symbol_mask) {
2219 *symbol_mask = (uint32_t)temp_val;
2220 }
2221 if (ti) {
2222 *ti = temp_ti;
2223 }
2224 return offset+2;
2225}
2226
2227/* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
2228static int dissect_bfwCompHdr(tvbuff_t *tvb, proto_tree *tree, int offset,
2229 uint32_t *iq_width, uint32_t *comp_meth, proto_item **comp_meth_ti)
2230{
2231 /* Subtree */
2232 proto_item *bfwcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompHdr,
2233 tvb, offset, 1, "",
2234 "bfwCompHdr");
2235 proto_tree *bfwcomphdr_tree = proto_item_add_subtree(bfwcomphdr_ti, ett_oran_bfwcomphdr);
2236
2237 /* Width and method */
2238 proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_iqWidth,
2239 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, iq_width);
2240 /* Special case: 0 -> 16 */
2241 *iq_width = (*iq_width==0) ? 16 : *iq_width;
2242 *comp_meth_ti = proto_tree_add_item_ret_uint(bfwcomphdr_tree, hf_oran_bfwCompHdr_compMeth,
2243 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, comp_meth);
2244 offset++;
2245
2246 /* Summary */
2247 proto_item_append_text(bfwcomphdr_ti, " (IqWidth=%u, compMeth=%s)",
2248 *iq_width,
2249 val_to_str_const(*comp_meth, bfw_comp_headers_comp_meth, "reserved"));
2250
2251 return offset;
2252}
2253
2254/* Return offset */
2255/* Returning number of entries set - would be good to also return an array of set TRX# so could show which array element
2256 each BFW is actually for.. */
2257static int dissect_active_beamspace_coefficient_mask(tvbuff_t *tvb, proto_tree *tree, int offset, unsigned *num_trx_entries, uint16_t **trx_entries)
2258{
2259 /* activeBeamspaceCoefficientMask - ceil(K/8) octets */
2260 /* K is the number of elements in uncompressed beamforming weight vector.
2261 * Calculated from parameters describing tx-array or tx-array */
2262 unsigned k_octets = (pref_num_bf_antennas + 7) / 8;
2263
2264 static uint16_t trx_enabled[1024];
2265
2266 /* TODO: could use a bigger bitmask array, but for now just uses this bytes-worth for each byte */
2267 static int * const mask_bits[] = {
2268 &hf_oran_active_beamspace_coefficient_n1,
2269 &hf_oran_active_beamspace_coefficient_n2,
2270 &hf_oran_active_beamspace_coefficient_n3,
2271 &hf_oran_active_beamspace_coefficient_n4,
2272 &hf_oran_active_beamspace_coefficient_n5,
2273 &hf_oran_active_beamspace_coefficient_n6,
2274 &hf_oran_active_beamspace_coefficient_n7,
2275 &hf_oran_active_beamspace_coefficient_n8,
2276 NULL((void*)0)
2277 };
2278
2279 *num_trx_entries = 0;
2280 uint64_t val;
2281 for (unsigned n=0; n < k_octets; n++) {
2282 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
2283 hf_oran_activeBeamspaceCoefficientMask,
2284 ett_oran_active_beamspace_coefficient_mask, mask_bits,
2285 ENC_BIG_ENDIAN0x00000000, &val);
2286 offset++;
2287 /* Add up the set bits for this byte (but be careful not to count beyond last real K bit..) */
2288 for (unsigned b=0; b < 8; b++) {
2289 if ((1 << b) & (unsigned)val) {
2290 if (((n*8)+b) < pref_num_bf_antennas) {
2291 if (*num_trx_entries < 1024-1) { /* Don't write beyond array (which should be plenty big) */
2292 trx_enabled[(*num_trx_entries)++] = (n*8) + b + 1;
2293 }
2294 }
2295 }
2296 }
2297 }
2298 /* Set pointer to static array */
2299 *trx_entries = trx_enabled;
2300
2301 /* Show how many bits set */
2302 proto_item *ti = proto_tree_add_uint(tree, hf_oran_activeBeamspaceCoefficientMask_bits_set, tvb,
2303 offset-k_octets, k_octets, *num_trx_entries);
2304 proto_item_set_generated(ti);
2305
2306 return offset;
2307}
2308
2309static void add_beam_id_to_tap(oran_tap_info *tap_info, uint16_t beam_id)
2310{
2311 if (tap_info->num_beams < MAX_BEAMS_IN_FRAME32) {
2312 tap_info->beams[tap_info->num_beams++] = beam_id;
2313 }
2314}
2315
2316
2317/* 7.7.1.3 bfwCompParam (beamforming weight compression parameter).
2318 * Depends upon passed-in bfwCompMeth (field may be empty) */
2319static int dissect_bfwCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset,
2320 proto_item *meth_ti, uint32_t *bfw_comp_method,
2321 uint32_t *exponent, bool_Bool *supported, unsigned *num_trx_entries, uint16_t **trx_entries)
2322{
2323 if (*bfw_comp_method == COMP_NONE0) {
2324 /* Absent! */
2325 *num_trx_entries = 0;
2326 *supported = true1;
2327 return offset;
2328 }
2329
2330 /* Subtree */
2331 proto_item *bfwcompparam_ti = proto_tree_add_string_format(tree, hf_oran_bfwCompParam,
2332 tvb, offset, 1, "",
2333 "bfwCompParam");
2334 proto_tree *bfwcompparam_tree = proto_item_add_subtree(bfwcompparam_ti, ett_oran_bfwcompparam);
2335
2336 proto_item_append_text(bfwcompparam_ti,
2337 " (meth=%s)", val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2338
2339 *num_trx_entries = 0;
2340 *supported = false0;
2341 switch (*bfw_comp_method) {
2342 case COMP_BLOCK_FP1: /* block floating point */
2343 /* 4 reserved bits + exponent */
2344 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2345 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent,
2346 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2347 proto_item_append_text(bfwcompparam_ti, " exponent=%u", *exponent);
2348 *supported = true1;
2349 offset++;
2350 break;
2351 case COMP_BLOCK_SCALE2: /* block scaling */
2352 /* Separate into integer and fractional bits? */
2353 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2354 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2355 offset++;
2356 break;
2357 case COMP_U_LAW3: /* u-law */
2358 /* compBitWidth, compShift */
2359 proto_tree_add_item(bfwcompparam_tree, hf_oran_compBitWidth,
2360 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2361 proto_tree_add_item(bfwcompparam_tree, hf_oran_compShift,
2362 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2363 offset++;
2364 break;
2365 case 4: /* beamspace I (BLOCK SCALING) */
2366 /* activeBeamspaceCoefficientMask */
2367 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2368 *bfw_comp_method = COMP_BLOCK_SCALE2;
2369 *supported = false0; /* TODO: true once BLOCK SCALE is supported */
2370 proto_tree_add_item(bfwcompparam_tree, hf_oran_blockScaler,
2371 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2372 offset++;
2373 break;
2374 case 5: /* beamspace II (BLOCK FLOATING POINT) */
2375 /* activeBeamspaceCoefficientMask */
2376 offset = dissect_active_beamspace_coefficient_mask(tvb, bfwcompparam_tree, offset, num_trx_entries, trx_entries);
2377 /* reserved (4 bits) + exponent (4 bits) */
2378 add_reserved_field(bfwcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
2379 proto_tree_add_item_ret_uint(bfwcompparam_tree, hf_oran_exponent, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, exponent);
2380 offset += 1;
2381 *bfw_comp_method = COMP_BLOCK_FP1;
2382 *supported = true1;
2383 break;
2384
2385 default:
2386 /* Not handled */
2387 break;
2388 }
2389
2390 proto_item_set_end(bfwcompparam_ti, tvb, offset);
2391
2392 /* Can't go on if compression scheme not supported */
2393 if (!(*supported) && meth_ti) {
2394 expert_add_info_format(pinfo, meth_ti, &ei_oran_unsupported_bfw_compression_method,
2395 "BFW Compression method %u (%s) not decompressed by dissector",
2396 *bfw_comp_method,
2397 val_to_str_const(*bfw_comp_method, bfw_comp_headers_comp_meth, "reserved"));
2398 }
2399 return offset;
2400}
2401
2402
2403/* Special case for uncompressed/16-bit value */
2404static float uncompressed_to_float(uint32_t h)
2405{
2406 int16_t i16 = h & 0x0000ffff;
2407 if (show_unscaled_values) {
2408 return (float)i16;
2409 }
2410 return ((float)i16) / 0x7fff;
2411}
2412
2413/* Decompress I/Q value, taking into account method, width, exponent, other input-specific methods */
2414static float decompress_value(uint32_t bits, uint32_t comp_method, uint8_t iq_width,
2415 uint32_t exponent,
2416 /* Modulation compression settings. N.B. should also pass in PRB + symbol? */
2417 section_mod_compr_config_t *m_c_p, uint8_t re)
2418{
2419 switch (comp_method) {
2420 case COMP_NONE0: /* no compression */
2421 return uncompressed_to_float(bits);
2422
2423 case COMP_BLOCK_FP1: /* block floating point */
2424 case BFP_AND_SELECTIVE_RE5:
2425 {
2426 /* A.1.3 Block Floating Point Decompression Algorithm */
2427 int32_t cPRB = bits;
2428 uint32_t scaler = 1 << exponent; /* i.e. 2^exponent */
2429
2430 /* Check last bit, in case we need to flip to -ve */
2431 if (cPRB >= (1<<(iq_width-1))) {
2432 cPRB -= (1<<iq_width);
2433 }
2434
2435 /* Unscale (8.1.3.1) */
2436 cPRB *= scaler;
2437 if (show_unscaled_values) {
2438 return (float)cPRB;
2439 }
2440
2441 uint32_t mantissa_scale_factor = 1 << (iq_width-1); /* 2^(mantissabits-1) */
2442 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 */
2443
2444 float ret = cPRB / ((float)(mantissa_scale_factor*exp_scale_factor));
2445 return ret;
2446 }
2447
2448 case COMP_BLOCK_SCALE2:
2449 case COMP_U_LAW3:
2450 /* Not supported! But will be reported as expert info outside of this function! */
2451 return 0.0;
2452
2453 case COMP_MODULATION4:
2454 case MOD_COMPR_AND_SELECTIVE_RE6:
2455 {
2456 /* Described in A.5 (with pseudo code) */
2457 /* N.B., Applies to downlink data only - is not used for BFW */
2458
2459 /* Defaults if not overridden. TODO: what should these be? */
2460 bool_Bool csf = false0;
2461 float mcScaler = (float)(1 << 11);
2462
2463 /* Find csf + mcScaler to use. Non-default configs gleaned from SE 4,5,23 */
2464 /* TODO: should ideally be filtering by symbol and PRB too (as configured from SE23) */
2465 if (re > 0 && m_c_p && m_c_p->num_configs > 0) {
2466 for (unsigned c=0; c<m_c_p->num_configs; c++) {
2467 if (m_c_p->configs[c].mod_compr_re_mask & (1 << (12-re))) {
2468 /* Return first (should be only) found */
2469 csf = m_c_p->configs[c].mod_compr_csf;
2470 mcScaler = m_c_p->configs[c].mod_compr_scaler;
2471 break;
2472 }
2473 }
2474 }
2475
2476 int32_t cPRB = bits;
2477
2478 /* 2) Map iqSample to iqSampleFx */
2479 /* Check last bit, in case we need to flip to -ve */
2480 if (cPRB >= (1<<(iq_width-1))) {
2481 cPRB -= (1<<iq_width);
2482 }
2483 float iqSampleFx = (float)cPRB / (1 << (iq_width-1));
2484
2485
2486 /* 3) or 4) (b) - add unshifted value if csf set */
2487 float csf_to_add = 0.0;
2488 if (csf) {
2489 /* Unshift the constellation point */
2490 csf_to_add = (float)1.0 / (1 << (iq_width));
2491 }
2492 iqSampleFx += csf_to_add;
2493
2494 /* 3) or 4) (c) - unscaling */
2495 float iqSampleScaled = mcScaler * iqSampleFx * (float)sqrt(2);
2496 return iqSampleScaled;
2497 }
2498
2499 default:
2500 /* Not supported! But will be reported as expert info outside of this function! */
2501 return 0.0;
2502 }
2503}
2504
2505/* Out-of-range value used for special case */
2506#define ORPHAN_BUNDLE_NUMBER999 999
2507
2508/* Bundle of PRBs/TRX I/Q samples (ext 11) */
2509static uint32_t dissect_bfw_bundle(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset,
2510 proto_item *comp_meth_ti, uint32_t bfwcomphdr_comp_meth,
2511 section_mod_compr_config_t *mod_compr_params,
2512 uint32_t num_weights_per_bundle,
2513 uint8_t iq_width,
2514 unsigned bundle_number,
2515 unsigned first_prb, unsigned last_prb, bool_Bool is_orphan,
2516 uint32_t symbol_count,
2517 section_details_t *section_details,
2518 oran_tap_info *tap_info)
2519{
2520 /* Set bundle name */
2521 char bundle_name[32];
2522 if (!is_orphan) {
2523 snprintf(bundle_name, 32, "Bundle %3u", bundle_number);
2524 }
2525 else {
2526 (void) g_strlcpy(bundle_name, "Orphaned ", 32);
2527 }
2528
2529 /* Create Bundle root */
2530 proto_item *bundle_ti;
2531 if (first_prb != last_prb) {
2532 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2533 tvb, offset, 0, "",
2534 "%s: (PRBs %3u-%3u)",
2535 bundle_name,
2536 first_prb, last_prb);
2537 }
2538 else {
2539 bundle_ti = proto_tree_add_string_format(tree, hf_oran_bfw_bundle,
2540 tvb, offset, 0, "",
2541 "%s: (PRB %3u)",
2542 bundle_name,
2543 first_prb);
2544 }
2545 proto_tree *bundle_tree = proto_item_add_subtree(bundle_ti, ett_oran_bfw_bundle);
2546
2547 /* Generated bundle id */
2548 proto_item *bundleid_ti = proto_tree_add_uint(bundle_tree, hf_oran_bfw_bundle_id, tvb, 0, 0,
2549 bundle_number);
2550 proto_item_set_generated(bundleid_ti);
2551 proto_item_set_hidden(bundleid_ti);
2552
2553 /* bfwCompParam */
2554 bool_Bool compression_method_supported = false0;
2555 unsigned exponent = 0;
2556 unsigned num_trx_entries = 0;
2557 uint16_t *trx_entries;
2558 offset = dissect_bfwCompParam(tvb, bundle_tree, pinfo, offset, comp_meth_ti,
2559 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
2560 &num_trx_entries, &trx_entries);
2561
2562 /* Create Bundle subtree */
2563 int bit_offset = offset*8;
2564 int bfw_offset;
2565
2566 /* contInd */
2567 proto_tree_add_item(bundle_tree, hf_oran_cont_ind,
2568 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2569 /* beamId */
2570 uint32_t beam_id;
2571 proto_tree_add_item_ret_uint(bundle_tree, hf_oran_beam_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
2572 proto_item_append_text(bundle_ti, " (beamId:%u) ", beam_id);
2573 bit_offset += 16;
2574 add_beam_id_to_tap(tap_info, beam_id);
2575
2576 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2577 if (section_details) {
2578 for (unsigned prb = first_prb; prb <= last_prb; prb++) {
2579 if (prb < 273) {
2580 section_details->beamIds[prb] = beam_id;
2581 }
2582 }
2583 }
2584 }
2585
2586 /* On first pass, record that beamId was defined here */
2587 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2588 bfw_definition *definition = wmem_new0(wmem_file_scope(), bfw_definition)((bfw_definition*)wmem_alloc0((wmem_file_scope()), sizeof(bfw_definition
)))
;
2589 definition->frame_defined = pinfo->num;
2590 definition->symbol_when_defined = symbol_count;
2591 wmem_tree_insert32(dl_beam_ids_defined, beam_id, definition);
2592 }
2593
2594
2595 /* Number of weights per bundle (from preference) */
2596 proto_item *wpb_ti = proto_tree_add_uint(bundle_tree, hf_oran_num_weights_per_bundle, tvb, 0, 0,
2597 num_weights_per_bundle);
2598 proto_item_set_generated(wpb_ti);
2599
2600 /* Add the weights for this bundle. Overwrite with what was seen in bfwCompParam if beamspace */
2601 if (num_trx_entries != 0) {
2602 num_weights_per_bundle = num_trx_entries;
2603 }
2604
2605 bool_Bool non_zero_weights_seen = false0;
2606 int bit_offset_before_weights = bit_offset;
2607 for (unsigned w=0; w < num_weights_per_bundle; w++) {
2608
2609 uint16_t trx_index = (num_trx_entries) ? trx_entries[w] : w+1;
2610
2611 /* Create subtree */
2612 bfw_offset = bit_offset / 8;
2613 uint8_t bfw_extent = ((bit_offset + (iq_width*2)) / 8) - bfw_offset;
2614 proto_item *bfw_ti = proto_tree_add_string_format(bundle_tree, hf_oran_bfw,
2615 tvb, bfw_offset, bfw_extent,
2616 "", "TRX %3u: (", trx_index);
2617 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
2618
2619 /* I */
2620 /* Get bits, and convert to float. */
2621 uint32_t bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2622 if (bits) {
2623 non_zero_weights_seen = true1;
2624 }
2625 float value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2626 exponent, mod_compr_params, 0 /* RE */);
2627 /* Add to tree. */
2628 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);
2629 bit_offset += iq_width;
2630 proto_item_append_text(bfw_ti, "I%u=%f ", w, value);
2631
2632 /* Q */
2633 /* Get bits, and convert to float. */
2634 bits = tvb_get_bits32(tvb, bit_offset, iq_width, ENC_BIG_ENDIAN0x00000000);
2635 if (bits) {
2636 non_zero_weights_seen = true1;
2637 }
2638
2639 value = decompress_value(bits, bfwcomphdr_comp_meth, iq_width,
2640 exponent, mod_compr_params, 0 /* RE */);
2641 /* Add to tree. */
2642 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);
2643 bit_offset += iq_width;
2644 proto_item_append_text(bfw_ti, "Q%u=%f)", w, value);
2645 }
2646
2647 if (!non_zero_weights_seen) {
2648 proto_tree_add_item(bundle_tree, hf_oran_bundle_weights_all_zero, tvb,
2649 bit_offset_before_weights, (bit_offset+7)/8 - (bit_offset_before_weights/8), ENC_NA0x00000000);
2650 }
2651
2652 /* Set extent of bundle */
2653 proto_item_set_end(bundle_ti, tvb, (bit_offset+7)/8);
2654
2655 return (bit_offset+7)/8;
2656}
2657
2658/* Return new bit offset. in/out will always be byte-aligned.. */
2659static int dissect_ciCompParam(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U___attribute__((unused)), unsigned bit_offset,
2660 unsigned comp_meth, uint8_t *exponent)
2661{
2662 if (comp_meth == COMP_NONE0) {
2663 /* Nothing in frame so don't even create subtree */
2664 return bit_offset;
2665 }
2666
2667 /* Subtree */
2668 proto_item *cicompparam_ti = proto_tree_add_string_format(tree, hf_oran_ciCompParam,
2669 tvb, bit_offset/8, 1, "",
2670 "ciCompParam");
2671 proto_tree *cicompparam_tree = proto_item_add_subtree(cicompparam_ti, ett_oran_cicompparam);
2672 uint32_t ci_exponent;
2673
2674 /* Contents differ by compression method */
2675 switch (comp_meth) {
2676 case COMP_BLOCK_FP1:
2677 add_reserved_field(cicompparam_tree, hf_oran_reserved_4bits, tvb, bit_offset/8, 1);
2678 proto_tree_add_item_ret_uint(cicompparam_tree, hf_oran_exponent,
2679 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000, &ci_exponent);
2680 *exponent = ci_exponent;
2681 proto_item_append_text(cicompparam_ti, " (Exponent=%u)", ci_exponent);
2682 bit_offset += 8; /* one byte */
2683 break;
2684 case COMP_BLOCK_SCALE2:
2685 /* Separate into integer (1) and fractional (7) bits? */
2686 proto_tree_add_item(cicompparam_tree, hf_oran_blockScaler,
2687 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2688 bit_offset += 8;
2689 break;
2690 case COMP_U_LAW3:
2691 /* compBitWidth, compShift (4 bits each) */
2692 proto_tree_add_item(cicompparam_tree, hf_oran_compBitWidth,
2693 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2694 proto_tree_add_item(cicompparam_tree, hf_oran_compShift,
2695 tvb, bit_offset/8, 1, ENC_BIG_ENDIAN0x00000000);
2696 bit_offset += 8;
2697 break;
2698
2699 default:
2700 /* reserved, ? bytes of zeros.. */
2701 break;
2702 }
2703
2704 return bit_offset;
2705}
2706
2707/* frameStructure (7.5.2.13) */
2708static unsigned dissect_frame_structure(proto_item *tree, tvbuff_t *tvb, unsigned offset,
2709 uint32_t subframeId, uint32_t slotId)
2710{
2711 uint32_t scs;
2712 /* FFT Size (4 bits) */
2713 proto_tree_add_item(tree, hf_oran_frameStructure_fft, tvb, offset, 1, ENC_NA0x00000000);
2714 /* Subcarrier spacing (SCS) */
2715 proto_tree_add_item_ret_uint(tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
2716
2717 /* Show slot within frame as a generated field. See table 7.5.13-3 */
2718 uint32_t slots_per_subframe = 1;
2719 if (scs <= 4) {
2720 slots_per_subframe = 1 << scs;
2721 }
2722 if (scs <= 4 || scs >= 12) {
2723 proto_item *ti = proto_tree_add_uint(tree, hf_oran_slot_within_frame, tvb, 0, 0,
2724 (slots_per_subframe*subframeId) + slotId);
2725 proto_item_set_generated(ti);
2726 }
2727 return offset + 1;
2728}
2729
2730static unsigned dissect_csf(proto_item *tree, tvbuff_t *tvb, unsigned bit_offset,
2731 unsigned iq_width, bool_Bool *p_csf)
2732{
2733 proto_item *csf_ti;
2734 uint64_t csf;
2735 csf_ti = proto_tree_add_bits_ret_val(tree, hf_oran_csf, tvb, bit_offset, 1, &csf, ENC_BIG_ENDIAN0x00000000);
2736 if (csf) {
2737 /* Table 7.7.4.2-1 Constellation shift definition (index is udIqWidth) */
2738 const char* shift_value[] = { "n/a", "1/2", "1/4", "1/8", "1/16", "1/32" };
2739 if (iq_width >=1 && iq_width <= 5) {
2740 proto_item_append_text(csf_ti, " (Shift Value is %s)", shift_value[iq_width]);
2741 }
2742 }
2743
2744 /* Set out parameter */
2745 if (p_csf != NULL((void*)0)) {
2746 *p_csf = (csf!=0);
2747 }
2748 return bit_offset+1;
2749}
2750
2751
2752/* Section 7.
2753 * N.B. these are the green parts of the tables showing Section Types, differing by section Type */
2754static int dissect_oran_c_section(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
2755 flow_state_t* state,
2756 uint32_t sectionType, oran_tap_info *tap_info, proto_item *protocol_item,
2757 uint32_t subframeId, uint32_t frameId, uint32_t slotId, uint32_t startSymbolId,
2758 uint8_t ci_iq_width, uint8_t ci_comp_meth, unsigned ci_comp_opt,
2759 unsigned num_sinr_per_prb)
2760{
2761 unsigned offset = 0;
2762 proto_tree *c_section_tree = NULL((void*)0);
2763 proto_item *sectionHeading = NULL((void*)0);
2764
2765 /* Section subtree */
2766 sectionHeading = proto_tree_add_string_format(tree, hf_oran_c_section,
2767 tvb, offset, 0, "", "Section");
2768 c_section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section);
2769
2770 uint32_t sectionId = 0;
2771
2772 uint32_t startPrbc=0, startPrbu=0;
2773 uint32_t numPrbc=0, numPrbu=0;
2774 uint32_t ueId = 0;
2775 proto_item *ueId_ti = NULL((void*)0);
2776 uint32_t section_beamId = 0;
2777 proto_item *section_beamId_ti = NULL((void*)0);
2778 bool_Bool section_beamId_ignored = false0;
2779
2780 proto_item *numsymbol_ti = NULL((void*)0);
2781 bool_Bool numsymbol_ignored = false0;
2782
2783 proto_item *numprbc_ti = NULL((void*)0);
2784
2785 /* Config affecting ext11 bundles (initially unset) */
2786 ext11_settings_t ext11_settings;
2787 memset(&ext11_settings, 0, sizeof(ext11_settings));
2788
2789 /* Section Type 10 needs to keep track of PRB range that should be reported
2790 for msgTypeId=5 (Interference plus Noise for unallocated PRBs) */
2791 /* All PRBs start as false */
2792#define MAX_PRBS273 273
2793 bool_Bool prbs_for_st10_type5[MAX_PRBS273];
2794 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
2795
2796 /* These UEIds are set by ST5, ST10 (single value), and extended by SE10 */
2797#define MAX_UEIDS16 16
2798 uint32_t ueids[MAX_UEIDS16];
2799 uint32_t number_of_ueids = 0;
2800
2801
2802 bool_Bool extension_flag = false0;
2803
2804 /* These sections (ST0, ST1, ST2, ST3, ST5, ST9, ST10, ST11) are similar, so handle as common with per-type differences */
2805 if (((sectionType <= SEC_C_UE_SCHED) || (sectionType >= SEC_C_SINR_REPORTING)) &&
2806 (sectionType != SEC_C_SLOT_CONTROL)) {
2807
2808 /* sectionID */
2809 proto_item *ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
2810 if (sectionId == 4095) {
2811 proto_item_append_text(ti, " (not default coupling C/U planes using sectionId)");
2812 }
2813 offset++;
2814
2815 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
2816 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
2817 }
2818
2819 /* rb */
2820 uint32_t rb;
2821 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
2822 /* symInc (1 bit) */
2823 /* TODO: mark as ignored if SE6, SE12 or SE19 present */
2824 if (sectionType != SEC_C_RRM_MEAS_REPORTS && /* Section Type 10 */
2825 sectionType != SEC_C_REQUEST_RRM_MEAS) { /* Section Type 11 */
2826 unsigned int sym_inc;
2827 proto_item *sym_inc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &sym_inc);
2828 if (sym_inc !=0 && (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
2829 /* "0 shall be used" */
2830 proto_item_append_text(sym_inc_ti, " (should be 0)");
2831 }
2832 }
2833 else {
2834 /* reserved (1 bit) */
2835 add_reserved_field(c_section_tree, hf_oran_reserved_bit5, tvb, offset, 1);
2836 }
2837
2838 /* startPrbx and numPrbx */
2839 if (sectionType == SEC_C_SINR_REPORTING) {
2840 /* startPrbu (10 bits) */
2841 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
2842 offset += 2;
2843
2844 /* numPrbu */
2845 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
2846 if (numPrbu == 0) {
2847 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2848 numPrbu = pref_data_plane_section_total_rbs;
2849 }
2850 offset += 1;
2851 }
2852 else {
2853 /* startPrbc (10 bits) */
2854 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
2855 offset += 2;
2856
2857 /* numPrbc */
2858 numprbc_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
2859 if (numPrbc == 0) {
2860 proto_item_append_text(numprbc_ti, " (all PRBs - configured as %u)", pref_data_plane_section_total_rbs);
2861 /* TODO: should probably set to pref_data_plane_section_total_rbs, and define MAX_PRBS to > 273 ? */
2862 numPrbc = MAX_PRBS273;
2863 }
2864 offset += 1;
2865 }
2866
2867 /* Start with range from section. May get changed by SE6, SE12, SE20 */
2868 for (unsigned n=startPrbc; n < startPrbc+numPrbc; n++) {
2869 if (n < MAX_PRBS273) {
2870 prbs_for_st10_type5[n] = true1;
2871 }
2872 }
2873
2874 if (sectionType != SEC_C_SINR_REPORTING) { /* *NOT* Section Type 9 */
2875 static int * const remask_flags[] = {
2876 &hf_oran_reMask_re1,
2877 &hf_oran_reMask_re2,
2878 &hf_oran_reMask_re3,
2879 &hf_oran_reMask_re4,
2880 &hf_oran_reMask_re5,
2881 &hf_oran_reMask_re6,
2882 &hf_oran_reMask_re7,
2883 &hf_oran_reMask_re8,
2884 &hf_oran_reMask_re9,
2885 &hf_oran_reMask_re10,
2886 &hf_oran_reMask_re11,
2887 &hf_oran_reMask_re12,
2888 NULL((void*)0)
2889 };
2890
2891 /* reMask */
2892 uint64_t remask;
2893 proto_tree_add_bitmask_ret_uint64(c_section_tree, tvb, offset,
2894 hf_oran_reMask, ett_oran_remask, remask_flags, ENC_BIG_ENDIAN0x00000000, &remask);
2895 offset++;
2896 /* numSymbol */
2897 uint32_t numSymbol;
2898 numsymbol_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numSymbol, tvb, offset, 1, ENC_NA0x00000000, &numSymbol);
2899 if ((sectionType == SEC_C_RRM_MEAS_REPORTS) && (numSymbol != 14)) { /* Section type 10 must have 14 symbols */
2900 proto_item_append_text(numsymbol_ti, " (for ST10, should be 14!)");
2901 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_st10_numsymbol_not_14,
2902 "numSymbol should be 14 for ST10 - found %u", numSymbol);
2903 }
2904 if ((startSymbolId + numSymbol) > 14) {
2905 /* Warn if startSymbol + numSymbol would be > 14 */
2906 expert_add_info_format(pinfo, numsymbol_ti, &ei_oran_too_many_symbols,
2907 "startSymbolId (%u) + numSymbol (%u) exceeds max of 14",
2908 startSymbolId, numSymbol);
2909 }
2910 offset++;
2911
2912 /* [ef] (extension flag) */
2913 switch (sectionType) {
2914 case SEC_C_UNUSED_RB: /* Section Type 0 */
2915 case SEC_C_NORMAL: /* Section Type 1 */
2916 case SEC_C_PRACH: /* Section Type 3 */
2917 case SEC_C_UE_SCHED: /* Section Type 5 */
2918 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
2919 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
2920 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
2921 break;
2922 default:
2923 /* Other section types don't support extensions */
2924 break;
2925 }
2926
2927 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbc, numPrbc, rb);
2928 proto_item_append_text(sectionHeading, ", Symbols: %2u", numSymbol);
2929
2930 if (numPrbc == 0) {
2931 /* Special case for all PRBs */
2932 numPrbc = pref_data_plane_section_total_rbs;
2933 startPrbc = 0; /* may already be 0... */
2934 }
2935 }
2936 else {
2937 /* Section Type 9 */
2938 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
2939 proto_item_append_text(sectionHeading, ", numSinrPerPrb: %2u", num_sinr_per_prb);
2940 }
2941
2942 /* Section type specific fields (after 'numSymbol') */
2943 switch (sectionType) {
2944 case SEC_C_UNUSED_RB: /* Section Type 0 - Table 7.4.2-1 */
2945 /* reserved (15 bits) */
2946 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
2947 offset += 2;
2948 break;
2949
2950 case SEC_C_NORMAL: /* Section Type 1 - Table 7.4.3-1 */
2951 /* beamId */
2952 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2953 offset += 2;
2954
2955 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2956 proto_item_append_text(sectionHeading, ", BeamId: %d", section_beamId);
2957 break;
2958
2959 case SEC_C_PRACH: /* Section Type 3 - Table 7.4.5-1 */
2960 {
2961 /* beamId */
2962 section_beamId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &section_beamId);
2963 offset += 2;
2964
2965 /* freqOffset */
2966 int32_t freqOffset; /* Yes, this is signed, so the cast is intentional. */
2967 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);
2968 freqOffset |= 0xff000000; /* Must sign-extend */
2969 proto_item_set_text(freq_offset_item, "Frequency offset: %d \u0394f", freqOffset);
2970 offset += 3;
2971
2972 /* reserved (8 bits) */
2973 add_reserved_field(c_section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
2974 offset += 1;
2975
2976 /* beamId might get invalidated by e.g., ext-6, ext-11, so unused value will still be shown here.. */
2977 proto_item_append_text(sectionHeading, ", BeamId: %d, FreqOffset: %d \u0394f", section_beamId, freqOffset);
2978 break;
2979 }
2980
2981 case SEC_C_UE_SCHED: /* Section Type 5 - Table 7.4.7-1 */
2982 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 - Table 7.4.12-1 */
2983 /* ueId */
2984 ueId_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
2985 offset += 2;
2986 if (ueId == 0x7fff) {
2987 proto_item_append_text(ueId_ti, " (PRBs not scheduled for eAxC ID in transport header)");
2988 }
2989 else {
2990 ueids[number_of_ueids++] = ueId;
2991 }
2992
2993 proto_item_append_text(sectionHeading, ", UEId: %d", ueId);
2994 break;
2995
2996 case SEC_C_SINR_REPORTING: /* Section Type 9 - SINR Reporting */
2997 {
2998 /* Hidden filter for bf (DMFS-BF) */
2999 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3000 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3001
3002 unsigned bit_offset = offset*8;
3003
3004 /* sinr iqWidth */
3005 proto_item *iq_width_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrIqWidth_pref, tvb, 0, 0, pref_sample_bit_width_sinr);
3006 proto_item_append_text(iq_width_item, " (from preferences)");
3007 proto_item_set_generated(iq_width_item);
3008
3009 /* sinr compMethod */
3010 proto_item *sinr_comp_meth_item = proto_tree_add_uint(c_section_tree, hf_oran_sinrCompHdrMeth_pref, tvb, 0, 0, pref_iqCompressionSINR);
3011 proto_item_append_text(sinr_comp_meth_item, " (from preferences)");
3012 proto_item_set_generated(sinr_comp_meth_item);
3013
3014 /* Add SINR entries for each PRB */
3015 for (unsigned prb=startPrbu; prb < startPrbu+numPrbu; prb++) {
3016 /* Create a subtree for each PRB */
3017 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_sinr_prb,
3018 tvb, offset, 0, "", "PRB %3u (", prb);
3019 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_sinr_prb);
3020
3021 /* Each prb starts byte-aligned */
3022 bit_offset = ((bit_offset+7)/8) * 8;
3023
3024 /* N.B., using width/method from UL U-plane preferences, not certain that this is correct.. */
3025
3026 /* sinrCompParam (udCompParam format, may be empty) */
3027 uint32_t exponent = 0; /* N.B. init to silence warnings, but will always be set if read in COMP_BLOCK_FP case */
3028 uint16_t sReSMask;
3029 bit_offset = dissect_udcompparam(tvb, pinfo, prb_tree, bit_offset/8,
3030 pref_iqCompressionSINR, &exponent, &sReSMask,
3031 true1) * 8; /* last param is for_sinr */
3032
3033 /* sinrValues for this PRB. */
3034 /* TODO: not sure how numSinrPerPrb interacts with rb==1... */
3035 for (unsigned n=0; n < num_sinr_per_prb; n++) {
3036 unsigned sinr_bits = tvb_get_bits32(tvb, bit_offset, pref_sample_bit_width_sinr, ENC_BIG_ENDIAN0x00000000);
3037
3038 /* Using SINR compression settings from preferences */
3039 float value = decompress_value(sinr_bits,
3040 pref_iqCompressionSINR, pref_sample_bit_width_sinr,
3041 exponent,
3042 NULL((void*)0) /* no ModCompr for SINR */, 0 /* RE */);
3043 unsigned sample_len_in_bytes = ((bit_offset%8)+pref_sample_bit_width_sinr+7)/8;
3044 proto_item *val_ti = proto_tree_add_float(prb_tree, hf_oran_sinr_value, tvb,
3045 bit_offset/8, sample_len_in_bytes, value);
3046 proto_item_append_text(prb_ti, " %8f", value);
3047
3048 /* Show here which subcarriers share which values (they all divide 12..) */
3049 if (num_sinr_per_prb == 12) {
3050 proto_item_append_text(val_ti, " (PRB=%u, subcarrier %u)",
3051 startPrbu+((prb-startPrbu)*(rb+1)), n*(12/num_sinr_per_prb));
3052 }
3053 else {
3054 proto_item_append_text(val_ti, " (PRB=%u, subcarriers %u-%u)",
3055 startPrbu+((prb-startPrbu)*(rb+1)),
3056 n*(12/num_sinr_per_prb), (n+1)*(12/num_sinr_per_prb)-1);
3057 }
3058 bit_offset += pref_sample_bit_width_sinr;
3059 }
3060
3061 /* 1-byte alignment per PRB (7.2.11) */
3062 offset = (bit_offset+7)/8;
3063 bit_offset = offset*8;
3064
3065 proto_item_append_text(prb_ti, ")");
3066 proto_item_set_end(prb_ti, tvb, offset);
3067 }
3068 break;
3069 }
3070 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 - Request RRM Measurements */
3071 /* Reserved (15 bits) */
3072 add_reserved_field(c_section_tree, hf_oran_reserved_15bits, tvb, offset, 2);
3073 offset += 2;
3074 break;
3075
3076 default:
3077 break;
3078 }
3079 }
3080 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
3081 /* ef */
3082 proto_tree_add_item_ret_boolean(c_section_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3083 /* ueId */
3084 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueId);
3085 offset += 2;
3086 /* regularizationFactor */
3087 proto_tree_add_item(c_section_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3088 offset += 2;
3089 /* reserved (4 bits) */
3090 add_reserved_field(c_section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
3091 /* rb ("Value=0 shall be set") */
3092 uint32_t rb;
3093 proto_item *rb_ti = proto_tree_add_item_ret_uint(c_section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
3094 if (rb != 0) {
3095 proto_item_append_text(rb_ti, " (should be set to 0)");
3096 expert_add_info(pinfo, rb_ti, &ei_oran_st6_rb_shall_be_0);
3097 }
3098 /* symInc */
3099 proto_tree_add_item(c_section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000);
3100 /* startPrbc */
3101 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_startPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbc);
3102 offset += 2;
3103 /* numPrbc */
3104 proto_tree_add_item_ret_uint(c_section_tree, hf_oran_numPrbc, tvb, offset, 1, ENC_NA0x00000000, &numPrbc);
3105 offset += 1;
3106
3107 /* Hidden filter for bf */
3108 proto_item *bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3109 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3110
3111 /* ciIsample,ciQsample pairs */
3112 unsigned m;
3113 unsigned prb;
3114 uint32_t bit_offset = offset*8;
3115
3116 /* Antenna count from preference */
3117 unsigned num_trx = pref_num_bf_antennas;
3118
3119 write_channel_section_info(sectionHeading, pinfo,
3120 sectionId, ueId, startPrbc, numPrbc, num_trx);
3121
3122 bool_Bool first_prb = true1;
3123 uint8_t exponent = 0;
3124 for (prb=startPrbc; prb < startPrbc+numPrbc; prb++) {
3125
3126 /* PRB subtree */
3127 unsigned prb_start_offset = bit_offset;
3128 proto_item *prb_ti = proto_tree_add_string_format(c_section_tree, hf_oran_samples_prb,
3129 tvb, bit_offset/8, 0,
3130 "", "PRB=%u", prb);
3131 proto_tree *prb_tree = proto_item_add_subtree(prb_ti, ett_oran_prb_cisamples);
3132
3133 /* There may be a ciCompParam here.. */
3134 if (first_prb || ci_comp_opt==1) {
3135 bit_offset = dissect_ciCompParam(tvb, prb_tree, pinfo, bit_offset, ci_comp_meth, &exponent);
3136 }
3137 first_prb = false0;
3138
3139 /* Antennas */
3140 for (m=0; m < num_trx; m++) {
3141
3142 unsigned sample_offset = bit_offset / 8;
3143 uint8_t sample_extent = ((bit_offset + (ci_iq_width*2)) / 8) - sample_offset;
3144
3145 /* Create subtree for antenna */
3146 proto_item *sample_ti = proto_tree_add_string_format(prb_tree, hf_oran_ciSample,
3147 tvb, sample_offset, sample_extent,
3148 "", "TRX=%2u: ", m);
3149 proto_tree *sample_tree = proto_item_add_subtree(sample_ti, ett_oran_cisample);
3150
3151 /* I */
3152 /* Get bits, and convert to float. */
3153 uint32_t bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3154 float value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3155
3156 /* Add to tree. */
3157 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);
3158 bit_offset += ci_iq_width;
3159 proto_item_append_text(sample_ti, "I%u=%f ", m, value);
3160
3161 /* Q */
3162 /* Get bits, and convert to float. */
3163 bits = tvb_get_bits32(tvb, bit_offset, ci_iq_width, ENC_BIG_ENDIAN0x00000000);
3164 value = decompress_value(bits, ci_comp_meth, ci_iq_width, exponent, NULL((void*)0) /* no ModCompr for ST6 */, 0 /* RE */);
3165
3166 /* Add to tree. */
3167 proto_tree_add_float_format_value(sample_tree, hf_oran_ciQsample, tvb, bit_offset/8, (ci_iq_width+7)/8, value, "#%u=%f", m, value);
3168 bit_offset += ci_iq_width;
3169 proto_item_append_text(sample_ti, "Q%u=%f ", m, value);
3170 }
3171 proto_item_set_len(prb_ti, (bit_offset-prb_start_offset+7)/8);
3172 }
3173
3174 /* Pad out by 1 or 4 bytes, according to preference */
3175 if (!st6_4byte_alignment) {
3176 offset = (bit_offset + 7) / 8;
3177 }
3178 else {
3179 int mode = bit_offset % 32;
3180 if (mode != 0) {
3181 offset = (bit_offset + (32-mode))/8;
3182 }
3183 else {
3184 offset = bit_offset/8;
3185 }
3186 }
3187 proto_item_set_end(c_section_tree, tvb, offset);
3188 }
3189
3190
3191 expected_section_data_t *data_section = NULL((void*)0);
3192 unsigned index_to_use = 0;
3193
3194 /* On first pass, allocate a section entry to use */
3195 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3196
3197 /* Look for existing entry for sectionId to overwrite first. */
3198 uint8_t direction = !tap_info->uplink;
3199 data_section = wmem_tree_lookup32(state->expected_sections[direction],
3200 sectionId);
3201 if (data_section == NULL((void*)0)) {
3202 /* None, so create */
3203 data_section = wmem_new0(wmem_file_scope(), expected_section_data_t)((expected_section_data_t*)wmem_alloc0((wmem_file_scope()), sizeof
(expected_section_data_t)))
;
3204 wmem_tree_insert32(state->expected_sections[direction],
3205 sectionId,
3206 data_section);
3207 }
3208
3209 /* If 2nd entry not in use, use that one */
3210 if (!data_section->details[1].in_use) {
3211 index_to_use = 1;
3212 }
3213 else {
3214 /* Both in use, so replace the older of the 2 entries */
3215 if (data_section->details[1].frame_number < data_section->details[0].frame_number) {
3216 index_to_use = 1;
3217 }
3218 }
3219
3220 if (data_section) {
3221 section_details_t *details = &data_section->details[index_to_use];
3222
3223 details->in_use = true1;
3224 details->frame = frameId;
3225 details->subframe = subframeId;
3226 details->slot = slotId;
3227 details->startSymbol = startSymbolId;
3228
3229 details->frame_number = pinfo->num;
3230 details->frame_time = pinfo->abs_ts;
3231 data_section->sectionId = sectionId;
3232 details->startPrb = startPrbc;
3233 details->numPrb = numPrbc;
3234 for (unsigned prb = startPrbc; prb <= startPrbc+numPrbc; prb++) {
3235 if (prb < 273) {
3236 details->beamIds[prb] = section_beamId;
3237 }
3238 }
3239 }
3240 }
3241
3242 bool_Bool seen_se10 = false0;
3243 uint32_t numPortc = 0;
3244 proto_item *bf_ti = NULL((void*)0);
3245
3246 /* Section extension commands */
3247 while (extension_flag) {
3248 int extension_start_offset = offset;
3249
3250 /* Prefetch extType so can use specific extension type ett */
3251 uint32_t exttype = tvb_get_uint8(tvb, offset) & 0x7f;
3252 uint32_t exttype_ett_index = exttype;
3253 if (exttype == 0 || exttype > HIGHEST_EXTTYPE32) {
3254 /* Just use first one if out of range */
3255 exttype_ett_index = 1;
3256 }
3257
3258 /* Create subtree for each extension (with summary) */
3259 proto_item *extension_ti = proto_tree_add_string_format(c_section_tree, hf_oran_extension,
3260 tvb, offset, 0, "", "Extension");
3261 proto_tree *extension_tree = proto_item_add_subtree(extension_ti, ett_oran_c_section_extension[exttype_ett_index-1]);
3262
3263 /* ef (i.e. another extension after this one?) */
3264 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_ef, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &extension_flag);
3265
3266 /* extType */
3267 proto_item *exttype_ti;
3268 exttype_ti = proto_tree_add_item(extension_tree, hf_oran_exttype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3269 offset++;
3270 proto_item_append_text(sectionHeading, " (ext-%u)", exttype);
3271
3272 proto_item_append_text(extension_ti, " (ext-%u: %s)", exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
3273
3274 /* Don't tap if out of range. */
3275 if (exttype > 0 && exttype <= HIGHEST_EXTTYPE32) {
3276 tap_info->extensions[exttype] = true1;
3277 }
3278
3279 /* Is this SE allowed for this section type? */
3280 if (!se_allowed_in_st(exttype, sectionType)) {
3281 expert_add_info_format(pinfo, extension_tree, &ei_oran_se_on_unsupported_st,
3282 "SE %u (%s) should not appear in ST %u (%s)!",
3283 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"),
3284 sectionType, rval_to_str_const(sectionType, section_types, "Unknown"));
3285 }
3286
3287
3288 /* extLen (number of 32-bit words) */
3289 uint32_t extlen_len = ((exttype==11)||(exttype==19)||(exttype==20)) ? 2 : 1; /* Extensions 11/19/20 are special */
3290 uint32_t extlen;
3291 proto_item *extlen_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_extlen, tvb,
3292 offset, extlen_len, ENC_BIG_ENDIAN0x00000000, &extlen);
3293 proto_item_append_text(extlen_ti, " (%u bytes)", extlen*4);
3294 offset += extlen_len;
3295 if (extlen == 0) {
3296 expert_add_info(pinfo, extlen_ti, &ei_oran_extlen_zero);
3297 /* Break out to avoid infinitely looping! */
3298 break;
3299 }
3300
3301 bool_Bool ext_unhandled = false0;
3302
3303 switch (exttype) {
3304
3305 case 1: /* SE 1: Beamforming Weights */
3306 {
3307 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
3308 proto_item *comp_meth_ti = NULL((void*)0);
3309
3310 /* Hidden filter for bf */
3311 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3312 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3313
3314 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
3315 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
3316 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
3317
3318 /* bfwCompParam */
3319 uint32_t exponent = 0;
3320 bool_Bool compression_method_supported = false0;
3321 unsigned num_trx = 0;
3322 uint16_t *trx; /* ptr to array */
3323 offset = dissect_bfwCompParam(tvb, extension_tree, pinfo, offset, comp_meth_ti,
3324 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
3325 &num_trx, &trx);
3326
3327 /* Can't show details of unsupported compression method */
3328 if (!compression_method_supported) {
3329 break;
3330 }
3331
3332 /* We know:
3333 - iq_width (above)
3334 - numBfWeights (taken from preference)
3335 - remaining bytes in extension
3336 We can therefore derive TRX (number of antennas).
3337 */
3338
3339 bool_Bool using_array = false0;
3340
3341 /* I & Q samples
3342 May know how many entries from activeBeamspaceCoefficientMask. */
3343 if (num_trx == 0) {
3344 /* Don't know how many there will be, so just fill available bytes... */
3345 unsigned weights_bytes = (extlen*4)-3;
3346 unsigned num_weights_pairs = (weights_bytes*8) / (bfwcomphdr_iq_width*2);
3347 num_trx = num_weights_pairs;
3348 }
3349 else {
3350 using_array = true1;
3351 num_trx = pref_num_bf_antennas;
3352 }
3353
3354 int bit_offset = offset*8;
3355
3356 for (unsigned n=0; n < num_trx; n++) {
3357 /* Create antenna subtree */
3358 int bfw_offset = bit_offset / 8;
3359
3360 uint16_t trx_index = (using_array) ? trx[n] : n+1;
3361
3362 proto_item *bfw_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfw,
3363 tvb, bfw_offset, 0, "", "TRX %3u: (", trx_index);
3364 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
3365
3366 /* I value */
3367 /* Get bits, and convert to float. */
3368 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3369 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3370 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3371 /* Add to tree. */
3372 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
3373 (bfwcomphdr_iq_width+7)/8, value);
3374 bit_offset += bfwcomphdr_iq_width;
3375 proto_item_append_text(bfw_ti, "I=%f ", value);
3376
3377 /* Leave a gap between I and Q values */
3378 proto_item_append_text(bfw_ti, " ");
3379
3380 /* Q value */
3381 /* Get bits, and convert to float. */
3382 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
3383 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent,
3384 NULL((void*)0) /* no ModCompr */, 0 /* RE */);
3385 /* Add to tree. */
3386 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
3387 (bfwcomphdr_iq_width+7)/8, value);
3388 bit_offset += bfwcomphdr_iq_width;
3389 proto_item_append_text(bfw_ti, "Q=%f", value);
3390
3391 proto_item_append_text(bfw_ti, ")");
3392 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
3393 }
3394 /* Need to round to next byte */
3395 offset = (bit_offset+7)/8;
3396
3397 break;
3398 }
3399
3400 case 2: /* SE 2: Beamforming attributes */
3401 {
3402 /* Hidden filter for bf */
3403 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3404 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3405
3406 /* bfaCompHdr (get widths of fields to follow) */
3407 uint32_t bfAzPtWidth, bfZePtWidth, bfAz3ddWidth, bfZe3ddWidth;
3408 /* subtree */
3409 proto_item *bfa_ti = proto_tree_add_string_format(extension_tree, hf_oran_bfaCompHdr,
3410 tvb, offset, 2, "", "bfaCompHdr");
3411 proto_tree *bfa_tree = proto_item_add_subtree(bfa_ti, ett_oran_bfacomphdr);
3412
3413 /* reserved (2 bits) */
3414 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3415 /* bfAzPtWidth (3 bits) */
3416 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAzPtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAzPtWidth);
3417 /* bfZePtWidth (3 bits) */
3418 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZePtWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZePtWidth);
3419 offset += 1;
3420
3421 /* reserved (2 bits) */
3422 add_reserved_field(bfa_tree, hf_oran_reserved_2bits, tvb, offset, 1);
3423 /* bfAz3ddWidth (3 bits) */
3424 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfAz3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfAz3ddWidth);
3425 /* bfZe3ddWidth (3 bits) */
3426 proto_tree_add_item_ret_uint(bfa_tree, hf_oran_bfZe3ddWidth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &bfZe3ddWidth);
3427 offset += 1;
3428
3429 unsigned bit_offset = offset*8;
3430
3431 /* bfAzPt */
3432 if (bfAzPtWidth > 0) {
3433 proto_tree_add_bits_item(extension_tree, hf_oran_bfAzPt, tvb, bit_offset, bfAzPtWidth+1, ENC_BIG_ENDIAN0x00000000);
3434 bit_offset += (bfAzPtWidth+1);
3435 }
3436 /* bfZePt */
3437 if (bfZePtWidth > 0) {
3438 proto_tree_add_bits_item(extension_tree, hf_oran_bfZePt, tvb, bit_offset, bfZePtWidth+1, ENC_BIG_ENDIAN0x00000000);
3439 bit_offset += (bfZePtWidth+1);
3440 }
3441 /* bfAz3dd */
3442 if (bfAz3ddWidth > 0) {
3443 proto_tree_add_bits_item(extension_tree, hf_oran_bfAz3dd, tvb, bit_offset, bfAz3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3444 bit_offset += (bfAz3ddWidth+1);
3445 }
3446 /* bfZe3dd */
3447 if (bfZe3ddWidth > 0) {
3448 proto_tree_add_bits_item(extension_tree, hf_oran_bfZe3dd, tvb, bit_offset, bfZe3ddWidth+1, ENC_BIG_ENDIAN0x00000000);
3449 bit_offset += (bfZe3ddWidth+1);
3450 }
3451
3452 /* Pad to next byte (unless last 2 fields already fit in this one) */
3453 if ((bit_offset % 8) > 2) {
3454 offset = (bit_offset+7) / 8;
3455 }
3456 else {
3457 offset = bit_offset / 8;
3458 }
3459
3460 /* bfAzSl (3 bits) */
3461 proto_tree_add_item(extension_tree, hf_oran_bfAzSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3462 /* bfZeSl (3 bits) */
3463 proto_tree_add_item(extension_tree, hf_oran_bfZeSl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3464 offset += 1;
3465 break;
3466 }
3467
3468 case 3: /* SE 3: DL precoding parameters */
3469 {
3470 /* codebookindex (8 bits) */
3471 /* "This parameter is not used and shall be set to zero." */
3472 proto_tree_add_item(extension_tree, hf_oran_codebook_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3473 offset += 1;
3474 /* layerid */
3475 uint32_t layerid;
3476 proto_tree_add_item_ret_uint(extension_tree, hf_oran_layerid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &layerid);
3477 /* numLayers */
3478 proto_tree_add_item(extension_tree, hf_oran_numlayers, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3479 offset += 1;
3480
3481 /* Stop here for non-first data layer */
3482 if (layerid != 0 && layerid != 0xf) {
3483 break;
3484 }
3485
3486 /* First data layer case */
3487 /* txScheme */
3488 proto_tree_add_item(extension_tree, hf_oran_txscheme, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3489 /* crsReMask */
3490 proto_tree_add_item(extension_tree, hf_oran_crs_remask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3491 offset += 2;
3492
3493 /* crsShift (1 bit) */
3494 proto_tree_add_item(extension_tree, hf_oran_crs_shift, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3495 /* reserved (3 bits) */
3496 add_reserved_field(extension_tree, hf_oran_reserved_bits123, tvb, offset, 1);
3497 /* crsSymNum (4 bits) */
3498 proto_tree_add_item(extension_tree, hf_oran_crs_symnum, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3499 offset += 1;
3500 /* reserved (8 bits) */
3501 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3502 offset += 1;
3503
3504 /* reserved (1 bit) */
3505 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3506 /* beamIdAP1 (15 bits) */
3507 proto_tree_add_item(extension_tree, hf_oran_beamid_ap1, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3508 offset += 2;
3509 /* reserved (1 bit) */
3510 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3511 /* beamIdAP2 (15 bits) */
3512 proto_tree_add_item(extension_tree, hf_oran_beamid_ap2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3513 offset += 2;
3514 /* reserved (1 bit) */
3515 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3516 /* beamIdAP3 (15 bits) */
3517 proto_tree_add_item(extension_tree, hf_oran_beamid_ap3, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3518 offset += 2;
3519 break;
3520 }
3521
3522 case 4: /* SE 4: Modulation compression params (5.4.7.4) (single sets) */
3523 {
3524 /* csf */
3525 bool_Bool csf;
3526 dissect_csf(extension_tree, tvb, offset*8, ci_iq_width, &csf);
3527
3528 /* modCompScaler */
3529 uint32_t modCompScaler;
3530 proto_item *ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_modcompscaler,
3531 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &modCompScaler);
3532 offset += 2;
3533
3534 /* Work out and show floating point value too. exponent and mantissa are both unsigned */
3535 uint16_t exponent = (modCompScaler >> 11) & 0x000f; /* m.s. 4 bits */
3536 uint16_t mantissa = modCompScaler & 0x07ff; /* l.s. 11 bits */
3537 float value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3538 proto_item_append_text(ti, " (%f)", value);
3539
3540 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3541
3542 /* Store these params in this flow's state */
3543 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3544 unsigned i = sect_config->num_configs;
3545 sect_config->configs[i].mod_compr_re_mask = 0xfff; /* Covers all REs */
3546 sect_config->configs[i].mod_compr_csf = csf;
3547 sect_config->configs[i].mod_compr_scaler = value;
3548 sect_config->num_configs++;
3549 }
3550 break;
3551 }
3552
3553 case 5: /* SE 5: Modulation Compression Additional Parameters (7.7.5) (multiple sets) */
3554 {
3555 /* Applies only to section types 1,3 and 5 */
3556 /* N.B. there may be multiple instances of this SE in the same frame */
3557
3558 /* There may be one or 2 entries, depending upon extlen */
3559 int sets = 1, reserved_bits = 0;
3560 switch (extlen) {
3561 case 2:
3562 sets = 1;
3563 reserved_bits = 20;
3564 break;
3565 case 3:
3566 sets = 2;
3567 reserved_bits = 24;
3568 break;
3569 case 4:
3570 /* sets can be 3 or 4, depending upon whether last 28 bits are 0.. */
3571 if ((tvb_get_ntohl(tvb, offset+10) & 0x0fffffff) == 0) {
3572 sets = 3;
3573 reserved_bits = 28;
3574 }
3575 else {
3576 sets = 4;
3577 reserved_bits = 0;
3578 }
3579 break;
3580
3581 default:
3582 /* Malformed error!!! */
3583 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
3584 "For section 5, extlen must be 2, 3 or 4, but %u was dissected",
3585 extlen);
3586 break;
3587 }
3588
3589 unsigned bit_offset = offset*8;
3590 /* Dissect each set */
3591 for (int n=0; n < sets; n++) {
3592 /* Subtree for each set */
3593 unsigned set_start_offset = bit_offset/8;
3594 proto_item *set_ti = proto_tree_add_string(extension_tree, hf_oran_modcomp_param_set,
3595 tvb, set_start_offset, 0, "");
3596 proto_tree *set_tree = proto_item_add_subtree(set_ti, ett_oran_modcomp_param_set);
3597
3598 uint64_t mcScaleReMask, mcScaleOffset;
3599 bool_Bool csf;
3600
3601 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
3602 static int * const remask_flags[] = {
3603 &hf_oran_mc_scale_re_mask_re1,
3604 &hf_oran_mc_scale_re_mask_re2,
3605 &hf_oran_mc_scale_re_mask_re3,
3606 &hf_oran_mc_scale_re_mask_re4,
3607 &hf_oran_mc_scale_re_mask_re5,
3608 &hf_oran_mc_scale_re_mask_re6,
3609 &hf_oran_mc_scale_re_mask_re7,
3610 &hf_oran_mc_scale_re_mask_re8,
3611 &hf_oran_mc_scale_re_mask_re9,
3612 &hf_oran_mc_scale_re_mask_re10,
3613 &hf_oran_mc_scale_re_mask_re11,
3614 &hf_oran_mc_scale_re_mask_re12,
3615 NULL((void*)0)
3616 };
3617 /* Same as above, but offset by 4 bits */
3618 static int * const remask_flags_even[] = {
3619 &hf_oran_mc_scale_re_mask_re1_even,
3620 &hf_oran_mc_scale_re_mask_re2_even,
3621 &hf_oran_mc_scale_re_mask_re3_even,
3622 &hf_oran_mc_scale_re_mask_re4_even,
3623 &hf_oran_mc_scale_re_mask_re5_even,
3624 &hf_oran_mc_scale_re_mask_re6_even,
3625 &hf_oran_mc_scale_re_mask_re7_even,
3626 &hf_oran_mc_scale_re_mask_re8_even,
3627 &hf_oran_mc_scale_re_mask_re9_even,
3628 &hf_oran_mc_scale_re_mask_re10_even,
3629 &hf_oran_mc_scale_re_mask_re11_even,
3630 &hf_oran_mc_scale_re_mask_re12_even,
3631 NULL((void*)0)
3632 };
3633
3634 /* RE Mask (12 bits) */
3635 proto_tree_add_bitmask_ret_uint64(set_tree, tvb, bit_offset / 8,
3636 (n % 2) ? hf_oran_mc_scale_re_mask_even : hf_oran_mc_scale_re_mask,
3637 ett_oran_mc_scale_remask,
3638 (n % 2) ? remask_flags_even : remask_flags, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
3639 bit_offset += 12;
3640
3641 /* csf (1 bit) */
3642 bit_offset = dissect_csf(set_tree, tvb, bit_offset, ci_iq_width, &csf);
3643 /* mcScaleOffset (15 bits) */
3644 proto_item *ti = proto_tree_add_bits_ret_val(set_tree, hf_oran_mc_scale_offset, tvb, bit_offset, 15, &mcScaleOffset, ENC_BIG_ENDIAN0x00000000);
3645 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
3646 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
3647 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
3648 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
3649 bit_offset += 15;
3650
3651 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
3652
3653 /* Record this config */
3654 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
3655 unsigned i = sect_config->num_configs;
3656 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
3657 sect_config->configs[i].mod_compr_csf = csf;
3658 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
3659 sect_config->num_configs++;
3660 }
3661
3662 /* Summary */
3663 proto_item_set_len(set_ti, (bit_offset+7)/8 - set_start_offset);
3664 proto_item_append_text(set_ti, " (mcScaleReMask=0x%03x csf=%5s mcScaleOffset=%f)",
3665 (unsigned)mcScaleReMask, tfs_get_true_false(csf)tfs_get_string(csf, ((void*)0)), mcScaleOffset_value);
3666 }
3667
3668 proto_item_append_text(extension_ti, " (%u sets)", sets);
3669
3670 /* Reserved (variable-length) */
3671 if (reserved_bits) {
3672 proto_tree_add_bits_item(extension_tree, hf_oran_reserved, tvb, bit_offset, reserved_bits, ENC_BIG_ENDIAN0x00000000);
3673 bit_offset += reserved_bits;
3674 }
3675
3676 offset = bit_offset/8;
3677 break;
3678 }
3679
3680 case 6: /* SE 6: Non-contiguous PRB allocation in time and frequency domain */
3681 {
3682 /* numSymbol not used in this case */
3683 if (numsymbol_ti && !numsymbol_ignored) {
3684 proto_item_append_text(numsymbol_ti, " (ignored)");
3685 numsymbol_ignored = true1;
3686 }
3687
3688 /* Will update ext6 recorded info */
3689 ext11_settings.ext6_set = true1;
3690
3691 /* repetition */
3692 proto_tree_add_bits_item(extension_tree, hf_oran_se6_repetition, tvb, offset*8, 1, ENC_BIG_ENDIAN0x00000000);
3693 /* rbgSize (PRBs per bit set in rbgMask) */
3694 uint32_t rbgSize;
3695 proto_item *rbg_size_ti;
3696 rbg_size_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgSize);
3697 if (rbgSize == 0) {
3698 /* N.B. this is only true if "se6-rb-bit-supported" is set... */
3699 expert_add_info(pinfo, rbg_size_ti, &ei_oran_rbg_size_reserved);
3700 }
3701 /* rbgMask (28 bits) */
3702 uint32_t rbgMask;
3703 proto_item *rbgmask_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000, &rbgMask);
3704 if (rbgSize == 0) {
3705 proto_item_append_text(rbgmask_ti, " (value ignored since rbgSize is 0)");
3706 }
3707
3708 /* TODO: if receiver detects non-zero bits outside the valid range, those shall be ignored. */
3709 offset += 4;
3710 /* priority */
3711 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3712 /* symbolMask */
3713 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
3714
3715 /* Look up rbg_size enum -> value */
3716 switch (rbgSize) {
3717 case 0:
3718 /* N.B. reserved, but covered above with expert info (would remain 0) */
3719 break;
3720 case 1:
3721 ext11_settings.ext6_rbg_size = 1; break;
3722 case 2:
3723 ext11_settings.ext6_rbg_size = 2; break;
3724 case 3:
3725 ext11_settings.ext6_rbg_size = 3; break;
3726 case 4:
3727 ext11_settings.ext6_rbg_size = 4; break;
3728 case 5:
3729 ext11_settings.ext6_rbg_size = 6; break;
3730 case 6:
3731 ext11_settings.ext6_rbg_size = 8; break;
3732 case 7:
3733 ext11_settings.ext6_rbg_size = 16; break;
3734 /* N.B., encoded in 3 bits, so no other values are possible */
3735 }
3736
3737 /* Set to looked-up value */
3738 rbgSize = ext11_settings.ext6_rbg_size;
3739
3740 uint32_t lastRbgid = 0;
3741 if (rbgSize != 0) {
3742 /* The O-DU shall not use combinations of startPrbc, numPrbc and rbgSize leading to a value of lastRbgid larger than 27 */
3743 /* i.e., leftmost bit used should not need to go off left end of rbgMask! */
3744 lastRbgid = (uint32_t)ceil((numPrbc + (startPrbc % rbgSize)) / (float)rbgSize) - 1;
3745 if (lastRbgid > 27) {
3746 expert_add_info_format(pinfo, rbg_size_ti, &ei_oran_lastRbdid_out_of_range,
3747 "SE6: rbgSize (%u) not compatible with startPrbc(%u) and numPrbc(%u)",
3748 rbgSize, startPrbc, numPrbc);
3749 break;
3750 }
3751 }
3752
3753 /* Record (and count) which bits are set in rbgMask */
3754 bool_Bool first_seen = false0;
3755 unsigned first_seen_pos=0, last_seen_pos=0;
3756 for (unsigned n=0; n < 28 && ext11_settings.ext6_num_bits_set < 28; n++) {
3757 if ((rbgMask >> n) & 0x01) {
3758 ext11_settings.ext6_bits_set[ext11_settings.ext6_num_bits_set++] = n;
3759 if (!first_seen) {
3760 first_seen = true1;
3761 first_seen_pos = n;
3762 }
3763 last_seen_pos = n;
3764 }
3765 }
3766
3767 /* Show how many bits were set in rbgMask */
3768 proto_item_append_text(rbgmask_ti, " (%u bits set)", ext11_settings.ext6_num_bits_set);
3769 /* Also, that is the range of bits */
3770 if (first_seen) {
3771 proto_item_append_text(rbgmask_ti, " (%u bits spread)", last_seen_pos-first_seen_pos+1);
3772
3773 /* Complain if last set bit is beyond lastRbgid */
3774 if (last_seen_pos > lastRbgid) {
3775 expert_add_info_format(pinfo, rbgmask_ti, &ei_oran_rbgMask_beyond_last_rbdid,
3776 "SE6: rbgMask (0x%07x) has bit %u set, but lastRbgId is %u",
3777 rbgMask, last_seen_pos, lastRbgid);
3778 }
3779 }
3780
3781 /* Also update prbs_for_st10_type5[] */
3782 if (sectionType == 10 && rbgSize != 0) {
3783 /* Unset all entries */
3784 memset(&prbs_for_st10_type5, 0, sizeof(prbs_for_st10_type5));
3785
3786 /* Work out which PRB first bit corresponds to */
3787 unsigned firstPrbStart = (startPrbc/rbgSize) * rbgSize;
3788
3789 /* Add PRBs corresponding to each bit set */
3790 for (unsigned n=0; n < 28 ; n++) {
3791 if ((rbgMask >> n) & 0x01) {
3792 /* Lazy way to clip any values that lie outside of range for section */
3793 for (unsigned p=0; p < rbgSize; p++) {
3794 unsigned start = firstPrbStart + (n*rbgSize);
3795 if ((start+p < MAX_PRBS273) && (start+p >= startPrbc) && (start+p <= startPrbc+numPrbc-1)) {
3796 prbs_for_st10_type5[start+p] = true1;
3797 }
3798 }
3799 }
3800 }
3801 }
3802
3803 break;
3804 }
3805
3806 case 7: /* SE 7: eAxC mask */
3807 /* Allow ST0 to address multiple eAxC_ID values for transmission blanking */
3808 proto_tree_add_item(extension_tree, hf_oran_eAxC_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3809 offset += 2;
3810 break;
3811
3812 case 8: /* SE 8: Regularization factor */
3813 proto_tree_add_item(extension_tree, hf_oran_regularizationFactor, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3814 offset += 2;
3815 break;
3816
3817 case 9: /* SE 9: Dynamic Spectrum Sharing parameters */
3818 proto_tree_add_item(extension_tree, hf_oran_technology, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3819 offset += 1;
3820 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3821 offset += 1;
3822 break;
3823
3824 case 10: /* SE 10: Group configuration of multiple ports */
3825 {
3826 seen_se10 = true1;
3827
3828 /* beamGroupType */
3829 uint32_t beam_group_type = 0;
3830 proto_item *bgt_ti;
3831 bgt_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamGroupType,
3832 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_group_type);
3833 proto_item_append_text(extension_ti, " (%s)", val_to_str_const(beam_group_type, beam_group_type_vals, "Unknown"));
3834
3835 /* numPortc */
3836 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
3837 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
3838 offset++;
3839
3840 /* Will append all beamId values to extension_ti, regardless of beamGroupType */
3841 unsigned n;
3842
3843 switch (beam_group_type) {
3844 case 0x0: /* common beam */
3845 case 0x1: /* beam matrix indication */
3846 /* Reserved byte */
3847 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
3848 offset++;
3849
3850 /* Explain how entries are allocated */
3851 if (beam_group_type == 0x0) {
3852 proto_item_append_text(extension_ti, " (all %u ueid/Beam entries are %u)", numPortc, ueId);
3853 }
3854 else {
3855 /* 'numPortc' consecutive BeamIds from section header */
3856 proto_item_append_text(extension_ti, " (ueId/beam entries are %u -> %u)", ueId, ueId+numPortc);
3857 }
3858
3859 if (sectionType == 5) {
3860 /* These types are not allowed */
3861 expert_add_info_format(pinfo, bgt_ti, &ei_oran_se10_not_allowed,
3862 "SE10: beamGroupType %u is not allowed for section type 5", beam_group_type);
3863 }
3864 break;
3865
3866 case 0x2: /* beam vector listing */
3867 {
3868 proto_item_append_text(extension_ti, " [ ");
3869
3870 /* Beam listing vector case */
3871 /* Work out how many port beam entries there is room for */
3872 /* Using numPortC as visible in issue 18116 */
3873 for (n=0; n < numPortc; n++) {
3874 /* 1 reserved bit */
3875 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3876
3877 /* port beam ID (or UEID) (15 bits) */
3878 uint32_t id;
3879 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3880 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3881 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3882 offset += 2;
3883
3884 if (id != 0x7fff) {
3885 if (number_of_ueids < MAX_UEIDS16) {
3886 ueids[number_of_ueids++] = id;
3887 }
3888 }
3889
3890 proto_item_append_text(extension_ti, "%u ", id);
3891 }
3892
3893 proto_item_append_text(extension_ti, "]");
3894 break;
3895 }
3896 case 0x3: /* beamId/ueId listing with associated port-list index */
3897 {
3898 proto_item_append_text(extension_ti, " [ ");
3899
3900 if (numPortc > 0) {
3901 /* first portListIndex is outside loop */
3902 uint32_t port_list_index;
3903 proto_item *pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3904 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3905 if (port_list_index == 0) {
3906 /* Value 0 is reserved */
3907 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3908 }
3909 offset += 1;
3910
3911 for (n=0; n < numPortc-1; n++) {
3912 /* 1 reserved bit */
3913 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
3914
3915 /* port beam ID (or UEID) */
3916 uint32_t id;
3917 proto_item *beamid_or_ueid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beamId,
3918 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &id);
3919 proto_item_append_text(beamid_or_ueid_ti, " port #%u beam ID (or UEId) %u", n, id);
3920 offset += 2;
3921
3922 if (id != 0x7fff) {
3923 if (number_of_ueids < MAX_UEIDS16) {
3924 ueids[number_of_ueids++] = id;
3925 }
3926 }
3927
3928 /* subsequent portListIndex */
3929 pli_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_port_list_index, tvb,
3930 offset, 1, ENC_BIG_ENDIAN0x00000000, &port_list_index);
3931 if (port_list_index == 0) {
3932 /* Value 0 is reserved */
3933 expert_add_info(pinfo, pli_ti, &ei_oran_port_list_index_zero);
3934 }
3935 offset += 1;
3936
3937 proto_item_append_text(extension_ti, "%u:%u ", port_list_index, id);
3938 }
3939 }
3940
3941 proto_item_append_text(extension_ti, "]");
3942 break;
3943 }
3944
3945
3946 default:
3947 /* Warning for unsupported/reserved value */
3948 expert_add_info(NULL((void*)0), bgt_ti, &ei_oran_se10_unknown_beamgrouptype);
3949 break;
3950 }
3951 break;
3952 }
3953
3954 case 11: /* SE 11: Flexible Weights Extension Type */
3955 {
3956 /* Hidden filter for bf */
3957 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
3958 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
3959
3960 /* beamId in section header should be ignored. Guard against appending multiple times.. */
3961 if (section_beamId_ti && !section_beamId_ignored) {
3962 proto_item_append_text(section_beamId_ti, " (ignored)");
3963 section_beamId_ignored = true1;
3964 }
3965
3966 bool_Bool disableBFWs;
3967 uint32_t numBundPrb;
3968 bool_Bool rad;
3969
3970 /* disableBFWs */
3971 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
3972 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
3973 if (disableBFWs) {
3974 proto_item_append_text(extension_ti, " (disableBFWs)");
3975 }
3976
3977 /* RAD */
3978 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_rad,
3979 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rad);
3980 /* bundleOffset (6 bits) */
3981 proto_tree_add_item(extension_tree, hf_oran_bundle_offset, tvb,
3982 offset, 1, ENC_BIG_ENDIAN0x00000000);
3983 offset++;
3984
3985 /* numBundPrb (number of prbs in each bundle) */
3986 proto_item *num_bund_prb_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_bund_prbs,
3987 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numBundPrb);
3988 offset++;
3989 /* value zero is reserved.. */
3990 if (numBundPrb == 0) {
3991 expert_add_info(pinfo, num_bund_prb_ti, &ei_oran_reserved_numBundPrb);
3992 }
3993
3994 uint32_t num_bundles;
3995 bool_Bool orphaned_prbs = false0;
3996
3997 /* N.B. glibly assuming that Mu=1 */
3998 uint32_t symbol_count = (frameId*20 + slotId) * 14 + startSymbolId;
3999
4000 if (!disableBFWs) {
4001 /********************************************/
4002 /* Table 7.7.1.1-1 */
4003 /********************************************/
4004
4005 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4006 proto_item *comp_meth_ti = NULL((void*)0);
4007
4008 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
4009 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4010 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4011
4012 /* Work out number of bundles, but take care not to divide by zero. */
4013 if (numBundPrb == 0) {
4014 break;
4015 }
4016
4017 /* Work out bundles! */
4018 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4019 num_bundles = ext11_settings.num_bundles;
4020
4021 /* Add (complete) bundles */
4022 for (unsigned b=0; b < num_bundles; b++) {
4023 offset = dissect_bfw_bundle(tvb, extension_tree, pinfo, offset,
4024 comp_meth_ti, bfwcomphdr_comp_meth,
4025 NULL((void*)0) /* no ModCompr */,
4026 (ext11_settings.ext21_set) ?
4027 numPrbc :
4028 pref_num_bf_antennas,
4029 bfwcomphdr_iq_width,
4030 b, /* bundle number */
4031 ext11_settings.bundles[b].start,
4032 ext11_settings.bundles[b].end,
4033 ext11_settings.bundles[b].is_orphan,
4034 symbol_count,
4035 (link_planes_together && data_section) ? &data_section->details[index_to_use] : NULL((void*)0),
4036 tap_info);
4037 if (!offset) {
4038 break;
4039 }
4040 }
4041 if (num_bundles > 0) {
4042 /* Set flag from last bundle entry */
4043 orphaned_prbs = ext11_settings.bundles[num_bundles-1].is_orphan;
4044 }
4045 }
4046 else {
4047 /********************************************/
4048 /* Table 7.7.1.1-2 */
4049 /* No weights in this case */
4050 /********************************************/
4051
4052 /* Work out number of bundles, but take care not to divide by zero. */
4053 if (numBundPrb == 0) {
4054 break;
4055 }
4056
4057 ext11_work_out_bundles(startPrbc, numPrbc, numBundPrb, &ext11_settings);
4058 num_bundles = ext11_settings.num_bundles;
4059
4060 for (unsigned n=0; n < num_bundles; n++) {
4061 /* contInd */
4062 proto_tree_add_item(extension_tree, hf_oran_cont_ind,
4063 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4064 /* beamId */
4065 /* N.B., only added to tap_info if not 0 or ignored (after SEs seen) */
4066 uint32_t beam_id;
4067 proto_item *beamid_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_id,
4068 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beam_id);
4069 if (!ext11_settings.bundles[n].is_orphan) {
4070 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Bundle %2u)",
4071 ext11_settings.bundles[n].start,
4072 ext11_settings.bundles[n].end,
4073 n);
4074 }
4075 else {
4076 orphaned_prbs = true1;
4077 proto_item_append_text(beamid_ti, " (PRBs %3u-%3u) (Orphaned PRBs)",
4078 ext11_settings.bundles[n].start,
4079 ext11_settings.bundles[n].end);
4080 }
4081 offset += 2;
4082
4083 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4084 if (data_section) {
4085 /* Set beamId only for range of PRBs */
4086 for (unsigned prb = ext11_settings.bundles[n].start; prb <= ext11_settings.bundles[n].end; prb++) {
4087 if (prb < 273) {
4088 data_section->details[index_to_use].beamIds[prb] = beam_id;
4089 }
4090 }
4091 }
4092 }
4093
4094 /* Look for where BFWs were sent for this beamId */
4095 bfw_definition *definition;
4096
4097 wmem_tree_key_t key[3];
4098 key[0].length = 1;
4099 key[0].key = &pinfo->num;
4100 key[1].length = 1;
4101 key[1].key = &beam_id;
4102 key[2].length = 0;
4103 key[2].key = NULL((void*)0);
4104
4105 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4106 /* Look up current result */
4107 definition = wmem_tree_lookup32(dl_beam_ids_defined, beam_id);
4108 if (definition != NULL((void*)0)) {
4109 /* Add to results table for this frame */
4110 wmem_tree_insert32_array(dl_beam_ids_results, key, definition);
4111 }
4112 }
4113 else {
4114 /* Look up from result table */
4115 definition = wmem_tree_lookup32_array(dl_beam_ids_results, key);
4116 }
4117
4118 /* Show link back to frame where/when beamId was defined */
4119 if (definition && definition->frame_defined != 0 && definition->frame_defined != pinfo->num) {
4120 proto_item *defined_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_frame_defined, tvb, offset, 0, definition->frame_defined);
4121 proto_item_set_generated(defined_ti);
4122 proto_item *since_ti = proto_tree_add_uint(extension_tree, hf_oran_bfws_symbols_since_defined, tvb, offset, 0,
4123 symbol_count - definition->symbol_when_defined);
4124 proto_item_set_generated(since_ti);
4125 }
4126 else {
4127 expert_add_info_format(NULL((void*)0), beamid_ti, &ei_oran_beamid_bfws_not_found,
4128 "ext11 for beamId %u and disableBFWs set, but can't find definition", beam_id);
4129 }
4130 }
4131
4132 }
4133
4134 /* Add summary to extension root */
4135 if (orphaned_prbs) {
4136 proto_item_append_text(extension_ti, " (%u full bundles + orphaned)", num_bundles-1);
4137 }
4138 else {
4139 proto_item_append_text(extension_ti, " (%u bundles)", num_bundles);
4140 }
4141 }
4142
4143 break;
4144
4145 case 12: /* SE 12: Non-Contiguous PRB Allocation with Frequency Ranges */
4146 {
4147 /* numSymbol not used in this case */
4148 if (numsymbol_ti && !numsymbol_ignored) {
4149 proto_item_append_text(numsymbol_ti, " (ignored)");
4150 numsymbol_ignored = true1;
4151 }
4152
4153 ext11_settings.ext12_set = true1;
4154
4155 /* priority */
4156 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4157
4158 /* symbolMask */
4159 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4160
4161 /* There are now 'R' pairs of (offStartPrb, numPrb) values. Fill extlen bytes with values. If last one is not set,
4162 should be populated with 0s. */
4163 uint32_t extlen_remaining_bytes = (extlen*4) - 4;
4164 uint8_t prb_index;
4165
4166 /* This is for ST10/ST11. First pair starts after frames signalled there */
4167 uint16_t st10_st11_offset = startPrbc + numPrbc;
4168
4169 for (prb_index = 1; extlen_remaining_bytes > 0; prb_index++)
4170 {
4171 /* Create a subtree for each pair */
4172 proto_item *pair_ti = proto_tree_add_string(extension_tree, hf_oran_frequency_range,
4173 tvb, offset, 2, "");
4174 proto_tree *pair_tree = proto_item_add_subtree(pair_ti, ett_oran_frequency_range);
4175
4176 /* offStartPrb */
4177 uint32_t off_start_prb;
4178 proto_tree_add_item_ret_uint(pair_tree, hf_oran_off_start_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &off_start_prb);
4179 offset++;
4180
4181 /* numPrb */
4182 uint32_t num_prb;
4183 proto_tree_add_item_ret_uint(pair_tree, hf_oran_num_prb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_prb);
4184 offset++;
4185
4186 extlen_remaining_bytes -= 2;
4187
4188 /* Last pair may be 0,0 if not used. Check for this */
4189 if ((extlen_remaining_bytes == 0) && (off_start_prb == 0) && (num_prb == 0)) {
4190 proto_item_append_text(pair_ti, " (not used)");
4191 }
4192 /* Add summary to pair root item, and configure details in ext11_settings */
4193 else {
4194 proto_item_append_text(pair_ti, "(%u) [%u : %u]",
4195 prb_index, off_start_prb, num_prb);
4196 proto_item_append_text(extension_ti, "[%u : %u]",
4197 off_start_prb, num_prb);
4198 if (ext11_settings.ext12_num_pairs < MAX_BFW_EXT12_PAIRS128) {
4199 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs].off_start_prb = off_start_prb;
4200 ext11_settings.ext12_pairs[ext11_settings.ext12_num_pairs++].num_prb = num_prb;
4201 }
4202
4203 /* Also update PRBs to be covered for ST10 type 5 */
4204 /* Original range from section is added to.. */
4205 /* TODO: I don't think this is quite right.. */
4206 for (unsigned prb=st10_st11_offset+off_start_prb; prb < st10_st11_offset+off_start_prb+num_prb; prb++) {
4207 if (prb < MAX_PRBS273) {
4208 prbs_for_st10_type5[prb] = true1;
4209 }
4210 }
4211
4212 /* Any next pair will begin after this one */
4213 st10_st11_offset += (off_start_prb + num_prb);
4214 }
4215 }
4216 break;
4217 }
4218
4219 case 13: /* SE 13: PRB Allocation with Frequency Hopping */
4220 {
4221 /* Will update settings for ext11 */
4222 ext11_settings.ext13_set = true1;
4223
4224 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4225 uint8_t allocation_index;
4226
4227 unsigned prev_next_symbol_id = 0, prev_next_start_prbc = 0;
4228
4229 for (allocation_index = 1; extlen_remaining_bytes > 0; allocation_index++)
4230 {
4231 /* Subtree for allocation */
4232 proto_item *allocation_ti = proto_tree_add_string(extension_tree, hf_oran_prb_allocation,
4233 tvb, offset, 2, "");
4234 proto_tree *allocation_tree = proto_item_add_subtree(allocation_ti, ett_oran_prb_allocation);
4235
4236 /* Reserved (2 bits) */
4237 add_reserved_field(allocation_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4238
4239 /* nextSymbolId (4 bits) */
4240 uint32_t next_symbol_id;
4241 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextSymbolId, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &next_symbol_id);
4242
4243 /* nextStartPrbc (10 bits) */
4244 uint32_t next_start_prbc;
4245 proto_tree_add_item_ret_uint(allocation_tree, hf_oran_nextStartPrbc, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &next_start_prbc);
4246 offset += 2;
4247
4248 /* Add summary to allocation root item */
4249 proto_item_append_text(allocation_ti, "(%u) nextSymbolId=%3u, nextStartPrbc=%u",
4250 allocation_index, next_symbol_id, next_start_prbc);
4251
4252 /* Checking for duplicates (expected if e.g. had only 2 entries but extlen bytes still to fill */
4253 if ((allocation_index > 1) && (next_symbol_id == prev_next_symbol_id) && (next_start_prbc == prev_next_start_prbc)) {
4254 proto_item_append_text(allocation_ti, " (repeated - to fill up extlen)");
4255 }
4256 else {
4257 /* Add entry for configuring ext11. don't store out of range */
4258 if (ext11_settings.ext13_num_start_prbs < MAX_BFW_EXT13_ALLOCATIONS128) {
4259 ext11_settings.ext13_start_prbs[ext11_settings.ext13_num_start_prbs++] = next_start_prbc;
4260 }
4261 }
4262 prev_next_symbol_id = next_symbol_id;
4263 prev_next_start_prbc = next_start_prbc;
4264
4265 extlen_remaining_bytes -= 2;
4266 }
4267 break;
4268 }
4269
4270 case 14: /* SE 14: Nulling-layer Info. for ueId-based beamforming */
4271 /* Hidden filter for bf (DMRS BF) */
4272 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4273 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4274
4275 if (!seen_se10) {
4276 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4277 offset += 1;
4278 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4279 offset += 1;
4280 }
4281 else {
4282 /* Loop over numPortc++1 (from SE 10) nullLayerInd fields */
4283 for (unsigned port=0; port < numPortc+1; port++) {
4284 proto_tree_add_item(extension_tree, hf_oran_nullLayerInd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4285 offset += 1;
4286 }
4287 }
4288 break;
4289
4290 case 15: /* SE 15: Mixed-numerology Info. for ueId-based beamforming */
4291 {
4292 /* frameStructure */
4293 offset = dissect_frame_structure(extension_tree, tvb, offset,
4294 subframeId, slotId);
4295 /* freqOffset */
4296 proto_tree_add_item(extension_tree, hf_oran_freqOffset, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
4297 offset += 3;
4298 /* cpLength */
4299 proto_item *cplength_ti = proto_tree_add_item(extension_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4300 if (sectionType != 0 && sectionType != 3) {
4301 proto_item_append_text(cplength_ti, " (ignored - used only with ST0 and ST3)");
4302 }
4303 offset += 2;
4304 break;
4305 }
4306
4307 case 16: /* SE 16: Antenna mapping in UE channel information based UL beamforming */
4308 {
4309 /* Just filling available bytes with antMask entries.
4310 N.B., if SE 10 also used, could associate each antMask with (beamId or UEId) RX eAxC */
4311 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4312 unsigned num_ant_masks = extlen_remaining_bytes / 8;
4313 for (unsigned n=0; n < num_ant_masks; n++) {
4314 proto_item *ti = proto_tree_add_item(extension_tree, hf_oran_antMask, tvb, offset, 8, ENC_BIG_ENDIAN0x00000000);
4315 proto_item_append_text(ti, " (RX eAxC #%u)", n+1);
4316 offset += 8;
4317 }
4318 break;
4319 }
4320
4321 case 17: /* SE 17: Indication of user port group. Applies to ST5 + SE10 with group type 1 (beam matrix indication) */
4322 {
4323 uint32_t extlen_remaining_bytes = (extlen*4) - 2;
4324 uint32_t end_bit = (offset+extlen_remaining_bytes) * 8;
4325 uint32_t ueid_index = 1;
4326
4327 /* "the preceding Section Type and extension messages implicitly provide the number of scheduled users" */
4328 for (uint32_t bit_offset=offset*8; (bit_offset < end_bit) && (ueid_index <= number_of_ueids); bit_offset+=4, ueid_index++) {
4329 /* numUeId (Number of UE Ids per user) */
4330 proto_item *ti = proto_tree_add_bits_item(extension_tree, hf_oran_num_ueid, tvb, bit_offset, 4, ENC_BIG_ENDIAN0x00000000);
4331 /* TODO: show ueids[ueid_index] here too? */
4332 proto_item_append_text(ti, " (user #%u)", ueid_index);
4333 }
4334 break;
4335 }
4336
4337 case 18: /* SE 18: Uplink transmission management */
4338 /* transmissionWindowOffset */
4339 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4340 offset += 2;
4341 /* reserved (2 bits) */
4342 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4343 /* transmissionWindowSize (14 bits) */
4344 proto_tree_add_item(extension_tree, hf_oran_transmissionWindowSize, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4345 offset += 2;
4346
4347 /* reserved (6 bits) */
4348 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4349 /* toT (2 bits) */
4350 proto_tree_add_item(extension_tree, hf_oran_toT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4351 offset += 1;
4352 break;
4353
4354 case 19: /* SE 19: Compact beamforming information for multiple port */
4355 {
4356 /* beamId in section header should be ignored. Guard against appending multiple times.. */
4357 if (section_beamId_ti && !section_beamId_ignored) {
4358 proto_item_append_text(section_beamId_ti, " (ignored)");
4359 section_beamId_ignored = true1;
4360 }
4361
4362 /* numSymbol not used in this case */
4363 if (numsymbol_ti && !numsymbol_ignored) {
4364 proto_item_append_text(numsymbol_ti, " (ignored)");
4365 numsymbol_ignored = true1;
4366 }
4367
4368 /* disableBFWs */
4369 bool_Bool disableBFWs;
4370 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_disable_bfws,
4371 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disableBFWs);
4372 if (disableBFWs) {
4373 proto_item_append_text(extension_ti, " (disableBFWs)");
4374 }
4375 /* repetition (1 bit) */
4376 uint64_t repetition;
4377 proto_tree_add_bits_ret_val(extension_tree, hf_oran_se19_repetition, tvb, (offset*8)+1, 1, &repetition, ENC_BIG_ENDIAN0x00000000);
4378 /* numPortc (6 bits) */
4379 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPortc,
4380 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPortc);
4381 offset++;
4382
4383 /* priority (2 bits) */
4384 proto_tree_add_item(extension_tree, hf_oran_noncontig_priority, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4385 /* symbolMask (14 bits) */
4386 offset = dissect_symbolmask(tvb, extension_tree, offset, NULL((void*)0), NULL((void*)0));
4387
4388 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
4389 proto_item *comp_meth_ti = NULL((void*)0);
4390
4391 if (!repetition) {
4392
4393 if (!disableBFWs) {
4394 /* bfwCompHdr */
4395 offset = dissect_bfwCompHdr(tvb, extension_tree, offset,
4396 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
4397 }
4398
4399 /* Add entries for each port */
4400 for (unsigned port=0; port < numPortc; port++) {
4401
4402 /* Create subtree for port entry*/
4403 int port_start_offset = offset;
4404 proto_item *port_ti = proto_tree_add_string_format(extension_tree, hf_oran_ext19_port,
4405 tvb, offset, 0,
4406 "", "Port %u: ", port);
4407 proto_tree *port_tree = proto_item_add_subtree(port_ti, ett_oran_ext19_port);
4408
4409 /* Reserved (4 bits) */
4410 add_reserved_field(port_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4411 /* portReMask (12 bits) */
4412 proto_tree_add_item(port_tree, hf_oran_portReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4413 offset += 2;
4414
4415 /* Reserved (2 bits) */
4416 add_reserved_field(port_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4417 /* portSymbolMask (14 bits) */
4418 proto_tree_add_item(port_tree, hf_oran_portSymbolMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4419 offset += 2;
4420
4421 /* Reserved (1 bit) */
4422 add_reserved_field(port_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4423 /* beamID (15 bits) */
4424 uint16_t beamId;
4425 proto_tree_add_item_ret_uint16(port_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &beamId);
4426 proto_item_append_text(port_ti, " (beamId=%u)", beamId);
4427 offset += 2;
4428
4429 /* No weights present */
4430 if (!disableBFWs) {
4431 /*******************************************************************/
4432 /* Table 7.7.19.1-1 (there is no part -2 for disableBFWs case...), */
4433 /* but for SE 11, bfwCompParam was only present for !disableBFWs */
4434 /*******************************************************************/
4435
4436 /* bfwCompParam */
4437 bool_Bool compression_method_supported = false0;
4438 uint32_t exponent = 0;
4439 unsigned num_trx_entries = 0;
4440 uint16_t *trx;
4441 offset = dissect_bfwCompParam(tvb, port_tree, pinfo, offset, comp_meth_ti,
4442 &bfwcomphdr_comp_meth, &exponent, &compression_method_supported,
4443 &num_trx_entries, &trx);
4444
4445 int bit_offset = offset*8;
4446 int bfw_offset;
4447
4448 /* Add weights for each TRX */
4449 unsigned trx_to_add = (num_trx_entries==0) ? pref_num_bf_antennas : num_trx_entries;
4450 for (unsigned b=0; b < trx_to_add; b++) {
4451
4452 uint16_t trx_index = (num_trx_entries) ? trx[b] : b+1;
4453
4454 /* Create BFW subtree */
4455 bfw_offset = bit_offset / 8;
4456 uint8_t bfw_extent = ((bit_offset + (bfwcomphdr_iq_width*2)) / 8) - bfw_offset;
4457 proto_item *bfw_ti = proto_tree_add_string_format(port_tree, hf_oran_bfw,
4458 tvb, bfw_offset, bfw_extent,
4459 "", "TRX %u: (", trx_index);
4460 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
4461
4462 /* I */
4463 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4464 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4465 /* Add to tree. */
4466 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
4467 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4468 bit_offset += bfwcomphdr_iq_width;
4469 proto_item_append_text(bfw_ti, "I%u=%f ", b, value);
4470
4471 /* Q */
4472 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
4473 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr */, 0 /* RE */);
4474 /* Add to tree. */
4475 proto_tree_add_float_format_value(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
4476 (bfwcomphdr_iq_width+7)/8, value, "#%u=%f", b, value);
4477 bit_offset += bfwcomphdr_iq_width;
4478 proto_item_append_text(bfw_ti, "Q%u=%f)", b, value);
4479 }
4480
4481 offset = (bit_offset+7)/8;
4482 }
4483 else {
4484 /* No weights... */
4485 }
4486
4487 /* Set length of this port entry */
4488 proto_item_set_len(port_ti, offset-port_start_offset);
4489 }
4490 }
4491 break;
4492 }
4493
4494 case 20: /* SE 20: Puncturing extension */
4495 {
4496 /* numPuncPatterns */
4497 uint32_t numPuncPatterns;
4498 proto_tree_add_item_ret_uint(extension_tree, hf_oran_numPuncPatterns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPatterns);
4499 offset += 1;
4500
4501 /* Add each puncturing pattern */
4502 for (uint32_t n=0; n < numPuncPatterns; n++) {
4503 unsigned pattern_start_offset = offset;
4504
4505 /* Subtree for this puncturing pattern */
4506 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_puncPattern,
4507 tvb, offset, 0,
4508 "", "Puncturing Pattern: %u/%u", n+1, numPuncPatterns);
4509 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_punc_pattern);
4510
4511 /* SymbolMask (14 bits) */
4512 proto_tree_add_item(pattern_tree, hf_oran_symbolMask_ext20, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4513 offset += 1;
4514
4515 uint32_t startPuncPrb, numPuncPrb;
4516
4517 /* startPuncPrb (10 bits) */
4518 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_startPuncPrb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPuncPrb);
4519 offset += 2;
4520 /* numPuncPrb (8 bits) */
4521 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_numPuncPrb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numPuncPrb);
4522 offset += 1;
4523
4524 proto_item_append_text(pattern_ti, " [%u->%u]", startPuncPrb, startPuncPrb+numPuncPrb-1);
4525
4526 /* Make a hole in range of PRBs to report */
4527 for (unsigned p=startPuncPrb; p < startPuncPrb+numPuncPrb; p++) {
4528 if (p < MAX_PRBS273) {
4529 prbs_for_st10_type5[p] = false0;
4530 }
4531 }
4532
4533 /* puncReMask (12 bits) */
4534 proto_tree_add_item(pattern_tree, hf_oran_puncReMask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4535 offset += 1;
4536 /* rb (1 bit) */
4537 proto_item *rb_ti = proto_tree_add_item(pattern_tree, hf_oran_rb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4538 /* reserved (1 bit) */
4539 add_reserved_field(pattern_tree, hf_oran_reserved_bit5, tvb, offset, 1);
4540 /* multiSDScope (1 bit) */
4541 proto_tree_add_item(pattern_tree, hf_oran_multiSDScope, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4542 /* rbgIncl (1 bit) */
4543 bool_Bool rbgIncl;
4544 proto_tree_add_item_ret_boolean(pattern_tree, hf_oran_RbgIncl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &rbgIncl);
4545 offset += 1;
4546
4547 if (rbgIncl) {
4548 /* reserved (1 bit) */
4549 add_reserved_field(pattern_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4550 /* rbgSize(3 bits) */
4551 proto_tree_add_item(pattern_tree, hf_oran_rbgSize, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4552 /* rbgMask (28 bits) */
4553 proto_tree_add_item(pattern_tree, hf_oran_rbgMask, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
4554 offset += 4;
4555
4556 proto_item_append_text(rb_ti, " (ignored)");
4557 }
4558
4559 proto_item_set_len(pattern_ti, offset-pattern_start_offset);
4560 }
4561
4562 break;
4563 }
4564 case 21: /* SE 21: Variable PRB group size for channel information */
4565 {
4566 /* ciPrbGroupSize */
4567 uint32_t ci_prb_group_size;
4568 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);
4569 offset += 1;
4570
4571 switch (ci_prb_group_size) {
4572 case 0:
4573 case 1:
4574 case 255:
4575 /* Reserved value */
4576 expert_add_info_format(pinfo, prb_group_size_ti, &ei_oran_ci_prb_group_size_reserved,
4577 "SE 11 ciPrbGroupSize is reserved value %u - must be 2-254",
4578 ci_prb_group_size);
4579 break;
4580 default:
4581 /* This value affects how SE 11 is interpreted */
4582 ext11_settings.ext21_set = true1;
4583 ext11_settings.ext21_ci_prb_group_size = ci_prb_group_size;
4584
4585 if (numPrbc == 0) {
4586 expert_add_info(pinfo, numprbc_ti, &ei_oran_numprbc_ext21_zero);
4587 }
4588 break;
4589 }
4590
4591 /* reserved (6 bits) */
4592 add_reserved_field(extension_tree, hf_oran_reserved_6bits, tvb, offset, 1);
4593
4594 /* prgSize (2 bits). Interpretation depends upon section type (5 or 6), but also mplane parameters? */
4595 if (sectionType == SEC_C_UE_SCHED) { /* Section Type 5 */
4596 proto_tree_add_item(extension_tree, hf_oran_prg_size_st5, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4597 }
4598 else if (sectionType == SEC_C_CH_INFO) { /* Section Type 6 */
4599 proto_tree_add_item(extension_tree, hf_oran_prg_size_st6, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4600 }
4601 offset += 1;
4602 break;
4603 }
4604
4605 case 22: /* SE 22: ACK/NACK request */
4606 {
4607 uint32_t ack_nack_req_id;
4608 proto_tree_add_item_ret_uint(extension_tree, hf_oran_ack_nack_req_id, tvb, offset, 2,
4609 ENC_BIG_ENDIAN0x00000000, &ack_nack_req_id);
4610 offset += 2;
4611
4612 if (state) {
4613 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
4614 /* Add this request into conversation state on first pass */
4615 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)))
;
4616 request_details->request_frame_number = pinfo->num;
4617 request_details->request_frame_time = pinfo->abs_ts;
4618 request_details->requestType = SE22;
4619 /* Insert into flow's tree */
4620 wmem_tree_insert32(state->ack_nack_requests, ack_nack_req_id, request_details);
4621 }
4622 else {
4623 /* Try to link forward to ST8 response */
4624 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
4625 ack_nack_req_id);
4626 if (response) {
4627 show_link_to_acknack_response(extension_tree, tvb, pinfo, response);
4628 }
4629 }
4630 }
4631 break;
4632 }
4633
4634 case 23: /* SE 23: Arbitrary symbol pattern modulation compression parameters */
4635 {
4636 /* Green common header */
4637
4638 /* numSymPrbPattern (4 bits) */
4639 uint32_t num_sym_prb_pattern;
4640 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_sym_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_sym_prb_pattern);
4641 /* reserved (3 bits) */
4642 add_reserved_field(extension_tree, hf_oran_reserved_bits456, tvb, offset, 1);
4643 /* prbMode (1 bit) */
4644 bool_Bool prb_mode;
4645 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_prb_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prb_mode);
4646 offset += 1;
4647
4648 /* reserved (8 bits) */
4649 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4650 offset += 1;
4651
4652 /* Dissect each SymPrbPattern */
4653 for (uint32_t n=0; n < num_sym_prb_pattern; n++) {
4654
4655 /* Subtree */
4656 proto_item *pattern_ti = proto_tree_add_string_format(extension_tree, hf_oran_sym_prb_pattern,
4657 tvb, offset, 1, "",
4658 prb_mode ? "PRB-BLOCK" : "PRB-MASK");
4659 proto_tree *pattern_tree = proto_item_add_subtree(pattern_ti, ett_oran_sym_prb_pattern);
4660
4661
4662 /* Orange part */
4663
4664 /* Reserved (2 bits) */
4665 add_reserved_field(pattern_tree, hf_oran_reserved_2bits, tvb, offset, 1);
4666 /* symMask (14 bits) */
4667 proto_tree_add_item(pattern_tree, hf_oran_sym_mask, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4668 offset += 2;
4669 /* numMcScaleOffset (4 bits) */
4670 uint32_t numMcScaleOffset;
4671 proto_tree_add_item_ret_uint(pattern_tree, hf_oran_num_mc_scale_offset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &numMcScaleOffset);
4672
4673 if (!prb_mode) { /* PRB-MASK */
4674 /* prbPattern (4 bits) */
4675 proto_tree_add_item(pattern_tree, hf_oran_prb_pattern, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4676 offset += 1;
4677 /* reserved (8 bits) */
4678 add_reserved_field(pattern_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4679 offset += 1;
4680 /* reserved (4 bits) */
4681 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4682 }
4683 else { /* PRB-BLOCK */
4684 /* prbBlkOffset (8 bits) */
4685 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_offset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4686 offset += 1;
4687 /* prbBlkSize (8 bits) */
4688 proto_tree_add_item(pattern_tree, hf_oran_prb_blk_size, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4689 offset += 1;
4690 }
4691
4692 for (unsigned c=0; c < numMcScaleOffset; c++) {
4693 if (c > 0) {
4694 /* reserved (4 bits) */
4695 add_reserved_field(pattern_tree, hf_oran_reserved_4bits, tvb, offset, 1);
4696 }
4697
4698 static int * const remask_flags_even[] = {
4699 &hf_oran_mc_scale_re_mask_re1_even,
4700 &hf_oran_mc_scale_re_mask_re2_even,
4701 &hf_oran_mc_scale_re_mask_re3_even,
4702 &hf_oran_mc_scale_re_mask_re4_even,
4703 &hf_oran_mc_scale_re_mask_re5_even,
4704 &hf_oran_mc_scale_re_mask_re6_even,
4705 &hf_oran_mc_scale_re_mask_re7_even,
4706 &hf_oran_mc_scale_re_mask_re8_even,
4707 &hf_oran_mc_scale_re_mask_re9_even,
4708 &hf_oran_mc_scale_re_mask_re10_even,
4709 &hf_oran_mc_scale_re_mask_re11_even,
4710 &hf_oran_mc_scale_re_mask_re12_even,
4711 NULL((void*)0)
4712 };
4713
4714 /* mcScaleReMask (12 bits). Defines which REs the following csf and mcScaleOffset apply to */
4715 uint64_t mcScaleReMask, mcScaleOffset;
4716 proto_tree_add_bitmask_ret_uint64(pattern_tree, tvb, offset,
4717 hf_oran_mc_scale_re_mask_even,
4718 ett_oran_mc_scale_remask,
4719 remask_flags_even, ENC_BIG_ENDIAN0x00000000, &mcScaleReMask);
4720 offset += 2;
4721
4722 /* csf (1 bit) */
4723 bool_Bool csf;
4724 dissect_csf(pattern_tree, tvb, offset*8, ci_iq_width, &csf);
4725 /* mcScaleOffset (15 bits) */
4726 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);
4727 uint16_t exponent = (mcScaleOffset >> 11) & 0x000f; /* m.s. 4 bits */
4728 uint16_t mantissa = mcScaleOffset & 0x07ff; /* l.s. 11 bits */
4729 float mcScaleOffset_value = ((float)mantissa/(1<<11)) * ((float)1.0 / (1 << exponent));
4730 proto_item_append_text(ti, " (%f)", mcScaleOffset_value);
4731
4732 offset += 2;
4733
4734 /* Record this config. */
4735 /* TODO: at some point, will also want to store/use PRB + symbol filters */
4736 section_mod_compr_config_t* sect_config = get_mod_compr_section_to_write(state, sectionId);
4737
4738 if (sect_config && sect_config->num_configs < MAX_MOD_COMPR_CONFIGS12) {
4739 unsigned i = sect_config->num_configs;
4740 sect_config->configs[i].mod_compr_re_mask = (uint16_t)mcScaleReMask;
4741 sect_config->configs[i].mod_compr_csf = csf;
4742 sect_config->configs[i].mod_compr_scaler = mcScaleOffset_value;
4743 sect_config->num_configs++;
4744 }
4745 }
4746
4747 proto_item_set_end(pattern_ti, tvb, offset);
4748 }
4749 break;
4750 }
4751
4752 case 24: /* SE 24: PUSCH DMRS configuration */
4753 {
4754 /* Hidden filter for bf (DMRS BF) */
4755 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
4756 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
4757
4758 /* alpnPerSym (1 bit) */
4759 proto_tree_add_item(extension_tree, hf_oran_alpn_per_sym, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4760 /* antDmrsSnr (1 bit) */
4761 proto_tree_add_item(extension_tree, hf_oran_ant_dmrs_snr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4762 /* reserved (1 bit) */
4763 add_reserved_field(extension_tree, hf_oran_reserved_bit2, tvb, offset, 1);
4764 /* userGroupSize (5 bits) */
4765 uint32_t user_group_size;
4766 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);
4767 if (user_group_size == 0) {
4768 proto_item_append_text(ugs_ti, " (not used)");
4769 }
4770 else if (user_group_size > 12) {
4771 proto_item_append_text(ugs_ti, " (reserved)");
4772 }
4773 offset += 1;
4774 /* userGroupId (8 bits)*/
4775 uint32_t user_group_id;
4776 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);
4777 if (user_group_id == 0) {
4778 /* TODO: Value 0 can happen in several cases, described in 7.7.24.7.. */
4779 }
4780 if (user_group_id == 255) {
4781 /* Value 255 is reserved */
4782 expert_add_info(pinfo, ugi_ti, &ei_oran_user_group_id_reserved_value);
4783 }
4784 offset += 1;
4785
4786 bool_Bool seen_value_to_inherit = false0;
4787 bool_Bool inherited_config_has_transform_precoding = false0;
4788 int dmrs_configs_seen = 0;
4789
4790 /* Dissect each entry until reach number of configured ueIds (or run out of extlen bytes..) */
4791 uint32_t ueid_index = 0;
4792 while ((offset < (extension_start_offset + extlen*4)) && (ueid_index < number_of_ueids)) {
4793 dmrs_configs_seen++;
4794
4795 /* Subtree */
4796 proto_item *entry_ti = proto_tree_add_string_format(extension_tree, hf_oran_dmrs_entry,
4797 tvb, offset, 0, "",
4798 "Entry");
4799 proto_tree *entry_tree = proto_item_add_subtree(entry_ti, ett_oran_dmrs_entry);
4800
4801 /* entryType (3 bits) */
4802 uint32_t entry_type;
4803 proto_item *entry_type_ti;
4804 entry_type_ti = proto_tree_add_item_ret_uint(entry_tree, hf_oran_entry_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &entry_type);
4805 if (entry_type > 3) {
4806 proto_item_append_text(entry_type_ti, " (reserved)");
4807 }
4808
4809 /* dmrsPortNumber (5 bits). Values 0-11 allowed */
4810 unsigned int dmrs_port_number;
4811 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);
4812 if (dmrs_port_number > 11) {
4813 proto_item_append_text(dpn_ti, " (12-31 are reserved)");
4814 }
4815 offset += 1;
4816
4817 /* What follows depends upon entryType */
4818 switch (entry_type) {
4819 case 0: /* dmrsPortNumber config same as previous, ueId ueIdReset=0 */
4820 case 1: /* dmrsPortNumber config same as previous, ueId ueIdReset=1 */
4821 /* No further fields for these */
4822 /* Error here if no previous values to inherit!! */
4823 if (!seen_value_to_inherit) {
4824 expert_add_info_format(pinfo, entry_type_ti, &ei_oran_se24_nothing_to_inherit,
4825 "SE24: have seen entry type %u, but no previous config (type 2 or 3) to inherit config from", entry_type);
4826
4827 }
4828 /* TODO: would be useful to repeat whole inherited config here? */
4829 break;
4830
4831 case 2: /* transform precoding disabled */
4832 case 3: /* transform precoding enabled */
4833 {
4834 /* Type 2/3 are very similar.. */
4835
4836 /* ueIdReset (1 bit) */
4837 proto_tree_add_item(entry_tree, hf_oran_ueid_reset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4838 /* posMeas (1 bit) */
4839 proto_tree_add_item(entry_tree, hf_oran_pos_meas, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4840
4841 /* dmrsSymbolMask (14 bits) */
4842 static int * const dmrs_symbol_mask_flags[] = {
4843 &hf_oran_dmrs_symbol_mask_s13,
4844 &hf_oran_dmrs_symbol_mask_s12,
4845 &hf_oran_dmrs_symbol_mask_s11,
4846 &hf_oran_dmrs_symbol_mask_s10,
4847 &hf_oran_dmrs_symbol_mask_s9,
4848 &hf_oran_dmrs_symbol_mask_s8,
4849 &hf_oran_dmrs_symbol_mask_s7,
4850 &hf_oran_dmrs_symbol_mask_s6,
4851 &hf_oran_dmrs_symbol_mask_s5,
4852 &hf_oran_dmrs_symbol_mask_s4,
4853 &hf_oran_dmrs_symbol_mask_s3,
4854 &hf_oran_dmrs_symbol_mask_s2,
4855 &hf_oran_dmrs_symbol_mask_s1,
4856 &hf_oran_dmrs_symbol_mask_s0,
4857 NULL((void*)0)
4858 };
4859 proto_tree_add_bitmask(entry_tree, tvb, offset,
4860 hf_oran_dmrs_symbol_mask, ett_oran_dmrs_symbol_mask, dmrs_symbol_mask_flags, ENC_BIG_ENDIAN0x00000000);
4861 offset += 2;
4862
4863 /* scrambling */
4864 proto_tree_add_item(entry_tree, hf_oran_scrambling, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4865 offset += 2;
4866
4867 /* nscid (1 bit) */
4868 proto_tree_add_item(entry_tree, hf_oran_nscid, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4869
4870 /* These 5 bits differ depending upon entry type */
4871 if (entry_type == 2) { /* type 2 */
4872 /* dType (1 bit) */
4873 proto_tree_add_item(entry_tree, hf_oran_dtype, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4874 /* cdmWithoutData (2 bits) */
4875 proto_tree_add_item(entry_tree, hf_oran_cmd_without_data, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4876 /* lambda (2 bits) */
4877 proto_tree_add_item(entry_tree, hf_oran_lambda, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4878 }
4879 else { /* type 3 */
4880 /* reserved (1 bit) */
4881 add_reserved_field(entry_tree, hf_oran_reserved_bit1, tvb, offset, 1);
4882 /* lowPaprType (2 bits) */
4883 proto_tree_add_item(entry_tree, hf_oran_low_papr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4884 /* hoppingMode (2 bits) */
4885 proto_tree_add_item(entry_tree, hf_oran_hopping_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4886 }
4887
4888 /* firstPrb (9 bits) */
4889 proto_tree_add_item(entry_tree, hf_oran_first_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4890 offset += 1;
4891 /* lastPrb (9 bits) */
4892 proto_tree_add_item(entry_tree, hf_oran_last_prb, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
4893 offset += 2;
4894 /* Reserved (16 bits) */
4895 add_reserved_field(entry_tree, hf_oran_reserved_16bits, tvb, offset, 2);
4896 offset += 2;
4897
4898 /* Could now see entry types 0 or 1 - they have these values to inherit */
4899 seen_value_to_inherit = true1;
4900 inherited_config_has_transform_precoding = (entry_type == 3);
4901 break;
4902 }
4903
4904 default:
4905 /* reserved - expert info */
4906 break;
4907 }
4908
4909 proto_item_append_text(entry_ti, " [UEId=%u] (dmrsPortNumber=%2u) (type %u - %s) ",
4910 ueids[ueid_index++], dmrs_port_number, entry_type, val_to_str_const(entry_type, entry_type_vals, "Unknown"));
4911 proto_item_set_end(entry_ti, tvb, offset);
4912
4913 if (entry_type <= 1) {
4914 proto_item_append_text(entry_ti, " [transform-precoding %s]",
4915 inherited_config_has_transform_precoding ? "enabled" : "disabled");
4916 }
4917 }
4918
4919 proto_item_append_text(extension_ti, " (%d DMRS configs seen)", dmrs_configs_seen);
4920 break;
4921 }
4922
4923 case 25: /* SE 25: Symbol reordering for DMRS-BF */
4924 /* Just dissect each available block of 7 bytes as the 14 symbols for a layer,
4925 where each layer could be one or apply to all layers. */
4926 {
4927 /* TODO: should only appear in one section of a message - check? */
4928 unsigned layer = 0;
4929 proto_item *layer_ti;
4930 while (offset+7 <= (extension_start_offset + extlen*4)) {
4931 /* Layer subtree */
4932 layer_ti = proto_tree_add_string_format(extension_tree, hf_oran_symbol_reordering_layer,
4933 tvb, offset, 7, "",
4934 "Layer");
4935 proto_tree *layer_tree = proto_item_add_subtree(layer_ti, ett_oran_symbol_reordering_layer);
4936
4937 /* All 14 symbols for a layer (or all layers) */
4938 for (unsigned s=0; s < 14; s++) {
4939 proto_item *sym_ti;
4940 /* txWinForOnAirSymbol */
4941 unsigned int tx_win_for_on_air_symbol;
4942 sym_ti = proto_tree_add_item_ret_uint(layer_tree,
4943 (s % 2) ? hf_oran_tx_win_for_on_air_symbol_r : hf_oran_tx_win_for_on_air_symbol_l,
4944 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &tx_win_for_on_air_symbol);
4945 if (tx_win_for_on_air_symbol == 0x0F) {
4946 /* Ordering not affected */
4947 proto_item_append_text(sym_ti, " (sym %u - no info)", s);
4948 }
4949 else {
4950 proto_item_append_text(sym_ti, " (sym %u)", s);
4951 }
4952 if (s % 2) {
4953 offset += 1;
4954 }
4955 }
4956
4957 proto_item_append_text(layer_ti, " (layer %u)", ++layer);
4958 proto_item_append_text(extension_ti, " (layer %u)", layer);
4959 }
4960 /* Set layer subtree label */
4961 if (layer == 1) {
4962 proto_item_append_text(layer_ti, " (all)");
4963 proto_item_append_text(extension_ti, " (all)");
4964 }
4965 if (layer == 0) {
4966 /* TODO: are no layers valid? What does it mean? */
4967 proto_item_append_text(extension_ti, " (none)");
4968 }
4969 break;
4970 }
4971
4972 case 26: /* SE 26: Frequency offset feedback */
4973 /* Reserved (8 bits) */
4974 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
4975 offset += 1;
4976 /* Reserved (1 bit) */
4977 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
4978 /* numFoFb (7 bits) */
4979 unsigned num_fo_fb;
4980 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_fo_fb, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_fo_fb);
4981 offset += 1;
4982
4983 /* Add each freqOffsetFb value */
4984 for (unsigned n=0; n < num_fo_fb; n++) {
4985 unsigned freq_offset_fb;
4986 /* freqOffsetFb (16 bits) */
4987 proto_item *offset_ti = proto_tree_add_item_ret_uint(extension_tree, hf_oran_freq_offset_fb,
4988 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &freq_offset_fb);
4989 /* Show if maps onto a -ve number */
4990 if ((freq_offset_fb >= 0x8ad0) && (freq_offset_fb <= 0xffff)) {
4991 proto_item_append_text(offset_ti, "(value %d)", -1 - (0xffff-freq_offset_fb));
4992 }
4993 proto_item_append_text(offset_ti, " [#%u]", n+1);
4994 offset += 2;
4995 }
4996 break;
4997
4998 case 27: /* SE 27: O-DU controlled dimensionality reduction */
4999 {
5000 /* Hidden filter for bf (DMRS BF) */
5001 bf_ti = proto_tree_add_item(tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5002 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5003
5004 /* beamType (2 bits) */
5005 unsigned beam_type;
5006 proto_tree_add_item_ret_uint(extension_tree, hf_oran_beam_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &beam_type);
5007 /* reserved (6 bits) */
5008 add_reserved_field(extension_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
5009 offset += 1;
5010
5011 /* numElements */
5012 unsigned num_elements;
5013 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);
5014 if (num_elements == 0) {
5015 num_elements = 256;
5016 proto_item_append_text(num_elements_ti, " (256");
5017 }
5018
5019 offset += 1;
5020
5021 /* beamId value(s) */
5022 switch (beam_type) {
5023 case 0:
5024 for (unsigned n=0; n < num_elements; n++) {
5025 /* reserved (1 bit) + beamId */
5026 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5027 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5028 offset += 2;
5029 }
5030 break;
5031 case 1:
5032 /* reserved (1 bit) + beamId */
5033 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5034 proto_tree_add_item(c_section_tree, hf_oran_beamId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5035 offset += 2;
5036 break;
5037 default:
5038 /* Unknown type... */
5039 break;
5040 }
5041 break;
5042 }
5043
5044 case 28: /* SE 28: O-DU controlled frequency resolution for SINR reporting */
5045 {
5046 /* reserved (3 bits) */
5047 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5048 /* numUeSinrRpt (5 bits) */
5049 uint32_t num_ue_sinr_rpt;
5050 proto_tree_add_item_ret_uint(extension_tree, hf_oran_num_ue_sinr_rpt, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_ue_sinr_rpt);
5051 offset += 1;
5052
5053 for (uint32_t n=0; n < num_ue_sinr_rpt; n++) {
5054 /* reserved (1 bit) */
5055 add_reserved_field(extension_tree, (n % 2) ? hf_oran_reserved_bit4 : hf_oran_reserved_1bit,
5056 tvb, offset, 1);
5057
5058 /* numSinrPerPrb (3 bits). Taken from alternate nibbles within byte. */
5059 proto_tree_add_item(extension_tree, (n % 2) ? hf_oran_num_sinr_per_prb_right : hf_oran_num_sinr_per_prb,
5060 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5061 if (n % 2) {
5062 offset += 1;
5063 }
5064 }
5065
5066 /* May need to skip beyond half-used byte */
5067 if (num_ue_sinr_rpt % 2) {
5068 offset += 1;
5069 }
5070 break;
5071 }
5072
5073 case 29: /* SE 29: Cyclic delay adjustment */
5074 /* reserved (4 bits) */
5075 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5076 /* cdScgSize (4 bits) */
5077 proto_tree_add_item(extension_tree, hf_oran_cd_scg_size, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5078 offset += 1;
5079
5080 /* cdScgPhaseStep */
5081 proto_tree_add_item(extension_tree, hf_oran_cd_scg_phase_step, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5082 offset += 1;
5083 break;
5084
5085 case 30: /* SE 30: PUSCH repetition indication */
5086 {
5087 /* Only valid for UL */
5088 if (!tap_info->uplink) {
5089 expert_add_info(pinfo, extension_ti, &ei_oran_se30_not_ul);
5090 }
5091
5092 /* ueids[], number_of_ueids may have been rewritten by SE10 */
5093
5094 /* reserved (4 bits) */
5095 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5096 /* numRepUe (4 bits) */
5097 uint8_t num_rep_ue;
5098 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_rep_ue, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_rep_ue);
5099 offset ++;
5100 /* reserved (8 bits) */
5101 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5102 offset += 1;
5103
5104 if (num_rep_ue == 1) {
5105 /* SE10 *not* present. N.B. this should tally with number_of_ueids being set to only 1? */
5106 /* reserved (1 bit) */
5107 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5108 /* isLastRep (1 bit). Value meaningless here? */
5109 proto_tree_add_item(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5110 /* repIndex (6 bits) */
5111 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5112 offset += 1;
5113
5114 /* reserved (2 bits) */
5115 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5116 /* numReps (6 bits) */
5117 uint8_t num_reps;
5118 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_reps, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_reps);
5119 /* TODO: should numReps be 0 here? */
5120 offset += 1;
5121
5122 /* reserved (2 bits) */
5123 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5124 offset += 2;
5125
5126 }
5127 else {
5128 /* SE10 present */
5129 bool_Bool is_last_rep = false0;
5130 /* TODO: should is_last_rep (also) cause loop exit? */
5131 for (uint8_t ue_idx=0; (ue_idx < num_rep_ue) && !is_last_rep; ue_idx++) {
5132 /* reserved (1 bit) */
5133 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5134 /* isLastRep (1 bit) */
5135 proto_tree_add_item_ret_boolean(extension_tree, hf_oran_is_last_rep, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &is_last_rep);
5136 /* repIndex (6 bits) */
5137 proto_tree_add_item(extension_tree, hf_oran_rep_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5138 offset += 1;
5139
5140 /* reserved (2 bits) */
5141 add_reserved_field(extension_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5142 /* numReps (6 bits) */
5143 uint8_t num_reps;
5144 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);
5145 /* TODO: values 33-63 are reserved */
5146 if (num_reps > 32) {
5147 proto_item_append_text(num_reps_ti, " (reserved)");
5148 }
5149 offset += 1;
5150
5151 for (uint8_t rep=0; rep < num_reps; rep++) {
5152 /* reserved (1 bit) */
5153 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5154 /* repUeId (15 bits) */
5155 /* TODO: should be fetching and comparing with ueids[] from SE10? */
5156 uint16_t ueid;
5157 proto_item *ueid_ti = proto_tree_add_item_ret_uint16(extension_tree, hf_oran_rep_ueid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ueid);
5158
5159 /* Check that this ueid is recognised (among ueids[], number_of_ueids) */
5160 bool_Bool matched = false0;
5161 for (unsigned u=0; u < number_of_ueids; u++) {
5162 if (ueid == ueids[u])
5163 matched = true1;
5164 }
5165 if (!matched) {
5166 expert_add_info_format(pinfo, ueid_ti, &ei_oran_se30_unknown_ueid,
5167 "SE 30 mentions UEId %u - not seen in SE10", ueid);
5168 }
5169 offset += 2;
5170 }
5171 }
5172 }
5173 break;
5174 }
5175 case 31: /* SE 31: MCS Information */
5176 {
5177 /* TODO: show ueid (from ST5 or SE10) as generated field? Maybe add a subtree for each entry? */
5178 for (uint32_t u=0; u < number_of_ueids; u++) {
5179 /* reserved (4 bits) */
5180 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5181 /* mcsTable (4 bits) */
5182 proto_tree_add_item(extension_tree, hf_oran_mcs_table, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5183 offset += 1;
5184
5185 /* reserved (2 bits) */
5186 add_reserved_field(extension_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5187 /* mcsIndex (6 bits) */
5188 proto_tree_add_item(extension_tree, hf_oran_mcs_index, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5189 }
5190 break;
5191 }
5192
5193 case 32: /* SE 32: Rank and TPMI measurement request */
5194 {
5195 /* reserved (3 bits) */
5196 add_reserved_field(extension_tree, hf_oran_reserved_3bits, tvb, offset, 1);
5197 /* numMeasReq (5 bits) */
5198 uint8_t num_meas_req;
5199 proto_tree_add_item_ret_uint8(extension_tree, hf_oran_num_meas_req, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_meas_req);
5200 offset += 1;
5201
5202 /* reserved (8 bits) */
5203 add_reserved_field(extension_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5204 offset += 1;
5205
5206 /* Show each measurement request */
5207 for (unsigned r=0; r < num_meas_req; r++) {
5208 /* Reserved (1 bit) */
5209 add_reserved_field(extension_tree, hf_oran_reserved_1bit, tvb, offset, 1);
5210 /* ueId (14 bits) */
5211 proto_tree_add_item(extension_tree, hf_oran_ueId, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5212 offset += 2;
5213
5214 /* numOfUeAntPorts (4 bits) */
5215 proto_tree_add_item(extension_tree, hf_oran_num_of_ue_ant_ports, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5216 /* ueRank (4 bits) */
5217 proto_tree_add_item(extension_tree, hf_oran_ue_rank, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5218 offset += 1;
5219
5220 /* codebookSubset (2 bits) */
5221 proto_tree_add_item(extension_tree, hf_oran_codebook_subset, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5222 /* TODO: tpmiIndex (6 bits) */
5223 offset += 1;
5224
5225 /* fullPwrMode (2 bits) */
5226 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5227 /* fullPwrMode2TmpiGroup (14 bits) */
5228 /* TODO: add as a bitset */
5229 proto_tree_add_item(extension_tree, hf_oran_full_pwr_mode_2_tpmi_group, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5230 offset += 2;
5231
5232 /* reserved (2 bytes) */
5233 add_reserved_field(extension_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5234 offset += 2;
5235 }
5236 break;
5237 }
5238
5239 default:
5240 /* Other/unexpected extension types */
5241 expert_add_info_format(pinfo, exttype_ti, &ei_oran_unhandled_se,
5242 "SE %u (%s) not supported by dissector",
5243 exttype, val_to_str_ext_const(exttype, &exttype_vals_ext, "Reserved"));
5244 ext_unhandled = true1;
5245 break;
5246 }
5247
5248 /* Check offset compared with extlen. There should be 0-3 bytes of padding */
5249 int num_padding_bytes = (extension_start_offset + (extlen*4) - offset);
5250 if (!ext_unhandled && ((num_padding_bytes<0) || (num_padding_bytes>3))) {
5251 expert_add_info_format(pinfo, extlen_ti, &ei_oran_extlen_wrong,
5252 "extlen signalled %u bytes (+ 0-3 bytes padding), but %u were dissected",
5253 extlen*4, offset-extension_start_offset);
5254 }
5255
5256 /* Move offset to beyond signalled length of extension */
5257 offset = extension_start_offset + (extlen*4);
5258
5259 /* Set length of extension header. */
5260 proto_item_set_len(extension_ti, extlen*4);
5261 }
5262 /* End of section extension handling */
5263
5264 /* Tap section beamId if not overwritten by SEs */
5265 if (!section_beamId_ignored && section_beamId != 0) {
5266 add_beam_id_to_tap(tap_info, section_beamId);
5267 }
5268
5269
5270 /* RRM measurement reports have measurement reports *after* extensions */
5271 if (sectionType == SEC_C_RRM_MEAS_REPORTS) /* Section Type 10 */
5272 {
5273 /* Hidden filter for bf (DMFS-BF). No BF weights though.. */
5274 bf_ti = proto_tree_add_item(c_section_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
5275 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
5276
5277 bool_Bool mf;
5278 do {
5279 /* Measurement report subtree */
5280 proto_item *mr_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_report,
5281 tvb, offset, 1, "", "Measurement Report");
5282 proto_tree *mr_tree = proto_item_add_subtree(mr_ti, ett_oran_measurement_report);
5283 unsigned report_start_offset = offset;
5284
5285 /* measurement flag (i.e., more reports after this one) (1 bit) */
5286 proto_tree_add_item_ret_boolean(mr_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5287
5288 /* measTypeId (7 bits) */
5289 uint32_t meas_type_id;
5290 proto_item *meas_type_id_ti;
5291 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);
5292 offset += 1;
5293
5294 /* Common to all measurement types */
5295 unsigned num_elements = 0;
5296 if (meas_type_id == 6) {
5297 /* numElements */
5298 proto_tree_add_item_ret_uint(mr_tree, hf_oran_num_elements, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &num_elements);
5299 }
5300 else {
5301 /* All other meas ids have a reserved byte */
5302 add_reserved_field(mr_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5303 }
5304 offset += 1;
5305
5306 /* measDataSize (16 bits). N.B. begins at mf field, i.e. 2 bytes before this one */
5307 unsigned meas_data_size;
5308 proto_item *meas_data_size_ti;
5309 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);
5310 meas_data_size *= 4;
5311 proto_item_append_text(meas_data_size_ti, " (%u bytes)", meas_data_size);
5312 offset += 2;
5313
5314 /* Summary for measurement report root */
5315 proto_item_append_text(mr_ti, " (measTypeId=%u - %s)",
5316 meas_type_id, val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5317 /* And section header */
5318 proto_item_append_text(tree, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5319 /* And Info column */
5320 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5321
5322 /* Handle specific message type fields */
5323 switch (meas_type_id) {
5324 case 1:
5325 {
5326 /* ueTae */
5327 unsigned ue_tae;
5328 proto_item *ue_tae_ti;
5329 ue_tae_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ue_tae, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ue_tae);
5330 /* Show if maps onto a -ve number */
5331 if ((ue_tae >= 0x8ad0) && (ue_tae <= 0xffff)) {
5332 proto_item_append_text(ue_tae_ti, "(value %d)", -1 - (0xffff-ue_tae));
5333 }
5334 offset += 2;
5335
5336 /* Reserved (16 bits) */
5337 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5338 offset += 2;
5339 break;
5340 }
5341 case 2:
5342 /* ueLayerPower entries (how many? for now just use up meas_data_size..) */
5343 /* TODO: add number of distinct dmrsPortNumber entries seen in SE24 and save in state? */
5344 /* Or would it make sense to use the preference 'pref_num_bf_antennas' ? */
5345 for (unsigned n=0; n < (meas_data_size-4)/2; n++) {
5346 unsigned ue_layer_power;
5347 proto_item *ue_layer_power_ti;
5348 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);
5349 /* Show if maps onto a -ve number */
5350 if ((ue_layer_power >= 0x8ad0) && (ue_layer_power <= 0xffff)) {
5351 proto_item_append_text(ue_layer_power_ti, "(value %d)", -1 - (0xffff-ue_layer_power));
5352 }
5353 offset += 2;
5354 }
5355 /* padding out to 4 bytes */
5356 break;
5357 case 3:
5358 {
5359 /* ueFreqOffset */
5360 unsigned ue_freq_offset;
5361 proto_item *ue_freq_offset_ti;
5362 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);
5363 /* Show if maps onto a -ve number */
5364 if ((ue_freq_offset >= 0x8ad0) && (ue_freq_offset <= 0xffff)) {
5365 proto_item_append_text(ue_freq_offset_ti, "(value %d)", -1 - (0xffff-ue_freq_offset));
5366 }
5367 offset += 2;
5368
5369 /* Reserved (16 bits) */
5370 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5371 offset += 2;
5372 break;
5373 }
5374 case 4:
5375 case 5:
5376 /* reserved (2 bits) */
5377 add_reserved_field(mr_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5378 /* symbolMask (14 bits) */
5379 offset = dissect_symbolmask(tvb, mr_tree, offset, NULL((void*)0), NULL((void*)0));
5380
5381 /* 2 bytes for each PRB ipnPower */
5382 for (unsigned prb=0; prb<MAX_PRBS273; prb++) {
5383 /* Skip if should not be reported */
5384 if (!prbs_for_st10_type5[prb]) {
5385 continue;
5386 }
5387 unsigned ipn_power;
5388 proto_item *ipn_power_ti;
5389 /* ipnPower (2 bytes) */
5390 ipn_power_ti = proto_tree_add_item_ret_uint(mr_tree, hf_oran_ipn_power, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ipn_power);
5391 proto_item_append_text(ipn_power_ti, " (PRB %3d)", prb);
5392 /* Show if maps onto a -ve number */
5393 if ((ipn_power >= 0x8ad0) && (ipn_power <= 0xffff)) {
5394 proto_item_append_text(ipn_power_ti, " (value %d)", -1 - (0xffff-ipn_power));
5395 }
5396 offset += 2;
5397 }
5398 /* padding out to 4 bytes */
5399 break;
5400 case 6:
5401 /* antDmrsSnrVal entries */
5402 for (unsigned n=0; n < num_elements; n++) {
5403 unsigned snr_value;
5404 proto_item *snr_value_ti;
5405 /* antDmrsSnrVal (2 bytes) */
5406 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);
5407 proto_item_append_text(snr_value_ti, " (elem %2u)", n+1);
5408 /* Show if maps onto a -ve number */
5409 if ((snr_value >= 0x8ad0) && (snr_value <= 0xffff)) {
5410 proto_item_append_text(snr_value_ti, " (value %d)", -1 - (0xffff-snr_value));
5411 }
5412 offset += 2;
5413 }
5414 break;
5415 case 7:
5416 {
5417 /* UE positioning measurement report */
5418 float start_value;
5419
5420 /* ueAzAoa (16 bits) */
5421 uint32_t ue_az_aoa;
5422 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);
5423 if (ue_az_aoa <= 0xE0F) {
5424 if (ue_az_aoa >= 0x0708) {
5425 start_value = (ue_az_aoa-0x0708) * (float)0.1;
5426 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5427 }
5428 else {
5429 start_value = 180 + (ue_az_aoa * (float)0.1);
5430 proto_item_append_text(ue_az_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5431 }
5432 }
5433 else if (ue_az_aoa == 0xffff) {
5434 proto_item_append_text(ue_az_aoa_ti, " (invalid measurement result)");
5435 }
5436 else {
5437 proto_item_append_text(ue_az_aoa_ti, " (reserved)");
5438 }
5439 offset += 2;
5440
5441 /* Reserved (16 bits) */
5442 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5443 offset += 2;
5444
5445 /* ueZeAoa (16 bits) */
5446 uint32_t ue_ze_aoa;
5447 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);
5448 if (ue_ze_aoa <= 0x707) {
5449 start_value = ue_ze_aoa * (float)0.1;
5450 proto_item_append_text(ue_ze_aoa_ti, " (%.1f <= val < %.1f degrees)", start_value, start_value + (float)0.1);
5451 }
5452 else if (ue_az_aoa == 0xffff) {
5453 proto_item_append_text(ue_ze_aoa_ti, " (invalid measurement result)");
5454 }
5455 else {
5456 proto_item_append_text(ue_ze_aoa_ti, " (reserved)");
5457 }
5458 offset += 2;
5459
5460 /* Reserved (16 bits) */
5461 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5462 offset += 2;
5463
5464 /* uePosToaOffset (16 bits) */
5465 uint32_t ue_pos_toa_offset;
5466 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);
5467 if (ue_pos_toa_offset == 0) {
5468 proto_item_append_text(ue_pos_toa_offset_ti, " (no UE ToA offset, 0 symbols)");
5469 }
5470 else if (ue_pos_toa_offset <= 0x7fff) {
5471 proto_item_append_text(ue_pos_toa_offset_ti, " (+ve UE ToA offset)");
5472 }
5473 else if (ue_pos_toa_offset == 0x8000) {
5474 proto_item_append_text(ue_pos_toa_offset_ti, " (invalid measurement result)");
5475 }
5476 else {
5477 proto_item_append_text(ue_pos_toa_offset_ti, " (-ve UE ToA offset)");
5478 }
5479 offset += 2;
5480
5481 /* Reserved (16 bits) */
5482 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5483 offset += 2;
5484 break;
5485 }
5486 case 8:
5487 {
5488 /* UE radial speed measurement report */
5489
5490 /* ueRadialSpeed (16 bits) */
5491 uint32_t radial_speed;
5492 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);
5493 if (radial_speed <= 10000) {
5494 proto_item_append_text(radial_speed_ti, " (%.1f km/h)", radial_speed * (float)0.1);
5495 }
5496 else if (radial_speed == 0x8000) {
5497 proto_item_append_text(radial_speed_ti, " (invalid measurement result)");
5498 }
5499 else {
5500 proto_item_append_text(radial_speed_ti, " (reserved value)");
5501 }
5502 offset += 2;
5503
5504 /* Reserved (16 bits) */
5505 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5506 offset += 2;
5507 break;
5508 }
5509 case 9:
5510 {
5511 /* TODO: UE post-equalization MU interference measurement */
5512
5513 /* reserved (16 bits) */
5514 add_reserved_field(mr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5515 offset += 2;
5516
5517 /* TODO: muInterferenceLevel (all layers * all PRB blocks) */
5518 break;
5519 }
5520 case 10:
5521 {
5522 /* UE TPMI and rank recommendation measurement */
5523
5524 /* numCandRanks (4 bits - only 1-4 valid) */
5525 uint8_t num_cand_ranks;
5526 proto_tree_add_item_ret_uint8(mr_tree, hf_oran_num_cand_ranks, tvb, offset, 1, ENC_NA0x00000000, &num_cand_ranks);
5527 if (num_cand_ranks > 4) {
5528 num_cand_ranks = 4;
5529 }
5530 if (num_cand_ranks < 1) {
5531 num_cand_ranks = 1;
5532 }
5533
5534 /* uePrefRank (4 bits) */
5535 add_reserved_field(mr_tree, hf_oran_ue_pref_rank, tvb, offset, 1);
5536 offset += 1;
5537
5538 for (uint8_t cand_rank=1; cand_rank <= num_cand_ranks; cand_rank++) {
5539 /* ueTpmiRankY (1 byte) */
5540 proto_item *rank_y_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y,
5541 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5542 proto_item_append_text(rank_y_ti, " (rank %u)", cand_rank);
5543
5544 offset += 1;
5545
5546 for (uint8_t sinr = 1; sinr <= cand_rank; sinr++) {
5547 /* ueTpmiRankYSinrLX (2 bytes) */
5548 proto_item *rank_y_sinr_x_ti = proto_tree_add_item(mr_tree, hf_oran_ue_tpmi_rank_y_sinr_lx,
5549 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5550 proto_item_append_text(rank_y_sinr_x_ti, " (rank %u, sinr %u)", cand_rank, sinr);
5551 offset += 2;
5552 }
5553 }
5554 break;
5555 }
5556 case 11:
5557 {
5558 /* UE layer pre-equalization SINR report */
5559 /* TODO: how to know how many layers? Just fill up available data? */
5560 unsigned num_layers = (meas_data_size-1) * 4;
5561 for (unsigned layer=0; layer < num_layers; layer++) {
5562 /* ueLayerPreEqSinr (2 bytes each) */
5563 proto_item *pre_eq_sinr_ti = proto_tree_add_item(mr_tree, hf_oran_ue_layer_pre_eq_sinr,
5564 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5565 proto_item_append_text(pre_eq_sinr_ti, " (layer %u)", layer);
5566 offset += 2;
5567 }
5568 break;
5569 }
5570
5571 default:
5572 /* Anything else is not expected */
5573 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5574 "measTypeId %u (%s) not supported - only 1-6 are expected",
5575 meas_type_id,
5576 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5577 break;
5578
5579 }
5580
5581 /* Pad out to next 4 bytes */
5582 offset += WS_PADDING_TO_4(offset-report_start_offset)((4U - ((offset-report_start_offset) % 4U)) % 4U);
5583
5584 /* TODO: verify dissected size of report vs meas_data_size? */
5585
5586 /* End of measurement report tree */
5587 proto_item_set_end(mr_ti, tvb, offset);
5588 } while (mf);
5589 }
5590
5591 /* Request for RRM Measurements has measurement commands after extensions */
5592 else if (sectionType == SEC_C_REQUEST_RRM_MEAS) /* Section Type 11 */
5593 {
5594 bool_Bool mf = true1;
5595 do {
5596 /* Measurement command subtree */
5597 proto_item *mc_ti = proto_tree_add_string_format(c_section_tree, hf_oran_measurement_command,
5598 tvb, offset, 8, "", "Measurement Command");
5599 proto_tree *mc_tree = proto_item_add_subtree(mc_ti, ett_oran_measurement_command);
5600
5601 /* mf (1 bit). 1st measurement command is always preset */
5602 proto_tree_add_item_ret_boolean(mc_tree, hf_oran_mf, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mf);
5603
5604 /* measTypeId (7 bits) */
5605 uint32_t meas_type_id;
5606 proto_item *meas_type_id_ti;
5607 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);
5608 offset += 1;
5609
5610 proto_item *meas_command_ti;
5611 uint32_t meas_command_size;
5612
5613 switch (meas_type_id) {
5614 case 5: /* command for IpN for unallocated PRBs */
5615 /* reserved (1 byte) */
5616 add_reserved_field(mc_tree, hf_oran_reserved_8bits, tvb, offset, 1);
5617 offset += 1;
5618 /* measCmdSize. Presumably number of words so in future could skip unrecognised command types.. */
5619 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);
5620 proto_item_append_text(meas_command_ti, " (%u bytes)", meas_command_size*4);
5621 offset += 2;
5622 /* reserved (2 bits) */
5623 add_reserved_field(mc_tree, hf_oran_reserved_2bits, tvb, offset, 1);
5624 /* symbolMask (14 bits) */
5625 offset = dissect_symbolmask(tvb, mc_tree, offset, NULL((void*)0), NULL((void*)0));
5626 /* reserved (16 bits) */
5627 add_reserved_field(mc_tree, hf_oran_reserved_16bits, tvb, offset, 2);
5628 offset += 2;
5629 break;
5630
5631 default:
5632 /* Anything else is not expected */
5633 expert_add_info_format(pinfo, meas_type_id_ti, &ei_oran_unexpected_measTypeId,
5634 "measTypeId %u (%s) not supported - only 5 is expected",
5635 meas_type_id,
5636 val_to_str_const(meas_type_id, meas_type_id_vals, "reserved"));
5637 break;
5638 }
5639 proto_item_append_text(mc_ti, " (%s)", val_to_str_const(meas_type_id, meas_type_id_vals, "unknown"));
5640
5641 } while (mf);
5642 }
5643
5644 /* Set extent of overall section */
5645 proto_item_set_len(sectionHeading, offset);
5646
5647 return offset;
5648}
5649
5650/* Dissect udCompHdr (user data compression header, 7.5.2.10) */
5651/* bit_width and comp_meth are out params */
5652static int dissect_udcomphdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset,
5653 bool_Bool cplane, bool_Bool ignore,
5654 unsigned *bit_width, unsigned *comp_meth, proto_item **comp_meth_ti,
5655 oran_tap_info *tap_info)
5656{
5657 /* Subtree */
5658 proto_item *udcomphdr_ti = proto_tree_add_string_format(tree, hf_oran_udCompHdr,
5659 tvb, offset, 1, "",
5660 "udCompHdr");
5661 proto_tree *udcomphdr_tree = proto_item_add_subtree(udcomphdr_ti, ett_oran_udcomphdr);
5662
5663 /* udIqWidth */
5664 uint32_t hdr_iq_width;
5665 proto_item *iq_width_item = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5666 *bit_width = (hdr_iq_width) ? hdr_iq_width : 16;
5667 proto_item_append_text(iq_width_item, " (%u bits)", *bit_width);
5668
5669 /* udCompMeth */
5670 uint32_t ud_comp_meth;
5671 *comp_meth_ti = proto_tree_add_item_ret_uint(udcomphdr_tree, hf_oran_udCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ud_comp_meth);
5672 if (comp_meth) {
5673 *comp_meth = ud_comp_meth;
5674 }
5675
5676 /* Populate tap header with compression settings */
5677 if (!ignore) {
5678 tap_info->compression_methods |= (1 << ud_comp_meth);
5679 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))
;
5680 /* Summary */
5681 proto_item_append_text(udcomphdr_ti, " (IqWidth=%u, udCompMeth=%s)",
5682 *bit_width, rval_to_str_const(ud_comp_meth, ud_comp_header_meth, "Unknown"));
5683 }
5684 else {
5685 proto_item_append_text(udcomphdr_ti, " (ignored)");
5686 if (hdr_iq_width || ud_comp_meth) {
5687 if (cplane) {
5688 /* Only ignore DL for cplane */
5689 expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5690 "udCompHdr in C-Plane for DL should be 0 - found 0x%02x",
5691 tvb_get_uint8(tvb, offset));
5692 }
5693 else {
5694 /* TODO: Ignore UL if using m-plane/preference setting rather than c-plane, but wrong to be set? */
5695 /* expert_add_info_format(pinfo, udcomphdr_ti, &ei_oran_udpcomphdr_should_be_zero,
5696 "udCompHdr in C-Plane for UL should be 0 - found 0x%02x",
5697 tvb_get_uint8(tvb, offset));
5698 */
5699 }
5700
5701 }
5702 }
5703 return offset+1;
5704}
5705
5706/* Dissect udCompParam (user data compression parameter, 8.3.3.15) */
5707/* bit_width and comp_meth are out params */
5708static int dissect_udcompparam(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5709 unsigned comp_meth,
5710 uint32_t *exponent, uint16_t *sReSMask,
5711 bool_Bool for_sinr)
5712{
5713 if (for_sinr && (comp_meth != COMP_BLOCK_FP1)) {
5714 /* sinrCompParam only present when bfp is used */
5715 return offset;
5716 }
5717
5718 if (comp_meth == COMP_NONE0 ||
5719 comp_meth == COMP_MODULATION4 ||
5720 comp_meth == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) {
5721
5722 /* Not even creating a subtree for udCompMeth 0, 4, 8 */
5723 return offset;
5724 }
5725
5726 /* Subtree */
5727 unsigned start_offset = offset;
5728 proto_item *udcompparam_ti = proto_tree_add_string_format(tree, hf_oran_udCompParam,
5729 tvb, offset, 1, "",
5730 (for_sinr) ? "sinrCompParam" : "udCompParam");
5731 proto_tree *udcompparam_tree = proto_item_add_subtree(udcompparam_ti, ett_oran_udcompparam);
5732
5733 /* Show comp_meth as a generated field */
5734 proto_item *meth_ti = proto_tree_add_uint(udcompparam_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, comp_meth);
5735 proto_item_set_generated(meth_ti);
5736
5737 uint32_t param_exponent;
5738 uint64_t param_sresmask;
5739
5740 static int * const sres_mask_flags[] = {
5741 &hf_oran_sReSMask_re12,
5742 &hf_oran_sReSMask_re11,
5743 &hf_oran_sReSMask_re10,
5744 &hf_oran_sReSMask_re9,
5745 &hf_oran_sReSMask_re8,
5746 &hf_oran_sReSMask_re7,
5747 &hf_oran_sReSMask_re6,
5748 &hf_oran_sReSMask_re5,
5749 &hf_oran_sReSMask_re4,
5750 &hf_oran_sReSMask_re3,
5751 &hf_oran_sReSMask_re2,
5752 &hf_oran_sReSMask_re1,
5753 NULL((void*)0)
5754 };
5755
5756 switch (comp_meth) {
5757 case COMP_BLOCK_FP1: /* 1 */
5758 case BFP_AND_SELECTIVE_RE_WITH_MASKS7: /* 7 */
5759 /* reserved (4 bits) */
5760 add_reserved_field(udcompparam_tree, hf_oran_reserved_4bits, tvb, offset, 1);
5761 /* exponent (4 bits) */
5762 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5763 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5764 *exponent = param_exponent;
5765 proto_item_append_text(udcompparam_ti, " (Exponent=%u)", param_exponent);
5766 offset += 1;
5767 break;
5768
5769 case COMP_BLOCK_SCALE2: /* 2 */
5770 /* Separate into integer and fractional bits? */
5771 proto_tree_add_item(udcompparam_tree, hf_oran_blockScaler,
5772 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5773 offset++;
5774 break;
5775
5776 case COMP_U_LAW3: /* 3 */
5777 /* compBitWidth, compShift */
5778 proto_tree_add_item(udcompparam_tree, hf_oran_compBitWidth,
5779 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5780 proto_tree_add_item(udcompparam_tree, hf_oran_compShift,
5781 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
5782 offset += 1;
5783 break;
5784
5785 case BFP_AND_SELECTIVE_RE5: /* 5 */
5786 {
5787 /* sReSMask (exponent in middle!) */
5788 proto_item *sresmask_ti;
5789 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5790 hf_oran_sReSMask,
5791 ett_oran_sresmask,
5792 sres_mask_flags,
5793 ENC_NA0x00000000,
5794 &param_sresmask);
5795
5796 /* Get rid of exponent-shaped gap */
5797 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5798 unsigned res = 0;
5799 for (unsigned n=0; n < 12; n++) {
5800 if ((param_sresmask >> n) & 0x1) {
5801 res++;
5802 }
5803 }
5804 proto_item_append_text(sresmask_ti, " (%2u REs)", res);
5805
5806 /* exponent */
5807 proto_tree_add_item_ret_uint(udcompparam_tree, hf_oran_exponent,
5808 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &param_exponent);
5809 *sReSMask = (uint16_t)param_sresmask;
5810 *exponent = param_exponent;
5811
5812 proto_item_append_text(udcompparam_ti, " (exponent=%u, %u REs)", *exponent, res);
5813 offset += 2;
5814 break;
5815 }
5816
5817 case MOD_COMPR_AND_SELECTIVE_RE6: /* 6 */
5818 {
5819 /* sReSMask (exponent in middle!) */
5820 proto_item *sresmask_ti;
5821
5822 sresmask_ti = proto_tree_add_bitmask_ret_uint64(udcompparam_tree, tvb, offset,
5823 hf_oran_sReSMask,
5824 ett_oran_sresmask,
5825 sres_mask_flags,
5826 ENC_NA0x00000000,
5827 &param_sresmask);
5828
5829 /* Get rid of reserved-shaped gap */
5830 param_sresmask = ((param_sresmask >> 4) & 0x0f00) | (param_sresmask & 0xff);
5831 unsigned res = 0;
5832 for (unsigned n=0; n < 12; n++) {
5833 if ((param_sresmask >> n) & 0x1) {
5834 res++;
5835 }
5836 }
5837 proto_item_append_text(sresmask_ti, " (%u REs)", res);
5838
5839 /* reserved (4 bits) */
5840 add_reserved_field(udcompparam_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
5841 *sReSMask = (uint16_t)param_sresmask;
5842
5843 proto_item_append_text(udcompparam_ti, " (%u REs)", res);
5844 offset += 2;
5845 break;
5846 }
5847
5848 default:
5849 /* reserved (set to all zeros), but how many bytes?? */
5850 break;
5851 }
5852
5853 proto_item_set_len(udcompparam_ti, offset-start_offset);
5854 return offset;
5855}
5856
5857
5858/* Dissect ciCompHdr (channel information compression header, 7.5.2.15) */
5859/* bit_width and comp_meth are out params */
5860static int dissect_cicomphdr(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree, unsigned offset,
5861 unsigned *bit_width, unsigned *comp_meth, uint8_t *comp_opt)
5862{
5863 /* Subtree */
5864 proto_item *cicomphdr_ti = proto_tree_add_string_format(tree, hf_oran_ciCompHdr,
5865 tvb, offset, 1, "",
5866 "ciCompHdr");
5867 proto_tree *cicomphdr_tree = proto_item_add_subtree(cicomphdr_ti, ett_oran_cicomphdr);
5868
5869 /* ciIqWidth */
5870 uint32_t hdr_iq_width;
5871 proto_item *iq_width_item = proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrIqWidth , tvb, offset, 1, ENC_NA0x00000000, &hdr_iq_width);
5872 hdr_iq_width = (hdr_iq_width) ? hdr_iq_width : 16;
5873 if (bit_width) {
5874 *bit_width = hdr_iq_width;
5875 }
5876 proto_item_append_text(iq_width_item, " (%u bits)", hdr_iq_width);
5877
5878 /* ciCompMeth */
5879 uint32_t ci_comp_meth;
5880 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompHdrMeth, tvb, offset, 1, ENC_NA0x00000000, &ci_comp_meth);
5881 if (comp_meth) {
5882 *comp_meth = ci_comp_meth;
5883 }
5884
5885 /* ciCompOpt */
5886 uint32_t opt;
5887 proto_tree_add_item_ret_uint(cicomphdr_tree, hf_oran_ciCompOpt, tvb, offset, 1, ENC_NA0x00000000, &opt);
5888 *comp_opt = opt;
5889 offset += 1;
5890
5891 /* Summary */
5892 proto_item_append_text(cicomphdr_ti, " (IqWidth=%u, ciCompMeth=%s, ciCompOpt=%s)",
5893 hdr_iq_width,
5894 rval_to_str_const(ci_comp_meth, ud_comp_header_meth, "Unknown"),
5895 (*comp_opt) ? "compression per PRB" : "compression per UE");
5896 return offset;
5897}
5898
5899static void dissect_payload_version(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, unsigned offset)
5900{
5901 unsigned version;
5902 proto_item *ti = proto_tree_add_item_ret_uint(tree, hf_oran_payload_version, tvb, offset, 1, ENC_NA0x00000000, &version);
5903 if (version != 1) {
5904 expert_add_info_format(pinfo, ti, &ei_oran_version_unsupported,
5905 "PayloadVersion %u not supported by dissector (only 1 is known)",
5906 version);
5907 /* TODO: should throw an exception? */
5908 }
5909}
5910
5911static void show_link_to_acknack_request(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5912 ack_nack_request_t *request)
5913{
5914 /* Request frame */
5915 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_request_frame,
5916 tvb, 0, 0, request->request_frame_number);
5917 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5918
5919 /* Work out gap between frames (in ms) */
5920 int seconds_between_packets = (int)
5921 (pinfo->abs_ts.secs - request->request_frame_time.secs);
5922 int nseconds_between_packets =
5923 pinfo->abs_ts.nsecs - request->request_frame_time.nsecs;
5924
5925 int total_gap = (seconds_between_packets*1000) +
5926 ((nseconds_between_packets+500000) / 1000000);
5927
5928 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_time,
5929 tvb, 0, 0, total_gap);
5930 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5931
5932 /* Type of request */
5933 ti = proto_tree_add_uint(tree, hf_oran_acknack_request_type,
5934 tvb, 0, 0, request->requestType);
5935 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5936}
5937
5938static void show_link_to_acknack_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5939 ack_nack_request_t *response)
5940{
5941 if (response->response_frame_number == 0) {
5942 /* Requests may not get a response, and can't always tell when to expect one */
5943 return;
5944 }
5945
5946 /* Response frame */
5947 proto_item *ti = proto_tree_add_uint(tree, hf_oran_acknack_response_frame,
5948 tvb, 0, 0, response->response_frame_number);
5949 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5950
5951 /* Work out gap between frames (in ms) */
5952 int seconds_between_packets = (int)
5953 (response->response_frame_time.secs - pinfo->abs_ts.secs);
5954 int nseconds_between_packets =
5955 response->response_frame_time.nsecs - pinfo->abs_ts.nsecs;
5956
5957 int total_gap = (seconds_between_packets*1000) +
5958 ((nseconds_between_packets+500000) / 1000000);
5959
5960 ti = proto_tree_add_uint(tree, hf_oran_acknack_response_time,
5961 tvb, 0, 0, total_gap);
5962 PROTO_ITEM_SET_GENERATED(ti)proto_item_set_generated((ti));
5963}
5964
5965
5966
5967/* Control plane dissector (section 7). */
5968static int dissect_oran_c(tvbuff_t *tvb, packet_info *pinfo,
5969 proto_tree *tree, oran_tap_info *tap_info, void *data _U___attribute__((unused)))
5970{
5971 /* Hidden filter for plane */
5972 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_cplane, tvb, 0, 0, ENC_NA0x00000000);
5973 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
5974
5975 /* Set up structures needed to add the protocol subtree and manage it */
5976 unsigned offset = 0;
5977
5978 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-C");
5979 col_set_str(pinfo->cinfo, COL_INFO, "C-Plane");
5980
5981 tap_info->userplane = false0;
5982
5983 /* Create display subtree for the protocol */
5984 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
5985 proto_item_append_text(protocol_item, "-C");
5986 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
5987
5988 /* ecpriRtcid (eAxC ID) */
5989 uint16_t eAxC;
5990 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_rtcid, &eAxC, tap_info);
5991 tap_info->eaxc = eAxC;
5992
5993 /* Look up any existing conversation state for eAxC+plane */
5994 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, false0);
5995 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
5996
5997 /* Message identifier */
5998 uint32_t seq_id, sub_seq_id, e;
5999 proto_item *seq_id_ti;
6000 offset = addSeqid(tvb, oran_tree, offset, ORAN_C_PLANE0, &seq_id, &seq_id_ti, pinfo, &sub_seq_id, &e);
6001
6002 /* Section common subtree */
6003 int section_tree_offset = offset;
6004 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_c_section_common,
6005 tvb, offset, 0, "", "C-Plane Section Type ");
6006 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_c_section_common);
6007
6008 /* Peek ahead at the section type */
6009 uint32_t sectionType = 0;
6010 sectionType = tvb_get_uint8(tvb, offset+5);
6011
6012 uint32_t scs = 0;
6013 proto_item *scs_ti = NULL((void*)0);
6014
6015 /* dataDirection */
6016 uint32_t direction = 0;
6017 proto_item *datadir_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
6018 tap_info->uplink = (direction==0);
6019
6020 /* Update/report status of conversation */
6021 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6022
6023 if (state == NULL((void*)0)) {
6024 /* Allocate new state */
6025 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
6026 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
6027 wmem_tree_insert32(flow_states_table, key, state);
6028 /* Tables for each direction */
6029 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
6030 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
6031 }
6032
6033 /* Check sequence analysis status */
6034 if (state->last_frame_seen[direction] && (seq_id != state->next_expected_sequence_number[direction])) {
6035 /* Store this result */
6036 flow_result_t *result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
6037 result->unexpected_seq_number = true1;
6038 result->expected_sequence_number = state->next_expected_sequence_number[direction];
6039 result->previous_frame = state->last_frame[direction];
6040 result->u_plane_frames = wmem_list_new(wmem_file_scope());
6041 wmem_tree_insert32(flow_results_table, pinfo->num, result);
6042 }
6043 /* Update conversation info */
6044 state->last_frame[direction] = pinfo->num;
6045 state->last_frame_seen[direction] = true1;
6046 state->next_expected_sequence_number[direction] = (seq_id+1) % 256;
6047 }
6048
6049 /* Show any issues associated with this frame number */
6050 flow_result_t *result = wmem_tree_lookup32(flow_results_table, pinfo->num);
6051 if (result!=NULL((void*)0) && result->unexpected_seq_number) {
6052 expert_add_info_format(pinfo, seq_id_ti,
6053 (direction == DIR_UPLINK0) ?
6054 &ei_oran_cplane_unexpected_sequence_number_ul :
6055 &ei_oran_cplane_unexpected_sequence_number_dl,
6056 "Sequence number %u expected, but got %u",
6057 result->expected_sequence_number, seq_id);
6058
6059 /* Update tap info */
6060 uint32_t missing_sns = (256 + seq_id - result->expected_sequence_number) % 256;
6061 /* Don't get confused by being slightly out of order.. */
6062 if (missing_sns < 128) {
6063 tap_info->missing_sns = missing_sns;
6064 }
6065 else {
6066 tap_info->missing_sns = 0;
6067 }
6068
6069 /* TODO: could add previous/next frames (in seqId tree?) ? */
6070 }
6071
6072 /* payloadVersion */
6073 dissect_payload_version(section_tree, tvb, pinfo, offset);
6074
6075 /* filterIndex */
6076 if (sectionType == SEC_C_SLOT_CONTROL || sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6077 /* scs (for ST4 and ST8) */
6078 scs_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_frameStructure_subcarrier_spacing, tvb, offset, 1, ENC_NA0x00000000, &scs);
6079 }
6080 else if (sectionType == SEC_C_RRM_MEAS_REPORTS || sectionType == SEC_C_REQUEST_RRM_MEAS) {
6081 /* reserved (4 bits) */
6082 add_reserved_field(section_tree, hf_oran_reserved_last_4bits, tvb, offset, 1);
6083 }
6084 else if (sectionType != SEC_C_LAA) {
6085 /* filterIndex (most common case) */
6086 proto_tree_add_item(section_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
6087 }
6088 offset += 1;
6089
6090 unsigned ref_a_offset = offset;
6091 /* frameId */
6092 uint32_t frameId = 0;
6093 proto_tree_add_item_ret_uint(section_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
6094 tap_info->frame = frameId;
6095 offset += 1;
6096
6097 /* subframeId */
6098 uint32_t subframeId = 0;
6099 proto_tree_add_item_ret_uint(section_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
6100 /* slotId */
6101 uint32_t slotId = 0;
6102 proto_tree_add_item_ret_uint(section_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
6103 tap_info->slot = slotId;
6104 offset++;
6105
6106 /* startSymbolId */
6107 uint32_t startSymbolId = 0;
6108 proto_item *ssid_ti = NULL((void*)0);
6109 if ((sectionType == SEC_C_ACK_NACK_FEEDBACK) || /* Section Type 8 */
6110 (sectionType == SEC_C_SINR_REPORTING)) { /* Section Type 9 */
6111 /* symbolId */
6112 proto_tree_add_item_ret_uint(section_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6113 }
6114 else if (sectionType != SEC_C_LAA) {
6115 /* startSymbolId is in most section types */
6116 ssid_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_start_symbol_id, tvb, offset, 1, ENC_NA0x00000000, &startSymbolId);
6117 if (startSymbolId && (sectionType == SEC_C_RRM_MEAS_REPORTS)) { /* Section Type 10 */
6118 proto_item_append_text(ssid_ti, " (should be 0 for ST10!)");
6119 expert_add_info_format(pinfo, ssid_ti, &ei_oran_st10_startsymbolid_not_0,
6120 "startSymbolId should be 0 for ST10 - found %u", startSymbolId);
6121 }
6122 }
6123 else {
6124 /* reserved (6 bits) */
6125 add_reserved_field(section_tree, hf_oran_reserved_last_6bits, tvb, offset, 1);
6126 }
6127 offset++;
6128
6129
6130 char id[16];
6131 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, startSymbolId);
6132 proto_item *pi = proto_tree_add_string(section_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
6133 proto_item_set_generated(pi);
6134
6135 uint32_t cmd_scope = 0;
6136 bool_Bool st8_ready = false0;
6137
6138 /* numberOfSections (or whatever section has instead) */
6139 uint32_t nSections = 0;
6140 if (sectionType == SEC_C_SLOT_CONTROL) { /* Section Type 4 */
6141 /* Slot Control has these fields instead */
6142 /* reserved (4 bits) */
6143 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6144 /* cmdScope (4 bits) */
6145 proto_tree_add_item_ret_uint(section_tree, hf_oran_cmd_scope, tvb, offset, 1, ENC_NA0x00000000, &cmd_scope);
6146 }
6147 else if (sectionType == SEC_C_ACK_NACK_FEEDBACK) { /* Section Type 8 */
6148 /* reserved (7 bits) */
6149 add_reserved_field(section_tree, hf_oran_reserved_7bits, tvb, offset, 1);
6150 /* ready (1 bit) */
6151 /* TODO: when set, ready in slotId+1.. */
6152 proto_tree_add_item_ret_boolean(section_tree, hf_oran_ready, tvb, offset, 1, ENC_NA0x00000000, &st8_ready);
6153 if (!st8_ready) {
6154 /* SCS value is ignored, and may be set to any value by O-RU */
6155 proto_item_append_text(scs_ti, " (ignored)");
6156 }
6157 }
6158 else if (sectionType != SEC_C_LAA) {
6159 /* numberOfSections */
6160 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfSections, tvb, offset, 1, ENC_NA0x00000000, &nSections);
6161 }
6162 else {
6163 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6164 }
6165 offset++;
6166
6167 /* sectionType */
6168 proto_tree_add_item_ret_uint(section_tree, hf_oran_sectionType, tvb, offset, 1, ENC_NA0x00000000, &sectionType);
6169 offset += 1;
6170
6171 /* Check that dataDirection is consistent with section type */
6172 if (sectionType == SEC_C_SINR_REPORTING && direction != 0) { /* Section Type 9 */
6173 expert_add_info(pinfo, datadir_ti, &ei_oran_st9_not_ul);
6174 }
6175 if (sectionType == SEC_C_RRM_MEAS_REPORTS && direction != 0) { /* Section Type 10 */
6176 expert_add_info(pinfo, datadir_ti, &ei_oran_st10_not_ul);
6177 }
6178
6179 /* Note this section type in stats */
6180 if (sectionType < SEC_C_MAX_INDEX) {
6181 tap_info->section_types[sectionType] = true1;
6182 }
6183
6184 /* Section-type-specific fields following common header (white entries in Section Type diagrams) */
6185 unsigned bit_width = 0;
6186 unsigned comp_meth = 0;
6187 proto_item *comp_meth_ti;
6188 unsigned ci_comp_method = 0;
6189 uint8_t ci_comp_opt = 0;
6190
6191 uint32_t num_ues = 0;
6192 uint32_t number_of_acks = 0, number_of_nacks = 0;
6193
6194 uint32_t num_sinr_per_prb = 0;
6195
6196 switch (sectionType) {
6197 case SEC_C_UNUSED_RB: /* Section Type 0 */
6198 /* timeOffset */
6199 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6200 offset += 2;
6201 /* frameStructure */
6202 offset = dissect_frame_structure(section_tree, tvb, offset,
6203 subframeId, slotId);
6204
6205 /* cpLength */
6206 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6207 offset += 2;
6208 /* reserved (8 bits) */
6209 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6210 offset += 1;
6211 break;
6212
6213 case SEC_C_NORMAL: /* Section Type 1 */
6214 case SEC_C_UE_SCHED: /* Section Type 5 */
6215 /* udCompHdr */
6216 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6217 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6218 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6219 /* reserved (8 bits) */
6220 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6221 offset += 1;
6222 break;
6223
6224 case SEC_C_SLOT_CONTROL: /* Section Type 4 */
6225 break;
6226
6227 case SEC_C_PRACH: /* Section Type 3 */
6228 /* timeOffset */
6229 proto_tree_add_item(section_tree, hf_oran_timeOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6230 offset += 2;
6231 /* frameStructure */
6232 offset = dissect_frame_structure(section_tree, tvb, offset,
6233 subframeId, slotId);
6234 /* cpLength */
6235 proto_tree_add_item(section_tree, hf_oran_cpLength, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6236 offset += 2;
6237 /* udCompHdr */
6238 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset,
6239 true1, direction==0 && pref_override_ul_compression, /* ignore for DL or if using mplane for UL settings */
6240 &bit_width, &comp_meth, &comp_meth_ti, tap_info);
6241 break;
6242
6243 case SEC_C_CH_INFO: /* Section Type 6 */
6244 /* numberOfUEs */
6245 proto_tree_add_item_ret_uint(section_tree, hf_oran_numberOfUEs, tvb, offset, 1, ENC_NA0x00000000, &num_ues);
6246 offset += 1;
6247 /* ciCompHdr (was reserved) */
6248 offset = dissect_cicomphdr(tvb, pinfo, section_tree, offset, &bit_width, &ci_comp_method, &ci_comp_opt);
6249
6250 /* Number of sections may not be filled in (at all, or correctly), so set to the number of UEs.
6251 The data entries are per-UE... they don't have a sectionID, but they could have section extensions... */
6252 if (nSections == 0 || num_ues > nSections) {
6253 nSections = num_ues;
6254 }
6255 break;
6256
6257 case SEC_C_RSVD2:
6258 break;
6259
6260 case SEC_C_LAA: /* Section Type 7 */
6261 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6262 offset += 2;
6263 break;
6264
6265 case SEC_C_ACK_NACK_FEEDBACK: /* Section Type 8 */
6266 /* numberOfAcks (1 byte) */
6267 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_acks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_acks);
6268 offset += 1;
6269 /* numberOfNacks (1 byte) */
6270 proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_nacks, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &number_of_nacks);
6271 offset += 1;
6272
6273 /* Show ACKs and NACKs. For both, try to link back to request. */
6274 for (unsigned int n=1; n <= number_of_acks; n++) {
6275 uint32_t ackid;
6276 proto_item *ack_ti;
6277 ack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_ackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ackid);
6278 offset += 2;
6279
6280 /* Look up request table in state (which really should be set by now, but test anyway). */
6281 if (state && state->ack_nack_requests) {
6282 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, ackid);
6283 if (request != NULL((void*)0)) {
6284 /* On first pass, update with this response */
6285 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6286 request->response_frame_number = pinfo->num;
6287 request->response_frame_time = pinfo->abs_ts;
6288 }
6289
6290 /* Show request details */
6291 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6292 }
6293 else {
6294 /* Request not found */
6295 expert_add_info_format(pinfo, ack_ti, &ei_oran_acknack_no_request,
6296 "Response for ackId=%u received, but no request found",
6297 ackid);
6298 }
6299 }
6300 }
6301 for (unsigned int m=1; m <= number_of_nacks; m++) {
6302 uint32_t nackid;
6303 proto_item *nack_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_nackid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &nackid);
6304 offset += 2;
6305
6306 expert_add_info_format(pinfo, nack_ti, &ei_oran_st8_nackid,
6307 "Received Nack for ackNackId=%u",
6308 nackid);
6309
6310 /* Look up request table in state. */
6311 if (state && state->ack_nack_requests) {
6312 ack_nack_request_t *request = wmem_tree_lookup32(state->ack_nack_requests, nackid);
6313 if (request) {
6314 /* On first pass, update with this response */
6315 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6316 request->response_frame_number = pinfo->num;
6317 request->response_frame_time = pinfo->abs_ts;
6318 }
6319
6320 /* Show request details */
6321 show_link_to_acknack_request(section_tree, tvb, pinfo, request);
6322 }
6323 else {
6324 /* Request not found */
6325 expert_add_info_format(pinfo, nack_ti, &ei_oran_acknack_no_request,
6326 "Response for nackId=%u received, but no request found",
6327 nackid);
6328 }
6329 }
6330 }
6331 break;
6332
6333 case SEC_C_SINR_REPORTING: /* Section Type 9 */
6334 {
6335 /* numSinrPerPrb (3 bits) */
6336 proto_item *nspp_ti;
6337 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);
6338 switch (num_sinr_per_prb) {
6339 case 0:
6340 num_sinr_per_prb = 1; break;
6341 case 1:
6342 num_sinr_per_prb = 2; break;
6343 case 2:
6344 num_sinr_per_prb = 3; break;
6345 case 3:
6346 num_sinr_per_prb = 4; break;
6347 case 4:
6348 num_sinr_per_prb = 6; break;
6349 case 5:
6350 num_sinr_per_prb = 12; break;
6351
6352 default:
6353 proto_item_append_text(nspp_ti, " (invalid)");
6354 num_sinr_per_prb = 1;
6355 expert_add_info_format(pinfo, nspp_ti, &ei_oran_num_sinr_per_prb_unknown,
6356 "Invalid numSinrPerPrb value (%u)",
6357 num_sinr_per_prb);
6358 }
6359
6360 /* oruControlSinrSlotMaskId (5 bits) */
6361 proto_tree_add_item(section_tree, hf_oran_oru_control_sinr_slot_mask_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6362 offset += 1;
6363 /* reserved (8 bits) */
6364 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6365 offset += 1;
6366 break;
6367 }
6368
6369 case SEC_C_RRM_MEAS_REPORTS: /* Section Type 10 */
6370 case SEC_C_REQUEST_RRM_MEAS: /* Section Type 11 */
6371 /* reserved (16 bits) */
6372 add_reserved_field(section_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6373 offset += 2;
6374 break;
6375 };
6376
6377 /* Update udCompHdr details in state for UL U-Plane */
6378 if (state && direction==0) {
6379 switch (sectionType) {
6380 case SEC_C_NORMAL: /* Section Type 1 */
6381 case SEC_C_PRACH: /* Section Type 3 */
6382 case SEC_C_UE_SCHED: /* Section Type 5 */
6383 state->ul_ud_comp_hdr_set = true1;
6384 state->ul_ud_comp_hdr_bit_width = bit_width;
6385 state->ul_ud_comp_hdr_compression = comp_meth;
6386 state->ul_ud_comp_hdr_frame = pinfo->num;
6387 break;
6388 default:
6389 break;
6390 }
6391 }
6392
6393
6394 proto_item_append_text(sectionHeading, "%d, %s, frameId: %d, subframeId: %d, slotId: %d, startSymbolId: %d",
6395 sectionType, val_to_str_const(direction, data_direction_vals, "Unknown"),
6396 frameId, subframeId, slotId, startSymbolId);
6397 if (nSections) {
6398 proto_item_append_text(sectionHeading, ", numberOfSections=%u", nSections);
6399 }
6400
6401 write_pdu_label_and_info(protocol_item, NULL((void*)0), pinfo, ", Type: %2d %s", sectionType,
6402 rval_to_str_const(sectionType, section_types_short, "Unknown"));
6403
6404 /* Set actual length of C-Plane section header */
6405 proto_item_set_len(section_tree, offset - section_tree_offset);
6406
6407 if (sectionType == SEC_C_ACK_NACK_FEEDBACK) {
6408 write_pdu_label_and_info(oran_tree, section_tree, pinfo,
6409 (st8_ready) ? " (Ready)" : " (ACK)");
6410 }
6411
6412
6413 /* Section type 4 doesn't have normal sections, so deal with here before normal sections */
6414 if (sectionType == SEC_C_SLOT_CONTROL) {
6415 /* numberOfST4Cmds */
6416 uint32_t no_st4_cmds, st4_cmd_len, num_slots, ack_nack_req_id, st4_cmd_type;
6417 proto_item *no_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_number_of_st4_cmds,
6418 tvb, offset, 1, ENC_NA0x00000000, &no_st4_cmds);
6419 if (no_st4_cmds == 0) {
6420 expert_add_info(pinfo, no_ti, &ei_oran_st4_no_cmds);
6421 }
6422 offset += 1;
6423
6424 /* reserved (1 byte) */
6425 add_reserved_field(section_tree, hf_oran_reserved_8bits, tvb, offset, 1);
6426 offset += 1;
6427
6428 /* Loop over commands. Each has 8-byte common header, followed by cmd-specific payload */
6429 proto_item *len_ti;
6430 for (uint32_t n=0; n < no_st4_cmds; n++) {
6431 /* Table 7.4.6-2: Section Type 4 Command common header format */
6432 proto_item *hdr_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd_header,
6433 tvb, offset, 8, "",
6434 "Type 4 Command common header");
6435 proto_tree *hdr_tree = proto_item_add_subtree(hdr_ti, ett_oran_st4_cmd_header);
6436
6437 /* st4CmdType */
6438 proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_type, tvb, offset, 1, ENC_NA0x00000000, &st4_cmd_type);
6439 offset += 1;
6440
6441 /* st4CmdLen */
6442 len_ti = proto_tree_add_item_ret_uint(hdr_tree, hf_oran_st4_cmd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &st4_cmd_len);
6443 if (st4_cmd_len == 0) {
6444 /* Meaning of 0 not yet defined (v15.00) */
6445 proto_item_append_text(len_ti, " (reserved)");
6446 expert_add_info(pinfo, len_ti, &ei_oran_st4_zero_len_cmd);
6447 }
6448 else {
6449 proto_item_append_text(len_ti, " (%u bytes)", st4_cmd_len*4);
6450 }
6451 offset += 2;
6452
6453 /* numSlots */
6454 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);
6455 if (num_slots == 0) {
6456 proto_item_append_text(slots_ti, " (until changed)");
6457 }
6458 offset += 1;
6459
6460 /* ackNackReqId */
6461 proto_item *ack_nack_req_id_ti;
6462 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);
6463 offset += 2;
6464 if (ack_nack_req_id == 0) {
6465 proto_item_append_text(ack_nack_req_id_ti, " (no Section type 8 response expected)");
6466 }
6467
6468 /* reserved (16 bits) */
6469 add_reserved_field(hdr_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6470 offset += 2;
6471
6472 /* Set common header summary */
6473 proto_item_append_text(hdr_ti, " (cmd=%s, len=%u, slots=%u, ackNackReqId=%u)",
6474 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"),
6475 st4_cmd_len, num_slots, ack_nack_req_id);
6476
6477 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
6478 rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6479
6480
6481 /* Subtree for this command body */
6482 proto_item *command_ti = proto_tree_add_string_format(section_tree, hf_oran_st4_cmd,
6483 tvb, offset, 0, "",
6484 "Type 4 Command (%s)", rval_to_str_const(st4_cmd_type, st4_cmd_type_vals, "Unknown"));
6485 proto_tree *command_tree = proto_item_add_subtree(command_ti, ett_oran_st4_cmd);
6486
6487 unsigned command_start_offset = offset;
6488
6489 /* Check fields compatible with chosen command. */
6490 if (st4_cmd_type==1) {
6491 if (num_slots != 0) {
6492 /* "the value of numSlots should be set to zero for this command type" */
6493 expert_add_info_format(pinfo, slots_ti, &ei_oran_numslots_not_zero,
6494 "numSlots should be zero for ST4 command 1 - found %u",
6495 num_slots);
6496 }
6497 }
6498
6499 if (st4_cmd_type==3 || st4_cmd_type==4) {
6500 if (startSymbolId != 0) {
6501 /* "expected reception window for the commands is the symbol zero reception window" */
6502 expert_add_info_format(pinfo, ssid_ti, &ei_oran_start_symbol_id_not_zero,
6503 "startSymbolId should be zero for ST4 commands 3&4 - found %u",
6504 startSymbolId);
6505 }
6506 }
6507
6508 /* Add format for this command */
6509 switch (st4_cmd_type) {
6510 case 1: /* TIME_DOMAIN_BEAM_CONFIG */
6511 {
6512 bool_Bool disable_tdbfns;
6513 uint32_t bfwcomphdr_iq_width, bfwcomphdr_comp_meth;
6514
6515 /* Hidden filter for bf */
6516 proto_item *bf_ti = proto_tree_add_item(command_tree, hf_oran_bf, tvb, 0, 0, ENC_NA0x00000000);
6517 PROTO_ITEM_SET_HIDDEN(bf_ti)proto_item_set_hidden((bf_ti));
6518
6519 /* reserved (2 bits) */
6520 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6521 /* symbolMask (14 bits) */
6522 uint32_t symbol_mask;
6523 proto_item *symbol_mask_ti;
6524 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &symbol_mask_ti);
6525 /* 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 */
6526 /* lsb is symbol 0 */
6527 for (unsigned s=0; s < 14; s++) {
6528 if ((startSymbolId & (1 << s)) && (startSymbolId > s)) {
6529 proto_item_append_text(symbol_mask_ti, " (startSymbolId is %u, so some lower symbol bits ignored!)", startSymbolId);
6530 expert_add_info(pinfo, symbol_mask_ti, &ei_oran_start_symbol_id_bits_ignored);
6531 break;
6532 }
6533 }
6534
6535 /* disableTDBFNs (1 bit) */
6536 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfns, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfns);
6537
6538 /* tdBeamNum (15 bits) */
6539 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6540 offset += 2;
6541
6542 /* bfwCompHdr (2 subheaders - bfwIqWidth and bfwCompMeth)*/
6543 offset = dissect_bfwCompHdr(tvb, command_tree, offset,
6544 &bfwcomphdr_iq_width, &bfwcomphdr_comp_meth, &comp_meth_ti);
6545 /* reserved (3 bytes) */
6546 proto_tree_add_bits_item(command_tree, hf_oran_reserved, tvb, offset*8, 24, ENC_BIG_ENDIAN0x00000000);
6547 offset += 3;
6548
6549 if (disable_tdbfns) {
6550 /* No beamnum information to show so get out. */
6551 break;
6552 }
6553
6554 /* Read beam entries until reach end of command length */
6555 while ((offset - command_start_offset) < (st4_cmd_len * 4)) {
6556
6557 /* disableTDBFWs (1 bit) */
6558 bool_Bool disable_tdbfws;
6559 proto_tree_add_item_ret_boolean(command_tree, hf_oran_disable_tdbfws, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &disable_tdbfws);
6560
6561 /* tdBeamNum (15 bits) */
6562 proto_tree_add_item(command_tree, hf_oran_td_beam_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6563 offset += 2;
6564
6565 /* Showing BFWs? */
6566 if (!disable_tdbfws) {
6567
6568 /* bfwCompParam */
6569 unsigned exponent = 0;
6570 bool_Bool supported = false0;
6571 unsigned num_trx_entries;
6572 uint16_t *trx_entries;
6573 offset = dissect_bfwCompParam(tvb, command_tree, pinfo, offset, comp_meth_ti,
6574 &bfwcomphdr_comp_meth, &exponent, &supported,
6575 &num_trx_entries, &trx_entries);
6576
6577 /* Antenna count from preference */
6578 unsigned num_trx = pref_num_bf_antennas;
6579 int bit_offset = offset*8;
6580
6581 for (unsigned trx=0; trx < num_trx; trx++) {
6582 /* Create antenna subtree */
6583 int bfw_offset = bit_offset / 8;
6584 proto_item *bfw_ti = proto_tree_add_string_format(command_tree, hf_oran_bfw,
6585 tvb, bfw_offset, 0, "", "TRX %3u: (", trx);
6586 proto_tree *bfw_tree = proto_item_add_subtree(bfw_ti, ett_oran_bfw);
6587
6588 /* I value */
6589 /* Get bits, and convert to float. */
6590 uint32_t bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6591 float value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6592 /* Add to tree. */
6593 proto_tree_add_float(bfw_tree, hf_oran_bfw_i, tvb, bit_offset/8,
6594 (bfwcomphdr_iq_width+7)/8, value);
6595 bit_offset += bfwcomphdr_iq_width;
6596 proto_item_append_text(bfw_ti, "I=%f ", value);
6597
6598 /* Leave a gap between I and Q values */
6599 proto_item_append_text(bfw_ti, " ");
6600
6601 /* Q value */
6602 /* Get bits, and convert to float. */
6603 bits = tvb_get_bits32(tvb, bit_offset, bfwcomphdr_iq_width, ENC_BIG_ENDIAN0x00000000);
6604 value = decompress_value(bits, bfwcomphdr_comp_meth, bfwcomphdr_iq_width, exponent, NULL((void*)0) /* no ModCompr*/, 0 /* RE */);
6605 /* Add to tree. */
6606 proto_tree_add_float(bfw_tree, hf_oran_bfw_q, tvb, bit_offset/8,
6607 (bfwcomphdr_iq_width+7)/8, value);
6608 bit_offset += bfwcomphdr_iq_width;
6609 proto_item_append_text(bfw_ti, "Q=%f", value);
6610
6611 proto_item_append_text(bfw_ti, ")");
6612 proto_item_set_len(bfw_ti, (bit_offset+7)/8 - bfw_offset);
6613 }
6614 /* Need to round to next byte */
6615 offset = (bit_offset+7)/8;
6616 }
6617 }
6618 break;
6619 }
6620 case 2: /* TDD_CONFIG_PATTERN */
6621 /* reserved (2 bits) */
6622 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6623 /* dirPattern (14 bits) */
6624 proto_tree_add_item(command_tree, hf_oran_dir_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6625 offset += 2;
6626
6627 /* reserved (2 bits) */
6628 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6629 /* guardPattern (14 bits) */
6630 proto_tree_add_item(command_tree, hf_oran_guard_pattern, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6631 offset += 2;
6632 break;
6633
6634 case 3: /* TRX_CONTROL */
6635 case 5: /* TRX_CONTROL_BIDIR */
6636 {
6637 /* Only allowed cmdScope is ARRAY-COMMAND */
6638 if (cmd_scope != 0) {
6639 expert_add_info(pinfo, command_tree, &ei_oran_trx_control_cmd_scope);
6640 }
6641
6642 /* reserved (2 bits) */
6643 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6644 /* log2MaskBits (4 bits) */
6645 unsigned log2maskbits;
6646 proto_tree_add_item_ret_uint(command_tree, hf_oran_log2maskbits, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &log2maskbits);
6647 /* sleepMode (2 bits) */
6648 uint32_t sleep_mode;
6649 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_trx, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6650 offset += 1;
6651
6652 /* reserved (4 bits) */
6653 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6654 /* numSlotsExt (20 bits) */
6655 uint32_t num_slots_ext;
6656 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);
6657 if (num_slots==0 && num_slots_ext==0) {
6658 proto_item_append_text(num_slots_ext_ti, " (undefined sleep period)");
6659 }
6660 else {
6661 /* Time should be rounded up according to SCS */
6662 float total = (float)(num_slots + num_slots_ext);
6663 /* From table 7.5.2.13-3 */
6664 const float slot_length_by_scs[16] = { 1000, 500, 250, 125, 62.5, 31.25,
6665 0, 0, 0, 0, 0, 0, /* reserved */
6666 1000, 1000, 1000, 1000 };
6667 float slot_length = slot_length_by_scs[scs];
6668 /* Only using valid SCS. TODO: is this test ok? */
6669 if (slot_length != 0) {
6670 /* Round up to next slot */
6671 total = ((int)(total / slot_length) + 1) * slot_length;
6672 proto_item_append_text(num_slots_ext_ti, " (defined sleep period of %f us)", total);
6673 }
6674 }
6675 offset += 3;
6676
6677 /* reserved (2 bits) */
6678 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6679
6680 /* symbolMask (14 bits) */
6681 uint32_t symbol_mask;
6682 proto_item *sm_ti;
6683 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6684 if (symbol_mask == 0x0) {
6685 proto_item_append_text(sm_ti, " (wake)");
6686 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6687 }
6688 else if (symbol_mask == 0x3fff) {
6689 proto_item_append_text(sm_ti, " (sleep)");
6690 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6691 }
6692 else {
6693 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6694 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6695 sleep_mode, symbol_mask);
6696 }
6697 offset += 2;
6698
6699 /* antMask (16-2048 bits). Size is lookup from log2MaskBits enum.. */
6700 unsigned antmask_length = 2;
6701 if (log2maskbits >= 4) {
6702 antmask_length = (1 << log2maskbits) / 8;
6703 }
6704 proto_item *ant_mask_ti = proto_tree_add_item(command_tree, hf_oran_antMask_trx_control, tvb, offset, antmask_length, ENC_NA0x00000000);
6705 /* show count */
6706 unsigned antenna_count = 0;
6707 for (unsigned b=0; b < antmask_length; b++) {
6708 uint8_t byte = tvb_get_uint8(tvb, offset+b);
6709 for (unsigned bit=0; bit < 8; bit++) {
6710 if ((1 << bit) & byte) {
6711 antenna_count++;
6712 }
6713 }
6714 }
6715 proto_item_append_text(ant_mask_ti, " (%u antennas)", antenna_count);
6716 offset += antmask_length;
6717
6718 /* Pad to next 4-byte boundary */
6719 offset = WS_ROUNDUP_4(offset)(((offset) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U))
))
;
6720 break;
6721 }
6722
6723 case 4: /* ASM (advanced sleep mode) */
6724 /* reserved (2+4=6 bits) */
6725 add_reserved_field(command_tree, hf_oran_reserved_6bits, tvb, offset, 1);
6726 /* sleepMode (2 bits) */
6727 uint32_t sleep_mode;
6728 proto_tree_add_item_ret_uint(command_tree, hf_oran_sleepmode_asm, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &sleep_mode);
6729 offset += 1;
6730
6731 /* reserved (4 bits) */
6732 add_reserved_field(command_tree, hf_oran_reserved_4bits, tvb, offset, 1);
6733 /* numSlotsExt (20 bits) */
6734 proto_tree_add_item(command_tree, hf_oran_num_slots_ext, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6735 offset += 3;
6736
6737 /* reserved (2 bits) */
6738 add_reserved_field(command_tree, hf_oran_reserved_2bits, tvb, offset, 1);
6739 /* symbolMask (14 bits) */
6740 uint32_t symbol_mask;
6741 proto_item *sm_ti;
6742 offset = dissect_symbolmask(tvb, command_tree, offset, &symbol_mask, &sm_ti);
6743 if (symbol_mask == 0x0) {
6744 proto_item_append_text(sm_ti, " (wake)");
6745 col_append_str(pinfo->cinfo, COL_INFO, " (wake)");
6746 }
6747 else if (symbol_mask == 0x3fff) {
6748 proto_item_append_text(sm_ti, " (sleep)");
6749 col_append_str(pinfo->cinfo, COL_INFO, " (sleep)");
6750 }
6751 else {
6752 expert_add_info_format(pinfo, sm_ti, &ei_oran_bad_symbolmask,
6753 "For non-zero sleepMode (%u), symbolMask should be 0x0 or 0x3fff - found 0x%05x",
6754 sleep_mode, symbol_mask);
6755 }
6756 offset += 2;
6757
6758 /* reserved (2 bytes) */
6759 add_reserved_field(command_tree, hf_oran_reserved_16bits, tvb, offset, 2);
6760 offset += 2;
6761 break;
6762
6763 default:
6764 /* Error! */
6765 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_unknown_cmd,
6766 "Dissected ST4 command (%u) not recognised",
6767 st4_cmd_type);
6768 break;
6769 }
6770
6771 /* Check apparent size of padding (0-3 bytes ok) */
6772 long padding_remaining = command_start_offset + (st4_cmd_len * 4) - offset;
6773 if (padding_remaining > 3) {
6774 expert_add_info_format(pinfo, len_ti, &ei_oran_st4_wrong_len_cmd,
6775 "Dissected ST4 command does not match signalled st4CmdLen - set to %u (%u bytes) but dissected %u bytes",
6776 st4_cmd_len, st4_cmd_len*4, offset-command_start_offset);
6777 }
6778
6779 /* Advance by signalled length (needs to be aligned on 4-byte boundary) */
6780 offset = command_start_offset + (st4_cmd_len * 4);
6781
6782 /* Set end of command tree */
6783 proto_item_set_end(command_ti, tvb, offset);
6784
6785 if (ack_nack_req_id != 0 && state && state->ack_nack_requests) {
6786 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
6787 /* Add this request into conversation state on first pass */
6788 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)))
;
6789 request_details->request_frame_number = pinfo->num;
6790 request_details->request_frame_time = pinfo->abs_ts;
6791 request_details->requestType = ST4Cmd1+st4_cmd_type-1;
6792
6793 wmem_tree_insert32(state->ack_nack_requests,
6794 ack_nack_req_id,
6795 request_details);
6796 }
6797 else {
6798 /* On later passes, try to link forward to ST8 response */
6799 ack_nack_request_t *response = wmem_tree_lookup32(state->ack_nack_requests,
6800 ack_nack_req_id);
6801 if (response) {
6802 show_link_to_acknack_response(section_tree, tvb, pinfo, response);
6803 }
6804 }
6805 }
6806 }
6807 }
6808 /* LAA doesn't have sections either.. */
6809 else if (sectionType == SEC_C_LAA) { /* Section Type 7 */
6810 /* 7.2.5 Table 6.4-6 */
6811 unsigned mcot;
6812 proto_item *mcot_ti;
6813
6814 /* laaMsgType */
6815 uint32_t laa_msg_type;
6816 proto_item *laa_msg_type_ti;
6817 laa_msg_type_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgType, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_type);
6818 /* laaMsgLen */
6819 uint32_t laa_msg_len;
6820 proto_item *len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_laaMsgLen, tvb, offset, 1, ENC_NA0x00000000, &laa_msg_len);
6821 proto_item_append_text(len_ti, " (%u bytes)", 4*laa_msg_len);
6822 if (laa_msg_len == 0) {
6823 proto_item_append_text(len_ti, " (reserved)");
6824 }
6825 offset += 1;
6826
6827 int payload_offset = offset;
6828
6829 /* Payload */
6830 switch (laa_msg_type) {
6831 case 0:
6832 /* LBT_PDSCH_REQ */
6833 /* lbtHandle (16 bits) */
6834 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6835 offset += 2;
6836 /* lbtOffset (10 bits) */
6837 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6838 offset += 1;
6839 /* lbtMode (2 bits) */
6840 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6841 /* reserved (1 bit) */
6842 add_reserved_field(section_tree, hf_oran_reserved_bit4, tvb, offset, 1);
6843 /* lbtDeferFactor (3 bits) */
6844 proto_tree_add_item(section_tree, hf_oran_lbtDeferFactor, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6845 offset += 1;
6846 /* lbtBackoffCounter (10 bits) */
6847 proto_tree_add_item(section_tree, hf_oran_lbtBackoffCounter, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6848 offset += 1;
6849 /* MCOT (4 bits) */
6850 mcot_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_MCOT, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &mcot);
6851 if (mcot<1 || mcot>10) {
6852 proto_item_append_text(mcot_ti, " (should be in range 1-10!)");
6853 expert_add_info_format(pinfo, mcot_ti, &ei_oran_mcot_out_of_range,
6854 "MCOT seen with value %u (must be 1-10)", mcot);
6855
6856 }
6857 /* reserved (10 bits) */
6858 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+6, 10, ENC_BIG_ENDIAN0x00000000);
6859 break;
6860 case 1:
6861 /* LBT_DRS_REQ */
6862 /* lbtHandle (16 bits) */
6863 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6864 offset += 2;
6865 /* lbtOffset (10 bits) */
6866 proto_tree_add_item(section_tree, hf_oran_lbtOffset, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6867 offset += 1;
6868 /* lbtMode (2 bits) */
6869 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8+2, 2, ENC_BIG_ENDIAN0x00000000);
6870 /* reserved (28 bits) */
6871 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+4, 28, ENC_BIG_ENDIAN0x00000000);
6872 break;
6873 case 2:
6874 /* LBT_PDSCH_RSP */
6875 /* lbtHandle (16 bits) */
6876 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6877 offset += 2;
6878 /* lbtPdschRes (2 bits) */
6879 proto_tree_add_item(section_tree, hf_oran_lbtPdschRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6880 /* inParSF (1 bit) */
6881 proto_tree_add_item(section_tree, hf_oran_initialPartialSF, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6882 /* sfStatus (1 bit) */
6883 proto_tree_add_item(section_tree, hf_oran_sfStatus, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6884 /* sfnSf (12 bits) */
6885 proto_tree_add_item(section_tree, hf_oran_sfnSfEnd, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6886 offset += 2;
6887 /* reserved (24 bits) */
6888 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8), 24, ENC_BIG_ENDIAN0x00000000);
6889 break;
6890 case 3:
6891 /* LBT_DRS_RSP */
6892 /* lbtHandle (16 bits) */
6893 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6894 offset += 2;
6895 /* lbtDrsRes (1 bit) */
6896 proto_tree_add_item(section_tree, hf_oran_lbtDrsRes, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6897 /* reserved (7 bits) */
6898 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6899 break;
6900 case 4:
6901 /* LBT_Buffer_Error */
6902 /* lbtHandle (16 bits) */
6903 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6904 offset += 2;
6905 /* lbtBufErr (1 bit) */
6906 proto_tree_add_item(section_tree, hf_oran_lbtBufErr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6907 /* reserved (7 bits) */
6908 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6909 break;
6910 case 5:
6911 /* LBT_CWCONFIG_REQ */
6912 /* lbtHandle (16 bits) */
6913 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6914 offset += 2;
6915 /* lbtCWConfig_H (8 bits) */
6916 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_H, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6917 offset += 1;
6918 /* lbtCWConfig_T (8 bits) */
6919 proto_tree_add_item(section_tree, hf_oran_lbtCWConfig_T, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6920 offset += 1;
6921 /* lbtMode (2 bits) */
6922 proto_tree_add_bits_item(section_tree, hf_oran_lbtMode, tvb, offset*8, 2, ENC_BIG_ENDIAN0x00000000);
6923 /* lbtTrafficClass (3 bits) */
6924 proto_tree_add_item(section_tree, hf_oran_lbtTrafficClass, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6925 /* reserved (19 bits) */
6926 proto_tree_add_bits_item(section_tree, hf_oran_reserved, tvb, (offset*8)+5, 19, ENC_BIG_ENDIAN0x00000000);
6927 break;
6928 case 6:
6929 /* LBT_CWCONFIG_RSP */
6930 /* lbtHandle (16 bits) */
6931 proto_tree_add_item(section_tree, hf_oran_lbtHandle, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
6932 offset += 2;
6933 /* lbtCWR_Rst (1 bit) */
6934 proto_tree_add_item(section_tree, hf_oran_lbtCWR_Rst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
6935 /* reserved (7 bits) */
6936 add_reserved_field(section_tree, hf_oran_reserved_last_7bits, tvb, offset, 1);
6937 break;
6938
6939 default:
6940 /* Unhandled! */
6941 expert_add_info_format(pinfo, laa_msg_type_ti, &ei_oran_laa_msg_type_unsupported,
6942 "laaMsgType %u not supported by dissector",
6943 laa_msg_type);
6944
6945 break;
6946 }
6947 /* For now just skip indicated length of bytes */
6948 offset = payload_offset + 4*(laa_msg_len+1);
6949 }
6950
6951
6952 /* Dissect each C section */
6953 for (uint32_t i = 0; i < nSections; ++i) {
6954 tvbuff_t *section_tvb = tvb_new_subset_remaining(tvb, offset);
6955 offset += dissect_oran_c_section(section_tvb, oran_tree, pinfo, state, sectionType, tap_info,
6956 protocol_item,
6957 subframeId, frameId, slotId, startSymbolId,
6958 bit_width, ci_comp_method, ci_comp_opt,
6959 num_sinr_per_prb);
6960 }
6961
6962 /* Expert error if we are short of tvb by > 3 bytes */
6963 if (tvb_reported_length_remaining(tvb, offset) > 3) {
6964 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
6965 "%u bytes remain at end of frame - should be 0-3",
6966 tvb_reported_length_remaining(tvb, offset));
6967 }
6968
6969 if (PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && result) {
6970 /* Show list of frames that have corresponding U-plane data */
6971 wmem_list_frame_t *list_frame;
6972 for (list_frame = wmem_list_head(result->u_plane_frames); list_frame != NULL((void*)0); list_frame = wmem_list_frame_next(list_frame)) {
6973 corresponding_uplane_frame *frame = wmem_list_frame_data(list_frame);
6974 proto_item *uplane_frame_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frame, tvb, 0, 0,
6975 frame->frame_number);
6976 proto_item_append_text(uplane_frame_ti, " sectionId:%2u symbol:%2u PRBs %3u->%3u (in %uus)",
6977 frame->sectionId, frame->symbol, frame->startPrbu, frame->startPrbu+frame->numPrbu-1, frame->gap_in_usecs);
6978 proto_item_set_generated(uplane_frame_ti);
6979 }
6980 /* Also show total number of corresponding u-plane frames */
6981 proto_item *uplane_frame_count_ti = proto_tree_add_uint(oran_tree, hf_oran_corresponding_uplane_frames_total, tvb, 0, 0,
6982 wmem_list_count(result->u_plane_frames));
6983 proto_item_set_generated(uplane_frame_count_ti);
6984 }
6985
6986 return tvb_captured_length(tvb);
6987}
6988
6989static int dissect_oran_u_re(tvbuff_t *tvb, proto_tree *tree,
6990 unsigned sample_number, int samples_offset,
6991 oran_tap_info *tap_info,
6992 unsigned sample_bit_width,
6993 int comp_meth,
6994 uint32_t exponent,
6995 section_mod_compr_config_t *mod_compr_params,
6996 uint8_t re)
6997{
6998 /* I */
6999 unsigned i_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7000 float i_value = decompress_value(i_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7001 unsigned sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7002 proto_item *i_ti = proto_tree_add_float(tree, hf_oran_iSample, tvb, samples_offset/8, sample_len_in_bytes, i_value);
7003 proto_item_set_text(i_ti, "iSample: % 0.7f 0x%04x (RE-%2u in the PRB)", i_value, i_bits, sample_number);
7004 samples_offset += sample_bit_width;
7005 /* Q */
7006 unsigned q_bits = tvb_get_bits32(tvb, samples_offset, sample_bit_width, ENC_BIG_ENDIAN0x00000000);
7007 float q_value = decompress_value(q_bits, comp_meth, sample_bit_width, exponent, mod_compr_params, re);
7008 sample_len_in_bytes = ((samples_offset%8)+sample_bit_width+7)/8;
7009 proto_item *q_ti = proto_tree_add_float(tree, hf_oran_qSample, tvb, samples_offset/8, sample_len_in_bytes, q_value);
7010 proto_item_set_text(q_ti, "qSample: % 0.7f 0x%04x (RE-%2u in the PRB)", q_value, q_bits, sample_number);
7011 samples_offset += sample_bit_width;
7012
7013 /* Update RE stats */
7014 tap_info->num_res++;
7015 /* if (i_value == 0.0 && q_value == 0.0) { */
7016 /* TODO: is just checking bits from frame good enough - assuming this always corresponds to a zero value? */
7017 if (i_bits == 0 && q_bits == 0) {
7018 tap_info->num_res_zero++;
7019 }
7020 else {
7021 tap_info->non_zero_re_in_current_prb = true1;
7022 }
7023 return samples_offset;
7024}
7025
7026
7027static bool_Bool udcomplen_appears_present(bool_Bool udcomphdr_present, tvbuff_t *tvb, int offset)
7028{
7029 if (!udcomplen_heuristic_result_set) {
7030 /* All sections will start the same way */
7031 unsigned int section_bytes_before_field = (udcomphdr_present) ? 6 : 4;
7032
7033 /* Move offset back to the start of the section */
7034 offset -= section_bytes_before_field;
7035
7036 do {
7037 /* This field appears several bytes into the U-plane section */
7038 uint32_t length_remaining = tvb_reported_length_remaining(tvb, offset);
7039 /* Are there enough bytes to still read the length field? */
7040 if (section_bytes_before_field+2 > length_remaining) {
7041 udcomplen_heuristic_result = false0;
7042 udcomplen_heuristic_result_set = true1;
7043 break;
7044 }
7045
7046 /* Read the length field */
7047 uint16_t udcomplen = tvb_get_ntohs(tvb, offset+section_bytes_before_field);
7048
7049 /* Is this less than a valid section? Realistic minimal section will be bigger than this..
7050 * Could take into account numPrbU, etc */
7051 if (udcomplen < section_bytes_before_field+2) {
7052 udcomplen_heuristic_result = false0;
7053 udcomplen_heuristic_result_set = true1;
7054 break;
7055 }
7056
7057 /* Does this section fit into the frame? */
7058 if (udcomplen > length_remaining) {
7059 udcomplen_heuristic_result = false0;
7060 udcomplen_heuristic_result_set = true1;
7061 break;
7062 }
7063
7064 /* Move past this section */
7065 offset += udcomplen;
7066
7067 /* Are we at the end of the frame? */
7068 /* TODO: if frame is less than 60 bytes, there may be > 4 bytes, likely zeros.. */
7069 if (tvb_reported_length_remaining(tvb, offset) < 4) {
7070 udcomplen_heuristic_result = true1;
7071 udcomplen_heuristic_result_set = true1;
7072 }
7073 } while (!udcomplen_heuristic_result_set);
7074 }
7075 return udcomplen_heuristic_result;
7076}
7077
7078static bool_Bool at_udcomphdr(tvbuff_t *tvb, int offset)
7079{
7080 if (tvb_captured_length_remaining(tvb, offset) < 2) {
7081 return false0;
7082 }
7083 uint8_t first_byte = tvb_get_uint8(tvb, offset);
7084 uint8_t reserved_byte = tvb_get_uint8(tvb, offset+1);
7085
7086 /* - iq width could be anything, though unlikely to be signalled as (say) < 1-3? */
7087 /* - meth should be 0-8 */
7088 /* - reserved byte should be 0 */
7089 return (((first_byte & 0x0f) <= MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8) && (reserved_byte == 0));
7090}
7091
7092static bool_Bool udcomphdr_appears_present(flow_state_t *flow, uint32_t direction, tvbuff_t *tvb, int offset)
7093{
7094 /* Should really not happen, but guard against this anyway. */
7095 if (flow == NULL((void*)0)) {
7096 /* No state to update. */
7097 return false0;
7098 }
7099
7100 if (direction == DIR_UPLINK0) {
7101 if (flow->udcomphdrUplink_heuristic_result_set) {
7102 /* Return cached value */
7103 return flow->udcomphdrUplink_heuristic_result;
7104 }
7105 else {
7106 /* Work it out, and save answer for next time */
7107 flow->udcomphdrUplink_heuristic_result_set = true1;
7108 flow->udcomphdrUplink_heuristic_result = at_udcomphdr(tvb, offset);
7109 return flow->udcomphdrUplink_heuristic_result;
7110 }
7111 }
7112 else {
7113 /* Downlink */
7114 if (flow->udcomphdrDownlink_heuristic_result_set) {
7115 /* Return cached value */
7116 return flow->udcomphdrDownlink_heuristic_result;
7117 }
7118 else {
7119 /* Work it out, and save answer for next time */
7120 flow->udcomphdrDownlink_heuristic_result_set = true1;
7121 flow->udcomphdrDownlink_heuristic_result = at_udcomphdr(tvb, offset);
7122 return flow->udcomphdrDownlink_heuristic_result;
7123 }
7124 }
7125}
7126
7127static bool_Bool copy_section_entry(const void *key, void* value, void *userdata)
7128{
7129 /* Cast parameters to their types */
7130 uint32_t sectionId = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
7131 expected_section_data_t *result_value = (expected_section_data_t *)value;
7132 wmem_tree_t *result_tree = (wmem_tree_t*)userdata;
7133
7134 /* Deep copy of section data */
7135 expected_section_data_t *copy = wmem_new0(wmem_file_scope(), expected_section_data_t)((expected_section_data_t*)wmem_alloc0((wmem_file_scope()), sizeof
(expected_section_data_t)))
;
7136 *copy = *result_value;
7137
7138 /* Add into result tree */
7139 wmem_tree_insert32(result_tree, sectionId, copy);
7140
7141 return false0;
7142}
7143
7144/* User plane dissector (section 8) */
7145static int
7146dissect_oran_u(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7147 oran_tap_info *tap_info, void *data _U___attribute__((unused)))
7148{
7149 /* Hidden filter for plane */
7150 proto_item *plane_ti = proto_tree_add_item(tree, hf_oran_uplane, tvb, 0, 0, ENC_NA0x00000000);
7151 PROTO_ITEM_SET_HIDDEN(plane_ti)proto_item_set_hidden((plane_ti));
7152
7153 /* Set up structures needed to add the protocol subtree and manage it */
7154 unsigned offset = 0;
7155
7156 col_set_str(pinfo->cinfo, COL_PROTOCOL, "O-RAN-FH-U");
7157 col_set_str(pinfo->cinfo, COL_INFO, "U-Plane");
7158
7159 tap_info->userplane = true1;
7160
7161 /* Create display subtree for the protocol */
7162 proto_item *protocol_item = proto_tree_add_item(tree, proto_oran, tvb, 0, -1, ENC_NA0x00000000);
7163 proto_item_append_text(protocol_item, "-U");
7164 proto_tree *oran_tree = proto_item_add_subtree(protocol_item, ett_oran);
7165
7166 /* Transport header */
7167 /* Real-time control data / IQ data transfer message series identifier */
7168 uint16_t eAxC;
7169 addPcOrRtcid(tvb, oran_tree, &offset, hf_oran_ecpri_pcid, &eAxC, tap_info);
7170 tap_info->eaxc = eAxC;
7171
7172 /* Update/report status of conversation */
7173 uint32_t key = make_flow_key(pinfo, eAxC, ORAN_U_PLANE1, false0);
7174 flow_state_t* state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, key);
7175
7176 flow_result_t *result = NULL((void*)0);
7177
7178 /* Message identifier */
7179 proto_item *seqIdItem;
7180 uint32_t seqId, subSeqId, e;
7181 offset = addSeqid(tvb, oran_tree, offset, ORAN_U_PLANE1, &seqId, &seqIdItem, pinfo, &subSeqId, &e);
7182
7183 /* Common header for time reference */
7184 proto_item *timingHeader = proto_tree_add_string_format(oran_tree, hf_oran_timing_header,
7185 tvb, offset, 4, "", "Timing Header (");
7186 proto_tree *timing_header_tree = proto_item_add_subtree(timingHeader, ett_oran_u_timing);
7187
7188 /* dataDirection */
7189 uint32_t direction;
7190 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_data_direction, tvb, offset, 1, ENC_NA0x00000000, &direction);
7191 tap_info->uplink = (direction==0);
1
Assuming 'direction' is not equal to 0
7192 /* payloadVersion */
7193 dissect_payload_version(timing_header_tree, tvb, pinfo, offset);
7194 /* filterIndex */
7195 proto_tree_add_item(timing_header_tree, hf_oran_filter_index, tvb, offset, 1, ENC_NA0x00000000);
7196 offset += 1;
7197
7198 int ref_a_offset = offset;
7199
7200 /* frameId */
7201 uint32_t frameId = 0;
7202 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_frame_id, tvb, offset, 1, ENC_NA0x00000000, &frameId);
7203 tap_info->frame = frameId;
7204 offset += 1;
7205
7206 /* subframeId */
7207 uint32_t subframeId = 0;
7208 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_subframe_id, tvb, offset, 1, ENC_NA0x00000000, &subframeId);
7209 /* slotId */
7210 uint32_t slotId = 0;
7211 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &slotId);
7212 tap_info->slot = slotId;
7213 offset++;
7214 /* symbolId */
7215 uint32_t symbolId = 0;
7216 proto_tree_add_item_ret_uint(timing_header_tree, hf_oran_symbolId, tvb, offset, 1, ENC_NA0x00000000, &symbolId);
7217 offset++;
7218
7219 char id[16];
7220 snprintf(id, 16, "%u-%u-%u-%u", frameId, subframeId, slotId, symbolId);
7221 proto_item *pi = proto_tree_add_string(timing_header_tree, hf_oran_refa, tvb, ref_a_offset, 3, id);
7222 proto_item_set_generated(pi);
7223
7224 proto_item_append_text(timingHeader, "%s, frameId: %d, subframeId: %d, slotId: %d, symbolId: %d)",
7225 val_to_str_const(direction, data_direction_vals, "Unknown"), frameId, subframeId, slotId, symbolId);
7226
7227 unsigned sample_bit_width;
7228 unsigned compression;
7229 int includeUdCompHeader;
7230
7231 /* Also lookup C-PLANE state (sent in opposite direction for UL) so may check current compression settings */
7232 uint32_t cplane_key = make_flow_key(pinfo, eAxC, ORAN_C_PLANE0, direction
1.1
'direction' is not equal to 0
== 0);
7233 flow_state_t* cplane_state = (flow_state_t*)wmem_tree_lookup32(flow_states_table, cplane_key);
7234
7235 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
2
Assuming field 'visited' is not equal to 0
3
Taking false branch
7236 /* Create state/conversation if doesn't exist yet */
7237 if (!state) {
7238 /* Allocate new state */
7239 state = wmem_new0(wmem_file_scope(), flow_state_t)((flow_state_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_state_t
)))
;
7240 state->ack_nack_requests = wmem_tree_new(wmem_file_scope());
7241 state->expected_sections[0] = wmem_tree_new(wmem_file_scope());
7242 state->expected_sections[1] = wmem_tree_new(wmem_file_scope());
7243 wmem_tree_insert32(flow_states_table, key, state);
7244 }
7245
7246 result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7247 result->expected_sections = wmem_tree_new(wmem_file_scope());
7248 result->u_plane_frames = wmem_list_new(wmem_file_scope());
7249
7250 wmem_tree_insert32(flow_results_table, pinfo->num, result);
7251
7252 /* Check sequence analysis status (but not if later part of radio layer fragmentation) */
7253 if (state->last_frame_seen[direction] && (subSeqId==0) && (seqId != state->next_expected_sequence_number[direction])) {
7254 /* Store this result */
7255 result->unexpected_seq_number = true1;
7256 result->expected_sequence_number = state->next_expected_sequence_number[direction];
7257 result->previous_frame = state->last_frame[direction];
7258 }
7259 /* Update sequence analysis state */
7260 state->last_frame[direction] = pinfo->num;
7261 state->last_frame_seen[direction] = true1;
7262 state->next_expected_sequence_number[direction] = (seqId+1) % 256;
7263 }
7264
7265 /* Show any issues associated with this frame number */
7266 result = wmem_tree_lookup32(flow_results_table, pinfo->num);
4
Value assigned to 'result'
7267 if (result) {
5
Assuming 'result' is null
7268 if (result->unexpected_seq_number) {
7269 expert_add_info_format(pinfo, seqIdItem,
7270 (direction == DIR_UPLINK0) ?
7271 &ei_oran_uplane_unexpected_sequence_number_ul :
7272 &ei_oran_uplane_unexpected_sequence_number_dl,
7273 "Sequence number %u expected, but got %u",
7274 result->expected_sequence_number, seqId);
7275 tap_info->missing_sns = (256 + seqId - result->expected_sequence_number) % 256;
7276 /* TODO: could add previous/next frame (in seqId tree?) ? */
7277 }
7278 }
7279
7280 /* Checking UL timing within current slot. Disabled if limit set to 0. */
7281 /* N.B., timing is relative to first seen frame,
7282 not some notion of the beginning of the slot from sync, offset by some timing.. */
7283 if (direction
5.1
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0 && us_allowed_for_ul_in_symbol > 0) {
7284 uint32_t timing_key = get_timing_key(frameId, subframeId, slotId, symbolId);
7285 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7286 /* Set state on first pass */
7287 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7288 if (!timing) {
7289 /* Allocate new state */
7290 timing = wmem_new0(wmem_file_scope(), ul_timing_for_slot)((ul_timing_for_slot*)wmem_alloc0((wmem_file_scope()), sizeof
(ul_timing_for_slot)))
;
7291 timing->first_frame = pinfo->num;
7292 timing->first_frame_time = pinfo->abs_ts;
7293 timing->frames_seen_in_symbol = 1;
7294 timing->last_frame_in_symbol = pinfo->num;
7295 wmem_tree_insert32(ul_symbol_timing, timing_key, timing);
7296 }
7297 else {
7298 /* Update existing state */
7299 timing->frames_seen_in_symbol++;
7300 timing->last_frame_in_symbol = pinfo->num;
7301 }
7302 }
7303 else {
7304 /* Subsequent passes - look up result */
7305 ul_timing_for_slot* timing = (ul_timing_for_slot*)wmem_tree_lookup32(ul_symbol_timing, timing_key);
7306 if (timing) { /* Really shouldn't fail! */
7307 if (timing->frames_seen_in_symbol > 1) {
7308 /* Work out gap between frames (in microseconds) back to frame carrying first seen symbol */
7309 int seconds_between_packets = (int)
7310 (pinfo->abs_ts.secs - timing->first_frame_time.secs);
7311 int nseconds_between_packets =
7312 pinfo->abs_ts.nsecs - timing->first_frame_time.nsecs;
7313
7314 /* Round to nearest microsecond. */
7315 uint32_t total_gap = (seconds_between_packets*1000000) +
7316 ((nseconds_between_packets+500) / 1000);
7317
7318 /* Show how long it has been */
7319 proto_item *ti = NULL((void*)0);
7320 if (pinfo->num != timing->first_frame) {
7321 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_time, tvb, 0, 0, total_gap);
7322 proto_item_set_generated(ti);
7323 }
7324
7325 if (total_gap > us_allowed_for_ul_in_symbol) {
7326 expert_add_info_format(pinfo, ti, &ei_oran_ul_uplane_symbol_too_long,
7327 "UL U-Plane Tx took longer (%u us) than limit set in preferences (%u us)",
7328 total_gap, us_allowed_for_ul_in_symbol);
7329 proto_item_append_text(timingHeader, " (%uus since first frame seen for symbol)", total_gap);
7330 }
7331
7332 /* Show how many frames were received */
7333 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_frames, tvb, 0, 0, timing->frames_seen_in_symbol);
7334 proto_item_set_generated(ti);
7335
7336 /* Link to first frame for this symbol */
7337 if (pinfo->num != timing->first_frame) {
7338 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_first_frame, tvb, 0, 0, timing->first_frame);
7339 proto_item_set_generated(ti);
7340 }
7341
7342 /* And also last frame */
7343 if (pinfo->num != timing->last_frame_in_symbol) {
7344 ti = proto_tree_add_uint(timingHeader, hf_oran_u_section_ul_symbol_last_frame, tvb, 0, 0, timing->last_frame_in_symbol);
7345 proto_item_set_generated(ti);
7346 }
7347
7348 tap_info->ul_delay_in_us = total_gap;
7349 }
7350 }
7351 }
7352 }
7353
7354
7355 /* Look up preferences for samples */
7356 if (direction
5.2
'direction' is not equal to DIR_UPLINK
== DIR_UPLINK0) {
6
Taking false branch
7357 sample_bit_width = pref_sample_bit_width_uplink;
7358 compression = pref_iqCompressionUplink;
7359 includeUdCompHeader = pref_includeUdCompHeaderUplink;
7360 } else {
7361 sample_bit_width = pref_sample_bit_width_downlink;
7362 compression = pref_iqCompressionDownlink;
7363 includeUdCompHeader = pref_includeUdCompHeaderDownlink;
7364 }
7365
7366 /* If uplink, load any udCompHdr settings written by C-Plane */
7367 bool_Bool ud_cmp_hdr_cplane = false0;
7368 if (cplane_state && direction
7.1
'direction' is not equal to 0
== 0) {
7
Assuming 'cplane_state' is non-null
8
Taking false branch
7369 /* Initialise settings from udpCompHdr from C-Plane */
7370 if (cplane_state->ul_ud_comp_hdr_set && !pref_override_ul_compression) {
7371 sample_bit_width = cplane_state->ul_ud_comp_hdr_bit_width;
7372 compression = cplane_state->ul_ud_comp_hdr_compression;
7373 ud_cmp_hdr_cplane = true1;
7374 }
7375 }
7376
7377 /* Need a valid value (e.g. 9, 14). 0 definitely won't work, as won't progress around loop! */
7378 /* N.B. may yet be overwritten by udCompHdr settings in sections below! */
7379 if (sample_bit_width == 0) {
9
Assuming 'sample_bit_width' is not equal to 0
10
Taking false branch
7380 expert_add_info_format(pinfo, protocol_item, &ei_oran_invalid_sample_bit_width,
7381 "%cL Sample bit width from %s (%u) not valid, so can't decode sections",
7382 (direction == DIR_UPLINK0) ? 'U' : 'D',
7383 !ud_cmp_hdr_cplane ? "preference" : "C-Plane",
7384 sample_bit_width);
7385 return offset;
7386 }
7387
7388 unsigned bytesLeft;
7389 unsigned number_of_sections = 0;
7390 unsigned nBytesPerPrb =0;
7391
7392 if (link_planes_together && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && cplane_state) {
11
Assuming 'link_planes_together' is false
7393 /* Take a deep-copy of this state on first pass */
7394 wmem_tree_foreach(cplane_state->expected_sections[direction], copy_section_entry, result->expected_sections);
7395 }
7396
7397 /* Add each section (not from count, just keep parsing until payload used) */
7398 do {
7399 /* Section subtree */
7400 unsigned section_start_offset = offset;
7401 proto_item *sectionHeading = proto_tree_add_string_format(oran_tree, hf_oran_u_section,
7402 tvb, offset, 0, "", "Section");
7403 proto_tree *section_tree = proto_item_add_subtree(sectionHeading, ett_oran_u_section);
7404
7405 /* Section Header fields (darker green part) */
7406
7407 /* sectionId */
7408 uint32_t sectionId = 0;
7409 proto_item *sectionId_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_section_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &sectionId);
7410 if (sectionId == 4095) {
12
Assuming 'sectionId' is not equal to 4095
13
Taking false branch
7411 proto_item_append_text(sectionId_ti, " (not default coupling C/U planes using sectionId)");
7412 }
7413 offset++;
7414
7415 if (tap_info->num_section_ids < MAX_SECTION_IDs32) {
14
Assuming field 'num_section_ids' is >= MAX_SECTION_IDs
15
Taking false branch
7416 tap_info->section_ids[tap_info->num_section_ids++] = sectionId;
7417 }
7418
7419 section_details_t *section_details = NULL((void*)0);
7420 corresponding_uplane_frame *details = NULL((void*)0);
7421
7422 /* Lookup corresponding C-plane frame/info */
7423 if (link_planes_together) {
16
Assuming 'link_planes_together' is true
17
Taking true branch
7424 if (cplane_state
17.1
'cplane_state' is not equal to NULL
!= NULL((void*)0)) {
18
Taking true branch
7425
7426 expected_section_data_t *section_data = NULL((void*)0);
7427 section_data = wmem_tree_lookup32(result->expected_sections, sectionId);
19
Access to field 'expected_sections' results in a dereference of a null pointer (loaded from variable 'result')
7428
7429 if (section_data) {
7430 /* Need to work out which of 2 entries is in use for this data frame */
7431 unsigned index_to_use = 0;
7432
7433 /* Does the first entry match the timing for this frame? */
7434 if (section_data->details[0].frame == frameId &&
7435 section_data->details[0].subframe == subframeId &&
7436 section_data->details[0].slot == slotId &&
7437 /* Check that symbolId is in range */
7438 section_data->details[0].startSymbol <= symbolId &&
7439 (unsigned)(section_data->details[0].startSymbol + section_data->details[0].numSymbols) <= (unsigned)symbolId) {
7440
7441 index_to_use = 0;
7442 }
7443 else if (section_data->details[1].frame == frameId &&
7444 section_data->details[1].subframe == subframeId &&
7445 section_data->details[1].slot == slotId &&
7446 /* Check that symbolId is in range */
7447 section_data->details[1].startSymbol <= symbolId &&
7448 (unsigned)(section_data->details[1].startSymbol + section_data->details[1].numSymbols) <= (unsigned)symbolId) {
7449
7450 index_to_use = 1;
7451 }
7452 else {
7453 /* There was a sectionId, but timing header didn't exactly match, so neither index may be used.. */
7454 index_to_use = 2; /* invalid value */
7455 /* Expert info */
7456 expert_add_info_format(NULL((void*)0), sectionId_ti,
7457 &ei_oran_cplane_entry_not_found,
7458 "C-plane entry for %s sectionId %u at timing header %u-%u-%u-%u",
7459 (direction) ? "DL" : "UL", sectionId,
7460 frameId, subframeId, slotId, symbolId);
7461 }
7462
7463 if (index_to_use <= 1) {
7464 section_details = &section_data->details[index_to_use];
7465
7466 /* Cplane frame number */
7467 proto_item *cplane_frame_ti = proto_tree_add_uint(section_tree, hf_oran_corresponding_cplane_frame, tvb, 0, 0,
7468 section_details->frame_number);
7469 proto_item_set_generated(cplane_frame_ti);
7470
7471 /* usecs since cplane frame */
7472 time_t total_gap = 0;
7473
7474 if ((pinfo->abs_ts.secs == section_details->frame_time.secs) || (pinfo->abs_ts.secs == section_details->frame_time.secs+1)) {
7475 total_gap = ((pinfo->abs_ts.secs - section_details->frame_time.secs) * 1000000) +
7476 ((pinfo->abs_ts.nsecs - section_details->frame_time.nsecs)/1000);
7477 }
7478
7479 if (total_gap > 0) {
7480 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);
7481 proto_item_set_generated(cplane_delta_ti);
7482 }
7483
7484 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
7485 /* Look up 'result' for c-plane frame, and tell it about this frame.. */
7486 flow_result_t *cplane_result = wmem_tree_lookup32(flow_results_table, section_details->frame_number);
7487 if (!cplane_result) {
7488 cplane_result = wmem_new0(wmem_file_scope(), flow_result_t)((flow_result_t*)wmem_alloc0((wmem_file_scope()), sizeof(flow_result_t
)))
;
7489 cplane_result->u_plane_frames = wmem_list_new(wmem_file_scope());
7490 wmem_tree_insert32(flow_results_table, section_details->frame_number, cplane_result);
7491 }
7492 /* PRB range filled in below.. */
7493
7494 details = wmem_new(wmem_file_scope(), corresponding_uplane_frame)((corresponding_uplane_frame*)wmem_alloc((wmem_file_scope()),
sizeof(corresponding_uplane_frame)))
;
7495 details->frame_number = pinfo->num;
7496 details->gap_in_usecs = (uint32_t)total_gap;
7497 details->sectionId = sectionId;
7498 details->symbol = symbolId;
7499
7500 wmem_list_append(cplane_result->u_plane_frames, details);
7501 }
7502 }
7503 }
7504 else {
7505 /* No section entry at all */
7506 expert_add_info_format(NULL((void*)0), sectionId_ti,
7507 &ei_oran_cplane_entry_not_found,
7508 "C-plane entry for %s sectionId %u not found",
7509 (direction) ? "DL" : "UL", sectionId);
7510 }
7511 }
7512 }
7513
7514 /* rb */
7515 uint32_t rb;
7516 proto_tree_add_item_ret_uint(section_tree, hf_oran_rb, tvb, offset, 1, ENC_NA0x00000000, &rb);
7517 /* symInc. "use of symInc=1 shall be prohibited in the U-plane" */
7518 uint8_t syminc;
7519 proto_item *syminc_ti = proto_tree_add_item_ret_uint8(section_tree, hf_oran_symInc, tvb, offset, 1, ENC_NA0x00000000, &syminc);
7520 if (syminc) {
7521 expert_add_info(NULL((void*)0), syminc_ti, &ei_oran_syminc_set_for_uplane);
7522 }
7523 /* startPrbu */
7524 uint32_t startPrbu = 0;
7525 proto_tree_add_item_ret_uint(section_tree, hf_oran_startPrbu, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &startPrbu);
7526 offset += 2;
7527
7528 /* numPrbu */
7529 uint32_t numPrbu = 0;
7530 proto_tree_add_item_ret_uint(section_tree, hf_oran_numPrbu, tvb, offset, 1, ENC_NA0x00000000, &numPrbu);
7531 offset += 1;
7532
7533 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && details) {
7534 details->startPrbu = startPrbu;
7535 details->numPrbu = (numPrbu) ? numPrbu : 273;
7536 }
7537
7538 proto_item *ud_comp_meth_item, *ud_comp_len_ti=NULL((void*)0);
7539 uint32_t ud_comp_len = 0;
7540
7541 /* udCompHdr (if preferences indicate will be present) */
7542 bool_Bool included = (includeUdCompHeader==1) || /* 1 means present.. */
7543 (includeUdCompHeader==2 && udcomphdr_appears_present(state, direction, tvb, offset));
7544 if (included) {
7545 /* 7.5.2.10 */
7546 /* Extract these values to inform how wide IQ samples in each PRB will be. */
7547 offset = dissect_udcomphdr(tvb, pinfo, section_tree, offset, false0, direction == 0, &sample_bit_width,
7548 &compression, &ud_comp_meth_item, tap_info);
7549
7550 /* Not part of udCompHdr */
7551 uint32_t reserved;
7552 proto_item *res_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_reserved_8bits, tvb, offset, 1, ENC_NA0x00000000, &reserved);
7553 offset += 1;
7554 if (reserved != 0) {
7555 expert_add_info_format(pinfo, res_ti, &ei_oran_reserved_not_zero,
7556 "reserved field (0x%x) not zero - perhaps udCompHdr is not really present?",
7557 reserved);
7558 }
7559 }
7560 else {
7561 /* No fields to dissect - just showing comp values from prefs */
7562 /* iqWidth */
7563 proto_item *iq_width_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrIqWidth_pref, tvb, 0, 0, sample_bit_width);
7564 proto_item_append_text(iq_width_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7565 proto_item_set_generated(iq_width_item);
7566
7567 /* udCompMethod */
7568 ud_comp_meth_item = proto_tree_add_uint(section_tree, hf_oran_udCompHdrMeth_pref, tvb, 0, 0, compression);
7569 proto_item_append_text(ud_comp_meth_item, (ud_cmp_hdr_cplane) ? " (from c-plane)" : " (from preferences)");
7570 proto_item_set_generated(ud_comp_meth_item);
7571
7572 /* Point back to C-Plane, if used */
7573 /* TODO: doesn't work with multiple port mappings using SE10.. */
7574 if (ud_cmp_hdr_cplane) {
7575 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);
7576 proto_item_set_generated(cplane_ti);
7577 }
7578
7579 tap_info->compression_methods |= (1 << compression);
7580 tap_info->compression_width = sample_bit_width;
7581 }
7582
7583 /* Consider fragmentation after first section header */
7584 if (do_radio_transport_layer_reassembly && (number_of_sections == 0) && (e !=1 || subSeqId!= 0)) {
7585
7586 /* Set fragmented flag. */
7587 bool_Bool save_fragmented = pinfo->fragmented;
7588 pinfo->fragmented = true1;
7589 fragment_head *fh;
7590 unsigned frag_data_len = tvb_reported_length_remaining(tvb, offset);
7591
7592 /* Add this fragment into reassembly table */
7593 uint32_t reassembly_id = make_reassembly_id(seqId, direction, eAxC,
7594 frameId, subframeId, slotId, symbolId);
7595 fh = fragment_add_seq(&oran_reassembly_table, tvb, offset, pinfo,
7596 reassembly_id, /* id */
7597 GUINT_TO_POINTER(reassembly_id)((gpointer) (gulong) (reassembly_id)), /* data */
7598 subSeqId, /* frag_number */
7599 frag_data_len, /* frag_data_len */
7600 !e, /* more_frags */
7601 0);
7602
7603 bool_Bool update_col_info = true1;
7604
7605 /* See if this completes an SDU */
7606 tvbuff_t *original_tvb = tvb;
7607 tvbuff_t *next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled O-RAN FH CUS Payload",
7608 fh, &oran_frag_items,
7609 &update_col_info, oran_tree);
7610 if (next_tvb) {
7611 /* Have reassembled data */
7612 proto_tree_add_item(oran_tree, hf_oran_payload, next_tvb, 0, -1, ENC_NA0x00000000);
7613 col_append_fstr(pinfo->cinfo, COL_INFO, " Reassembled Data (%u bytes)", tvb_reported_length(next_tvb));
7614 /* Dissection should resume at start of reassembled tvb */
7615 offset = 0;
7616 }
7617 /* Will continue with either reassembled tvb or NULL */
7618 tvb = next_tvb;
7619
7620 /* Restore fragmented flag */
7621 pinfo->fragmented = save_fragmented;
7622
7623 /* Don't dissect any more if not complete yet.. */
7624 if (tvb == NULL((void*)0)) {
7625 return tvb_captured_length(original_tvb);
7626 }
7627 }
7628
7629
7630 /* Not supported! TODO: other places where comp method is looked up (e.g., bfw?) */
7631 switch (compression) {
7632 case COMP_NONE0:
7633 case COMP_BLOCK_FP1:
7634 case BFP_AND_SELECTIVE_RE5:
7635 case COMP_MODULATION4:
7636 case MOD_COMPR_AND_SELECTIVE_RE6:
7637 break;
7638 default:
7639 expert_add_info_format(pinfo, ud_comp_meth_item, &ei_oran_unsupported_compression_method,
7640 "Compression method %u (%s) not supported by dissector",
7641 compression,
7642 rval_to_str_const(compression, ud_comp_header_meth, "reserved"));
7643 }
7644
7645 /* udCompLen (when supported, methods 5,6,7,8) */
7646 if (compression >= BFP_AND_SELECTIVE_RE5) {
7647 bool_Bool supported = (pref_support_udcompLen==1) || /* supported */
7648 (pref_support_udcompLen==2 && udcomplen_appears_present(includeUdCompHeader, tvb, offset));
7649
7650 if (supported) {
7651 ud_comp_len_ti = proto_tree_add_item_ret_uint(section_tree, hf_oran_udCompLen, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &ud_comp_len);
7652 if (ud_comp_len <= 1) {
7653 proto_item_append_text(ud_comp_len_ti, " (reserved)");
7654 }
7655 /* TODO: report if less than a viable section in frame? */
7656 /* Check that there is this much length left in the frame */
7657 if (ud_comp_len > tvb_reported_length_remaining(tvb, section_start_offset)) {
7658 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7659 "udCompLen indicates %u bytes in section, but only %u are left in frame",
7660 ud_comp_len, tvb_reported_length_remaining(tvb, section_start_offset));
7661 }
7662 /* Actual length of section will be checked below, at the end of the section */
7663 offset += 2;
7664 }
7665 }
7666
7667 /* sReSMask1 + sReSMask2 (depends upon compression method) */
7668 uint64_t sresmask1=0, sresmask2=0;
7669 if (compression == BFP_AND_SELECTIVE_RE_WITH_MASKS7 ||
7670 compression == MOD_COMPR_AND_SELECTIVE_RE_WITH_MASKS8)
7671 {
7672 static int * const sres_mask1_2_flags[] = {
7673 &hf_oran_sReSMask1_2_re12,
7674 &hf_oran_sReSMask1_2_re11,
7675 &hf_oran_sReSMask1_2_re10,
7676 &hf_oran_sReSMask1_2_re9,
7677 &hf_oran_sReSMask_re8,
7678 &hf_oran_sReSMask_re7,
7679 &hf_oran_sReSMask_re6,
7680 &hf_oran_sReSMask_re5,
7681 &hf_oran_sReSMask_re4,
7682 &hf_oran_sReSMask_re3,
7683 &hf_oran_sReSMask_re2,
7684 &hf_oran_sReSMask_re1,
7685 NULL((void*)0)
7686 };
7687
7688 /* reserved (4 bits) */
7689 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7690 /* sReSMask1 (12 bits) */
7691 proto_item *sresmask_ti;
7692 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7693 hf_oran_sReSMask1,
7694 ett_oran_sresmask,
7695 sres_mask1_2_flags,
7696 ENC_NA0x00000000,
7697 &sresmask1);
7698 offset += 2;
7699 /* Count REs present */
7700 unsigned res = 0;
7701 for (unsigned n=0; n < 12; n++) {
7702 if ((sresmask1 >> n) & 0x1) {
7703 res++;
7704 }
7705 }
7706 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7707
7708
7709 /* reserved (4 bits) */
7710 add_reserved_field(section_tree, hf_oran_reserved_4bits, tvb, offset, 1);
7711 /* sReSMask2 (12 bits) */
7712 sresmask_ti = proto_tree_add_bitmask_ret_uint64(section_tree, tvb, offset,
7713 hf_oran_sReSMask2,
7714 ett_oran_sresmask,
7715 sres_mask1_2_flags,
7716 ENC_NA0x00000000,
7717 &sresmask2);
7718 offset += 2;
7719
7720 if (rb == 1) {
7721 proto_item_append_text(sresmask_ti, " (ignored)");
7722 if (sresmask2 != 0) {
7723 expert_add_info(pinfo, ud_comp_len_ti, &ei_oran_sresmask2_not_zero_with_rb);
7724 }
7725 }
7726 else {
7727 /* Count REs present */
7728 res = 0;
7729 for (unsigned n=0; n < 12; n++) {
7730 if ((sresmask2 >> n) & 0x1) {
7731 res++;
7732 }
7733 }
7734 proto_item_append_text(sresmask_ti, " (%u REs)", res);
7735 }
7736 }
7737
7738 write_section_info(sectionHeading, pinfo, protocol_item, sectionId, startPrbu, numPrbu, rb);
7739
7740 /* TODO: should this use the same pref as c-plane? */
7741 if (numPrbu == 0) {
7742 /* Special case for all PRBs (NR: the total number of PRBs may be > 255) */
7743 numPrbu = pref_data_plane_section_total_rbs;
7744 startPrbu = 0; /* may already be 0... */
7745 }
7746
7747 section_mod_compr_config_t* mod_compr_config = get_mod_compr_section_to_read(cplane_state, sectionId);
7748
7749 /* Add each PRB */
7750 for (unsigned i = 0; i < numPrbu; i++) {
7751 /* Create subtree */
7752 proto_item *prbHeading = proto_tree_add_string_format(section_tree, hf_oran_samples_prb,
7753 tvb, offset, 0,
7754 "", "PRB");
7755 proto_tree *rb_tree = proto_item_add_subtree(prbHeading, ett_oran_u_prb);
7756 uint32_t exponent = 0;
7757 uint16_t sresmask = 0;
7758
7759 /* udCompParam (depends upon compression method) */
7760 int before = offset;
7761 offset = dissect_udcompparam(tvb, pinfo, rb_tree, offset, compression, &exponent, &sresmask, false0);
7762 int udcompparam_len = offset-before;
7763
7764 /* Show PRB number in root */
7765 proto_item_append_text(prbHeading, " %3u", startPrbu + i*(1+rb));
7766
7767 /* Work out how many REs / PRB */
7768 unsigned res_per_prb = 12;
7769 uint16_t sresmask_to_use = 0x0fff;
7770
7771 if (compression >= BFP_AND_SELECTIVE_RE5) {
7772 /* Work out which mask should be used */
7773 if (compression==BFP_AND_SELECTIVE_RE5 || compression==MOD_COMPR_AND_SELECTIVE_RE6) {
7774 /* Selective RE cases, use value from compModParam */
7775 sresmask_to_use = (uint16_t)sresmask;
7776 }
7777 else {
7778 /* With masks (in section). Choose between sresmask1 and sresmask2 */
7779 if (rb==1 || (i%2)==0) {
7780 /* Even values */
7781 sresmask_to_use = (uint16_t)sresmask1;
7782 }
7783 else {
7784 /* Odd values */
7785 sresmask_to_use = (uint16_t)sresmask2;
7786 }
7787 }
7788
7789 /* Count REs present using sresmask */
7790 res_per_prb = 0;
7791 /* Use sresmask to pick out which REs are present */
7792 for (unsigned n=0; n<12; n++) {
7793 if (sresmask_to_use & (1<<n)) {
7794 res_per_prb++;
7795 }
7796 }
7797 }
7798
7799 /* N.B. bytes for samples need to be padded out to next byte
7800 (certainly where there aren't 12 REs in PRB..) */
7801 unsigned nBytesForSamples = (sample_bit_width * res_per_prb * 2 + 7) / 8;
7802 nBytesPerPrb = nBytesForSamples + udcompparam_len;
7803
7804 proto_tree_add_item(rb_tree, hf_oran_iq_user_data, tvb, offset, nBytesForSamples, ENC_NA0x00000000);
7805
7806 if (section_details) {
7807 if ((startPrbu + i*(1+rb)) < 273) {
7808 proto_item *beamid_ti = proto_tree_add_uint(rb_tree, hf_oran_beamId, tvb, 0, 0,
7809 section_details->beamIds[startPrbu + i*(1+rb)]);
7810 proto_item_set_generated(beamid_ti);
7811 }
7812 }
7813
7814
7815 tap_info->non_zero_re_in_current_prb = false0;
7816
7817 /* Optionally trying to show I/Q RE values */
7818 if (pref_showIQSampleValues) {
7819 /* Individual values */
7820 unsigned samples_offset = offset*8;
7821 unsigned samples_start = offset;
7822 unsigned samples = 0;
7823
7824 if (compression >= BFP_AND_SELECTIVE_RE5) {
7825 /* Use sresmask to pick out which REs are present */
7826 for (unsigned n=1; n<=12; n++) {
7827 if (sresmask_to_use & (1<<(n-1))) {
7828 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7829 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7830 samples++;
7831 }
7832 }
7833 }
7834 else {
7835 /* All 12 REs are present */
7836 for (unsigned n=1; n<=12; n++) {
7837 samples_offset = dissect_oran_u_re(tvb, rb_tree,
7838 n, samples_offset, tap_info, sample_bit_width, compression, exponent, mod_compr_config, n);
7839 samples++;
7840 }
7841 }
7842 proto_item_append_text(prbHeading, " (%u REs)", samples);
7843 if (section_details) {
7844 if ((startPrbu + i*(1+rb)) < 273) {
7845 proto_item_append_text(prbHeading, " [BeamId:%u]", section_details->beamIds[startPrbu + i*(1+rb)]);
7846 }
7847 }
7848
7849 /* Was this PRB all zeros? */
7850 if (!tap_info->non_zero_re_in_current_prb) {
7851 tap_info->num_prbs_zero++;
7852 /* Add a filter to make zero-valued PRBs more findable */
7853 proto_item *zero_ti = proto_tree_add_item(rb_tree, hf_oran_zero_prb, tvb,
7854 samples_start, nBytesForSamples, ENC_NA0x00000000);
7855 proto_item_set_hidden(zero_ti);
7856 proto_item_append_text(prbHeading, " (all zeros)");
7857 }
7858 else {
7859 proto_item *nonzero_ti = proto_tree_add_item(rb_tree, hf_oran_nonzero_prb, tvb, samples_start, nBytesForSamples, ENC_NA0x00000000);
7860 proto_item_set_hidden(nonzero_ti);
7861 }
7862 }
7863
7864 tap_info->num_prbs++;
7865
7866
7867 /* Advance past samples */
7868 offset += nBytesForSamples;
7869
7870 /* Set end of prb subtree */
7871 proto_item_set_end(prbHeading, tvb, offset);
7872 }
7873
7874 /* Set extent of section */
7875 proto_item_set_len(sectionHeading, offset-section_start_offset);
7876 if (ud_comp_len_ti != NULL((void*)0) && ((offset-section_start_offset != ud_comp_len))) {
7877 expert_add_info_format(pinfo, ud_comp_len_ti, &ei_oran_ud_comp_len_wrong_size,
7878 "udCompLen indicates %u bytes in section, but dissected %u instead",
7879 ud_comp_len, offset-section_start_offset);
7880 }
7881
7882 bytesLeft = tvb_captured_length(tvb) - offset;
7883 number_of_sections++;
7884 } while (bytesLeft >= (4 + nBytesPerPrb)); /* FIXME: bad heuristic */
7885
7886 /* Show number of sections found */
7887 proto_item *ti = proto_tree_add_uint(oran_tree, hf_oran_numberOfSections, tvb, 0, 0, number_of_sections);
7888 proto_item_set_generated(ti);
7889
7890 /* Expert error if we are short of tvb by > 3 bytes */
7891 if (tvb_reported_length_remaining(tvb, offset) > 3) {
7892 expert_add_info_format(pinfo, protocol_item, &ei_oran_frame_length,
7893 "%u bytes remain at end of frame - should be 0-3",
7894 tvb_reported_length_remaining(tvb, offset));
7895 }
7896
7897 return tvb_captured_length(tvb);
7898}
7899
7900
7901/**********************************************************************/
7902/* Main dissection function. */
7903/* N.B. ecpri message type passed in as 'data' arg by eCPRI dissector */
7904static int
7905dissect_oran(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7906{
7907 uint32_t ecpri_message_type = *(uint32_t *)data;
7908 unsigned offset = 0;
7909
7910 /* Allocate and zero tap struct */
7911 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
)))
;
7912 tap_info->pdu_size = pinfo->fd->pkt_len;
7913 tap_info->ul_delay_configured_max = us_allowed_for_ul_in_symbol;
7914
7915 switch (ecpri_message_type) {
7916 case ECPRI_MT_IQ_DATA0:
7917 offset = dissect_oran_u(tvb, pinfo, tree, tap_info, data);
7918 break;
7919 case ECPRI_MT_RT_CTRL_DATA2:
7920 offset = dissect_oran_c(tvb, pinfo, tree, tap_info, data);
7921 break;
7922 default:
7923 /* Not dissecting other types - assume these are handled by eCPRI dissector */
7924 return 0;
7925 }
7926
7927 tap_queue_packet(oran_tap, pinfo, tap_info);
7928
7929 return offset;
7930}
7931
7932static void oran_init_protocol(void)
7933{
7934 udcomplen_heuristic_result_set = false0;
7935 udcomplen_heuristic_result = false0;
7936}
7937
7938
7939/* Register the protocol with Wireshark. */
7940void
7941proto_register_oran(void)
7942{
7943 static hf_register_info hf[] = {
7944
7945 /* Section 5.1.3.2.7 */
7946 { &hf_oran_du_port_id,
7947 { "DU Port ID", "oran_fh_cus.du_port_id",
7948 FT_UINT16, BASE_DEC,
7949 NULL((void*)0), 0x0,
7950 "Processing unit at O-RU - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7951 },
7952
7953 /* Section 5.1.3.2.7 */
7954 { &hf_oran_bandsector_id,
7955 { "BandSector ID", "oran_fh_cus.bandsector_id",
7956 FT_UINT16, BASE_DEC,
7957 NULL((void*)0), 0x0,
7958 "Aggregated cell identified - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7959 },
7960
7961 /* Section 5.1.3.2.7 */
7962 { &hf_oran_cc_id,
7963 { "CC ID", "oran_fh_cus.cc_id",
7964 FT_UINT16, BASE_DEC,
7965 NULL((void*)0), 0x0,
7966 "Component Carrier - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7967 },
7968
7969 /* Section 5.1.3.2.7 */
7970 { &hf_oran_ru_port_id,
7971 { "RU Port ID", "oran_fh_cus.ru_port_id",
7972 FT_UINT16, BASE_DEC,
7973 NULL((void*)0), 0x0,
7974 "Logical flow - width set in dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7975 },
7976
7977 /* Section 5.1.3.2.8 */
7978 { &hf_oran_sequence_id,
7979 { "Sequence ID", "oran_fh_cus.sequence_id",
7980 FT_UINT8, BASE_DEC,
7981 NULL((void*)0), 0x0,
7982 "The Sequence ID wraps around individually per eAxC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7983 },
7984
7985 /* Section 5.1.3.2.8 */
7986 { &hf_oran_e_bit,
7987 { "E Bit", "oran_fh_cus.e_bit",
7988 FT_UINT8, BASE_DEC,
7989 VALS(e_bit)((0 ? (const struct _value_string*)0 : ((e_bit)))), 0x80,
7990 "Indicate the last message of a subsequence (U-Plane only)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7991 },
7992
7993 /* Section 5.1.3.2.8 */
7994 { &hf_oran_subsequence_id,
7995 { "Subsequence ID", "oran_fh_cus.subsequence_id",
7996 FT_UINT8, BASE_DEC,
7997 NULL((void*)0), 0x7f,
7998 "The subsequence ID (for eCPRI layer fragmentation)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
7999 },
8000
8001 { &hf_oran_previous_frame,
8002 { "Previous frame in stream", "oran_fh_cus.previous-frame",
8003 FT_FRAMENUM, BASE_NONE,
8004 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
8005 "Previous frame in sequence", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8006 },
8007
8008 /* Section 7.5.2.1 */
8009 { &hf_oran_data_direction,
8010 { "Data Direction", "oran_fh_cus.data_direction",
8011 FT_UINT8, BASE_DEC,
8012 VALS(data_direction_vals)((0 ? (const struct _value_string*)0 : ((data_direction_vals)
)))
, 0x80,
8013 "gNB data direction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8014 },
8015
8016 /* Section 7.5.2.2 */
8017 { &hf_oran_payload_version,
8018 { "Payload Version", "oran_fh_cus.payloadVersion",
8019 FT_UINT8, BASE_DEC,
8020 NULL((void*)0), 0x70,
8021 "Payload protocol version the following IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8022 },
8023
8024 /* Section 7.5.2.3 */
8025 { &hf_oran_filter_index,
8026 { "Filter Index", "oran_fh_cus.filterIndex",
8027 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8028 RVALS(filter_indices)((0 ? (const struct _range_string*)0 : ((filter_indices)))), 0x0f,
8029 "used between IQ data and air interface, both in DL and UL", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8030 },
8031
8032 /* Section 7.5.2.4 */
8033 { &hf_oran_frame_id,
8034 { "Frame ID", "oran_fh_cus.frameId",
8035 FT_UINT8, BASE_DEC,
8036 NULL((void*)0), 0x0,
8037 "A counter for 10 ms frames (wrapping period 2.56 seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8038 },
8039
8040 /* Section 7.5.2.5 */
8041 { &hf_oran_subframe_id,
8042 { "Subframe ID", "oran_fh_cus.subframe_id",
8043 FT_UINT8, BASE_DEC,
8044 NULL((void*)0), 0xf0,
8045 "A counter for 1 ms sub-frames within 10ms frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8046 },
8047
8048 /* Section 7.5.2.6 */
8049 { &hf_oran_slot_id,
8050 { "Slot ID", "oran_fh_cus.slotId",
8051 FT_UINT16, BASE_DEC,
8052 NULL((void*)0), 0x0fc0,
8053 "Slot number within a 1ms sub-frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8054 },
8055
8056 /* Generated for convenience */
8057 { &hf_oran_slot_within_frame,
8058 { "Slot within frame", "oran_fh_cus.slot-within-frame",
8059 FT_UINT16, BASE_DEC,
8060 NULL((void*)0), 0x0,
8061 "Slot within frame, to match DCT logs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8062 },
8063
8064 /* Section 7.5.2.7 */
8065 { &hf_oran_start_symbol_id,
8066 { "Start Symbol ID", "oran_fh_cus.startSymbolId",
8067 FT_UINT8, BASE_DEC,
8068 NULL((void*)0), 0x3f,
8069 "The first symbol number within slot affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8070 },
8071
8072 /* Section 7.5.2.8 */
8073 { &hf_oran_numberOfSections,
8074 { "Number of Sections", "oran_fh_cus.numberOfSections",
8075 FT_UINT8, BASE_DEC,
8076 NULL((void*)0), 0x0,
8077 "The number of section IDs included in this message", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8078 },
8079
8080 /* Section 7.5.2.9 */
8081 { &hf_oran_sectionType,
8082 { "Section Type", "oran_fh_cus.sectionType",
8083 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8084 RVALS(section_types)((0 ? (const struct _range_string*)0 : ((section_types)))), 0x0,
8085 "Determines the characteristics of U-plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8086 },
8087
8088 /* Section 7.5.2.10 */
8089 { &hf_oran_udCompHdr,
8090 { "udCompHdr", "oran_fh_cus.udCompHdr",
8091 FT_STRING, BASE_NONE,
8092 NULL((void*)0), 0x0,
8093 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8094 },
8095
8096 /* Section 7.5.2.11 */
8097 { &hf_oran_numberOfUEs,
8098 { "Number Of UEs", "oran_fh_cus.numberOfUEs",
8099 FT_UINT8, BASE_DEC,
8100 NULL((void*)0), 0x0,
8101 "Indicates number of UEs for which channel info is provided", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8102 },
8103
8104 /* Section 7.5.2.12 */
8105 { &hf_oran_timeOffset,
8106 { "Time Offset", "oran_fh_cus.timeOffset",
8107 FT_UINT16, BASE_DEC,
8108 NULL((void*)0), 0x0,
8109 "from start of the slot to start of CP in samples", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8110 },
8111
8112 /* Section 7.5.2.13 */
8113 { &hf_oran_frameStructure_fft,
8114 { "FFT Size", "oran_fh_cus.frameStructure.fft",
8115 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8116 RVALS(frame_structure_fft)((0 ? (const struct _range_string*)0 : ((frame_structure_fft)
)))
, 0xf0,
8117 "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) }
8118 },
8119
8120 /* Section 7.5.2.13 */
8121 { &hf_oran_frameStructure_subcarrier_spacing,
8122 { "Subcarrier Spacing", "oran_fh_cus.frameStructure.spacing",
8123 FT_UINT8, BASE_HEX | BASE_RANGE_STRING0x00000100,
8124 RVALS(subcarrier_spacings)((0 ? (const struct _range_string*)0 : ((subcarrier_spacings)
)))
, 0x0f,
8125 "The sub carrier spacing as well as the number of slots per 1ms sub-frame",
8126 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
8127 },
8128
8129 /* Section 7.5.2.14 */
8130 { &hf_oran_cpLength,
8131 { "cpLength", "oran_fh_cus.cpLength",
8132 FT_UINT16, BASE_DEC,
8133 NULL((void*)0), 0x0,
8134 "cyclic prefix length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8135 },
8136
8137 { &hf_oran_timing_header,
8138 { "Timing Header", "oran_fh_cus.timingHeader",
8139 FT_STRING, BASE_NONE,
8140 NULL((void*)0), 0x0,
8141 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8142 },
8143
8144 /* Section 7.5.3.1 */
8145 { &hf_oran_section_id,
8146 { "sectionId", "oran_fh_cus.sectionId",
8147 FT_UINT16, BASE_DEC,
8148 NULL((void*)0), 0xfff0,
8149 "section identifier of data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8150 },
8151
8152 /* Section 7.5.3.2 */
8153 { &hf_oran_rb,
8154 { "rb", "oran_fh_cus.rb",
8155 FT_UINT8, BASE_DEC,
8156 VALS(rb_vals)((0 ? (const struct _value_string*)0 : ((rb_vals)))), 0x08,
8157 "resource block indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8158 },
8159
8160 /* Section 7.5.5.3 */
8161 { &hf_oran_symInc,
8162 { "symInc", "oran_fh_cus.symInc",
8163 FT_UINT8, BASE_DEC,
8164 VALS(sym_inc_vals)((0 ? (const struct _value_string*)0 : ((sym_inc_vals)))), 0x04,
8165 "Symbol Number Increment Command", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8166 },
8167
8168 /* Section 7.5.3.4 */
8169 { &hf_oran_startPrbc,
8170 { "startPrbc", "oran_fh_cus.startPrbc",
8171 FT_UINT16, BASE_DEC,
8172 NULL((void*)0), 0x03ff,
8173 "Starting PRB of Control Plane Section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8174 },
8175
8176 /* Section 7.5.3.5 */
8177 { &hf_oran_reMask_re1,
8178 { "RE 1", "oran_fh_cus.reMask-RE1",
8179 FT_BOOLEAN, 16,
8180 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
8181 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8182 },
8183 { &hf_oran_reMask_re2,
8184 { "RE 2", "oran_fh_cus.reMask-RE2",
8185 FT_BOOLEAN, 16,
8186 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
8187 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8188 },
8189 { &hf_oran_reMask_re3,
8190 { "RE 3", "oran_fh_cus.reMask-RE3",
8191 FT_BOOLEAN, 16,
8192 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
8193 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8194 },
8195 { &hf_oran_reMask_re4,
8196 { "RE 4", "oran_fh_cus.reMask-RE4",
8197 FT_BOOLEAN, 16,
8198 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
8199 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8200 },
8201 { &hf_oran_reMask_re5,
8202 { "RE 5", "oran_fh_cus.reMask-RE5",
8203 FT_BOOLEAN, 16,
8204 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
8205 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8206 },
8207 { &hf_oran_reMask_re6,
8208 { "RE 6", "oran_fh_cus.reMask-RE6",
8209 FT_BOOLEAN, 16,
8210 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
8211 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8212 },
8213 { &hf_oran_reMask_re7,
8214 { "RE 7", "oran_fh_cus.reMask-RE7",
8215 FT_BOOLEAN, 16,
8216 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
8217 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8218 },
8219 { &hf_oran_reMask_re8,
8220 { "RE 8", "oran_fh_cus.reMask-RE8",
8221 FT_BOOLEAN, 16,
8222 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
8223 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8224 },
8225 { &hf_oran_reMask_re9,
8226 { "RE 9", "oran_fh_cus.reMask-RE9",
8227 FT_BOOLEAN, 16,
8228 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
8229 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8230 },
8231 { &hf_oran_reMask_re10,
8232 { "RE 10", "oran_fh_cus.reMask-RE10",
8233 FT_BOOLEAN, 16,
8234 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
8235 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8236 },
8237 { &hf_oran_reMask_re11,
8238 { "RE 11", "oran_fh_cus.reMask-RE11",
8239 FT_BOOLEAN, 16,
8240 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
8241 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8242 },
8243 { &hf_oran_reMask_re12,
8244 { "RE 12", "oran_fh_cus.reMask-RE12",
8245 FT_BOOLEAN, 16,
8246 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
8247 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8248 },
8249 { &hf_oran_reMask,
8250 { "RE Mask", "oran_fh_cus.reMask",
8251 FT_UINT16, BASE_HEX,
8252 NULL((void*)0), 0xfff0,
8253 "The Resource Element (RE) mask within a PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8254 },
8255
8256 /* Section 7.5.3.6 */
8257 { &hf_oran_numPrbc,
8258 { "numPrbc", "oran_fh_cus.numPrbc",
8259 FT_UINT8, BASE_DEC,
8260 NULL((void*)0), 0x0,
8261 "Number of contiguous PRBs per data section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8262 },
8263 /* Section 7.5.3.7 */
8264 { &hf_oran_numSymbol,
8265 { "Number of Symbols", "oran_fh_cus.numSymbol",
8266 FT_UINT8, BASE_DEC,
8267 NULL((void*)0), 0x0f,
8268 "Defines number of symbols to which the section control is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8269 },
8270 /* Section 7.5.3.8 */
8271 { &hf_oran_ef,
8272 { "Extension Flag", "oran_fh_cus.ef",
8273 FT_BOOLEAN, 8,
8274 NULL((void*)0), 0x80,
8275 "Indicates if more section extensions follow", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8276 },
8277 /* Section 7.5.3.9 */
8278 { &hf_oran_beamId,
8279 { "Beam ID", "oran_fh_cus.beamId",
8280 FT_UINT16, BASE_DEC,
8281 NULL((void*)0), 0x7fff,
8282 "Defines the beam pattern to be applied to the U-Plane data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8283 },
8284
8285 { &hf_oran_extension,
8286 { "Extension", "oran_fh_cus.extension",
8287 FT_STRING, BASE_NONE,
8288 NULL((void*)0), 0x0,
8289 "Section extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8290 },
8291
8292 /* Section 7.6.2.1 */
8293 { &hf_oran_exttype,
8294 { "extType", "oran_fh_cus.extType",
8295 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200,
8296 &exttype_vals_ext, 0x7f,
8297 "The extension type, which provides additional parameters specific to subject data extension", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8298 },
8299
8300 /* Section 7.6.2.3 */
8301 { &hf_oran_extlen,
8302 { "extLen", "oran_fh_cus.extLen",
8303 FT_UINT16, BASE_DEC,
8304 NULL((void*)0), 0x0,
8305 "Extension length in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8306 },
8307
8308 /* Section 7.7.1 */
8309 { &hf_oran_bfw,
8310 { "bfw", "oran_fh_cus.bfw",
8311 FT_STRING, BASE_NONE,
8312 NULL((void*)0), 0x0,
8313 "Set of weights for a particular antenna", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8314 },
8315 { &hf_oran_bfw_bundle,
8316 { "Bundle", "oran_fh_cus.bfw.bundle",
8317 FT_STRING, BASE_NONE,
8318 NULL((void*)0), 0x0,
8319 "Bundle of BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8320 },
8321 { &hf_oran_bfw_bundle_id,
8322 { "Bundle Id", "oran_fh_cus.bfw.bundleId",
8323 FT_UINT32, BASE_DEC,
8324 NULL((void*)0), 0x0,
8325 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8326 },
8327 /* Section 7.7.1.4 */
8328 { &hf_oran_bfw_i,
8329 { "bfwI", "oran_fh_cus.bfwI",
8330 FT_FLOAT, BASE_NONE,
8331 NULL((void*)0), 0x0,
8332 "In-phase", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8333 },
8334 /* Section 7.7.1.5 */
8335 { &hf_oran_bfw_q,
8336 { "bfwQ", "oran_fh_cus.bfwQ",
8337 FT_FLOAT, BASE_NONE,
8338 NULL((void*)0), 0x0,
8339 "Quadrature", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8340 },
8341
8342 /* Section 7.5.3.10 */
8343 { &hf_oran_ueId,
8344 { "UE ID", "oran_fh_cus.ueId",
8345 FT_UINT16, BASE_DEC,
8346 NULL((void*)0), 0x7fff,
8347 "logical identifier for set of channel info", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8348 },
8349 /* Section 7.5.3.11 */
8350 { &hf_oran_freqOffset,
8351 { "Frequency Offset", "oran_fh_cus.freqOffset",
8352 FT_UINT24, BASE_DEC,
8353 NULL((void*)0), 0x0,
8354 "with respect to the carrier center frequency before additional filtering", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8355 },
8356
8357 /* Section 7.5.3.12 */
8358 { &hf_oran_regularizationFactor,
8359 { "Regularization Factor", "oran_fh_cus.regularizationFactor",
8360 FT_INT16, BASE_DEC,
8361 NULL((void*)0), 0x0,
8362 "Signed value to support MMSE operation within O-RU", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8363 },
8364 /* Section 7.5.3.14 */
8365 { &hf_oran_laaMsgType,
8366 { "LAA Message Type", "oran_fh_cus.laaMsgType",
8367 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8368 RVALS(laaMsgTypes)((0 ? (const struct _range_string*)0 : ((laaMsgTypes)))), 0xf0,
8369 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8370 },
8371 /* Section 7.5.3.15 */
8372 { &hf_oran_laaMsgLen,
8373 { "LAA Message Length", "oran_fh_cus.laaMsgLen",
8374 FT_UINT8, BASE_DEC,
8375 NULL((void*)0), 0x0f,
8376 "number of 32-bit words in the LAA section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8377 },
8378 /* Section 7.5.3.16 */
8379 { &hf_oran_lbtHandle,
8380 { "LBT Handle", "oran_fh_cus.lbtHandle",
8381 FT_UINT16, BASE_HEX,
8382 NULL((void*)0), 0x0,
8383 "label to identify transaction", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8384 },
8385 /* Section 7.5.3.17 */
8386 { &hf_oran_lbtDeferFactor,
8387 { "Defer Factor", "oran_fh_cus.lbtDeferFactor",
8388 FT_UINT8, BASE_DEC,
8389 NULL((void*)0), 0x07,
8390 "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)}
8391 },
8392 /* Section 7.5.3.18 */
8393 { &hf_oran_lbtBackoffCounter,
8394 { "Backoff Counter", "oran_fh_cus.lbtBackoffCounter",
8395 FT_UINT16, BASE_DEC,
8396 NULL((void*)0), 0xffc0,
8397 "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)}
8398 },
8399 /* Section 7.5.3.19 */
8400 { &hf_oran_lbtOffset,
8401 { "LBT Offset", "oran_fh_cus.lbtOffset",
8402 FT_UINT16, BASE_DEC,
8403 NULL((void*)0), 0xffc0,
8404 "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)}
8405 },
8406 /* Section 7.5.3.20 */
8407 { &hf_oran_MCOT,
8408 { "Maximum Channel Occupancy Time", "oran_fh_cus.MCOT",
8409 FT_UINT8, BASE_DEC,
8410 NULL((void*)0), 0x3c,
8411 "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)}
8412 },
8413 /* Section 7.5.3.21 */
8414 { &hf_oran_lbtMode,
8415 { "LBT Mode", "oran_fh_cus.lbtMode",
8416 FT_UINT8, BASE_DEC,
8417 VALS(lbtMode_vals)((0 ? (const struct _value_string*)0 : ((lbtMode_vals)))), 0x0,
8418 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8419 },
8420 /* Section 7.5.3.22 */
8421 { &hf_oran_lbtPdschRes,
8422 { "lbtPdschRes", "oran_fh_cus.lbtPdschRes",
8423 FT_UINT8, BASE_DEC,
8424 VALS(lbtPdschRes_vals)((0 ? (const struct _value_string*)0 : ((lbtPdschRes_vals)))), 0xc0,
8425 "LBT result of SFN/SF", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8426 },
8427 /* Section 7.5.3.23 */
8428 { &hf_oran_sfStatus,
8429 { "sfStatus", "oran_fh_cus.sfStatus",
8430 FT_BOOLEAN, 8,
8431 TFS(&tfs_sfStatus)((0 ? (const struct true_false_string*)0 : ((&tfs_sfStatus
))))
, 0x10,
8432 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8433 },
8434 /* Section 7.5.3.24 */
8435 { &hf_oran_lbtDrsRes,
8436 { "lbtDrsRes", "oran_fh_cus.lbtDrsRes",
8437 FT_BOOLEAN, 8,
8438 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8439 "Indicates whether the subframe was dropped or transmitted", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8440 },
8441 /* Section 7.5.3.25 */
8442 { &hf_oran_initialPartialSF,
8443 { "Initial partial SF", "oran_fh_cus.initialPartialSF",
8444 FT_BOOLEAN, 8,
8445 TFS(&tfs_partial_full_sf)((0 ? (const struct true_false_string*)0 : ((&tfs_partial_full_sf
))))
, 0x40,
8446 "Indicates whether the initial SF in the LBT process is full or partial", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8447 },
8448 /* Section 7.5.3.26. */
8449 { &hf_oran_lbtBufErr,
8450 { "lbtBufErr", "oran_fh_cus.lbtBufErr",
8451 FT_BOOLEAN, 8,
8452 TFS(&tfs_lbtBufErr)((0 ? (const struct true_false_string*)0 : ((&tfs_lbtBufErr
))))
, 0x80,
8453 "LBT buffer error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8454 },
8455 /* Section 7.5.3.27 */
8456 { &hf_oran_sfnSfEnd,
8457 { "SFN/SF End", "oran_fh_cus.sfnSfEnd",
8458 FT_UINT16, BASE_DEC,
8459 NULL((void*)0), 0x0fff,
8460 "SFN/SF by which the DRS window must end", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8461 },
8462 /* Section 7.5.3.28 */
8463 { &hf_oran_lbtCWConfig_H,
8464 { "lbtCWConfig_H", "oran_fh_cus.lbtCWConfig_H",
8465 FT_UINT8, BASE_DEC,
8466 NULL((void*)0), 0x0,
8467 "HARQ parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8468 },
8469 /* Section 7.5.3.29 */
8470 { &hf_oran_lbtCWConfig_T,
8471 { "lbtCWConfig_T", "oran_fh_cus.lbtCWConfig_T",
8472 FT_UINT8, BASE_DEC,
8473 NULL((void*)0), 0x0,
8474 "TB parameters for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8475 },
8476 /* Section 7.5.3.30 */
8477 { &hf_oran_lbtTrafficClass,
8478 { "lbtTrafficClass", "oran_fh_cus.lbtTrafficClass",
8479 FT_UINT8, BASE_DEC,
8480 VALS(lbtTrafficClass_vals)((0 ? (const struct _value_string*)0 : ((lbtTrafficClass_vals
))))
, 0x38,
8481 "Traffic class priority for congestion window management", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8482 },
8483 /* Section 7.5.3.31 */
8484 { &hf_oran_lbtCWR_Rst,
8485 { "lbtCWR_Rst", "oran_fh_cus.lbtCWR_Rst",
8486 FT_BOOLEAN, 8,
8487 TFS(&tfs_fail_success)((0 ? (const struct true_false_string*)0 : ((&tfs_fail_success
))))
, 0x80,
8488 "notification about packet reception successful or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8489 },
8490
8491 /* Reserved fields */
8492 { &hf_oran_reserved,
8493 { "reserved", "oran_fh_cus.reserved",
8494 FT_UINT64, BASE_HEX,
8495 NULL((void*)0), 0x0,
8496 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8497 },
8498 { &hf_oran_reserved_1bit,
8499 { "reserved", "oran_fh_cus.reserved",
8500 FT_UINT8, BASE_HEX,
8501 NULL((void*)0), 0x80,
8502 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8503 },
8504 { &hf_oran_reserved_2bits,
8505 { "reserved", "oran_fh_cus.reserved",
8506 FT_UINT8, BASE_HEX,
8507 NULL((void*)0), 0xc0,
8508 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8509 },
8510 { &hf_oran_reserved_3bits,
8511 { "reserved", "oran_fh_cus.reserved",
8512 FT_UINT8, BASE_HEX,
8513 NULL((void*)0), 0xe0,
8514 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8515 },
8516 { &hf_oran_reserved_4bits,
8517 { "reserved", "oran_fh_cus.reserved",
8518 FT_UINT8, BASE_HEX,
8519 NULL((void*)0), 0xf0,
8520 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8521 },
8522 { &hf_oran_reserved_last_4bits,
8523 { "reserved", "oran_fh_cus.reserved",
8524 FT_UINT8, BASE_HEX,
8525 NULL((void*)0), 0x0f,
8526 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8527 },
8528 { &hf_oran_reserved_last_5bits,
8529 { "reserved", "oran_fh_cus.reserved",
8530 FT_UINT8, BASE_HEX,
8531 NULL((void*)0), 0x1f,
8532 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8533 },
8534 { &hf_oran_reserved_6bits,
8535 { "reserved", "oran_fh_cus.reserved",
8536 FT_UINT8, BASE_HEX,
8537 NULL((void*)0), 0xfc,
8538 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8539 },
8540 { &hf_oran_reserved_last_6bits,
8541 { "reserved", "oran_fh_cus.reserved",
8542 FT_UINT8, BASE_HEX,
8543 NULL((void*)0), 0x3f,
8544 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8545 },
8546 { &hf_oran_reserved_7bits,
8547 { "reserved", "oran_fh_cus.reserved",
8548 FT_UINT8, BASE_HEX,
8549 NULL((void*)0), 0xfe,
8550 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8551 },
8552 { &hf_oran_reserved_last_7bits,
8553 { "reserved", "oran_fh_cus.reserved",
8554 FT_UINT8, BASE_HEX,
8555 NULL((void*)0), 0x7f,
8556 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8557 },
8558 { &hf_oran_reserved_8bits,
8559 { "reserved", "oran_fh_cus.reserved",
8560 FT_UINT8, BASE_HEX,
8561 NULL((void*)0), 0x0,
8562 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8563 },
8564 { &hf_oran_reserved_16bits,
8565 { "reserved", "oran_fh_cus.reserved",
8566 FT_UINT16, BASE_HEX,
8567 NULL((void*)0), 0x0,
8568 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8569 },
8570 { &hf_oran_reserved_15bits,
8571 { "reserved", "oran_fh_cus.reserved",
8572 FT_UINT16, BASE_HEX,
8573 NULL((void*)0), 0x7fff,
8574 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8575 },
8576 { &hf_oran_reserved_bit1,
8577 { "reserved", "oran_fh_cus.reserved",
8578 FT_UINT8, BASE_HEX,
8579 NULL((void*)0), 0x40,
8580 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8581 },
8582 { &hf_oran_reserved_bit2,
8583 { "reserved", "oran_fh_cus.reserved",
8584 FT_UINT8, BASE_HEX,
8585 NULL((void*)0), 0x20,
8586 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8587 },
8588 { &hf_oran_reserved_bit4,
8589 { "reserved", "oran_fh_cus.reserved",
8590 FT_UINT8, BASE_HEX,
8591 NULL((void*)0), 0x08,
8592 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8593 },
8594 { &hf_oran_reserved_bit5,
8595 { "reserved", "oran_fh_cus.reserved",
8596 FT_UINT8, BASE_HEX,
8597 NULL((void*)0), 0x04,
8598 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8599 },
8600 { &hf_oran_reserved_bits123,
8601 { "reserved", "oran_fh_cus.reserved",
8602 FT_UINT8, BASE_HEX,
8603 NULL((void*)0), 0x70,
8604 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8605 },
8606 { &hf_oran_reserved_bits456,
8607 { "reserved", "oran_fh_cus.reserved",
8608 FT_UINT8, BASE_HEX,
8609 NULL((void*)0), 0x0e,
8610 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8611 },
8612
8613 /* 7.7.11.9 */
8614 { &hf_oran_cont_ind,
8615 { "contInd", "oran_fh_cus.contInd",
8616 FT_BOOLEAN, 8,
8617 TFS(&continuity_indication_tfs)((0 ? (const struct true_false_string*)0 : ((&continuity_indication_tfs
))))
, 0x80,
8618 "PRB region continuity flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8619 },
8620 /* 7.7.11.10 */
8621 { &hf_oran_bundle_offset,
8622 { "BundleOffset", "oran_fh_cus.bundleOffset",
8623 FT_UINT8, BASE_DEC,
8624 NULL((void*)0), 0x3f,
8625 "offset between start of first PRB bundle and startPrbc", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8626 },
8627
8628 /* 7.7.1.2 bfwCompHdr (beamforming weight compression header) */
8629 { &hf_oran_bfwCompHdr,
8630 { "bfwCompHdr", "oran_fh_cus.bfwCompHdr",
8631 FT_STRING, BASE_NONE,
8632 NULL((void*)0), 0x0,
8633 "Compression method and IQ bit width for beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8634 },
8635 { &hf_oran_bfwCompHdr_iqWidth,
8636 { "IQ Bit Width", "oran_fh_cus.bfwCompHdr_iqWidth",
8637 FT_UINT8, BASE_HEX,
8638 VALS(bfw_comp_headers_iq_width)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_iq_width
))))
, 0xf0,
8639 "IQ bit width for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8640 },
8641 { &hf_oran_bfwCompHdr_compMeth,
8642 { "Compression Method", "oran_fh_cus.bfwCompHdr_compMeth",
8643 FT_UINT8, BASE_HEX,
8644 VALS(bfw_comp_headers_comp_meth)((0 ? (const struct _value_string*)0 : ((bfw_comp_headers_comp_meth
))))
, 0x0f,
8645 "compression method for the beamforming weights", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8646 },
8647
8648 /* 7.5.3.32 */
8649 { &hf_oran_ciCompParam,
8650 { "ciCompParam", "oran_fh_cus.ciCompParam",
8651 FT_STRING, BASE_NONE,
8652 NULL((void*)0), 0x0,
8653 "channel information compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8654 },
8655
8656 /* Table 7.5.3.32-1 */
8657 { &hf_oran_blockScaler,
8658 { "blockScaler", "oran_fh_cus.blockScaler",
8659 FT_UINT8, BASE_HEX,
8660 NULL((void*)0), 0x0,
8661 "unsigned, 1 integer bit, 7 fractional bits", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8662 },
8663 { &hf_oran_compBitWidth,
8664 { "compBitWidth", "oran_fh_cus.compBitWidth",
8665 FT_UINT8, BASE_DEC,
8666 NULL((void*)0), 0xf0,
8667 "Length of I bits and length of Q bits after compression over entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8668 },
8669 { &hf_oran_compShift,
8670 { "compShift", "oran_fh_cus.compShift",
8671 FT_UINT8, BASE_DEC,
8672 NULL((void*)0), 0x0f,
8673 "The shift applied to the entire PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8674 },
8675
8676 { &hf_oran_active_beamspace_coefficient_n1,
8677 { "N1", "oran_fh_cus.activeBeamspace_Coefficient_n1",
8678 FT_BOOLEAN, 8,
8679 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x80,
8680 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8681 },
8682 { &hf_oran_active_beamspace_coefficient_n2,
8683 { "N2", "oran_fh_cus.activeBeamspace_Coefficient_n2",
8684 FT_BOOLEAN, 8,
8685 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x40,
8686 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8687 },
8688 { &hf_oran_active_beamspace_coefficient_n3,
8689 { "N3", "oran_fh_cus.activeBeamspace_Coefficient_n3",
8690 FT_BOOLEAN, 8,
8691 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x20,
8692 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8693 },
8694 { &hf_oran_active_beamspace_coefficient_n4,
8695 { "N4", "oran_fh_cus.activeBeamspace_Coefficient_n4",
8696 FT_BOOLEAN, 8,
8697 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x10,
8698 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8699 },
8700 { &hf_oran_active_beamspace_coefficient_n5,
8701 { "N5", "oran_fh_cus.activeBeamspace_Coefficient_n5",
8702 FT_BOOLEAN, 8,
8703 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x08,
8704 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8705 },
8706 { &hf_oran_active_beamspace_coefficient_n6,
8707 { "N6", "oran_fh_cus.activeBeamspace_Coefficient_n6",
8708 FT_BOOLEAN, 8,
8709 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x04,
8710 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8711 },
8712 { &hf_oran_active_beamspace_coefficient_n7,
8713 { "N7", "oran_fh_cus.activeBeamspace_Coefficient_n7",
8714 FT_BOOLEAN, 8,
8715 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x02,
8716 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8717 },
8718 { &hf_oran_active_beamspace_coefficient_n8,
8719 { "N8", "oran_fh_cus.activeBeamspace_Coefficient_n8",
8720 FT_BOOLEAN, 8,
8721 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x01,
8722 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8723 },
8724
8725 { &hf_oran_activeBeamspaceCoefficientMask,
8726 { "activeBeamspaceCoefficientMask", "oran_fh_cus.activeBeamspaceCoefficientMask",
8727 FT_UINT8, BASE_HEX,
8728 NULL((void*)0), 0xff,
8729 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8730 },
8731 { &hf_oran_activeBeamspaceCoefficientMask_bits_set,
8732 { "Array elements set", "oran_fh_cus.activeBeamspaceCoefficientMask.bits-set",
8733 FT_UINT32, BASE_DEC,
8734 NULL((void*)0), 0x0,
8735 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8736 },
8737
8738 /* Section 7.7.6.6 */
8739 { &hf_oran_se6_repetition,
8740 { "repetition", "oran_fh_cus.repetition",
8741 FT_BOOLEAN, BASE_NONE,
8742 TFS(&repetition_se6_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se6_tfs
))))
, 0x0,
8743 "Repetition of a highest priority data section for C-Plane", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8744 },
8745 /* 7.7.20.9 */
8746 { &hf_oran_rbgSize,
8747 { "rbgSize", "oran_fh_cus.rbgSize",
8748 FT_UINT8, BASE_HEX,
8749 VALS(rbg_size_vals)((0 ? (const struct _value_string*)0 : ((rbg_size_vals)))), 0x70,
8750 "Number of PRBs of the resource block groups allocated by the bit mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8751 },
8752 /* 7.7.20.10 */
8753 { &hf_oran_rbgMask,
8754 { "rbgMask", "oran_fh_cus.rbgMask",
8755 FT_UINT32, BASE_HEX,
8756 NULL((void*)0), 0x0fffffff,
8757 "Each bit indicates whether a corresponding resource block group is present", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8758 },
8759 /* 7.7.6.5. Also 7.7.12.3 and 7.7.19.5 */
8760 { &hf_oran_noncontig_priority,
8761 { "priority", "oran_fh_cus.priority",
8762 FT_UINT8, BASE_HEX,
8763 VALS(priority_vals)((0 ? (const struct _value_string*)0 : ((priority_vals)))), 0xc0,
8764 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8765 },
8766
8767 /* 7.7.6.4 */
8768 { &hf_oran_symbol_mask,
8769 { "symbolMask", "oran_fh_cus.symbolMask",
8770 FT_UINT16, BASE_HEX,
8771 NULL((void*)0), 0x3fff,
8772 "Each bit indicates whether the rbgMask applies to a given symbol in the slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8773 },
8774 { &hf_oran_symbol_mask_s13,
8775 { "symbol 13", "oran_fh_cus.symbolMask.symbol-13",
8776 FT_BOOLEAN, 16,
8777 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
8778 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8779 },
8780 { &hf_oran_symbol_mask_s12,
8781 { "symbol 12", "oran_fh_cus.symbolMask.symbol-12",
8782 FT_BOOLEAN, 16,
8783 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
8784 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8785 },
8786 { &hf_oran_symbol_mask_s11,
8787 { "symbol 11", "oran_fh_cus.symbolMask.symbol-11",
8788 FT_BOOLEAN, 16,
8789 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
8790 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8791 },
8792 { &hf_oran_symbol_mask_s10,
8793 { "symbol 10", "oran_fh_cus.symbolMask.symbol-10",
8794 FT_BOOLEAN, 16,
8795 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
8796 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8797 },
8798 { &hf_oran_symbol_mask_s9,
8799 { "symbol 9", "oran_fh_cus.symbolMask.symbol-9",
8800 FT_BOOLEAN, 16,
8801 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
8802 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8803 },
8804 { &hf_oran_symbol_mask_s8,
8805 { "symbol 8", "oran_fh_cus.symbolMask.symbol-8",
8806 FT_BOOLEAN, 16,
8807 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
8808 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8809 },
8810 { &hf_oran_symbol_mask_s7,
8811 { "symbol 7", "oran_fh_cus.symbolMask.symbol-7",
8812 FT_BOOLEAN, 16,
8813 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
8814 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8815 },
8816 { &hf_oran_symbol_mask_s6,
8817 { "symbol 6", "oran_fh_cus.symbolMask.symbol-6",
8818 FT_BOOLEAN, 16,
8819 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
8820 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8821 },
8822 { &hf_oran_symbol_mask_s5,
8823 { "symbol 5", "oran_fh_cus.symbolMask.symbol-5",
8824 FT_BOOLEAN, 16,
8825 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
8826 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8827 },
8828 { &hf_oran_symbol_mask_s4,
8829 { "symbol 4", "oran_fh_cus.symbolMask.symbol-4",
8830 FT_BOOLEAN, 16,
8831 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
8832 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8833 },
8834 { &hf_oran_symbol_mask_s3,
8835 { "symbol 3", "oran_fh_cus.symbolMask.symbol-3",
8836 FT_BOOLEAN, 16,
8837 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
8838 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8839 },
8840 { &hf_oran_symbol_mask_s2,
8841 { "symbol 2", "oran_fh_cus.symbolMask.symbol-2",
8842 FT_BOOLEAN, 16,
8843 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
8844 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8845 },
8846 { &hf_oran_symbol_mask_s1,
8847 { "symbol 1", "oran_fh_cus.symbolMask.symbol-1",
8848 FT_BOOLEAN, 16,
8849 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
8850 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8851 },
8852 { &hf_oran_symbol_mask_s0,
8853 { "symbol 0", "oran_fh_cus.symbolMask.symbol-0",
8854 FT_BOOLEAN, 16,
8855 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
8856 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8857 },
8858
8859
8860 /* 7.7.22.2 */
8861 { &hf_oran_ack_nack_req_id,
8862 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
8863 FT_UINT16, BASE_HEX,
8864 NULL((void*)0), 0x0,
8865 "Indicates the ACK/NACK request ID of a section description", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8866 },
8867
8868 /* Subtree for next 2 items */
8869 { &hf_oran_frequency_range,
8870 { "Frequency Range", "oran_fh_cus.frequencyRange",
8871 FT_STRING, BASE_NONE,
8872 NULL((void*)0), 0x0,
8873 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8874 },
8875
8876 /* 7.7.12.4 */
8877 { &hf_oran_off_start_prb,
8878 { "offStartPrb", "oran_fh_cus.offStartPrb",
8879 FT_UINT8, BASE_DEC,
8880 NULL((void*)0), 0x0,
8881 "Offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8882 },
8883 /* 7.7.12.5 */
8884 { &hf_oran_num_prb,
8885 { "numPrb", "oran_fh_cus.numPrb",
8886 FT_UINT8, BASE_DEC,
8887 NULL((void*)0), 0x0,
8888 "Number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8889 },
8890
8891 /* symbolId 8.3.3.7 */
8892 { &hf_oran_symbolId,
8893 { "Symbol Identifier", "oran_fh_cus.symbolId",
8894 FT_UINT8, BASE_DEC,
8895 NULL((void*)0), 0x3f,
8896 "Identifies a symbol number within a slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8897 },
8898
8899 /* startPrbu 8.3.3.11 */
8900 { &hf_oran_startPrbu,
8901 { "startPrbu", "oran_fh_cus.startPrbu",
8902 FT_UINT16, BASE_DEC,
8903 NULL((void*)0), 0x03ff,
8904 "starting PRB of user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8905 },
8906
8907 /* numPrbu 8.3.3.12 */
8908 { &hf_oran_numPrbu,
8909 { "numPrbu", "oran_fh_cus.numPrbu",
8910 FT_UINT8, BASE_DEC,
8911 NULL((void*)0), 0x0,
8912 "number of PRBs per user plane section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8913 },
8914
8915 /* 7.7.1.3 */
8916 { &hf_oran_bfwCompParam,
8917 { "bfwCompParam", "oran_fh_cus.bfwCompParam",
8918 FT_STRING, BASE_NONE,
8919 NULL((void*)0), 0x0,
8920 "Beamforming weight compression parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8921 },
8922
8923 /* 6.3.3.13 */
8924 { &hf_oran_udCompHdrMeth,
8925 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8926 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8927 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0f,
8928 "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)}
8929 },
8930 { &hf_oran_udCompHdrMeth_pref,
8931 { "User Data Compression Method", "oran_fh_cus.udCompHdrMeth",
8932 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8933 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8934 "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)}
8935 },
8936 /* 8.3.3.18 */
8937 { &hf_oran_udCompLen,
8938 { "udCompLen", "oran_fh_cus.udCompLen",
8939 FT_UINT16, BASE_DEC,
8940 NULL((void*)0), 0x0,
8941 "PRB field length in octets", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8942 },
8943
8944 /* 7.5.2.10 */
8945 { &hf_oran_udCompHdrIqWidth,
8946 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth",
8947 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8948 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
8949 "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)}
8950 },
8951 { &hf_oran_udCompHdrIqWidth_pref,
8952 { "User Data IQ width", "oran_fh_cus.udCompHdrWidth.pref",
8953 FT_UINT8, BASE_DEC,
8954 NULL((void*)0), 0x0,
8955 "IQ bit width for the user data in every section in the C-Plane message, from preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8956 },
8957
8958 { &hf_oran_sinrCompHdrIqWidth_pref,
8959 { "SINR IQ width", "oran_fh_cus.sinrCompHdrWidth",
8960 FT_UINT8, BASE_DEC,
8961 NULL((void*)0), 0x0,
8962 "Defines the IQ bit width for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8963 },
8964 { &hf_oran_sinrCompHdrMeth_pref,
8965 { "SINR Compression Method", "oran_fh_cus.sinrCompHdrMeth",
8966 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
8967 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0,
8968 "Defines the compression method for SINR data in section type 9", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8969 },
8970
8971 /* Section 8.3.3.15 (not always present - depends upon meth) */
8972 { &hf_oran_udCompParam,
8973 { "User Data Compression Parameter", "oran_fh_cus.udCompParam",
8974 FT_STRING, BASE_NONE,
8975 NULL((void*)0), 0x0,
8976 "Applies to whatever compression method is specified by the associated sectionID's compMeth value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8977 },
8978 /* 8.3.3.18 */
8979 { &hf_oran_sReSMask,
8980 { "sReSMask", "oran_fh_cus.sReSMask",
8981 FT_UINT16, BASE_HEX,
8982 NULL((void*)0), 0xf0ff,
8983 "selective RE sending mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8984 },
8985
8986 { &hf_oran_sReSMask_re12,
8987 { "RE-12", "oran_fh_cus.sReSMask-re12",
8988 FT_BOOLEAN, 16,
8989 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x8000,
8990 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8991 },
8992 { &hf_oran_sReSMask_re11,
8993 { "RE-11", "oran_fh_cus.sReSMask-re11",
8994 FT_BOOLEAN, 16,
8995 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x4000,
8996 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
8997 },
8998 { &hf_oran_sReSMask_re10,
8999 { "RE-10", "oran_fh_cus.sReSMask-re10",
9000 FT_BOOLEAN, 16,
9001 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
9002 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9003 },
9004 { &hf_oran_sReSMask_re9,
9005 { "RE-9", "oran_fh_cus.sReSMask-re9",
9006 FT_BOOLEAN, 16,
9007 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
9008 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9009 },
9010 { &hf_oran_sReSMask_re8,
9011 { "RE-8", "oran_fh_cus.sReSMask-re8",
9012 FT_BOOLEAN, 16,
9013 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
9014 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9015 },
9016 { &hf_oran_sReSMask_re7,
9017 { "RE-7", "oran_fh_cus.sReSMask-re7",
9018 FT_BOOLEAN, 16,
9019 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
9020 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9021 },
9022 { &hf_oran_sReSMask_re6,
9023 { "RE-6", "oran_fh_cus.sReSMask-re6",
9024 FT_BOOLEAN, 16,
9025 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
9026 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9027 },
9028 { &hf_oran_sReSMask_re5,
9029 { "RE-5", "oran_fh_cus.sReSMask-re5",
9030 FT_BOOLEAN, 16,
9031 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
9032 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9033 },
9034 { &hf_oran_sReSMask_re4,
9035 { "RE-4", "oran_fh_cus.sReSMask-re4",
9036 FT_BOOLEAN, 16,
9037 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
9038 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9039 },
9040 { &hf_oran_sReSMask_re3,
9041 { "RE-3", "oran_fh_cus.sReSMask-re3",
9042 FT_BOOLEAN, 16,
9043 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
9044 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9045 },
9046 { &hf_oran_sReSMask_re2,
9047 { "RE-2", "oran_fh_cus.sReSMask-re2",
9048 FT_BOOLEAN, 16,
9049 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
9050 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9051 },
9052 { &hf_oran_sReSMask_re1,
9053 { "RE-1", "oran_fh_cus.sReSMask-re1",
9054 FT_BOOLEAN, 16,
9055 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
9056 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9057 },
9058
9059 /* 8.3.3.20 */
9060 { &hf_oran_sReSMask1,
9061 { "sReSMask1", "oran_fh_cus.sReSMask1",
9062 FT_UINT16, BASE_HEX,
9063 NULL((void*)0), 0x0fff,
9064 "selective RE sending mask 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9065 },
9066 /* 8.3.3.21 */
9067 { &hf_oran_sReSMask2,
9068 { "sReSMask2", "oran_fh_cus.sReSMask2",
9069 FT_UINT16, BASE_HEX,
9070 NULL((void*)0), 0x0fff,
9071 "selective RE sending mask 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9072 },
9073
9074 { &hf_oran_sReSMask1_2_re12,
9075 { "RE-12", "oran_fh_cus.sReSMask-re12",
9076 FT_BOOLEAN, 16,
9077 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
9078 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9079 },
9080 { &hf_oran_sReSMask1_2_re11,
9081 { "RE-11", "oran_fh_cus.sReSMask-re11",
9082 FT_BOOLEAN, 16,
9083 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
9084 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9085 },
9086 { &hf_oran_sReSMask1_2_re10,
9087 { "RE-10", "oran_fh_cus.sReSMask-re10",
9088 FT_BOOLEAN, 16,
9089 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
9090 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9091 },
9092 { &hf_oran_sReSMask1_2_re9,
9093 { "RE-9", "oran_fh_cus.sReSMask-re9",
9094 FT_BOOLEAN, 16,
9095 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
9096 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9097 },
9098
9099 /* Section 6.3.3.15 */
9100 { &hf_oran_iSample,
9101 { "iSample", "oran_fh_cus.iSample",
9102 FT_FLOAT, BASE_NONE,
9103 NULL((void*)0), 0x0,
9104 "In-phase Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9105 },
9106
9107 /* Section 6.3.3.16 */
9108 { &hf_oran_qSample,
9109 { "qSample", "oran_fh_cus.qSample",
9110 FT_FLOAT, BASE_NONE,
9111 NULL((void*)0), 0x0,
9112 "Quadrature Sample value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9113 },
9114
9115 { &hf_oran_exponent,
9116 { "Exponent", "oran_fh_cus.exponent",
9117 FT_UINT8, BASE_DEC,
9118 NULL((void*)0), 0x0f,
9119 "Exponent applicable to the I & Q mantissas", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9120 },
9121
9122 { &hf_oran_iq_user_data,
9123 { "IQ User Data", "oran_fh_cus.iq_user_data",
9124 FT_BYTES, BASE_NONE,
9125 NULL((void*)0), 0x0,
9126 "Used for the In-phase and Quadrature sample mantissa", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9127 },
9128
9129
9130 { &hf_oran_u_section_ul_symbol_time,
9131 { "Microseconds since first UL U-plane frame for this symbol", "oran_fh_cus.us-since-first-ul-frame",
9132 FT_UINT32, BASE_DEC,
9133 NULL((void*)0), 0x0,
9134 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9135 },
9136 { &hf_oran_u_section_ul_symbol_frames,
9137 { "Number of UL frames sent for this symbol", "oran_fh_cus.number-ul-frames-in-symbol",
9138 FT_UINT32, BASE_DEC,
9139 NULL((void*)0), 0x0,
9140 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9141 },
9142 { &hf_oran_u_section_ul_symbol_first_frame,
9143 { "First UL frame for this symbol", "oran_fh_cus.first-ul-frame-in-symbol",
9144 FT_FRAMENUM, BASE_NONE,
9145 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9146 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9147 },
9148 { &hf_oran_u_section_ul_symbol_last_frame,
9149 { "Last UL frame for this symbol", "oran_fh_cus.last-ul-frame-in-symbol",
9150 FT_FRAMENUM, BASE_NONE,
9151 FRAMENUM_TYPE(FT_FRAMENUM_NONE)((gpointer) (glong) (FT_FRAMENUM_NONE)), 0x0,
9152 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9153 },
9154
9155 { &hf_oran_c_eAxC_ID,
9156 { "c_eAxC_ID", "oran_fh_cus.c_eaxc_id",
9157 FT_STRING, BASE_NONE,
9158 NULL((void*)0), 0x0,
9159 "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) }
9160 },
9161
9162 { &hf_oran_refa,
9163 { "RefA", "oran_fh_cus.refa",
9164 FT_STRING, BASE_NONE,
9165 NULL((void*)0), 0x0,
9166 "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) }
9167 },
9168
9169
9170 /* Section 7.5.2.15 */
9171 { &hf_oran_ciCompHdr,
9172 { "ciCompHdr", "oran_fh_cus.ciCompHdr",
9173 FT_STRING, BASE_NONE,
9174 NULL((void*)0), 0x0,
9175 "Channel Information Compression Header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9176 },
9177 { &hf_oran_ciCompHdrMeth,
9178 { "User Data Compression Method", "oran_fh_cus.ciCompHdrMeth",
9179 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9180 RVALS(ud_comp_header_meth)((0 ? (const struct _range_string*)0 : ((ud_comp_header_meth)
)))
, 0x0e,
9181 "Compression method for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9182 },
9183 { &hf_oran_ciCompHdrIqWidth,
9184 { "User Data IQ width", "oran_fh_cus.ciCompHdrWidth",
9185 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9186 RVALS(ud_comp_header_width)((0 ? (const struct _range_string*)0 : ((ud_comp_header_width
))))
, 0xf0,
9187 "IQ bit width for Channel Information", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9188 },
9189 { &hf_oran_ciCompOpt,
9190 { "ciCompOpt", "oran_fh_cus.ciCompOpt",
9191 FT_UINT8, BASE_DEC,
9192 VALS(ci_comp_opt_vals)((0 ? (const struct _value_string*)0 : ((ci_comp_opt_vals)))), 0x01,
9193 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9194 },
9195
9196 /* 7.7.11.7 */
9197 { &hf_oran_disable_bfws,
9198 { "disableBFWs", "oran_fh_cus.disableBFWs",
9199 FT_BOOLEAN, 8,
9200 NULL((void*)0), 0x80,
9201 "Indicate if BFWs under section extension are disabled", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9202 },
9203 /* 7.7.11.8 */
9204 { &hf_oran_rad,
9205 { "RAD", "oran_fh_cus.rad",
9206 FT_BOOLEAN, 8,
9207 NULL((void*)0), 0x40,
9208 "Reset After PRB Discontinuity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9209 },
9210 /* 7.7.11.4 */
9211 { &hf_oran_num_bund_prbs,
9212 { "numBundPrb", "oran_fh_cus.numBundPrb",
9213 FT_UINT8, BASE_DEC,
9214 NULL((void*)0), 0x0,
9215 "Number of bundled PRBs per BFWs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9216 },
9217 { &hf_oran_beam_id,
9218 { "beamId", "oran_fh_cus.beamId",
9219 FT_UINT16, BASE_DEC,
9220 NULL((void*)0), 0x7fff,
9221 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9222 },
9223 { &hf_oran_num_weights_per_bundle,
9224 { "Num weights per bundle", "oran_fh_cus.num_weights_per_bundle",
9225 FT_UINT16, BASE_DEC,
9226 NULL((void*)0), 0x0,
9227 "From dissector preference", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9228 },
9229
9230 { &hf_oran_samples_prb,
9231 {"PRB", "oran_fh_cus.prb",
9232 FT_STRING, BASE_NONE,
9233 NULL((void*)0), 0x0,
9234 "Grouping of samples for a particular Physical Resource Block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9235 },
9236
9237 /* 7.5.3.13 */
9238 { &hf_oran_ciSample,
9239 { "ciSample", "oran_fh_cus.ciSample",
9240 FT_STRING, BASE_NONE,
9241 NULL((void*)0), 0x0,
9242 "Sample (I and Q values)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9243 },
9244 { &hf_oran_ciIsample,
9245 { "ciIsample", "oran_fh_cus.ciISample",
9246 FT_FLOAT, BASE_NONE,
9247 NULL((void*)0), 0x0,
9248 "Channel information complex value - I part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9249 },
9250 { &hf_oran_ciQsample,
9251 { "ciQsample", "oran_fh_cus.ciQSample",
9252 FT_FLOAT, BASE_NONE,
9253 NULL((void*)0), 0x0,
9254 "Channel information complex value - Q part", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9255 },
9256
9257 /* 7.7.10.2 */
9258 { &hf_oran_beamGroupType,
9259 { "beamGroupType", "oran_fh_cus.beamGroupType",
9260 FT_UINT8, BASE_DEC,
9261 VALS(beam_group_type_vals)((0 ? (const struct _value_string*)0 : ((beam_group_type_vals
))))
, 0xc0,
9262 "The type of beam grouping", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9263 },
9264 /* 7.7.10.3 */
9265 { &hf_oran_numPortc,
9266 { "numPortc", "oran_fh_cus.numPortc",
9267 FT_UINT8, BASE_DEC,
9268 NULL((void*)0), 0x3f,
9269 "The number of eAxC ports", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9270 },
9271
9272 /* 7.7.4.2 (1 bit) */
9273 { &hf_oran_csf,
9274 { "csf", "oran_fh_cus.csf",
9275 FT_BOOLEAN, BASE_NONE,
9276 NULL((void*)0), 0x0,
9277 "constellation shift flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9278 },
9279 /* 7.7.4.3 */
9280 { &hf_oran_modcompscaler,
9281 { "modCompScaler", "oran_fh_cus.modcompscaler",
9282 FT_UINT16, BASE_DEC,
9283 NULL((void*)0), 0x7fff,
9284 "modulation compression scaler value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9285 },
9286
9287 /* 7.7.5.1 */
9288 { &hf_oran_modcomp_param_set,
9289 { "Set", "oran_fh_cus.modcomp-param-set",
9290 FT_STRING, BASE_NONE,
9291 NULL((void*)0), 0x0,
9292 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9293 },
9294
9295
9296
9297 /* mcScaleReMask 7.7.5.2 (12 bits) */
9298
9299 /* First entry (starts with msb within byte) */
9300 { &hf_oran_mc_scale_re_mask_re1,
9301 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9302 FT_BOOLEAN, 16,
9303 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x8000,
9304 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9305 },
9306 { &hf_oran_mc_scale_re_mask_re2,
9307 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9308 FT_BOOLEAN, 16,
9309 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x4000,
9310 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9311 },
9312 { &hf_oran_mc_scale_re_mask_re3,
9313 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9314 FT_BOOLEAN, 16,
9315 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x2000,
9316 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9317 },
9318 { &hf_oran_mc_scale_re_mask_re4,
9319 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9320 FT_BOOLEAN, 16,
9321 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x1000,
9322 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9323 },
9324 { &hf_oran_mc_scale_re_mask_re5,
9325 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9326 FT_BOOLEAN, 16,
9327 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9328 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9329 },
9330 { &hf_oran_mc_scale_re_mask_re6,
9331 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9332 FT_BOOLEAN, 16,
9333 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9334 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9335 },
9336 { &hf_oran_mc_scale_re_mask_re7,
9337 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9338 FT_BOOLEAN, 16,
9339 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9340 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9341 },
9342 { &hf_oran_mc_scale_re_mask_re8,
9343 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9344 FT_BOOLEAN, 16,
9345 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9346 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9347 },
9348 { &hf_oran_mc_scale_re_mask_re9,
9349 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9350 FT_BOOLEAN, 16,
9351 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9352 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9353 },
9354 { &hf_oran_mc_scale_re_mask_re10,
9355 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9356 FT_BOOLEAN, 16,
9357 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9358 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9359 },
9360 { &hf_oran_mc_scale_re_mask_re11,
9361 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9362 FT_BOOLEAN, 16,
9363 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9364 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9365 },
9366 { &hf_oran_mc_scale_re_mask_re12,
9367 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9368 FT_BOOLEAN, 16,
9369 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9370 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9371 },
9372
9373 /* Even tries entry (starts with 5th bit within byte) */
9374 { &hf_oran_mc_scale_re_mask_re1_even,
9375 { "RE 1", "oran_fh_cus.mcscalermask-RE1",
9376 FT_BOOLEAN, 16,
9377 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0800,
9378 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9379 },
9380 { &hf_oran_mc_scale_re_mask_re2_even,
9381 { "RE 2", "oran_fh_cus.mcscalermask-RE2",
9382 FT_BOOLEAN, 16,
9383 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0400,
9384 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9385 },
9386 { &hf_oran_mc_scale_re_mask_re3_even,
9387 { "RE 3", "oran_fh_cus.mcscalermask-RE3",
9388 FT_BOOLEAN, 16,
9389 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0200,
9390 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9391 },
9392 { &hf_oran_mc_scale_re_mask_re4_even,
9393 { "RE 4", "oran_fh_cus.mcscalermask-RE4",
9394 FT_BOOLEAN, 16,
9395 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0100,
9396 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9397 },
9398 { &hf_oran_mc_scale_re_mask_re5_even,
9399 { "RE 5", "oran_fh_cus.mcscalermask-RE5",
9400 FT_BOOLEAN, 16,
9401 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0080,
9402 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9403 },
9404 { &hf_oran_mc_scale_re_mask_re6_even,
9405 { "RE 6", "oran_fh_cus.mcscalermask-RE6",
9406 FT_BOOLEAN, 16,
9407 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0040,
9408 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9409 },
9410 { &hf_oran_mc_scale_re_mask_re7_even,
9411 { "RE 7", "oran_fh_cus.mcscalermask-RE7",
9412 FT_BOOLEAN, 16,
9413 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0020,
9414 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9415 },
9416 { &hf_oran_mc_scale_re_mask_re8_even,
9417 { "RE 8", "oran_fh_cus.mcscalermask-RE8",
9418 FT_BOOLEAN, 16,
9419 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0010,
9420 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9421 },
9422 { &hf_oran_mc_scale_re_mask_re9_even,
9423 { "RE 9", "oran_fh_cus.mcscalermask-RE9",
9424 FT_BOOLEAN, 16,
9425 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0008,
9426 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9427 },
9428 { &hf_oran_mc_scale_re_mask_re10_even,
9429 { "RE 10", "oran_fh_cus.mcscalermask-RE10",
9430 FT_BOOLEAN, 16,
9431 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0004,
9432 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9433 },
9434 { &hf_oran_mc_scale_re_mask_re11_even,
9435 { "RE 11", "oran_fh_cus.mcscalermask-RE11",
9436 FT_BOOLEAN, 16,
9437 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0002,
9438 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9439 },
9440 { &hf_oran_mc_scale_re_mask_re12_even,
9441 { "RE 12", "oran_fh_cus.mcscalermask-RE12",
9442 FT_BOOLEAN, 16,
9443 TFS(&tfs_applicable_not_applicable)((0 ? (const struct true_false_string*)0 : ((&tfs_applicable_not_applicable
))))
, 0x0001,
9444 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9445 },
9446
9447 { &hf_oran_mc_scale_re_mask,
9448 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9449 FT_UINT16, BASE_HEX,
9450 NULL((void*)0), 0xfff0,
9451 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9452 },
9453 { &hf_oran_mc_scale_re_mask_even,
9454 { "mcScaleReMask", "oran_fh_cus.mcscaleremask",
9455 FT_UINT16, BASE_HEX,
9456 NULL((void*)0), 0x0fff,
9457 "modulation compression power scale RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9458 },
9459
9460 /* mcScaleOffset 7.7.5.4 (15 bits) */
9461 { &hf_oran_mc_scale_offset,
9462 { "mcScaleOffset", "oran_fh_cus.mcscaleoffset",
9463 FT_UINT24, BASE_DEC,
9464 NULL((void*)0), 0x0,
9465 "scaling value for modulation compression", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9466 },
9467 /* eAxCmask (7.7.7.2) */
9468 { &hf_oran_eAxC_mask,
9469 { "eAxC Mask", "oran_fh_cus.eaxcmask",
9470 FT_UINT16, BASE_HEX,
9471 NULL((void*)0), 0xffff,
9472 "Which eAxC_ID values the C-Plane message applies to", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9473 },
9474 /* technology (interface name) 7.7.9.2 */
9475 { &hf_oran_technology,
9476 { "Technology", "oran_fh_cus.technology",
9477 FT_UINT8, BASE_DEC,
9478 VALS(interface_name_vals)((0 ? (const struct _value_string*)0 : ((interface_name_vals)
)))
, 0x0,
9479 "Interface name (that C-PLane section applies to)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9480 },
9481 /* Exttype 14 (7.7.14.2) */
9482 { &hf_oran_nullLayerInd,
9483 { "nullLayerInd", "oran_fh_cus.nulllayerind",
9484 FT_BOOLEAN, BASE_NONE,
9485 NULL((void*)0), 0x0,
9486 "Whether corresponding layer is nulling-layer or not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9487 },
9488
9489 /* Exttype 19 */
9490 /* 7.7.19.3 */
9491 { &hf_oran_se19_repetition,
9492 { "repetition", "oran_fh_cus.repetition",
9493 FT_BOOLEAN, BASE_NONE,
9494 TFS(&repetition_se19_tfs)((0 ? (const struct true_false_string*)0 : ((&repetition_se19_tfs
))))
, 0x0,
9495 "repeat port info flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9496 },
9497 /* 7.7.19.8 */
9498 /* TODO: break down into each RE as done for 7.5.3.5 ? */
9499 { &hf_oran_portReMask,
9500 { "portReMask", "oran_fh_cus.portReMask",
9501 FT_BOOLEAN, 16,
9502 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x0fff,
9503 "RE bitmask per port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9504 },
9505 /* 7.7.19.9 */
9506 { &hf_oran_portSymbolMask,
9507 { "portSymbolMask", "oran_fh_cus.portSymbolMask",
9508 FT_BOOLEAN, 16,
9509 TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x3fff,
9510 "Symbol bitmask port port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9511 },
9512
9513 { &hf_oran_ext19_port,
9514 {"Port", "oran_fh_cus.ext19.port",
9515 FT_STRING, BASE_NONE,
9516 NULL((void*)0), 0x0,
9517 "Entry for a given port in ext19", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9518 },
9519
9520 /* Ext 13 */
9521 { &hf_oran_prb_allocation,
9522 {"PRB allocation", "oran_fh_cus.prb-allocation",
9523 FT_STRING, BASE_NONE,
9524 NULL((void*)0), 0x0,
9525 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9526 },
9527 /* 7.7.13.2 */
9528 { &hf_oran_nextSymbolId,
9529 { "nextSymbolId", "oran_fh_cus.nextSymbolId",
9530 FT_UINT8, BASE_DEC,
9531 NULL((void*)0), 0x3c,
9532 "offset of PRB range start", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9533 },
9534 /* 7.7.13.3 */
9535 { &hf_oran_nextStartPrbc,
9536 { "nextStartPrbc", "oran_fh_cus.nextStartPrbc",
9537 FT_UINT16, BASE_DEC,
9538 NULL((void*)0), 0x03ff,
9539 "number of PRBs in PRB range", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9540 },
9541
9542 /* Puncturing patters as appears in SE 20 */
9543 { &hf_oran_puncPattern,
9544 { "puncPattern", "oran_fh_cus.puncPattern",
9545 FT_STRING, BASE_NONE,
9546 NULL((void*)0), 0x0,
9547 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9548 },
9549
9550 /* 7.7.20.2 numPuncPatterns */
9551 { &hf_oran_numPuncPatterns,
9552 { "numPuncPatterns", "oran_fh_cus.numPuncPatterns",
9553 FT_UINT8, BASE_DEC,
9554 NULL((void*)0), 0x0,
9555 "number of puncturing patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
9556 },
9557 /* 7.7.20.3 symbolMask */
9558 { &hf_oran_symbolMask_ext20,
9559 { "symbolMask", "oran_fh_cus.symbolMask",
9560 FT_UINT16, BASE_HEX,
9561 NULL((void*)0), 0xfffc,
9562 "Bitmask where each bit indicates the symbols associated with the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9563 },
9564 /* 7.7.20.4 startPuncPrb */
9565 { &hf_oran_startPuncPrb,
9566 { "startPuncPrb", "oran_fh_cus.startPuncPrb",
9567 FT_UINT16, BASE_DEC,
9568 NULL((void*)0), 0x03ff,
9569 "starting PRB to which one puncturing pattern applies", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9570 },
9571 /* 7.7.20.5 numPuncPrb */
9572 { &hf_oran_numPuncPrb,
9573 { "numPuncPrb", "oran_fh_cus.numPuncPrb",
9574 FT_UINT8, BASE_DEC,
9575 NULL((void*)0), 0x0,
9576 "the number of PRBs of the puncturing pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9577 },
9578 /* 7.7.20.6 puncReMask */
9579 { &hf_oran_puncReMask,
9580 { "puncReMask", "oran_fh_cus.puncReMask",
9581 FT_UINT16, BASE_DEC,
9582 NULL((void*)0), 0xffc0,
9583 "puncturing pattern RE mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9584 },
9585 /* 7.7.20.12 multiSDScope */
9586 { &hf_oran_multiSDScope,
9587 { "multiSDScope", "oran_fh_cus.multiSDScope",
9588 FT_BOOLEAN, 8,
9589 TFS(&multi_sd_scope_tfs)((0 ? (const struct true_false_string*)0 : ((&multi_sd_scope_tfs
))))
, 0x02,
9590 "multiple section description scope flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9591 },
9592 /* 7.7.20.4 rbgIncl */
9593 { &hf_oran_RbgIncl,
9594 { "rbgIncl", "oran_fh_cus.rbgIncl",
9595 FT_BOOLEAN, 8,
9596 NULL((void*)0), 0x01,
9597 "rbg included flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9598 },
9599
9600 /* 7.7.21.2 ciPrbGroupSize */
9601 { &hf_oran_ci_prb_group_size,
9602 { "ciPrbGroupSize", "oran_fh_cus.ciPrbGroupSize",
9603 FT_UINT8, BASE_DEC,
9604 NULL((void*)0), 0x0,
9605 "channel information PRB group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9606 },
9607 /* 7.21.3 */
9608 { &hf_oran_prg_size_st5,
9609 { "prgSize", "oran_fh_cus.prgSize",
9610 FT_UINT8, BASE_DEC,
9611 VALS(prg_size_st5_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st5_vals)))
)
, 0x03,
9612 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9613 },
9614 { &hf_oran_prg_size_st6,
9615 { "prgSize", "oran_fh_cus.prgSize",
9616 FT_UINT8, BASE_DEC,
9617 VALS(prg_size_st6_vals)((0 ? (const struct _value_string*)0 : ((prg_size_st6_vals)))
)
, 0x03,
9618 "precoding resource block group size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9619 },
9620
9621 /* 7.7.17.2 numUeID */
9622 { &hf_oran_num_ueid,
9623 { "numUeID", "oran_fh_cus.numUeID",
9624 FT_UINT8, BASE_DEC,
9625 NULL((void*)0), 0x0,
9626 "number of ueIDs per user", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9627 },
9628
9629 /* 7.7.16.2 antMask */
9630 { &hf_oran_antMask,
9631 { "antMask", "oran_fh_cus.antMask",
9632 FT_UINT64, BASE_HEX,
9633 NULL((void*)0), 0xffffffffffffffff,
9634 "indices of antennas to be pre-combined per RX endpoint", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9635 },
9636
9637 /* 7.7.18.2 transmissionWindowOffset */
9638 { &hf_oran_transmissionWindowOffset,
9639 { "transmissionWindowOffset", "oran_fh_cus.transmissionWindowOffset",
9640 FT_UINT16, BASE_DEC,
9641 NULL((void*)0), 0x0,
9642 "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)}
9643 },
9644 /* 7.7.18.3 transmissionWindowSize */
9645 { &hf_oran_transmissionWindowSize,
9646 { "transmissionWindowSize", "oran_fh_cus.transmissionWindowSize",
9647 FT_UINT16, BASE_DEC,
9648 NULL((void*)0), 0x3fff,
9649 "size of the transmission window in resolution µs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9650 },
9651 /* 7.7.18.4 toT */
9652 { &hf_oran_toT,
9653 { "toT", "oran_fh_cus.toT",
9654 FT_UINT8, BASE_DEC,
9655 VALS(type_of_transmission_vals)((0 ? (const struct _value_string*)0 : ((type_of_transmission_vals
))))
, 0x03,
9656 "type of transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9657 },
9658
9659 /* 7.7.2.2 bfaCompHdr */
9660 { &hf_oran_bfaCompHdr,
9661 { "bfaCompHdr", "oran_fh_cus.bfaCompHdr",
9662 FT_STRING, BASE_NONE,
9663 NULL((void*)0), 0x0,
9664 "beamforming attributes compression header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9665 },
9666 /* 7.7.2.2-2: bfAzPtWidth */
9667 { &hf_oran_bfAzPtWidth,
9668 { "bfAzPtWidth", "oran_fh_cus.bfAzPtWidth",
9669 FT_UINT8, BASE_DEC,
9670 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9671 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9672 },
9673 /* 7.7.2.2-3: bfZePtWidth */
9674 { &hf_oran_bfZePtWidth,
9675 { "bfZePtWidth", "oran_fh_cus.bfZePtWidth",
9676 FT_UINT8, BASE_DEC,
9677 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9678 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9679 },
9680 /* 7.7.2.2-4: bfAz3ddWidth */
9681 { &hf_oran_bfAz3ddWidth,
9682 { "bfAz3ddWidth", "oran_fh_cus.bfAz3ddWidth",
9683 FT_UINT8, BASE_DEC,
9684 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x38,
9685 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9686 },
9687 /* 7.7.2.2-5: bfZe3ddWidth */
9688 { &hf_oran_bfZe3ddWidth,
9689 { "bfZe3ddWidth", "oran_fh_cus.bfZe3ddWidth",
9690 FT_UINT8, BASE_DEC,
9691 VALS(bfa_bw_vals)((0 ? (const struct _value_string*)0 : ((bfa_bw_vals)))), 0x07,
9692 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9693 },
9694
9695 /* 7.7.2.3 bfAzPt */
9696 { &hf_oran_bfAzPt,
9697 { "bfAzPt", "oran_fh_cus.bfAzPt",
9698 FT_UINT8, BASE_DEC,
9699 NULL((void*)0), 0x0,
9700 "beamforming azimuth pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9701 },
9702 /* 7.7.2.4 bfZePt */
9703 { &hf_oran_bfZePt,
9704 { "bfZePt", "oran_fh_cus.bfZePt",
9705 FT_UINT8, BASE_DEC,
9706 NULL((void*)0), 0x0,
9707 "beamforming zenith pointing parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9708 },
9709 /* 7.7.2.5 bfAz3dd */
9710 { &hf_oran_bfAz3dd,
9711 { "bfAz3dd", "oran_fh_cus.bfAz3dd",
9712 FT_UINT8, BASE_DEC,
9713 NULL((void*)0), 0x0,
9714 "beamforming azimuth beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9715 },
9716 /* 7.7.2.6 bfZe3dd */
9717 { &hf_oran_bfZe3dd,
9718 { "bfZe3dd", "oran_fh_cus.bfZe3dd",
9719 FT_UINT8, BASE_DEC,
9720 NULL((void*)0), 0x0,
9721 "beamforming zenith beamwidth parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9722 },
9723
9724 /* 7.7.2.7 bfAzSl */
9725 { &hf_oran_bfAzSl,
9726 { "bfAzSl", "oran_fh_cus.bfAzSl",
9727 FT_UINT8, BASE_DEC,
9728 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x38,
9729 "beamforming azimuth sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9730 },
9731 /* 7.7.2.8 bfZeSl */
9732 { &hf_oran_bfZeSl,
9733 { "bfZeSl", "oran_fh_cus.bfZeSl",
9734 FT_UINT8, BASE_DEC,
9735 VALS(sidelobe_suppression_vals)((0 ? (const struct _value_string*)0 : ((sidelobe_suppression_vals
))))
, 0x07,
9736 "beamforming zenith sidelobe parameter", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9737 },
9738
9739 /* 7.5.2.17 */
9740 { &hf_oran_cmd_scope,
9741 { "cmdScope", "oran_fh_cus.cmdScope",
9742 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9743 RVALS(cmd_scope_vals)((0 ? (const struct _range_string*)0 : ((cmd_scope_vals)))), 0x0f,
9744 "command scope", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9745 },
9746 /* 7.5.2.18 */
9747 { &hf_oran_number_of_st4_cmds,
9748 { "numberOfST4Cmds", "oran_fh_cus.numberOfST4Cmds",
9749 FT_UINT8, BASE_DEC,
9750 NULL((void*)0), 0x0,
9751 "Number of Section Type 4 commands", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9752 },
9753
9754 { &hf_oran_st4_cmd_header,
9755 { "Command common header", "oran_fh_cus.st4CmdCommonHeader",
9756 FT_STRING, BASE_NONE,
9757 NULL((void*)0), 0x0,
9758 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9759 },
9760
9761 /* 7.5.3.38 */
9762 { &hf_oran_st4_cmd_type,
9763 { "st4CmdType", "oran_fh_cus.st4CmdType",
9764 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
9765 RVALS(st4_cmd_type_vals)((0 ? (const struct _range_string*)0 : ((st4_cmd_type_vals)))
)
, 0x0,
9766 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9767 },
9768 /* 7.5.3.39 */
9769 { &hf_oran_st4_cmd_len,
9770 { "st4CmdLen", "oran_fh_cus.st4CmdLen",
9771 FT_UINT16, BASE_DEC,
9772 NULL((void*)0), 0x0,
9773 "Length of command in 32-bit words", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9774 },
9775 /* 7.5.3.40 */
9776 { &hf_oran_st4_cmd_num_slots,
9777 { "numSlots", "oran_fh_cus.st4NumSlots",
9778 FT_UINT8, BASE_DEC,
9779 NULL((void*)0), 0x0,
9780 "Contiguous slots for which command is applicable", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9781 },
9782 /* 7.5.3.41 */
9783 { &hf_oran_st4_cmd_ack_nack_req_id,
9784 { "ackNackReqId", "oran_fh_cus.ackNackReqId",
9785 FT_UINT16, BASE_DEC,
9786 NULL((void*)0), 0x0,
9787 "ACK/NACK Request Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9788 },
9789
9790 { &hf_oran_st4_cmd,
9791 { "Command", "oran_fh_cus.st4Cmd",
9792 FT_STRING, BASE_NONE,
9793 NULL((void*)0), 0x0,
9794 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9795 },
9796
9797 /* 7.5.3.52 */
9798 { &hf_oran_sleepmode_trx,
9799 { "sleepMode", "oran_fh_cus.sleepMode",
9800 FT_UINT8, BASE_HEX,
9801 VALS(sleep_mode_trx_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_trx_vals)
)))
, 0x03,
9802 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9803 },
9804 { &hf_oran_sleepmode_asm,
9805 { "sleepMode", "oran_fh_cus.sleepMode",
9806 FT_UINT8, BASE_HEX,
9807 VALS(sleep_mode_asm_vals)((0 ? (const struct _value_string*)0 : ((sleep_mode_asm_vals)
)))
, 0x03,
9808 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9809 },
9810
9811 /* 7.5.3.51 */
9812 { &hf_oran_log2maskbits,
9813 { "log2MaskBits", "oran_fh_cus.log2MaskBits",
9814 FT_UINT8, BASE_HEX,
9815 VALS(log2maskbits_vals)((0 ? (const struct _value_string*)0 : ((log2maskbits_vals)))
)
, 0x3c,
9816 "Number of bits to appear in antMask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9817 },
9818 /* 7.5.3.53 */
9819 { &hf_oran_num_slots_ext,
9820 { "numSlotsExt", "oran_fh_cus.numSlotsExt",
9821 FT_UINT24, BASE_HEX,
9822 NULL((void*)0), 0x0fffff,
9823 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9824 },
9825 /* 7.5.3.54 */
9826 { &hf_oran_antMask_trx_control,
9827 { "antMask", "oran_fh_cus.trxControl.antMask",
9828 FT_BYTES, BASE_NONE,
9829 NULL((void*)0), 0x0,
9830 "which antennas should sleep or wake-up", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9831 },
9832 /* 7.5.3.55 */
9833 { &hf_oran_ready,
9834 { "ready", "oran_fh_cus.ready",
9835 FT_BOOLEAN, 8,
9836 TFS(&ready_tfs)((0 ? (const struct true_false_string*)0 : ((&ready_tfs))
))
, 0x01,
9837 "wake-up ready indicator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9838 },
9839 /* 7.5.3.34 */
9840 { &hf_oran_number_of_acks,
9841 { "numberOfAcks", "oran_fh_cus.numberOfAcks",
9842 FT_UINT8, BASE_DEC,
9843 NULL((void*)0), 0x0,
9844 "number of ACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9845 },
9846 /* 7.5.3.35 */
9847 { &hf_oran_number_of_nacks,
9848 { "numberOfNacks", "oran_fh_cus.numberOfNacks",
9849 FT_UINT8, BASE_DEC,
9850 NULL((void*)0), 0x0,
9851 "number of NACKs for one eAxC_ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9852 },
9853 /* 7.5.3.36 */
9854 { &hf_oran_ackid,
9855 { "ackId", "oran_fh_cus.ackId",
9856 FT_UINT16, BASE_DEC,
9857 NULL((void*)0), 0x0,
9858 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9859 },
9860 /* 7.5.3.37 */
9861 { &hf_oran_nackid,
9862 { "nackId", "oran_fh_cus.nackId",
9863 FT_UINT16, BASE_DEC,
9864 NULL((void*)0), 0x0,
9865 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9866 },
9867
9868 /* Links between acknack requests & responses */
9869 { &hf_oran_acknack_request_frame,
9870 { "Request Frame", "oran_fh_cus.ackNackId.request-frame",
9871 FT_FRAMENUM, BASE_NONE,
9872 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
9873 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9874 },
9875 { &hf_oran_acknack_request_time,
9876 { "Time since request in ms", "oran_fh_cus.ackNackId.time-since-request",
9877 FT_UINT32, BASE_DEC,
9878 NULL((void*)0), 0x0,
9879 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9880 },
9881 { &hf_oran_acknack_request_type,
9882 { "Request Type", "oran_fh_cus.ackNackId.request-type",
9883 FT_UINT32, BASE_DEC,
9884 VALS(acknack_type_vals)((0 ? (const struct _value_string*)0 : ((acknack_type_vals)))
)
, 0x0,
9885 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9886 },
9887 { &hf_oran_acknack_response_frame,
9888 { "Response Frame", "oran_fh_cus.ackNackId.response-frame",
9889 FT_FRAMENUM, BASE_NONE,
9890 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0,
9891 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9892 },
9893 { &hf_oran_acknack_response_time,
9894 { "Time to response in ms", "oran_fh_cus.ackNackId.time-to-response",
9895 FT_UINT32, BASE_DEC,
9896 NULL((void*)0), 0x0,
9897 "Time between request and response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9898 },
9899
9900 /* 7.5.3.43 */
9901 { &hf_oran_disable_tdbfns,
9902 { "disableTDBFNs", "oran_fh_cus.disableTDBFNs",
9903 FT_BOOLEAN, 8,
9904 TFS(&disable_tdbfns_tfs)((0 ? (const struct true_false_string*)0 : ((&disable_tdbfns_tfs
))))
, 0x80,
9905 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9906 },
9907
9908 /* 7.5.3.44 */
9909 { &hf_oran_td_beam_group,
9910 { "tdBeamGrp", "oran_fh_cus.tdBeamGrp",
9911 FT_UINT16, BASE_HEX,
9912 NULL((void*)0), 0x7fff,
9913 "Applies to symbolMask in command header", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9914 },
9915 /* 7.5.3.43 */
9916 { &hf_oran_disable_tdbfws,
9917 { "disableTDBFWs", "oran_fh_cus.disableTDBFWs",
9918 FT_BOOLEAN, 8,
9919 TFS(&beam_numbers_included_tfs)((0 ? (const struct true_false_string*)0 : ((&beam_numbers_included_tfs
))))
, 0x80,
9920 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9921 },
9922
9923 /* 7.5.3.56 */
9924 { &hf_oran_td_beam_num,
9925 { "tdBeamNum", "oran_fh_cus.tdBeamNum",
9926 FT_UINT16, BASE_HEX,
9927 NULL((void*)0), 0x7fff,
9928 "time-domain beam number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9929 },
9930
9931 /* 7.5.3.49 */
9932 { &hf_oran_dir_pattern,
9933 { "dirPattern", "oran_fh_cus.dirPattern",
9934 FT_BOOLEAN, 16,
9935 TFS(&symbol_direction_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_direction_tfs
))))
, 0x3fff,
9936 "symbol data direction (gNB Tx/Rx) pattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9937 },
9938 /* 7.5.3.50 */
9939 { &hf_oran_guard_pattern,
9940 { "guardPattern", "oran_fh_cus.guardPattern",
9941 FT_BOOLEAN, 16,
9942 TFS(&symbol_guard_tfs)((0 ? (const struct true_false_string*)0 : ((&symbol_guard_tfs
))))
, 0x3fff,
9943 "guard pattern bitmask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9944 },
9945
9946 /* For convenient filtering */
9947 { &hf_oran_cplane,
9948 { "C-Plane", "oran_fh_cus.c-plane",
9949 FT_NONE, BASE_NONE,
9950 NULL((void*)0), 0x0,
9951 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9952 },
9953 { &hf_oran_uplane,
9954 { "U-Plane", "oran_fh_cus.u-plane",
9955 FT_NONE, BASE_NONE,
9956 NULL((void*)0), 0x0,
9957 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9958 },
9959 { &hf_oran_bf,
9960 { "BeamForming", "oran_fh_cus.bf",
9961 FT_NONE, BASE_NONE,
9962 NULL((void*)0), 0x0,
9963 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9964 },
9965 { &hf_oran_zero_prb,
9966 { "Zero PRB", "oran_fh_cus.zero-prb",
9967 FT_NONE, BASE_NONE,
9968 NULL((void*)0), 0x0,
9969 "All of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9970 },
9971 { &hf_oran_nonzero_prb,
9972 { "Non-Zero PRB", "oran_fh_cus.nonzero-prb",
9973 FT_NONE, BASE_NONE,
9974 NULL((void*)0), 0x0,
9975 "Not all of the REs in this PRB are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9976 },
9977 { &hf_oran_bundle_weights_all_zero,
9978 { "Bundle Weights all zero", "oran_fh_cus.zero-bundle",
9979 FT_NONE, BASE_NONE,
9980 NULL((void*)0), 0x0,
9981 "All of the weights in a bundle are zero", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9982 },
9983
9984
9985 /* 5.1.3.2.7 */
9986 { &hf_oran_ecpri_pcid,
9987 { "ecpriPcid", "oran_fh_cus.ecpriPcid",
9988 FT_NONE, BASE_NONE,
9989 NULL((void*)0), 0x0,
9990 "IQ data transfer message series identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9991 },
9992 { &hf_oran_ecpri_rtcid,
9993 { "ecpriRtcid", "oran_fh_cus.ecpriRtcid",
9994 FT_NONE, BASE_NONE,
9995 NULL((void*)0), 0x0,
9996 "Real time control data identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
9997 },
9998 /* 5.1.3.2.8 */
9999 { &hf_oran_ecpri_seqid,
10000 { "ecpriSeqid", "oran_fh_cus.ecpriSeqid",
10001 FT_NONE, BASE_NONE,
10002 NULL((void*)0), 0x0,
10003 "message identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10004 },
10005
10006 /* 7.7.23.2 */
10007 { &hf_oran_num_sym_prb_pattern,
10008 { "numSymPrbPattern", "oran_fh_cus.numSymPrbPattern",
10009 FT_UINT8, BASE_DEC,
10010 NULL((void*)0), 0xf0,
10011 "number of symbol and resource block patterns", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10012 },
10013 /* 7.7.23.9 */
10014 { &hf_oran_prb_mode,
10015 { "prbMode", "oran_fh_cus.prbMode",
10016 FT_BOOLEAN, 8,
10017 TFS(&prb_mode_tfs)((0 ? (const struct true_false_string*)0 : ((&prb_mode_tfs
))))
, 0x01,
10018 "PRB Mode", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10019 },
10020 /* 7.7.23.4 */
10021 { &hf_oran_sym_prb_pattern,
10022 { "symPrbPattern", "oran_fh_cus.symPrbPattern",
10023 FT_STRING, BASE_NONE,
10024 NULL((void*)0), 0x0,
10025 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10026 },
10027 /* 7.7.23.3 */
10028 { &hf_oran_sym_mask,
10029 { "symMask", "oran_fh_cus.symMask",
10030 FT_UINT16, BASE_HEX,
10031 NULL((void*)0), 0x3fff,
10032 "symbol mask part of symPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10033 },
10034 /* 7.7.23.5 */
10035 {&hf_oran_num_mc_scale_offset,
10036 {"numMcScaleOffset", "oran_fh_cus.numMcScaleOffset",
10037 FT_UINT8, BASE_DEC,
10038 NULL((void*)0), 0xf0,
10039 "number of modulation compression scaling value per symPrbPattern",
10040 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10041 },
10042 /* 7.7.23.4 */
10043 { &hf_oran_prb_pattern,
10044 { "prbPattern", "oran_fh_cus.prbPattern",
10045 FT_UINT8, BASE_DEC,
10046 NULL((void*)0), 0x0f,
10047 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10048 },
10049 /* 7.7.23.10 */
10050 { &hf_oran_prb_blk_offset,
10051 { "prbBlkOffset", "oran_fh_cus.prbBlkOffset",
10052 FT_UINT16, BASE_DEC,
10053 NULL((void*)0), 0x0ff0,
10054 "offset to start of PRB block", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10055 },
10056
10057 /* 7.7.23.11 */
10058 { &hf_oran_prb_blk_size,
10059 { "prbBlkSize", "oran_fh_cus.prbBlkSize",
10060 FT_UINT16, BASE_DEC,
10061 NULL((void*)0), 0x0ff0,
10062 "size of one PRB block of one SymPrbPattern", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10063 },
10064
10065 /* 7.7.3.2 */
10066 { &hf_oran_codebook_index,
10067 { "codebookIndex", "oran_fh_cus.codebookIndex",
10068 FT_UINT8, BASE_DEC,
10069 NULL((void*)0), 0x0,
10070 "precoder codebook used for transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10071 },
10072 /* 7.7.3.3 */
10073 { &hf_oran_layerid,
10074 { "layerID", "oran_fh_cus.layerID",
10075 FT_UINT8, BASE_DEC,
10076 NULL((void*)0), 0xf0,
10077 "Layer ID for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10078 },
10079 /* 7.7.3.5 */
10080 { &hf_oran_numlayers,
10081 { "numLayers", "oran_fh_cus.numLayers",
10082 FT_UINT8, BASE_DEC,
10083 NULL((void*)0), 0x0f,
10084 "number of layers for DL transmission", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10085 },
10086 /* 7.7.3.4 */
10087 { &hf_oran_txscheme,
10088 { "txScheme", "oran_fh_cus.txScheme",
10089 FT_UINT8, BASE_DEC,
10090 NULL((void*)0), 0xf0,
10091 "transmission scheme", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10092 },
10093 /* 7.7.3.6 */
10094 { &hf_oran_crs_remask,
10095 { "crsReMask", "oran_fh_cus.crsReMask",
10096 FT_UINT16, BASE_HEX,
10097 NULL((void*)0), 0x0fff,
10098 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10099 },
10100 /* 7.7.3.8 */
10101 { &hf_oran_crs_shift,
10102 { "crsShift", "oran_fh_cus.crsShift",
10103 FT_UINT8, BASE_HEX,
10104 NULL((void*)0), 0x80,
10105 "CRS resource element mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10106 },
10107 /* 7.7.3.7 */
10108 { &hf_oran_crs_symnum,
10109 { "crsSymNum", "oran_fh_cus.crsSymNum",
10110 FT_UINT8, BASE_DEC,
10111 NULL((void*)0), 0x0f,
10112 "CRS symbol number indication", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10113 },
10114 /* 7.7.3.9 */
10115 { &hf_oran_beamid_ap1,
10116 { "beamIdAP1", "oran_fh_cus.beamIdAP1",
10117 FT_UINT16, BASE_DEC,
10118 NULL((void*)0), 0x7f,
10119 "beam id to be used for antenna port 1", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10120 },
10121 /* 7.7.3.10 */
10122 { &hf_oran_beamid_ap2,
10123 { "beamIdAP2", "oran_fh_cus.beamIdAP2",
10124 FT_UINT16, BASE_DEC,
10125 NULL((void*)0), 0x7f,
10126 "beam id to be used for antenna port 2", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10127 },
10128 /* 7.7.3.11 */
10129 { &hf_oran_beamid_ap3,
10130 { "beamIdAP3", "oran_fh_cus.beamIdAP3",
10131 FT_UINT16, BASE_DEC,
10132 NULL((void*)0), 0x7f,
10133 "beam id to be used for antenna port 3", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10134 },
10135
10136 /* 7.7.10.3a */
10137 { &hf_oran_port_list_index,
10138 { "portListIndex", "oran_fh_cus.portListIndex",
10139 FT_UINT8, BASE_DEC,
10140 NULL((void*)0), 0x0,
10141 "the index of an eAxC_ID in the port-list", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10142 },
10143
10144 { &hf_oran_alpn_per_sym,
10145 { "alpnPerSym", "oran_fh_cus.alpnPerSym",
10146 FT_UINT8, BASE_HEX,
10147 VALS(alpn_per_sym_vals)((0 ? (const struct _value_string*)0 : ((alpn_per_sym_vals)))
)
, 0x80,
10148 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10149 },
10150 { &hf_oran_ant_dmrs_snr,
10151 { "antDmrsSnr", "oran_fh_cus.antDmrsSnr",
10152 FT_UINT8, BASE_HEX,
10153 VALS(ant_dmrs_snr_vals)((0 ? (const struct _value_string*)0 : ((ant_dmrs_snr_vals)))
)
, 0x40,
10154 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10155 },
10156
10157 /* 7.7.24.6 */
10158 { &hf_oran_user_group_size,
10159 { "userGroupSize", "oran_fh_cus.userGroupSize",
10160 FT_UINT8, BASE_DEC,
10161 NULL((void*)0), 0x1f,
10162 "number of UE data layers in the user group identified by userGroupId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10163 },
10164 /* 7.7.24.7 */
10165 { &hf_oran_user_group_id,
10166 { "userGroupId", "oran_fh_cus.userGroupId",
10167 FT_UINT8, BASE_DEC,
10168 NULL((void*)0), 0x0,
10169 "indicates user group described by the section", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10170 },
10171 /* 7.7.24.8 */
10172 { &hf_oran_entry_type,
10173 { "entryType", "oran_fh_cus.entryType",
10174 FT_UINT8, BASE_DEC,
10175 VALS(entry_type_vals)((0 ? (const struct _value_string*)0 : ((entry_type_vals)))), 0xe0,
10176 "indicates format of the entry", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10177 },
10178 /* 7.7.24.9 */
10179 { &hf_oran_dmrs_port_number,
10180 { "dmrsPortNumber", "oran_fh_cus.dmrsPortNumber",
10181 FT_UINT8, BASE_DEC,
10182 NULL((void*)0), 0x1f,
10183 "DMRS antenna port number for the associated ueId", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10184 },
10185 /* 7.7.24.10 */
10186 { &hf_oran_ueid_reset,
10187 { "ueidReset", "oran_fh_cus.ueidReset",
10188 FT_BOOLEAN, 8,
10189 TFS(&tfs_ueid_reset)((0 ? (const struct true_false_string*)0 : ((&tfs_ueid_reset
))))
, 0x80,
10190 "same UEID as the previous slot", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10191 },
10192 /* 7.7.24.11 */
10193 { &hf_oran_dmrs_symbol_mask,
10194 { "dmrsSymbolMask", "oran_fh_cus.dmrsSymbolMask",
10195 FT_UINT16, BASE_HEX,
10196 NULL((void*)0), 0x3fff,
10197 "symbols within the slot containing DMRS", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10198 },
10199 { &hf_oran_dmrs_symbol_mask_s13,
10200 { "symbol 13", "oran_fh_cus.dmrsSymbolMask.symbol-13",
10201 FT_BOOLEAN, 16,
10202 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x2000,
10203 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10204 },
10205 { &hf_oran_dmrs_symbol_mask_s12,
10206 { "symbol 12", "oran_fh_cus.dmrsSymbolMask.symbol-12",
10207 FT_BOOLEAN, 16,
10208 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x1000,
10209 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10210 },
10211 { &hf_oran_dmrs_symbol_mask_s11,
10212 { "symbol 11", "oran_fh_cus.dmrsSymbolMask.symbol-11",
10213 FT_BOOLEAN, 16,
10214 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0800,
10215 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10216 },
10217 { &hf_oran_dmrs_symbol_mask_s10,
10218 { "symbol 10", "oran_fh_cus.dmrsSymbolMask.symbol-10",
10219 FT_BOOLEAN, 16,
10220 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0400,
10221 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10222 },
10223 { &hf_oran_dmrs_symbol_mask_s9,
10224 { "symbol 9", "oran_fh_cus.dmrsSymbolMask.symbol-9",
10225 FT_BOOLEAN, 16,
10226 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0200,
10227 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10228 },
10229 { &hf_oran_dmrs_symbol_mask_s8,
10230 { "symbol 8", "oran_fh_cus.dmrsSymbolMask.symbol-8",
10231 FT_BOOLEAN, 16,
10232 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0100,
10233 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10234 },
10235 { &hf_oran_dmrs_symbol_mask_s7,
10236 { "symbol 7", "oran_fh_cus.dmrsSymbolMask.symbol-7",
10237 FT_BOOLEAN, 16,
10238 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0080,
10239 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10240 },
10241 { &hf_oran_dmrs_symbol_mask_s6,
10242 { "symbol 6", "oran_fh_cus.dmrsSymbolMask.symbol-6",
10243 FT_BOOLEAN, 16,
10244 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0040,
10245 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10246 },
10247 { &hf_oran_dmrs_symbol_mask_s5,
10248 { "symbol 5", "oran_fh_cus.dmrsSymbolMask.symbol-5",
10249 FT_BOOLEAN, 16,
10250 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0020,
10251 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10252 },
10253 { &hf_oran_dmrs_symbol_mask_s4,
10254 { "symbol 4", "oran_fh_cus.dmrsSymbolMask.symbol-4",
10255 FT_BOOLEAN, 16,
10256 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0010,
10257 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10258 },
10259 { &hf_oran_dmrs_symbol_mask_s3,
10260 { "symbol 3", "oran_fh_cus.dmrsSymbolMask.symbol-3",
10261 FT_BOOLEAN, 16,
10262 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0008,
10263 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10264 },
10265 { &hf_oran_dmrs_symbol_mask_s2,
10266 { "symbol 2", "oran_fh_cus.dmrsSymbolMask.symbol-2",
10267 FT_BOOLEAN, 16,
10268 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0004,
10269 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10270 },
10271 { &hf_oran_dmrs_symbol_mask_s1,
10272 { "symbol 1", "oran_fh_cus.dmrsSymbolMask.symbol-1",
10273 FT_BOOLEAN, 16,
10274 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0002,
10275 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10276 },
10277 { &hf_oran_dmrs_symbol_mask_s0,
10278 { "symbol 0", "oran_fh_cus.dmrsSymbolMask.symbol-0",
10279 FT_BOOLEAN, 16,
10280 TFS(&tfs_present_not_present)((0 ? (const struct true_false_string*)0 : ((&tfs_present_not_present
))))
, 0x0001,
10281 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10282 },
10283
10284 /* 7.7.24.12 */
10285 { &hf_oran_scrambling,
10286 { "scrambling", "oran_fh_cus.scrambling",
10287 FT_UINT16, BASE_HEX,
10288 NULL((void*)0), 0x0,
10289 "used to calculate the seed value required to initialize pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10290 },
10291 /* 7.7.24.13 */
10292 { &hf_oran_nscid,
10293 { "nscid", "oran_fh_cus.nscid",
10294 FT_UINT8, BASE_HEX,
10295 NULL((void*)0), 0x80,
10296 "used to calculate the seed value for pseudo-random generator", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10297 },
10298 /* 7.7.24.14 */
10299 { &hf_oran_dtype,
10300 { "dType", "oran_fh_cus.dType",
10301 FT_UINT8, BASE_HEX,
10302 VALS(dtype_vals)((0 ? (const struct _value_string*)0 : ((dtype_vals)))), 0x40,
10303 "PUSCH DMRS configuration type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10304 },
10305 /* 7.7.24.15 */
10306 { &hf_oran_cmd_without_data,
10307 { "cmdWithoutData", "oran_fh_cus.cmdWithoutData",
10308 FT_UINT8, BASE_HEX,
10309 NULL((void*)0), 0x30,
10310 "number of DMRS CDM groups without data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10311 },
10312 /* 7.7.24.16 */
10313 { &hf_oran_lambda,
10314 { "lambda", "oran_fh_cus.lambda",
10315 FT_UINT8, BASE_HEX,
10316 NULL((void*)0), 0x0c,
10317 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10318 },
10319 /* 7.7.24.19 */
10320 { &hf_oran_first_prb,
10321 { "firstPrb", "oran_fh_cus.firstPrb",
10322 FT_UINT16, BASE_DEC,
10323 NULL((void*)0), 0x03fe,
10324 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10325 },
10326 /* 7.7.24.20 */
10327 { &hf_oran_last_prb,
10328 { "lastPrb", "oran_fh_cus.lastPrb",
10329 FT_UINT16, BASE_DEC,
10330 NULL((void*)0), 0x01ff,
10331 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10332 },
10333
10334 /* 7.7.24.17 */
10335 /* TODO: add value_string */
10336 { &hf_oran_low_papr_type,
10337 { "lowPaprType", "oran_fh_cus.lowPaprType",
10338 FT_UINT8, BASE_HEX,
10339 VALS(papr_type_vals)((0 ? (const struct _value_string*)0 : ((papr_type_vals)))), 0x30,
10340 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10341 },
10342 /* 7.7.24.18 */
10343 { &hf_oran_hopping_mode,
10344 { "hoppingMode", "oran_fh_cus.hoppingMode",
10345 FT_UINT8, BASE_HEX,
10346 VALS(hopping_mode_vals)((0 ? (const struct _value_string*)0 : ((hopping_mode_vals)))
)
, 0x0c,
10347 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10348 },
10349
10350 { &hf_oran_tx_win_for_on_air_symbol_l,
10351 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10352 FT_UINT8, BASE_DEC,
10353 NULL((void*)0), 0xf0,
10354 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10355 },
10356 { &hf_oran_tx_win_for_on_air_symbol_r,
10357 { "txWinForOnAirSymbol", "oran_fh_cus.txWinForOnAirSymbol",
10358 FT_UINT8, BASE_DEC,
10359 NULL((void*)0), 0x0f,
10360 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10361 },
10362 /* 7.7.26.2 */
10363 { &hf_oran_num_fo_fb,
10364 { "numFoFb", "oran_fh_cus.numFoFb",
10365 FT_UINT8, BASE_DEC,
10366 NULL((void*)0), 0x7f,
10367 "number of frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10368 },
10369 /* 7.7.26.3 */
10370 { &hf_oran_freq_offset_fb,
10371 { "freqOffsetFb", "oran_fh_cus.freqOffsetFb",
10372 FT_UINT16, BASE_HEX_DEC | BASE_RANGE_STRING0x00000100,
10373 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10374 "UE frequency offset feedback", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10375 },
10376
10377 /* 7.7.28.2 */
10378 { &hf_oran_num_ue_sinr_rpt,
10379 { "numUeSinrRpt", "oran_fh_cus.numUeSinrRpt",
10380 FT_UINT8, BASE_DEC,
10381 NULL((void*)0), 0x1f,
10382 "number of sinr reported UEs {1 - 12}", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10383 },
10384
10385 /* 7.5.2.19 */
10386 { &hf_oran_num_sinr_per_prb,
10387 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10388 FT_UINT8, BASE_DEC,
10389 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x70,
10390 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10391 },
10392 { &hf_oran_num_sinr_per_prb_right,
10393 { "numSinrPerPrb", "oran_fh_cus.numSinrPerPrb",
10394 FT_UINT8, BASE_DEC,
10395 VALS(num_sinr_per_prb_vals)((0 ? (const struct _value_string*)0 : ((num_sinr_per_prb_vals
))))
, 0x07,
10396 "number of SINR values per PRB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10397 },
10398
10399 /* 7.5.3.68 */
10400 { &hf_oran_sinr_value,
10401 { "sinrValue", "oran_fh_cus.sinrValue",
10402 FT_FLOAT, BASE_NONE,
10403 NULL((void*)0), 0x0,
10404 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10405 },
10406
10407 { &hf_oran_measurement_report,
10408 { "Measurement Report", "oran_fh_cus.measurement-report",
10409 FT_STRING, BASE_NONE,
10410 NULL((void*)0), 0x0,
10411 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10412 },
10413 /* 7.5.3.57 */
10414 { &hf_oran_mf,
10415 { "mf", "oran_fh_cus.mf",
10416 FT_BOOLEAN, 8,
10417 TFS(&measurement_flag_tfs)((0 ? (const struct true_false_string*)0 : ((&measurement_flag_tfs
))))
, 0x80,
10418 "measurement flag", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10419 },
10420 /* 7.5.3.59 */
10421 { &hf_oran_meas_data_size,
10422 { "measDataSize", "oran_fh_cus.measDataSize",
10423 FT_UINT16, BASE_DEC,
10424 NULL((void*)0), 0x0,
10425 "measurement data size (in words)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10426 },
10427
10428 /* 7.5.3.58 */
10429 { &hf_oran_meas_type_id,
10430 { "measTypeId", "oran_fh_cus.measTypeId",
10431 FT_UINT8, BASE_DEC,
10432 VALS(meas_type_id_vals)((0 ? (const struct _value_string*)0 : ((meas_type_id_vals)))
)
, 0x7F,
10433 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10434 },
10435 /* 7.5.3.66 */
10436 { &hf_oran_num_elements,
10437 { "numElements", "oran_fh_cus.numElements",
10438 FT_UINT8, BASE_DEC,
10439 NULL((void*)0), 0x0,
10440 "measurement report type identifier", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10441 },
10442 /* 7.5.3.60 */
10443 { &hf_oran_ue_tae,
10444 { "ueTae", "oran_fh_cus.ueTae",
10445 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10446 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10447 "UE Timing Advance Error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10448 },
10449 /* 7.5.3.61 */
10450 { &hf_oran_ue_layer_power,
10451 { "ueLayerPower", "oran_fh_cus.ueLayerPower",
10452 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10453 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10454 "UE Layer Power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10455 },
10456
10457 /* 7.5.3.62 */
10458 { &hf_oran_ue_freq_offset,
10459 { "ueFreqOffset", "oran_fh_cus.ueFreqOffset",
10460 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10461 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10462 "UE frequency offset", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10463 },
10464 /* 7.5.3.63 */
10465 { &hf_oran_ipn_power,
10466 { "ipnPower", "oran_fh_cus.ipnPower",
10467 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10468 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10469 "Interference plus Noise power", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10470 },
10471 /* 7.5.3.64 */
10472 { &hf_oran_ant_dmrs_snr_val,
10473 { "antDmrsSnrVal", "oran_fh_cus.antDmrsSnrVal",
10474 FT_UINT16, BASE_DEC | BASE_RANGE_STRING0x00000100,
10475 RVALS(freq_offset_fb_values)((0 ? (const struct _range_string*)0 : ((freq_offset_fb_values
))))
, 0x0,
10476 "antenna DMRS-SNR", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10477 },
10478
10479 { &hf_oran_measurement_command,
10480 { "Measurement Command", "oran_fh_cus.measurement-command",
10481 FT_STRING, BASE_NONE,
10482 NULL((void*)0), 0x0,
10483 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10484 },
10485
10486 /* 7.5.27.2 */
10487 { &hf_oran_beam_type,
10488 {"beamType", "oran_fh_cus.beamType",
10489 FT_UINT16, BASE_DEC,
10490 VALS(beam_type_vals)((0 ? (const struct _value_string*)0 : ((beam_type_vals)))), 0xc0,
10491 NULL((void*)0),
10492 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10493 },
10494 /* 7.5.3.65 */
10495 { &hf_oran_meas_cmd_size,
10496 {"measCmdSize", "oran_fh_cus.measCmdSize",
10497 FT_UINT16, BASE_DEC,
10498 NULL((void*)0), 0x0,
10499 "measurement command size in words",
10500 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10501 },
10502
10503 { &hf_oran_symbol_reordering_layer,
10504 { "Layer", "oran_fh_cus.layer",
10505 FT_STRING, BASE_NONE,
10506 NULL((void*)0), 0x0,
10507 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10508 },
10509 { &hf_oran_dmrs_entry,
10510 { "Entry", "oran_fh_cus.dmrs-entry",
10511 FT_STRING, BASE_NONE,
10512 NULL((void*)0), 0x0,
10513 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10514 },
10515
10516 /* 7.7.29.3 */
10517 { &hf_oran_cd_scg_size,
10518 {"cdScgSize", "oran_fh_cus.cdScgSize",
10519 FT_UINT8, BASE_DEC | BASE_RANGE_STRING0x00000100,
10520 RVALS(cd_scg_size_vals)((0 ? (const struct _range_string*)0 : ((cd_scg_size_vals)))), 0x0f,
10521 "Cyclic delay subcarrier group size",
10522 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10523 },
10524 /* 7.7.29.4 */
10525 { &hf_oran_cd_scg_phase_step,
10526 {"cdScgPhaseStep", "oran_fh_cus.cdScgPhaseStep",
10527 FT_INT8, BASE_DEC,
10528 NULL((void*)0), 0x0,
10529 "Cyclic delay subcarrier group phase step",
10530 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10531 },
10532
10533 { &hf_oran_sinr_prb,
10534 { "PRB", "oran_fh_cus.sinr.prb",
10535 FT_STRING, BASE_NONE,
10536 NULL((void*)0), 0x0,
10537 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10538 },
10539 /* 7.5.2.20 */
10540 { &hf_oran_oru_control_sinr_slot_mask_id,
10541 {"oruControlSinrSlotMaskId", "oran_fh_cus.oruControlSinrSlotMaskId",
10542 FT_UINT8, BASE_DEC,
10543 NULL((void*)0), 0x1f,
10544 "SINR time resolution",
10545 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10546 },
10547 /* 7.7.24.21 */
10548 { &hf_oran_pos_meas,
10549 {"posMeas", "oran_fh_cus.posMeas",
10550 FT_BOOLEAN, 8,
10551 TFS(&tfs_report_no_report_pos_meas)((0 ? (const struct true_false_string*)0 : ((&tfs_report_no_report_pos_meas
))))
, 0x40,
10552 "Positioning measurement report request",
10553 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10554 },
10555
10556 /* 7.5.3.69 */
10557 { &hf_oran_ue_radial_speed,
10558 {"ueRadialSpeed", "oran_fh_cus.ueRadialSpeed",
10559 FT_UINT16, BASE_DEC,
10560 NULL((void*)0), 0x0,
10561 "UE radial speed",
10562 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10563 },
10564 /* 7.5.3.70 */
10565 { &hf_oran_ue_az_aoa,
10566 {"ueAzAoa", "oran_fh_cus.ueAzAoa",
10567 FT_UINT16, BASE_DEC,
10568 NULL((void*)0), 0x0,
10569 "UE azimuth angle of arrival",
10570 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10571 },
10572 /* 7.5.3.71 */
10573 { &hf_oran_ue_ze_aoa,
10574 {"ueZeAoa", "oran_fh_cus.ueZeAoa",
10575 FT_UINT16, BASE_DEC,
10576 NULL((void*)0), 0x0,
10577 "UE zenith angle of arrival",
10578 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10579 },
10580 /* 7.5.3.72 */
10581 { &hf_oran_ue_pos_toa_offset,
10582 {"uePosToaOffset", "oran_fh_cus.uePosToaOffset",
10583 FT_UINT16, BASE_DEC,
10584 NULL((void*)0), 0x0,
10585 "UE positioning time of arrival offset",
10586 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10587 },
10588
10589 /* 7.7.30.2 */
10590 { &hf_oran_num_rep_ue,
10591 {"numRepUe", "oran_fh_cus.numRepUe",
10592 FT_UINT8, BASE_DEC,
10593 NULL((void*)0), 0x0f,
10594 "Number of UEs with PUSCH repetition",
10595 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10596 },
10597 /* 7.7.30.3 */
10598 { &hf_oran_rep_ueid,
10599 {"repUeId", "oran_fh_cus.repUeId",
10600 FT_UINT16, BASE_DEC,
10601 NULL((void*)0), 0x7fff,
10602 "UEId the PUSCH is part of",
10603 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10604 },
10605 /* 7.7.30.4 */
10606 { &hf_oran_is_last_rep,
10607 {"isLastRep", "oran_fh_cus.isLastRep",
10608 FT_BOOLEAN, 8,
10609 NULL((void*)0), 0x40,
10610 "Last transmission in the repetition",
10611 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10612 },
10613 /* 7.7.30.5 */
10614 { &hf_oran_rep_index,
10615 {"repIndex", "oran_fh_cus.repIndex",
10616 FT_UINT8, BASE_DEC,
10617 NULL((void*)0), 0x3f,
10618 "Repetition index of the PUSCH transmission",
10619 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10620 },
10621 /* 7.7.30.6 */
10622 { &hf_oran_num_reps,
10623 {"numReps", "oran_fh_cus.numReps",
10624 FT_UINT8, BASE_DEC,
10625 NULL((void*)0), 0x3f,
10626 "The number of total PUSCH repetitions",
10627 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10628 },
10629
10630 /* 7.7.31.2 */
10631 { &hf_oran_mcs_table,
10632 {"mcsTable", "oran_fh_cus.mcsTable",
10633 FT_UINT8, BASE_DEC,
10634 VALS(mcs_table_vals)((0 ? (const struct _value_string*)0 : ((mcs_table_vals)))), 0x0f,
10635 "MCS index table",
10636 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10637 },
10638 /* 7.7.31.3 */
10639 { &hf_oran_mcs_index,
10640 {"mcsIndex", "oran_fh_cus.mcsIndex",
10641 FT_UINT8, BASE_DEC,
10642 NULL((void*)0), 0x3f,
10643 "MCS index value",
10644 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10645 },
10646
10647 /* 7.7.33.3 */
10648 { &hf_oran_num_meas_req,
10649 {"numMeasReq", "oran_fh_cus.numMeasReq",
10650 FT_UINT8, BASE_DEC,
10651 NULL((void*)0), 0x1f,
10652 "Number of UEs for which meas is requested",
10653 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10654 },
10655 /* 7.7.32.5 */
10656 { &hf_oran_ue_rank,
10657 {"ueRank", "oran_fh_cus.ueRank",
10658 FT_UINT8, BASE_DEC,
10659 VALS(ue_rank_vals)((0 ? (const struct _value_string*)0 : ((ue_rank_vals)))), 0x0f,
10660 "Number of UE layers under evaluation",
10661 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10662 },
10663 /* 7.7.32.6 */
10664 { &hf_oran_num_of_ue_ant_ports,
10665 {"numOfUeAntPorts", "oran_fh_cus.numofUeAntPorts",
10666 FT_UINT8, BASE_DEC,
10667 VALS(num_of_ue_ant_ports_vals)((0 ? (const struct _value_string*)0 : ((num_of_ue_ant_ports_vals
))))
, 0xf0,
10668 "Used for the PUSCH tx under evaluation",
10669 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10670 },
10671 /* 7.7.32.8 */
10672 { &hf_oran_codebook_subset,
10673 {"codebookSubset", "oran_fh_cus.codebookSubset",
10674 FT_UINT8, BASE_DEC,
10675 VALS(codebook_subset_vals)((0 ? (const struct _value_string*)0 : ((codebook_subset_vals
))))
, 0xc0,
10676 "UE capability wrt ULTPMI sets",
10677 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10678 },
10679 /* 7.7.32.9 */
10680 { &hf_oran_full_pwr_mode,
10681 {"fullPwrMode", "oran_fh_cus.fullPwrMode",
10682 FT_UINT8, BASE_DEC,
10683 VALS(full_pwr_mode_vals)((0 ? (const struct _value_string*)0 : ((full_pwr_mode_vals))
))
, 0xc0,
10684 "Transmission mode",
10685 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10686 },
10687 /* 7.7.32.10 */
10688 { &hf_oran_full_pwr_mode_2_tpmi_group,
10689 {"fullPwrMode2TpmiGroup", "oran_fh_cus.fullPwrMode2TpmiGroup",
10690 FT_UINT16, BASE_HEX,
10691 NULL((void*)0), 0x3fff,
10692 "Capabilities",
10693 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10694 },
10695
10696 /* 7.5.3.75 */
10697 { &hf_oran_num_cand_ranks,
10698 {"numCandRanks", "oran_fh_cus.numCandRanks",
10699 FT_UINT8, BASE_DEC,
10700 NULL((void*)0), 0xf0,
10701 NULL((void*)0),
10702 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10703 },
10704 /* 7.5.3.76 */
10705 { &hf_oran_ue_pref_rank,
10706 {"uePrefRank", "oran_fh_cus.uePrefRank",
10707 FT_UINT8, BASE_DEC,
10708 NULL((void*)0), 0x0f,
10709 "Most optimal UL Tx rank for UE",
10710 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10711 },
10712 /* 7.5.3.77 */
10713 { &hf_oran_ue_tpmi_rank_y,
10714 {"ueTpmiRankY", "oran_fh_cus.ueTpmiRankY",
10715 FT_UINT8, BASE_DEC,
10716 NULL((void*)0), 0x0,
10717 "TPMI index for codebook-based PUSCH tx",
10718 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10719 },
10720 /* 7.5.3.78 */
10721 { &hf_oran_ue_tpmi_rank_y_sinr_lx,
10722 {"ueTpmiRankYSinrLX", "oran_fh_cus.ueTpmiRankYSinrLX",
10723 FT_UINT16, BASE_HEX | BASE_RANGE_STRING0x00000100,
10724 RVALS(ue_tmpi_rank_sinr_vals)((0 ? (const struct _range_string*)0 : ((ue_tmpi_rank_sinr_vals
))))
, 0x0,
10725 "Estimation of post-equalization SINR",
10726 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10727 },
10728 /* 7.5.3.79 */
10729 { &hf_oran_ue_layer_pre_eq_sinr,
10730 {"ueLayerPreEqSinr", "oran_fh_cus.ueLayerPreEqSinr",
10731 FT_UINT16, BASE_HEX,
10732 NULL((void*)0), 0x0,
10733 "Pre-equalization SINR of a UE layer",
10734 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10735 },
10736
10737 { &hf_oran_c_section_common,
10738 { "Common Section", "oran_fh_cus.c-plane.section.common",
10739 FT_STRING, BASE_NONE,
10740 NULL((void*)0), 0x0,
10741 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10742 },
10743 { &hf_oran_c_section,
10744 { "Section", "oran_fh_cus.c-plane.section",
10745 FT_STRING, BASE_NONE,
10746 NULL((void*)0), 0x0,
10747 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10748 },
10749 { &hf_oran_u_section,
10750 { "Section", "oran_fh_cus.u-plane.section",
10751 FT_STRING, BASE_NONE,
10752 NULL((void*)0), 0x0,
10753 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10754 },
10755
10756 /* Link back to UL C-plane where udCompHdr was recorded */
10757 { &hf_oran_ul_cplane_ud_comp_hdr_frame,
10758 { "C-Plane UL udCompHdr frame", "oran_fh_cus.ul-cplane.udCompHdr",
10759 FT_FRAMENUM, BASE_NONE,
10760 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0,
10761 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10762 },
10763
10764 /* For ext11, where was a beamId (last) defined? */
10765 { &hf_oran_bfws_frame_defined,
10766 { "Beam defined in frame", "oran_fh_cus.bfw-defined",
10767 FT_FRAMENUM, BASE_NONE,
10768 FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV)((gpointer) (glong) (FT_FRAMENUM_RETRANS_PREV)), 0x0,
10769 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10770 },
10771 { &hf_oran_bfws_symbols_since_defined,
10772 { "Symbols since BFWs defined", "oran_fh_cus.symbols-since-bfw-defined",
10773 FT_UINT32, BASE_DEC,
10774 NULL((void*)0), 0x0,
10775 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10776 },
10777
10778 /* Corresponding C-plane frame for DL U-plane */
10779 { &hf_oran_corresponding_cplane_frame,
10780 { "C-plane frame", "oran_fh_cus.cplane-frame",
10781 FT_FRAMENUM, BASE_NONE,
10782 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST)((gpointer) (glong) (FT_FRAMENUM_REQUEST)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10783 },
10784 /* Time since corresponding C-plane frame for U-plane */
10785 { &hf_oran_corresponding_cplane_frame_time_delta,
10786 { "Time since C-plane frame", "oran_fh_cus.cplane-frame-time-delta",
10787 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10788 "Microseconds since C-plane frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10789 },
10790 /* Corresponding U-plane frame for C-plane */
10791 { &hf_oran_corresponding_uplane_frame,
10792 { "U-plane frame", "oran_fh_cus.uplane-frame",
10793 FT_FRAMENUM, BASE_NONE,
10794 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE)((gpointer) (glong) (FT_FRAMENUM_RESPONSE)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10795 },
10796 { &hf_oran_corresponding_uplane_frames_total,
10797 { "U-plane frames total", "oran_fh_cus.u-plane-frames-total",
10798 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
10799 "Number of corresponding U-plane frames", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}
10800 },
10801
10802 /* Reassembly */
10803 { &hf_oran_fragment,
10804 { "Fragment", "oran_fh_cus.fragment", FT_FRAMENUM, BASE_NONE,
10805 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10806 { &hf_oran_fragments,
10807 { "Fragments", "oran_fh_cus.fragments", FT_BYTES, BASE_NONE,
10808 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10809 { &hf_oran_fragment_overlap,
10810 { "Fragment overlap", "oran_fh_cus.fragment.overlap", FT_BOOLEAN, BASE_NONE,
10811 NULL((void*)0), 0x0, "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10812 { &hf_oran_fragment_overlap_conflict,
10813 { "Conflicting data in fragment overlap", "oran_fh_cus.fragment.overlap.conflict",
10814 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10815 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10816 { &hf_oran_fragment_multiple_tails,
10817 { "Multiple tail fragments found", "oran_fh_cus.fragment.multipletails",
10818 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10819 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10820 { &hf_oran_fragment_too_long_fragment,
10821 { "Fragment too long", "oran_fh_cus.fragment.toolongfragment",
10822 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
10823 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10824 { &hf_oran_fragment_error,
10825 { "Defragmentation error", "oran_fh_cus.fragment.error", FT_FRAMENUM, BASE_NONE,
10826 NULL((void*)0), 0x0, "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10827 { &hf_oran_fragment_count,
10828 { "Fragment count", "oran_fh_cus.fragment.count", FT_UINT32, BASE_DEC,
10829 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10830 { &hf_oran_reassembled_in,
10831 { "Reassembled payload in frame", "oran_fh_cus.reassembled_in", FT_FRAMENUM, BASE_NONE,
10832 NULL((void*)0), 0x0, "This payload packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10833 { &hf_oran_reassembled_length,
10834 { "Reassembled payload length", "oran_fh_cus.reassembled.length", FT_UINT32, BASE_DEC,
10835 NULL((void*)0), 0x0, "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10836 { &hf_oran_reassembled_data,
10837 { "Reassembled data", "oran_fh_cus.reassembled.data", FT_BYTES, BASE_NONE,
10838 NULL((void*)0), 0x0, "The reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10839
10840 { &hf_oran_payload,
10841 { "Payload", "oran_fh_cus.payload", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE0x00010000,
10842 NULL((void*)0), 0x0, "Complete or reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
10843 };
10844
10845 /* Setup protocol subtree array */
10846 static int *ett[] = {
10847 &ett_oran,
10848 &ett_oran_ecpri_pcid,
10849 &ett_oran_ecpri_rtcid,
10850 &ett_oran_ecpri_seqid,
10851 &ett_oran_section_type,
10852 &ett_oran_u_timing,
10853 &ett_oran_u_section,
10854 &ett_oran_u_prb,
10855 &ett_oran_section,
10856 &ett_oran_iq,
10857 &ett_oran_bfw_bundle,
10858 &ett_oran_bfw,
10859 &ett_oran_frequency_range,
10860 &ett_oran_prb_cisamples,
10861 &ett_oran_cisample,
10862 &ett_oran_udcomphdr,
10863 &ett_oran_udcompparam,
10864 &ett_oran_cicomphdr,
10865 &ett_oran_cicompparam,
10866 &ett_oran_bfwcomphdr,
10867 &ett_oran_bfwcompparam,
10868 &ett_oran_ext19_port,
10869 &ett_oran_prb_allocation,
10870 &ett_oran_punc_pattern,
10871 &ett_oran_bfacomphdr,
10872 &ett_oran_modcomp_param_set,
10873 &ett_oran_st4_cmd_header,
10874 &ett_oran_st4_cmd,
10875 &ett_oran_sym_prb_pattern,
10876 &ett_oran_measurement_report,
10877 &ett_oran_measurement_command,
10878 &ett_oran_sresmask,
10879 &ett_oran_c_section_common,
10880 &ett_oran_c_section,
10881 &ett_oran_remask,
10882 &ett_oran_mc_scale_remask,
10883 &ett_oran_symbol_reordering_layer,
10884 &ett_oran_dmrs_entry,
10885 &ett_oran_dmrs_symbol_mask,
10886 &ett_oran_symbol_mask,
10887 &ett_oran_active_beamspace_coefficient_mask,
10888 &ett_oran_sinr_prb,
10889
10890 &ett_oran_fragment,
10891 &ett_oran_fragments
10892 };
10893
10894 /* Separate subtree array for extensions. Used with [ext-1] */
10895 static int *ext_ett[HIGHEST_EXTTYPE32];
10896 for (unsigned extno=0; extno<HIGHEST_EXTTYPE32; extno++) {
10897 ext_ett[extno] = &ett_oran_c_section_extension[extno];
10898 }
10899
10900 expert_module_t* expert_oran;
10901
10902 static ei_register_info ei[] = {
10903 { &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)}}
}},
10904 { &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)}}
}},
10905 { &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)}}
}},
10906 { &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)}}
}},
10907 { &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)}}
}},
10908 { &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)}}
}},
10909 { &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)}}
}},
10910 { &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)}}
}},
10911 { &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)}}
}},
10912 { &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)}}
}},
10913 { &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)}}
}},
10914 { &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)}}
}},
10915 { &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)}}
}},
10916 { &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)}}
}},
10917 { &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)}}
}},
10918 { &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)}}
}},
10919 { &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)}}
}},
10920 { &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)}}
}},
10921 { &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)}}
}},
10922 { &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)}}
}},
10923 { &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)}}
}},
10924 { &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)}}
}},
10925 { &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)}}
}},
10926 { &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)}}
}},
10927 { &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)}}
}},
10928 { &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)}}
}},
10929 { &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)}}
}},
10930 { &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)}}
}},
10931 { &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)}}
}},
10932 { &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)}}
}},
10933 { &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)}}
}},
10934 { &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)}}
}},
10935 { &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)}}
}},
10936 { &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)}}
}},
10937 { &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)}}
}},
10938 { &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)}}
}},
10939 { &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)}}
}},
10940 { &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)}}
}},
10941 { &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)}}
}},
10942 { &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)}}
}},
10943 { &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)}}
}},
10944 { &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)}}
}},
10945 { &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)}}
}},
10946 { &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)}}
}},
10947 { &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)}}
}},
10948 { &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)}}
}},
10949 { &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)}}
}},
10950 { &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)}}
}},
10951 { &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)}}
}},
10952 { &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)}}
}},
10953 { &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)}}
}},
10954 { &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)}}
}},
10955 { &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)}}
}},
10956 { &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)}}
}},
10957 { &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)}}
}},
10958 { &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)}}
}},
10959 { &ei_oran_cplane_entry_not_found, { "oran_fh_cus.cplane_entry_not_found", PI_SEQUENCE0x02000000, PI_WARN0x00600000, "C-plane for this U-plane section not found", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10960 };
10961
10962
10963 /* Register the protocol name and description */
10964 proto_oran = proto_register_protocol("O-RAN Fronthaul CUS", "O-RAN FH CUS", "oran_fh_cus");
10965
10966 /* Allow dissector to find be found by name. */
10967 register_dissector("oran_fh_cus", dissect_oran, proto_oran);
10968
10969 /* Register the tap name. */
10970 oran_tap = register_tap("oran-fh-cus");
10971
10972 /* Required function calls to register the header fields and subtrees */
10973 proto_register_field_array(proto_oran, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
10974 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
10975 proto_register_subtree_array(ext_ett, array_length(ext_ett)(sizeof (ext_ett) / sizeof (ext_ett)[0]));
10976
10977 expert_oran = expert_register_protocol(proto_oran);
10978 expert_register_field_array(expert_oran, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10979
10980
10981 /* Preferences */
10982 module_t * oran_module = prefs_register_protocol(proto_oran, NULL((void*)0));
10983
10984 /* Register bit width/compression preferences separately by direction. */
10985 prefs_register_uint_preference(oran_module, "oran.du_port_id_bits", "DU Port ID bits [a]",
10986 "The bit width of DU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_du_port_id_bits);
10987 prefs_register_uint_preference(oran_module, "oran.bandsector_id_bits", "BandSector ID bits [b]",
10988 "The bit width of BandSector ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_bandsector_id_bits);
10989 prefs_register_uint_preference(oran_module, "oran.cc_id_bits", "CC ID bits [c]",
10990 "The bit width of CC ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_cc_id_bits);
10991 prefs_register_uint_preference(oran_module, "oran.ru_port_id_bits", "RU Port ID bits [d]",
10992 "The bit width of RU Port ID - sum of a,b,c&d (eAxC) must be 16", 10, &pref_ru_port_id_bits);
10993
10994 /* Uplink userplane */
10995 prefs_register_static_text_preference(oran_module, "oran.ul", "", "");
10996 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_up", "IQ Bitwidth Uplink",
10997 "The bit width of a sample in the Uplink (if no udcompHdr and no C-Plane)", 10, &pref_sample_bit_width_uplink);
10998 prefs_register_enum_preference(oran_module, "oran.ud_comp_up", "Uplink User Data Compression",
10999 "Uplink User Data Compression (if no udcompHdr and no C-Plane)", &pref_iqCompressionUplink, ul_compression_options, false0);
11000 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_up", "udCompHdr field is present for uplink",
11001 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
11002 "configuration of the O-RU. This preference instructs the dissector to expect "
11003 "this field to be present in uplink messages",
11004 &pref_includeUdCompHeaderUplink, udcomphdr_present_options, false0);
11005 prefs_register_bool_preference(oran_module, "oran.ignore_cplane_ul_udcomphdr", "Ignore UL compression settings from C-plane",
11006 "When set, override udCompHdr from UL C-Plane with compression method and width configured here", &pref_override_ul_compression);
11007 prefs_register_uint_preference(oran_module, "oran.ul_slot_us_limit", "Microseconds allowed for UL tx in symbol",
11008 "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",
11009 10, &us_allowed_for_ul_in_symbol);
11010
11011 /* Downlink userplane */
11012 prefs_register_static_text_preference(oran_module, "oran.dl", "", "");
11013 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_down", "IQ Bitwidth Downlink",
11014 "The bit width of a sample in the Downlink (if no udcompHdr)", 10, &pref_sample_bit_width_downlink);
11015 prefs_register_enum_preference(oran_module, "oran.ud_comp_down", "Downlink User Data Compression",
11016 "Downlink User Data Compression", &pref_iqCompressionDownlink, dl_compression_options, false0);
11017 prefs_register_enum_preference(oran_module, "oran.ud_comp_hdr_down", "udCompHdr field is present for downlink",
11018 "The udCompHdr field in U-Plane messages may or may not be present, depending on the "
11019 "configuration of the O-RU. This preference instructs the dissector to expect "
11020 "this field to be present in downlink messages",
11021 &pref_includeUdCompHeaderDownlink, udcomphdr_present_options, false0);
11022
11023 /* SINR */
11024 prefs_register_static_text_preference(oran_module, "oran.sinr", "", "");
11025 prefs_register_uint_preference(oran_module, "oran.iq_bitwidth_sinr", "IQ Bitwidth SINR",
11026 "The bit width of a sample in SINR", 10, &pref_sample_bit_width_sinr);
11027 prefs_register_enum_preference(oran_module, "oran.ud_comp_sinr", "SINR Compression",
11028 "SINR Compression", &pref_iqCompressionSINR, ul_compression_options, false0);
11029
11030 /* BF-related */
11031 prefs_register_static_text_preference(oran_module, "oran.bf", "", "");
11032 prefs_register_uint_preference(oran_module, "oran.num_bf_antennas", "Number of beam weights",
11033 "Number of array elements that BF weights will be provided for", 10, &pref_num_bf_antennas);
11034 prefs_register_obsolete_preference(oran_module, "oran.num_weights_per_bundle");
11035 prefs_register_obsolete_preference(oran_module, "oran.num_bf_weights");
11036 prefs_register_bool_preference(oran_module, "oran.st6_4byte_alignment_required", "Use 4-byte alignment for ST6 sections",
11037 "Default is 1-byte alignment", &st6_4byte_alignment);
11038
11039 /* Misc (and will seldom need to be accessed) */
11040 prefs_register_static_text_preference(oran_module, "oran.misc", "", "");
11041 prefs_register_bool_preference(oran_module, "oran.show_iq_samples", "Show IQ Sample values",
11042 "When enabled, for U-Plane frames show each I and Q value in PRB", &pref_showIQSampleValues);
11043 prefs_register_enum_preference(oran_module, "oran.support_udcomplen", "udCompLen supported",
11044 "When enabled, U-Plane messages with relevant compression schemes will include udCompLen",
11045 &pref_support_udcompLen, udcomplen_support_options, false0);
11046 prefs_register_uint_preference(oran_module, "oran.rbs_in_uplane_section", "Total RBs in User-Plane data section",
11047 "This is used if numPrbu is signalled as 0", 10, &pref_data_plane_section_total_rbs);
11048 prefs_register_bool_preference(oran_module, "oran.unscaled_iq", "Show unscaled I/Q values",
11049 "", &show_unscaled_values);
11050 prefs_register_bool_preference(oran_module, "oran.attempt_reassembly",
11051 "Attempt Radio Transport layer reassembly", "",
11052 &do_radio_transport_layer_reassembly);
11053 prefs_register_obsolete_preference(oran_module, "oran.k_antenna_ports");
11054
11055 prefs_register_bool_preference(oran_module, "oran.link_planes",
11056 "Link C-plane and U-plane using sectionId", "",
11057 &link_planes_together);
11058
11059
11060 flow_states_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11061 flow_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11062 ul_symbol_timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11063
11064 dl_beam_ids_defined = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11065 dl_beam_ids_results = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
11066
11067 register_init_routine(&oran_init_protocol);
11068
11069 /* Register reassembly table. */
11070 reassembly_table_register(&oran_reassembly_table,
11071 &oran_reassembly_table_functions);
11072}
11073
11074/*
11075* Editor modelines - http://www.wireshark.org/tools/modelines.html
11076*
11077* Local Variables:
11078* c-basic-offset: 4
11079* tab-width: 8
11080* indent-tabs-mode: nil
11081* End:
11082*
11083* ex: set shiftwidth=4 tabstop=8 expandtab:
11084* :indentSize=4:tabSize=8:noTabs=true:
11085*/