Bug Summary

File:epan/dissectors/packet-oran.c
Warning:line 2123, column 17
Value stored to 'cPRB' is never read

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