Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-mac-lte.c
blob414226476e764ee2ff8627b5c7df2dc4f7e83703
1 /* Routines for LTE MAC disassembly
3 * Martin Mathieson
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/exceptions.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
18 #include <epan/tap.h>
19 #include <epan/uat.h>
20 #include <epan/proto_data.h>
21 #include <epan/tfs.h>
22 #include <wsutil/array.h>
24 #include "packet-mac-lte.h"
25 #include "packet-rlc-lte.h"
27 void proto_register_mac_lte(void);
28 void proto_reg_handoff_mac_lte(void);
30 /* Described in:
31 * 3GPP TS 36.321 Evolved Universal Terrestrial Radio Access (E-UTRA)
32 * Medium Access Control (MAC) protocol specification v14.3.0
35 /* TODO:
36 * - use proto_tree_add_bitmask..() APIs for sets of bits where possible
39 /* Initialize the protocol and registered fields. */
40 int proto_mac_lte;
42 static int mac_lte_tap;
44 static dissector_handle_t rlc_lte_handle;
45 static dissector_handle_t lte_rrc_bcch_dl_sch_handle;
46 static dissector_handle_t lte_rrc_bcch_dl_sch_br_handle;
47 static dissector_handle_t lte_rrc_bcch_dl_sch_nb_handle;
48 static dissector_handle_t lte_rrc_bcch_bch_handle;
49 static dissector_handle_t lte_rrc_bcch_bch_nb_handle;
50 static dissector_handle_t lte_rrc_pcch_handle;
51 static dissector_handle_t lte_rrc_pcch_nb_handle;
52 static dissector_handle_t lte_rrc_ul_ccch_handle;
53 static dissector_handle_t lte_rrc_ul_ccch_nb_handle;
54 static dissector_handle_t lte_rrc_dl_ccch_handle;
55 static dissector_handle_t lte_rrc_dl_ccch_nb_handle;
56 static dissector_handle_t lte_rrc_sbcch_sl_bch_handle;
57 static dissector_handle_t lte_rrc_sc_mcch_handle;
60 /* Decoding context */
61 static int hf_mac_lte_context;
62 static int hf_mac_lte_context_radio_type;
63 static int hf_mac_lte_context_direction;
64 static int hf_mac_lte_context_rnti;
65 static int hf_mac_lte_context_rnti_type;
66 static int hf_mac_lte_context_ueid;
67 static int hf_mac_lte_context_sysframe_number;
68 static int hf_mac_lte_context_subframe_number;
69 static int hf_mac_lte_context_grant_subframe_number;
70 static int hf_mac_lte_context_predefined_frame;
71 static int hf_mac_lte_context_length;
72 static int hf_mac_lte_context_ul_grant_size;
73 static int hf_mac_lte_context_bch_transport_channel;
74 static int hf_mac_lte_context_retx_count;
75 static int hf_mac_lte_context_retx_reason;
76 static int hf_mac_lte_context_crc_status;
77 static int hf_mac_lte_context_carrier_id;
79 static int hf_mac_lte_context_rapid;
80 static int hf_mac_lte_context_rach_attempt_number;
82 /* Inferred context */
83 static int hf_mac_lte_ues_ul_per_tti;
84 static int hf_mac_lte_ues_dl_per_tti;
87 /* Extra PHY context */
88 static int hf_mac_lte_context_phy_ul;
89 static int hf_mac_lte_context_phy_ul_modulation_type;
90 static int hf_mac_lte_context_phy_ul_tbs_index;
91 static int hf_mac_lte_context_phy_ul_resource_block_length;
92 static int hf_mac_lte_context_phy_ul_resource_block_start;
93 static int hf_mac_lte_context_phy_ul_harq_id;
94 static int hf_mac_lte_context_phy_ul_ndi;
96 static int hf_mac_lte_context_phy_dl;
97 static int hf_mac_lte_context_phy_dl_dci_format;
98 static int hf_mac_lte_context_phy_dl_resource_allocation_type;
99 static int hf_mac_lte_context_phy_dl_aggregation_level;
100 static int hf_mac_lte_context_phy_dl_mcs_index;
101 static int hf_mac_lte_context_phy_dl_redundancy_version_index;
102 static int hf_mac_lte_context_phy_dl_retx;
103 static int hf_mac_lte_context_phy_dl_resource_block_length;
104 static int hf_mac_lte_context_phy_dl_harq_id;
105 static int hf_mac_lte_context_phy_dl_ndi;
106 static int hf_mac_lte_context_phy_dl_tb;
109 /* Out-of-band events */
110 static int hf_mac_lte_oob_send_preamble;
111 static int hf_mac_lte_number_of_srs;
113 /* MAC SCH/MCH header fields */
114 static int hf_mac_lte_ulsch;
115 static int hf_mac_lte_ulsch_header;
116 static int hf_mac_lte_dlsch;
117 static int hf_mac_lte_dlsch_header;
118 static int hf_mac_lte_sch_subheader;
119 static int hf_mac_lte_mch;
120 static int hf_mac_lte_mch_header;
121 static int hf_mac_lte_mch_subheader;
122 static int hf_mac_lte_slsch;
123 static int hf_mac_lte_slsch_header;
124 static int hf_mac_lte_slsch_subheader;
126 static int hf_mac_lte_sch_reserved;
127 static int hf_mac_lte_sch_format2;
128 static int hf_mac_lte_lcid;
129 static int hf_mac_lte_dlsch_lcid;
130 static int hf_mac_lte_ulsch_lcid;
131 static int hf_mac_lte_sch_extended;
132 static int hf_mac_lte_sch_format;
133 static int hf_mac_lte_sch_reserved2;
134 static int hf_mac_lte_sch_elcid;
135 static int hf_mac_lte_sch_length;
136 static int hf_mac_lte_mch_reserved;
137 static int hf_mac_lte_mch_format2;
138 static int hf_mac_lte_mch_lcid;
139 static int hf_mac_lte_mch_extended;
140 static int hf_mac_lte_mch_format;
141 static int hf_mac_lte_mch_length;
142 static int hf_mac_lte_slsch_version;
143 static int hf_mac_lte_slsch_reserved;
144 static int hf_mac_lte_slsch_src_l2_id;
145 static int hf_mac_lte_slsch_dst_l2_id;
146 static int hf_mac_lte_slsch_dst_l2_id2;
147 static int hf_mac_lte_slsch_reserved2;
148 static int hf_mac_lte_slsch_extended;
149 static int hf_mac_lte_slsch_lcid;
150 static int hf_mac_lte_slsch_format;
151 static int hf_mac_lte_slsch_length;
153 static int hf_mac_lte_sch_header_only;
154 static int hf_mac_lte_mch_header_only;
155 static int hf_mac_lte_slsch_header_only;
157 /* Data */
158 static int hf_mac_lte_sch_sdu;
159 static int hf_mac_lte_mch_sdu;
160 static int hf_mac_lte_bch_pdu;
161 static int hf_mac_lte_pch_pdu;
162 static int hf_mac_lte_slbch_pdu;
163 static int hf_mac_lte_slsch_sdu;
164 static int hf_mac_lte_predefined_pdu;
165 static int hf_mac_lte_raw_pdu;
166 static int hf_mac_lte_padding_data;
167 static int hf_mac_lte_padding_length;
170 /* RAR fields */
171 static int hf_mac_lte_rar;
172 static int hf_mac_lte_rar_headers;
173 static int hf_mac_lte_rar_header;
174 static int hf_mac_lte_rar_extension;
175 static int hf_mac_lte_rar_t;
176 static int hf_mac_lte_rar_bi;
177 static int hf_mac_lte_rar_bi_nb;
178 static int hf_mac_lte_rar_rapid;
179 static int hf_mac_lte_rar_no_of_rapids;
180 static int hf_mac_lte_rar_reserved;
181 static int hf_mac_lte_rar_body;
182 static int hf_mac_lte_rar_reserved2;
183 static int hf_mac_lte_rar_ta;
184 static int hf_mac_lte_rar_ul_grant_ce_mode_b;
185 static int hf_mac_lte_rar_ul_grant;
186 static int hf_mac_lte_rar_ul_grant_hopping;
187 static int hf_mac_lte_rar_ul_grant_fsrba;
188 static int hf_mac_lte_rar_ul_grant_tmcs;
189 static int hf_mac_lte_rar_ul_grant_tcsp;
190 static int hf_mac_lte_rar_ul_grant_ul_delay;
191 static int hf_mac_lte_rar_ul_grant_cqi_request;
192 static int hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a;
193 static int hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_a;
194 static int hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a;
195 static int hf_mac_lte_rar_ul_grant_mcs_ce_mode_a;
196 static int hf_mac_lte_rar_ul_grant_tpc_ce_mode_a;
197 static int hf_mac_lte_rar_ul_grant_csi_request_ce_mode_a;
198 static int hf_mac_lte_rar_ul_grant_ul_delay_ce_mode_a;
199 static int hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx;
200 static int hf_mac_lte_rar_ul_grant_padding_ce_mode_a;
201 static int hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b;
202 static int hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_b;
203 static int hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b;
204 static int hf_mac_lte_rar_ul_grant_tbs_ce_mode_b;
205 static int hf_mac_lte_rar_ul_grant_ul_subcarrier_spacing;
206 static int hf_mac_lte_rar_ul_grant_subcarrier_indication;
207 static int hf_mac_lte_rar_ul_grant_scheduling_delay;
208 static int hf_mac_lte_rar_ul_grant_msg3_repetition_number;
209 static int hf_mac_lte_rar_ul_grant_mcs_index;
210 static int hf_mac_lte_rar_ul_grant_padding_nb_mode;
211 static int hf_mac_lte_rar_temporary_crnti;
213 /* Common channel control values */
214 static int hf_mac_lte_control_bsr;
215 static int hf_mac_lte_control_bsr_lcg_id;
216 static int hf_mac_lte_control_short_bsr_buffer_size;
217 static int hf_mac_lte_control_long_bsr_buffer_size_0;
218 static int hf_mac_lte_control_long_bsr_buffer_size_1;
219 static int hf_mac_lte_control_long_bsr_buffer_size_2;
220 static int hf_mac_lte_control_long_bsr_buffer_size_3;
221 static int hf_mac_lte_control_short_ext_bsr_buffer_size;
222 static int hf_mac_lte_control_long_ext_bsr_buffer_size_0;
223 static int hf_mac_lte_control_long_ext_bsr_buffer_size_1;
224 static int hf_mac_lte_control_long_ext_bsr_buffer_size_2;
225 static int hf_mac_lte_control_long_ext_bsr_buffer_size_3;
226 static int hf_mac_lte_bsr_size_median;
227 static int hf_mac_lte_control_crnti;
228 static int hf_mac_lte_control_timing_advance;
229 static int hf_mac_lte_control_timing_advance_group_id;
230 static int hf_mac_lte_control_timing_advance_command;
231 static int hf_mac_lte_control_timing_advance_value_reserved;
232 static int hf_mac_lte_control_timing_advance_value;
233 static int hf_mac_lte_control_as_rai;
234 static int hf_mac_lte_control_as_rai_reserved;
235 static int hf_mac_lte_control_as_rai_quality_report;
236 static int hf_mac_lte_control_ue_contention_resolution;
237 static int hf_mac_lte_control_ue_contention_resolution_identity;
238 static int hf_mac_lte_control_ue_contention_resolution_msg3;
239 static int hf_mac_lte_control_ue_contention_resolution_msg3_matched;
240 static int hf_mac_lte_control_ue_contention_resolution_time_since_msg3;
241 static int hf_mac_lte_control_msg3_to_cr;
243 static int hf_mac_lte_control_power_headroom;
244 static int hf_mac_lte_control_power_headroom_reserved;
245 static int hf_mac_lte_control_power_headroom_level;
246 static int hf_mac_lte_control_dual_conn_power_headroom;
247 static int hf_mac_lte_control_dual_conn_power_headroom_c7;
248 static int hf_mac_lte_control_dual_conn_power_headroom_c6;
249 static int hf_mac_lte_control_dual_conn_power_headroom_c5;
250 static int hf_mac_lte_control_dual_conn_power_headroom_c4;
251 static int hf_mac_lte_control_dual_conn_power_headroom_c3;
252 static int hf_mac_lte_control_dual_conn_power_headroom_c2;
253 static int hf_mac_lte_control_dual_conn_power_headroom_c1;
254 static int hf_mac_lte_control_dual_conn_power_headroom_c15;
255 static int hf_mac_lte_control_dual_conn_power_headroom_c14;
256 static int hf_mac_lte_control_dual_conn_power_headroom_c13;
257 static int hf_mac_lte_control_dual_conn_power_headroom_c12;
258 static int hf_mac_lte_control_dual_conn_power_headroom_c11;
259 static int hf_mac_lte_control_dual_conn_power_headroom_c10;
260 static int hf_mac_lte_control_dual_conn_power_headroom_c9;
261 static int hf_mac_lte_control_dual_conn_power_headroom_c8;
262 static int hf_mac_lte_control_dual_conn_power_headroom_c23;
263 static int hf_mac_lte_control_dual_conn_power_headroom_c22;
264 static int hf_mac_lte_control_dual_conn_power_headroom_c21;
265 static int hf_mac_lte_control_dual_conn_power_headroom_c20;
266 static int hf_mac_lte_control_dual_conn_power_headroom_c19;
267 static int hf_mac_lte_control_dual_conn_power_headroom_c18;
268 static int hf_mac_lte_control_dual_conn_power_headroom_c17;
269 static int hf_mac_lte_control_dual_conn_power_headroom_c16;
270 static int hf_mac_lte_control_dual_conn_power_headroom_c31;
271 static int hf_mac_lte_control_dual_conn_power_headroom_c30;
272 static int hf_mac_lte_control_dual_conn_power_headroom_c29;
273 static int hf_mac_lte_control_dual_conn_power_headroom_c28;
274 static int hf_mac_lte_control_dual_conn_power_headroom_c27;
275 static int hf_mac_lte_control_dual_conn_power_headroom_c26;
276 static int hf_mac_lte_control_dual_conn_power_headroom_c25;
277 static int hf_mac_lte_control_dual_conn_power_headroom_c24;
279 static int hf_mac_lte_control_dual_conn_power_headroom_reserved;
280 static int hf_mac_lte_control_dual_conn_power_headroom_power_backoff;
281 static int hf_mac_lte_control_dual_conn_power_headroom_value;
282 static int hf_mac_lte_control_dual_conn_power_headroom_level;
283 static int hf_mac_lte_control_dual_conn_power_headroom_reserved2;
284 static int hf_mac_lte_control_dual_conn_power_headroom_pcmaxc;
285 static int hf_mac_lte_control_ext_power_headroom;
286 static int hf_mac_lte_control_ext_power_headroom_c7;
287 static int hf_mac_lte_control_ext_power_headroom_c6;
288 static int hf_mac_lte_control_ext_power_headroom_c5;
289 static int hf_mac_lte_control_ext_power_headroom_c4;
290 static int hf_mac_lte_control_ext_power_headroom_c3;
291 static int hf_mac_lte_control_ext_power_headroom_c2;
292 static int hf_mac_lte_control_ext_power_headroom_c1;
293 static int hf_mac_lte_control_ext_power_headroom_reserved;
294 static int hf_mac_lte_control_ext_power_headroom_power_backoff;
295 static int hf_mac_lte_control_ext_power_headroom_value;
296 static int hf_mac_lte_control_ext_power_headroom_level;
297 static int hf_mac_lte_control_ext_power_headroom_reserved2;
298 static int hf_mac_lte_control_ext_power_headroom_pcmaxc;
299 static int hf_mac_lte_control_activation_deactivation;
300 static int hf_mac_lte_control_activation_deactivation_c7;
301 static int hf_mac_lte_control_activation_deactivation_c6;
302 static int hf_mac_lte_control_activation_deactivation_c5;
303 static int hf_mac_lte_control_activation_deactivation_c4;
304 static int hf_mac_lte_control_activation_deactivation_c3;
305 static int hf_mac_lte_control_activation_deactivation_c2;
306 static int hf_mac_lte_control_activation_deactivation_c1;
307 static int hf_mac_lte_control_activation_deactivation_reserved;
308 static int hf_mac_lte_control_activation_deactivation_c15;
309 static int hf_mac_lte_control_activation_deactivation_c14;
310 static int hf_mac_lte_control_activation_deactivation_c13;
311 static int hf_mac_lte_control_activation_deactivation_c12;
312 static int hf_mac_lte_control_activation_deactivation_c11;
313 static int hf_mac_lte_control_activation_deactivation_c10;
314 static int hf_mac_lte_control_activation_deactivation_c9;
315 static int hf_mac_lte_control_activation_deactivation_c8;
316 static int hf_mac_lte_control_activation_deactivation_c23;
317 static int hf_mac_lte_control_activation_deactivation_c22;
318 static int hf_mac_lte_control_activation_deactivation_c21;
319 static int hf_mac_lte_control_activation_deactivation_c20;
320 static int hf_mac_lte_control_activation_deactivation_c19;
321 static int hf_mac_lte_control_activation_deactivation_c18;
322 static int hf_mac_lte_control_activation_deactivation_c17;
323 static int hf_mac_lte_control_activation_deactivation_c16;
324 static int hf_mac_lte_control_activation_deactivation_c31;
325 static int hf_mac_lte_control_activation_deactivation_c30;
326 static int hf_mac_lte_control_activation_deactivation_c29;
327 static int hf_mac_lte_control_activation_deactivation_c28;
328 static int hf_mac_lte_control_activation_deactivation_c27;
329 static int hf_mac_lte_control_activation_deactivation_c26;
330 static int hf_mac_lte_control_activation_deactivation_c25;
331 static int hf_mac_lte_control_activation_deactivation_c24;
332 static int hf_mac_lte_control_mch_scheduling_info;
333 static int hf_mac_lte_control_mch_scheduling_info_lcid;
334 static int hf_mac_lte_control_mch_scheduling_info_stop_mtch;
335 static int hf_mac_lte_control_sidelink_bsr;
336 static int hf_mac_lte_control_sidelink_bsr_destination_idx_odd;
337 static int hf_mac_lte_control_sidelink_bsr_lcg_id_odd;
338 static int hf_mac_lte_control_sidelink_bsr_buffer_size_odd;
339 static int hf_mac_lte_control_sidelink_bsr_destination_idx_even;
340 static int hf_mac_lte_control_sidelink_bsr_lcg_id_even;
341 static int hf_mac_lte_control_sidelink_bsr_buffer_size_even;
342 static int hf_mac_lte_control_sidelink_reserved;
343 static int hf_mac_lte_control_data_vol_power_headroom;
344 static int hf_mac_lte_control_data_vol_power_headroom_reserved;
345 static int hf_mac_lte_control_data_vol_power_headroom_level;
346 static int hf_mac_lte_control_data_vol_power_headroom_level_4_bits;
347 static int hf_mac_lte_control_data_vol_power_headroom_data_vol;
348 static int hf_mac_lte_control_recommended_bit_rate;
349 static int hf_mac_lte_control_recommended_bit_rate_lcid;
350 static int hf_mac_lte_control_recommended_bit_rate_dir;
351 static int hf_mac_lte_control_recommended_bit_rate_bit_rate;
352 static int hf_mac_lte_control_recommended_bit_rate_reserved;
353 static int hf_mac_lte_control_recommended_bit_rate_query;
354 static int hf_mac_lte_control_recommended_bit_rate_query_lcid;
355 static int hf_mac_lte_control_recommended_bit_rate_query_dir;
356 static int hf_mac_lte_control_recommended_bit_rate_query_bit_rate;
357 static int hf_mac_lte_control_recommended_bit_rate_query_reserved;
358 static int hf_mac_lte_control_activation_deactivation_csi_rs;
359 static int hf_mac_lte_control_activation_deactivation_csi_rs_a8;
360 static int hf_mac_lte_control_activation_deactivation_csi_rs_a7;
361 static int hf_mac_lte_control_activation_deactivation_csi_rs_a6;
362 static int hf_mac_lte_control_activation_deactivation_csi_rs_a5;
363 static int hf_mac_lte_control_activation_deactivation_csi_rs_a4;
364 static int hf_mac_lte_control_activation_deactivation_csi_rs_a3;
365 static int hf_mac_lte_control_activation_deactivation_csi_rs_a2;
366 static int hf_mac_lte_control_activation_deactivation_csi_rs_a1;
367 static int hf_mac_lte_control_activation_deactivation_pdcp_dup;
368 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d8;
369 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d7;
370 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d6;
371 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d5;
372 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d4;
373 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d3;
374 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d2;
375 static int hf_mac_lte_control_activation_deactivation_pdcp_dup_d1;
376 static int hf_mac_lte_control_hibernation;
377 static int hf_mac_lte_control_hibernation_c7;
378 static int hf_mac_lte_control_hibernation_c6;
379 static int hf_mac_lte_control_hibernation_c5;
380 static int hf_mac_lte_control_hibernation_c4;
381 static int hf_mac_lte_control_hibernation_c3;
382 static int hf_mac_lte_control_hibernation_c2;
383 static int hf_mac_lte_control_hibernation_c1;
384 static int hf_mac_lte_control_hibernation_reserved;
385 static int hf_mac_lte_control_hibernation_c15;
386 static int hf_mac_lte_control_hibernation_c14;
387 static int hf_mac_lte_control_hibernation_c13;
388 static int hf_mac_lte_control_hibernation_c12;
389 static int hf_mac_lte_control_hibernation_c11;
390 static int hf_mac_lte_control_hibernation_c10;
391 static int hf_mac_lte_control_hibernation_c9;
392 static int hf_mac_lte_control_hibernation_c8;
393 static int hf_mac_lte_control_hibernation_c23;
394 static int hf_mac_lte_control_hibernation_c22;
395 static int hf_mac_lte_control_hibernation_c21;
396 static int hf_mac_lte_control_hibernation_c20;
397 static int hf_mac_lte_control_hibernation_c19;
398 static int hf_mac_lte_control_hibernation_c18;
399 static int hf_mac_lte_control_hibernation_c17;
400 static int hf_mac_lte_control_hibernation_c16;
401 static int hf_mac_lte_control_hibernation_c31;
402 static int hf_mac_lte_control_hibernation_c30;
403 static int hf_mac_lte_control_hibernation_c29;
404 static int hf_mac_lte_control_hibernation_c28;
405 static int hf_mac_lte_control_hibernation_c27;
406 static int hf_mac_lte_control_hibernation_c26;
407 static int hf_mac_lte_control_hibernation_c25;
408 static int hf_mac_lte_control_hibernation_c24;
409 static int hf_mac_lte_control_aul_confirmation;
410 static int hf_mac_lte_control_aul_confirmation_c7;
411 static int hf_mac_lte_control_aul_confirmation_c6;
412 static int hf_mac_lte_control_aul_confirmation_c5;
413 static int hf_mac_lte_control_aul_confirmation_c4;
414 static int hf_mac_lte_control_aul_confirmation_c3;
415 static int hf_mac_lte_control_aul_confirmation_c2;
416 static int hf_mac_lte_control_aul_confirmation_c1;
417 static int hf_mac_lte_control_aul_confirmation_reserved;
418 static int hf_mac_lte_control_aul_confirmation_c15;
419 static int hf_mac_lte_control_aul_confirmation_c14;
420 static int hf_mac_lte_control_aul_confirmation_c13;
421 static int hf_mac_lte_control_aul_confirmation_c12;
422 static int hf_mac_lte_control_aul_confirmation_c11;
423 static int hf_mac_lte_control_aul_confirmation_c10;
424 static int hf_mac_lte_control_aul_confirmation_c9;
425 static int hf_mac_lte_control_aul_confirmation_c8;
426 static int hf_mac_lte_control_aul_confirmation_c23;
427 static int hf_mac_lte_control_aul_confirmation_c22;
428 static int hf_mac_lte_control_aul_confirmation_c21;
429 static int hf_mac_lte_control_aul_confirmation_c20;
430 static int hf_mac_lte_control_aul_confirmation_c19;
431 static int hf_mac_lte_control_aul_confirmation_c18;
432 static int hf_mac_lte_control_aul_confirmation_c17;
433 static int hf_mac_lte_control_aul_confirmation_c16;
434 static int hf_mac_lte_control_aul_confirmation_c31;
435 static int hf_mac_lte_control_aul_confirmation_c30;
436 static int hf_mac_lte_control_aul_confirmation_c29;
437 static int hf_mac_lte_control_aul_confirmation_c28;
438 static int hf_mac_lte_control_aul_confirmation_c27;
439 static int hf_mac_lte_control_aul_confirmation_c26;
440 static int hf_mac_lte_control_aul_confirmation_c25;
441 static int hf_mac_lte_control_aul_confirmation_c24;
445 static int hf_mac_lte_dl_harq_resend_original_frame;
446 static int hf_mac_lte_dl_harq_resend_time_since_previous_frame;
447 static int hf_mac_lte_dl_harq_resend_next_frame;
448 static int hf_mac_lte_dl_harq_resend_time_until_next_frame;
450 static int hf_mac_lte_ul_harq_resend_original_frame;
451 static int hf_mac_lte_ul_harq_resend_time_since_previous_frame;
452 static int hf_mac_lte_ul_harq_resend_next_frame;
453 static int hf_mac_lte_ul_harq_resend_time_until_next_frame;
455 static int hf_mac_lte_grant_answering_sr;
456 static int hf_mac_lte_failure_answering_sr;
457 static int hf_mac_lte_sr_leading_to_failure;
458 static int hf_mac_lte_sr_leading_to_grant;
459 static int hf_mac_lte_sr_time_since_request;
460 static int hf_mac_lte_sr_time_until_answer;
462 static int hf_mac_lte_drx_config;
463 static int hf_mac_lte_drx_config_frame_num;
464 static int hf_mac_lte_drx_config_previous_frame_num;
465 static int hf_mac_lte_drx_config_long_cycle;
466 static int hf_mac_lte_drx_config_cycle_offset;
467 static int hf_mac_lte_drx_config_onduration_timer;
468 static int hf_mac_lte_drx_config_inactivity_timer;
469 static int hf_mac_lte_drx_config_retransmission_timer;
470 static int hf_mac_lte_drx_config_short_cycle;
471 static int hf_mac_lte_drx_config_short_cycle_timer;
473 static int hf_mac_lte_drx_state;
474 static int hf_mac_lte_drx_state_long_cycle_offset;
475 /* static int hf_mac_lte_drx_state_long_cycle_on; */
476 static int hf_mac_lte_drx_state_short_cycle_offset;
477 /* static int hf_mac_lte_drx_state_short_cycle_on; */
478 static int hf_mac_lte_drx_state_inactivity_remaining;
479 static int hf_mac_lte_drx_state_onduration_remaining;
480 static int hf_mac_lte_drx_state_retransmission_remaining;
481 static int hf_mac_lte_drx_state_rtt_remaining;
482 static int hf_mac_lte_drx_state_short_cycle_remaining;
484 /* Subtrees. */
485 static int ett_mac_lte;
486 static int ett_mac_lte_context;
487 static int ett_mac_lte_phy_context;
488 static int ett_mac_lte_ulsch_header;
489 static int ett_mac_lte_dlsch_header;
490 static int ett_mac_lte_mch_header;
491 static int ett_mac_lte_sch_subheader;
492 static int ett_mac_lte_mch_subheader;
493 static int ett_mac_lte_slsch_header;
494 static int ett_mac_lte_slsch_subheader;
495 static int ett_mac_lte_rar_headers;
496 static int ett_mac_lte_rar_header;
497 static int ett_mac_lte_rar_body;
498 static int ett_mac_lte_rar_ul_grant;
499 static int ett_mac_lte_bsr;
500 static int ett_mac_lte_bch;
501 static int ett_mac_lte_pch;
502 static int ett_mac_lte_activation_deactivation;
503 static int ett_mac_lte_contention_resolution;
504 static int ett_mac_lte_timing_advance;
505 static int ett_mac_lte_power_headroom;
506 static int ett_mac_lte_dual_conn_power_headroom;
507 static int ett_mac_lte_dual_conn_power_headroom_cell;
508 static int ett_mac_lte_extended_power_headroom;
509 static int ett_mac_lte_extended_power_headroom_cell;
510 static int ett_mac_lte_mch_scheduling_info;
511 static int ett_mac_lte_oob;
512 static int ett_mac_lte_drx_config;
513 static int ett_mac_lte_drx_state;
514 static int ett_mac_lte_sidelink_bsr;
515 static int ett_mac_lte_data_vol_power_headroom;
516 static int ett_mac_lte_recommended_bit_rate;
517 static int ett_mac_lte_recommended_bit_rate_query;
518 static int ett_mac_lte_activation_deactivation_csi_rs;
519 static int ett_mac_lte_activation_deactivation_pdcp_dup;
520 static int ett_mac_lte_hibernation;
521 static int ett_mac_lte_aul_confirmation;
523 static expert_field ei_mac_lte_context_rnti_type;
524 static expert_field ei_mac_lte_lcid_unexpected;
525 static expert_field ei_mac_lte_ul_mac_frame_retx;
526 static expert_field ei_mac_lte_oob_sr_failure;
527 static expert_field ei_mac_lte_control_timing_advance_command_correction_needed;
528 static expert_field ei_mac_lte_sch_header_only_truncated;
529 static expert_field ei_mac_lte_mch_header_only_truncated;
530 static expert_field ei_mac_lte_slsch_header_only_truncated;
531 static expert_field ei_mac_lte_control_timing_advance_command_no_correction;
532 static expert_field ei_mac_lte_rar_timing_advance_not_zero_note;
533 static expert_field ei_mac_lte_padding_data_start_and_end;
534 static expert_field ei_mac_lte_bch_pdu;
535 static expert_field ei_mac_lte_rach_preamble_sent_note;
536 static expert_field ei_mac_lte_pch_pdu;
537 static expert_field ei_mac_lte_ul_harq_resend_next_frame;
538 static expert_field ei_mac_lte_control_bsr_multiple;
539 static expert_field ei_mac_lte_padding_data_multiple;
540 static expert_field ei_mac_lte_context_sysframe_number;
541 static expert_field ei_mac_lte_rar_bi_present;
542 static expert_field ei_mac_lte_control_element_size_invalid;
543 static expert_field ei_mac_lte_bsr_warn_threshold_exceeded;
544 static expert_field ei_mac_lte_too_many_subheaders;
545 static expert_field ei_mac_lte_oob_send_sr;
546 static expert_field ei_mac_lte_orig_tx_ul_frame_not_found;
547 static expert_field ei_mac_lte_control_ue_contention_resolution_msg3_matched;
548 static expert_field ei_mac_lte_sr_results_not_grant_or_failure_indication;
549 static expert_field ei_mac_lte_context_crc_status;
550 static expert_field ei_mac_lte_sr_invalid_event;
551 static expert_field ei_mac_lte_control_subheader_after_data_subheader;
552 static expert_field ei_mac_lte_rar_bi_not_first_subheader;
553 static expert_field ei_mac_lte_context_length;
554 static expert_field ei_mac_lte_reserved_not_zero;
555 static expert_field ei_mac_lte_rar_timing_advance_not_zero_warn;
556 static expert_field ei_mac_lte_dlsch_lcid;
557 static expert_field ei_mac_lte_padding_data_before_control_subheader;
558 static expert_field ei_mac_lte_rach_preamble_sent_warn;
559 static expert_field ei_mac_lte_no_per_frame_data;
560 static expert_field ei_mac_lte_sch_invalid_length;
561 static expert_field ei_mac_lte_mch_invalid_length;
562 static expert_field ei_mac_lte_invalid_sc_mcch_sc_mtch_subheader_multiplexing;
563 static expert_field ei_mac_lte_unknown_udp_framing_tag;
566 /* Constants and value strings */
568 static const value_string radio_type_vals[] =
570 { FDD_RADIO, "FDD"},
571 { TDD_RADIO, "TDD"},
572 { 0, NULL }
576 static const value_string direction_vals[] =
578 { DIRECTION_UPLINK, "Uplink"},
579 { DIRECTION_DOWNLINK, "Downlink"},
580 { 0, NULL }
584 static const value_string rnti_type_vals[] =
586 { NO_RNTI, "NO-RNTI"},
587 { P_RNTI, "P-RNTI"},
588 { RA_RNTI, "RA-RNTI"},
589 { C_RNTI, "C-RNTI"},
590 { SI_RNTI, "SI-RNTI"},
591 { SPS_RNTI, "SPS-RNTI"},
592 { M_RNTI, "M-RNTI"},
593 { SL_BCH_RNTI, "SL-BCH-RNTI"},
594 { SL_RNTI, "SL-RNTI"},
595 { SC_RNTI, "SC-RNTI"},
596 { G_RNTI, "G-RNTI"},
597 { 0, NULL }
600 static const value_string bch_transport_channel_vals[] =
602 { SI_RNTI, "DL-SCH"},
603 { NO_RNTI, "BCH"},
604 { 0, NULL }
607 static const value_string crc_status_vals[] =
609 { crc_success, "OK"},
610 { crc_fail, "Failed"},
611 { crc_high_code_rate, "High Code Rate"},
612 { crc_pdsch_lost, "PDSCH Lost"},
613 { crc_duplicate_nonzero_rv, "Duplicate_nonzero_rv"},
614 { crc_false_dci, "False DCI"},
615 { 0, NULL }
618 static const value_string carrier_id_vals[] =
620 { carrier_id_primary, "Primary"},
621 { carrier_id_secondary_1, "Secondary-1"},
622 { carrier_id_secondary_2, "Secondary-2"},
623 { carrier_id_secondary_3, "Secondary-3"},
624 { carrier_id_secondary_4, "Secondary-4"},
625 { carrier_id_secondary_5, "Secondary-5"},
626 { carrier_id_secondary_6, "Secondary-6"},
627 { carrier_id_secondary_7, "Secondary-7"},
628 { 0, NULL }
631 static const value_string dci_format_vals[] =
633 { 0, "0"},
634 { 1, "1"},
635 { 2, "1A"},
636 { 3, "1B"},
637 { 4, "1C"},
638 { 5, "1D"},
639 { 6, "2"},
640 { 7, "2A"},
641 { 8, "3/3A"},
642 { 9, "2B"},
643 { 10, "2C"},
644 { 11, "2D"},
645 { 12, "4"},
646 { 13, "6-0A"},
647 { 14, "6-1A"},
648 { 15, "6-2"},
649 { 16, "N0"},
650 { 17, "N1"},
651 { 18, "N2"},
652 { 0, NULL }
655 static const value_string aggregation_level_vals[] =
657 { 0, "1"},
658 { 1, "2"},
659 { 2, "4"},
660 { 3, "8"},
661 { 4, "16"},
662 { 5, "24"},
663 { 0, NULL }
666 static const value_string modulation_type_vals[] =
668 { 2, "QPSK"},
669 { 4, "QAM16"},
670 { 6, "QAM64"},
671 { 0, NULL }
674 static const value_string as_rai_vals[] =
676 { 0, "No RAI information"},
677 { 1, "No subsequent DL and UL data transmission is expected"},
678 { 2, "A single subsequent DL transmission is expected"},
679 { 3, "Reserved"},
680 { 0, NULL }
684 static const true_false_string scell_ph_tfs = {
685 "Reported",
686 "Not reported"
689 static const true_false_string power_backoff_tfs = {
690 "Applied",
691 "Not applied"
694 static const true_false_string ph_value_tfs = {
695 "Based on reference format",
696 "Based on real transmission"
699 static const true_false_string dormant_activate_tfs = {
700 "Make dormant",
701 "Activate"
705 #define EXT_LOGICAL_CHANNEL_ID_LCID 0x10
706 #define DCQR_COMMAND_LCID 0x11
707 #define ACTIVATION_DEACTIVATION_PDCP_DUP_LCID 0x12
708 #define HIBERNATION_1_OCTET_LCID 0x13
709 #define HIBERNATION_4_OCTETS_LCID 0x14
710 #define ACTIVATION_DEACTIVATION_CSI_RS_LCID 0x15
711 #define RECOMMENDED_BIT_RATE_LCID 0x16
712 #define SC_PTM_STOP_INDICATION_LCID 0x17
713 #define ACTIVATION_DEACTIVATION_4_BYTES_LCID 0x18
714 #define SC_MCCH_SC_MTCH_LCID 0x19
715 #define LONG_DRX_COMMAND_LCID 0x1a
716 #define ACTIVATION_DEACTIVATION_LCID 0x1b
717 #define UE_CONTENTION_RESOLUTION_IDENTITY_LCID 0x1c
718 #define TIMING_ADVANCE_LCID 0x1d
719 #define DRX_COMMAND_LCID 0x1e
720 #define PADDING_LCID 0x1f
722 static const value_string dlsch_lcid_vals[] =
724 { 0, "CCCH"},
725 { 1, "1"},
726 { 2, "2"},
727 { 3, "3"},
728 { 4, "4"},
729 { 5, "5"},
730 { 6, "6"},
731 { 7, "7"},
732 { 8, "8"},
733 { 9, "9"},
734 { 10, "10"},
735 { EXT_LOGICAL_CHANNEL_ID_LCID, "Extended logical channel ID field"},
736 { DCQR_COMMAND_LCID, "DCQR Command"},
737 { ACTIVATION_DEACTIVATION_PDCP_DUP_LCID, "Activation/Deactivation of PDCP Duplication"},
738 { HIBERNATION_1_OCTET_LCID, "Hibernation (1 octet)"},
739 { HIBERNATION_4_OCTETS_LCID, "Hibernation (4 octets)"},
740 { ACTIVATION_DEACTIVATION_CSI_RS_LCID, "Activation/Deactivation of CSI-RS"},
741 { RECOMMENDED_BIT_RATE_LCID, "Recommended Bit Rate"},
742 { SC_PTM_STOP_INDICATION_LCID, "SC-PTM Stop Indication"},
743 { ACTIVATION_DEACTIVATION_4_BYTES_LCID, "Activation/Deactivation"},
744 { SC_MCCH_SC_MTCH_LCID, "SC-MCCH/SC-MTCH"},
745 { LONG_DRX_COMMAND_LCID, "Long DRX Command"},
746 { ACTIVATION_DEACTIVATION_LCID, "Activation/Deactivation"},
747 { UE_CONTENTION_RESOLUTION_IDENTITY_LCID, "UE Contention Resolution Identity"},
748 { TIMING_ADVANCE_LCID, "Timing Advance"},
749 { DRX_COMMAND_LCID, "DRX Command"},
750 { PADDING_LCID, "Padding" },
751 { 0, NULL }
754 #define TIMING_ADVANCE_REPORT_LCID 0x0f
755 #define DCQR_AND_AS_RAI_LCID 0x11
756 #define AUL_CONFIRMATION_4_OCTETS 0x12
757 #define AUL_CONFIRMATION_1_OCTET 0x13
758 #define RECOMMENDED_BIT_RATE_QUERY_LCID 0x14
759 #define SPS_CONFIRMATION_LCID 0x15
760 #define TRUNCATED_SIDELINK_BSR_LCID 0x16
761 #define SIDELINK_BSR_LCID 0x17
762 #define DUAL_CONN_POWER_HEADROOM_REPORT_LCID 0x18
763 #define EXTENDED_POWER_HEADROOM_REPORT_LCID 0x19
764 #define POWER_HEADROOM_REPORT_LCID 0x1a
765 #define CRNTI_LCID 0x1b
766 #define TRUNCATED_BSR_LCID 0x1c
767 #define SHORT_BSR_LCID 0x1d
768 #define LONG_BSR_LCID 0x1e
770 static const value_string ulsch_lcid_vals[] =
772 { 0, "CCCH"},
773 { 1, "1"},
774 { 2, "2"},
775 { 3, "3"},
776 { 4, "4"},
777 { 5, "5"},
778 { 6, "6"},
779 { 7, "7"},
780 { 8, "8"},
781 { 9, "9"},
782 { 10, "10"},
783 { 11, "CCCH (Category 0)"},
784 { 12, "CCCH (frequency hopping for unicast)"},
785 { 13, "CCCH and Extended Power Headroom Report"},
786 { 14, "Reserved"},
787 { TIMING_ADVANCE_REPORT_LCID, "Timing Advance Report"},
788 { EXT_LOGICAL_CHANNEL_ID_LCID, "Extended logical channel ID field"},
789 { DCQR_AND_AS_RAI_LCID, "DCQR and AS RAI"},
790 { AUL_CONFIRMATION_4_OCTETS, "AUL confirmation (4 octets)"},
791 { AUL_CONFIRMATION_1_OCTET, "AUL confirmation (1 octet)"},
792 { RECOMMENDED_BIT_RATE_QUERY_LCID, "Recommended Bit Rate Query"},
793 { SPS_CONFIRMATION_LCID, "SPS Confirmation"},
794 { TRUNCATED_SIDELINK_BSR_LCID, "Truncated Sidelink BSR"},
795 { SIDELINK_BSR_LCID, "Sidelink BSR"},
796 { DUAL_CONN_POWER_HEADROOM_REPORT_LCID, "Dual Connectivity Power Headroom Report"},
797 { EXTENDED_POWER_HEADROOM_REPORT_LCID, "Extended Power Headroom Report"},
798 { POWER_HEADROOM_REPORT_LCID, "Power Headroom Report"},
799 { CRNTI_LCID, "C-RNTI"},
800 { TRUNCATED_BSR_LCID, "Truncated BSR"},
801 { SHORT_BSR_LCID, "Short BSR"},
802 { LONG_BSR_LCID, "Long BSR"},
803 { PADDING_LCID, "Padding" },
804 { 0, NULL }
807 #define MCH_SCHEDULING_INFO_LCID 0x1e
809 static const value_string mch_lcid_vals[] =
811 { 0, "MCCH"},
812 { 1, "1"},
813 { 2, "2"},
814 { 3, "3"},
815 { 4, "4"},
816 { 5, "5"},
817 { 6, "6"},
818 { 7, "7"},
819 { 8, "8"},
820 { 9, "9"},
821 { 10, "10"},
822 { 11, "11"},
823 { 12, "12"},
824 { 13, "13"},
825 { 14, "14"},
826 { 15, "15"},
827 { 16, "16"},
828 { 17, "17"},
829 { 18, "18"},
830 { 19, "19"},
831 { 20, "20"},
832 { 21, "21"},
833 { 22, "22"},
834 { 23, "23"},
835 { 24, "24"},
836 { 25, "25"},
837 { 26, "26"},
838 { 27, "27"},
839 { 28, "28"},
840 { 29, "Reserved"},
841 { MCH_SCHEDULING_INFO_LCID, "MCH Scheduling Information"},
842 { PADDING_LCID, "Padding" },
843 { 0, NULL }
847 /* Does this LCID relate to CCCH? */
848 static bool is_ccch_lcid(uint8_t lcid, uint8_t direction)
850 if (lcid==0) {
851 return true;
853 else {
854 /* Extra UL CCCH LCIDs */
855 return (direction == DIRECTION_UPLINK) && (lcid>=11 && lcid<=13);
859 /* Does this LCID represent variable-length data SDU?
860 N.B. assuming that all CCCH LCIDs do have associated SDU */
861 static bool is_data_lcid(uint8_t lcid, uint8_t direction)
863 return lcid<=10 || is_ccch_lcid(lcid, direction);
868 static const value_string slsch_lcid_vals[] =
870 { 0, "Reserved"},
871 { 1, "1"},
872 { 2, "2"},
873 { 3, "3"},
874 { 4, "4"},
875 { 5, "5"},
876 { 6, "6"},
877 { 7, "7"},
878 { 8, "8"},
879 { 9, "9"},
880 { 10, "10"},
881 { 28, "PC5-S messages that are not protected"},
882 { 29, "PC5-S messages \"Direct Security Mode Command\" and \"Direct Security Mode Complete\""},
883 { 30, "Other PC5-S messages that are protected"},
884 { PADDING_LCID, "Padding" },
885 { 0, NULL }
888 static const true_false_string format_vals =
890 "Data length is >= 128 bytes",
891 "Data length is < 128 bytes"
894 static const true_false_string format2_vals =
896 "Data length is >= 32768 bytes",
897 "Data length is < 32768 bytes"
900 static const value_string rar_type_vals[] =
902 { 0, "Backoff Indicator present"},
903 { 1, "RAPID present"},
904 { 0, NULL }
908 static const value_string rar_bi_vals[] =
910 { 0, "0"},
911 { 1, "10"},
912 { 2, "20"},
913 { 3, "30"},
914 { 4, "40"},
915 { 5, "60"},
916 { 6, "80"},
917 { 7, "120"},
918 { 8, "160"},
919 { 9, "240"},
920 { 10, "320"},
921 { 11, "480"},
922 { 12, "960"},
923 { 0, NULL }
927 static const value_string rar_bi_nb_vals[] =
929 { 0, "0"},
930 { 1, "256"},
931 { 2, "512"},
932 { 3, "1024"},
933 { 4, "2048"},
934 { 5, "4096"},
935 { 6, "8192"},
936 { 7, "16384"},
937 { 8, "32768"},
938 { 9, "65536"},
939 { 10, "131072"},
940 { 11, "262144"},
941 { 12, "524288"},
942 { 0, NULL }
946 static const value_string rar_ul_grant_tcsp_vals[] =
948 { 0, "-6 dB"},
949 { 1, "-4 dB" },
950 { 2, "-2 dB" },
951 { 3, "0 dB" },
952 { 4, "2 dB" },
953 { 5, "4 dB" },
954 { 6, "6 dB" },
955 { 7, "8 dB" },
956 { 0, NULL }
960 static const value_string rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b_vals[] =
962 { 0, "NBrar mod Nnb"},
963 { 1, "(NBrar+1) mod Nnb"},
964 { 2, "(NBrar+2) mod Nnb"},
965 { 3, "(NBrar+3) mod Nnb"},
966 { 0, NULL}
970 static const value_string rar_ul_grant_msg3_msg4_mpdcch_nb_idx_vals[] =
972 { 0, "NBrar mod Nnb2"},
973 { 1, "(NBrar+1) mod Nnb2"},
974 { 2, "(NBrar+2) mod Nnb2"},
975 { 3, "(NBrar+3) mod Nnb2"},
976 { 0, NULL}
980 static const value_string rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a_vals[] =
982 { 0, "Ya/8"},
983 { 1, "Ya/4"},
984 { 2, "Ya/2"},
985 { 3, "Ya"},
986 { 0, NULL}
990 static const value_string rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b_vals[] =
992 { 0, "Yb/128"},
993 { 1, "Yb/64"},
994 { 2, "Yb/32"},
995 { 3, "Yb/16"},
996 { 4, "Yb/8"},
997 { 5, "Yb/4"},
998 { 6, "Yb/2"},
999 { 7, "Yb"},
1000 { 0, NULL}
1004 static const true_false_string ul_subcarrier_spacing_val =
1006 "15 kHz",
1007 "3.75 kHz"
1011 static const value_string scheduling_delay_vals[]=
1013 { 0, "k0 = 8"},
1014 { 1, "k0 = 16"},
1015 { 2, "k0 = 32"},
1016 { 3, "k0 = 64"},
1017 { 0, NULL}
1021 static const value_string msg3_rep_nb_vals[] =
1023 { 0, "1"},
1024 { 1, "2"},
1025 { 2, "4"},
1026 { 3, "8"},
1027 { 4, "16"},
1028 { 5, "32"},
1029 { 6, "64"},
1030 { 7, "128"},
1031 { 0, NULL}
1035 static const value_string buffer_size_vals[] =
1037 { 0, "BS = 0"},
1038 { 1, "0 < BS <= 10"},
1039 { 2, "10 < BS <= 12"},
1040 { 3, "12 < BS <= 14"},
1041 { 4, "14 < BS <= 17"},
1042 { 5, "17 < BS <= 19"},
1043 { 6, "19 < BS <= 22"},
1044 { 7, "22 < BS <= 26"},
1045 { 8, "26 < BS <= 31"},
1046 { 9, "31 < BS <= 36"},
1047 { 10, "36 < BS <= 42"},
1048 { 11, "42 < BS <= 49"},
1049 { 12, "49 < BS <= 57"},
1050 { 13, "57 < BS <= 67"},
1051 { 14, "67 < BS <= 78"},
1052 { 15, "78 < BS <= 91"},
1053 { 16, "91 < BS <= 107"},
1054 { 17, "107 < BS <= 125"},
1055 { 18, "125 < BS <= 146"},
1056 { 19, "146 < BS <= 171"},
1057 { 20, "171 < BS <= 200"},
1058 { 21, "200 < BS <= 234"},
1059 { 22, "234 < BS <= 274"},
1060 { 23, "274 < BS <= 321"},
1061 { 24, "321 < BS <= 376"},
1062 { 25, "376 < BS <= 440"},
1063 { 26, "440 < BS <= 515"},
1064 { 27, "515 < BS <= 603"},
1065 { 28, "603 < BS <= 706"},
1066 { 29, "706 < BS <= 826"},
1067 { 30, "826 < BS <= 967"},
1068 { 31, "967 < BS <= 1132"},
1069 { 32, "1132 < BS <= 1326"},
1070 { 33, "1326 < BS <= 1552"},
1071 { 34, "1552 < BS <= 1817"},
1072 { 35, "1817 < BS <= 2127"},
1073 { 36, "2127 < BS <= 2490"},
1074 { 37, "2490 < BS <= 2915"},
1075 { 38, "2915 < BS <= 3413"},
1076 { 39, "3413 < BS <= 3995"},
1077 { 40, "3995 < BS <= 4677"},
1078 { 41, "4677 < BS <= 5476"},
1079 { 42, "5476 < BS <= 6411"},
1080 { 43, "6411 < BS <= 7505"},
1081 { 44, "7505 < BS <= 8787"},
1082 { 45, "8787 < BS <= 10276"},
1083 { 46, "10287 < BS <= 12043"},
1084 { 47, "12043 < BS <= 14099"},
1085 { 48, "14099 < BS <= 16507"},
1086 { 49, "16507 < BS <= 19325"},
1087 { 50, "19325 < BS <= 22624"},
1088 { 51, "22624 < BS <= 26487"},
1089 { 52, "26487 < BS <= 31009"},
1090 { 53, "31009 < BS <= 36304"},
1091 { 54, "36304 < BS <= 42502"},
1092 { 55, "42502 < BS <= 49759"},
1093 { 56, "49759 < BS <= 58255"},
1094 { 57, "58255 < BS <= 68201"},
1095 { 58, "68201 < BS <= 79846"},
1096 { 59, "79846 < BS <= 93479"},
1097 { 60, "93479 < BS <= 109439"},
1098 { 61, "109439 < BS <= 128125"},
1099 { 62, "128125 < BS <= 150000"},
1100 { 63, "BS > 150000"},
1101 { 0, NULL }
1103 static value_string_ext buffer_size_vals_ext = VALUE_STRING_EXT_INIT(buffer_size_vals);
1105 static uint32_t buffer_size_median[64] = {
1106 0, /* BS = 0 */
1107 5, /* 0 < BS <= 10 */
1108 11, /* 10 < BS <= 12 */
1109 13, /* 12 < BS <= 14 */
1110 15, /* 14 < BS <= 17 */
1111 18, /* 17 < BS <= 19 */
1112 21, /* 19 < BS <= 22 */
1113 24, /* 22 < BS <= 26 */
1114 29, /* 26 < BS <= 31 */
1115 34, /* 31 < BS <= 36 */
1116 39, /* 36 < BS <= 42 */
1117 46, /* 42 < BS <= 49 */
1118 53, /* 49 < BS <= 57 */
1119 62, /* 57 < BS <= 67 */
1120 74, /* 67 < BS <= 78 */
1121 85, /* 78 < BS <= 91 */
1122 99, /* 91 < BS <= 107 */
1123 116, /* 107 < BS <= 125 */
1124 135, /* 125 < BS <= 146 */
1125 159, /* 146 < BS <= 171 */
1126 185, /* 171 < BS <= 200 */
1127 217, /* 200 < BS <= 234 */
1128 254, /* 234 < BS <= 274 */
1129 297, /* 274 < BS <= 321 */
1130 348, /* 321 < BS <= 376 */
1131 408, /* 376 < BS <= 440 */
1132 477, /* 440 < BS <= 515 */
1133 559, /* 515 < BS <= 603 */
1134 654, /* 603 < BS <= 706 */
1135 766, /* 706 < BS <= 826 */
1136 896, /* 826 < BS <= 967 */
1137 1049, /* 967 < BS <= 1132 */
1138 1229, /* 1132 < BS <= 1326 */
1139 1439, /* 1326 < BS <= 1552 */
1140 1684, /* 1552 < BS <= 1817 */
1141 1972, /* 1817 < BS <= 2127 */
1142 2308, /* 2127 < BS <= 2490 */
1143 2702, /* 2490 < BS <= 2915 */
1144 3164, /* 2915 < BS <= 3413 */
1145 3704, /* 3413 < BS <= 3995 */
1146 4336, /* 3995 < BS <= 4677 */
1147 5076, /* 4677 < BS <= 5476 */
1148 5943, /* 5476 < BS <= 6411 */
1149 6958, /* 6411 < BS <= 7505 */
1150 8146, /* 7505 < BS <= 8787 */
1151 9531, /* 8787 < BS <= 10276 */
1152 11165, /* 10287 < BS <= 12043 */
1153 13071, /* 12043 < BS <= 14099 */
1154 15303, /* 14099 < BS <= 16507 */
1155 19716, /* 16507 < BS <= 19325 */
1156 20974, /* 19325 < BS <= 22624 */
1157 24555, /* 22624 < BS <= 26487 */
1158 28748, /* 26487 < BS <= 31009 */
1159 33656, /* 31009 < BS <= 36304 */
1160 39403, /* 36304 < BS <= 42502 */
1161 46130, /* 42502 < BS <= 49759 */
1162 54007, /* 49759 < BS <= 58255 */
1163 63228, /* 58255 < BS <= 68201 */
1164 74023, /* 68201 < BS <= 79846 */
1165 86662, /* 79846 < BS <= 93479 */
1166 101459, /* 93479 < BS <= 109439 */
1167 118782, /* 109439 < BS <= 128125 */
1168 139062, /* 128125 < BS <= 150000 */
1169 150001 /* BS > 150000 */
1172 static const value_string ext_buffer_size_vals[] =
1174 { 0, "BS = 0"},
1175 { 1, "0 < BS <= 10"},
1176 { 2, "10 < BS <= 13"},
1177 { 3, "13 < BS <= 16"},
1178 { 4, "16 < BS <= 19"},
1179 { 5, "19 < BS <= 23"},
1180 { 6, "23 < BS <= 29"},
1181 { 7, "29 < BS <= 35"},
1182 { 8, "35 < BS <= 43"},
1183 { 9, "43 < BS <= 53"},
1184 { 10, "53 < BS <= 65"},
1185 { 11, "65 < BS <= 80"},
1186 { 12, "80 < BS <= 98"},
1187 { 13, "98 < BS <= 120"},
1188 { 14, "120 < BS <= 147"},
1189 { 15, "147 < BS <= 181"},
1190 { 16, "181 < BS <= 223"},
1191 { 17, "223 < BS <= 274"},
1192 { 18, "274 < BS <= 337"},
1193 { 19, "337 < BS <= 414"},
1194 { 20, "414 < BS <= 509"},
1195 { 21, "509 < BS <= 625"},
1196 { 22, "625 < BS <= 769"},
1197 { 23, "769 < BS <= 945"},
1198 { 24, "945 < BS <= 1162"},
1199 { 25, "1162 < BS <= 1429"},
1200 { 26, "1429 < BS <= 1757"},
1201 { 27, "1757 < BS <= 2161"},
1202 { 28, "2161 < BS <= 2657"},
1203 { 29, "2657 < BS <= 3267"},
1204 { 30, "3267 < BS <= 4017"},
1205 { 31, "4017 < BS <= 4940"},
1206 { 32, "4940 < BS <= 6074"},
1207 { 33, "6074 < BS <= 7469"},
1208 { 34, "7469 < BS <= 9185"},
1209 { 35, "9185 < BS <= 11294"},
1210 { 36, "11294 < BS <= 13888"},
1211 { 37, "13888 < BS <= 17077"},
1212 { 38, "17077 < BS <= 20999"},
1213 { 39, "20999 < BS <= 25822"},
1214 { 40, "25822 < BS <= 31752"},
1215 { 41, "31752 < BS <= 39045"},
1216 { 42, "39045 < BS <= 48012"},
1217 { 43, "48012 < BS <= 59039"},
1218 { 44, "59039 < BS <= 72598"},
1219 { 45, "72598 < BS <= 89272"},
1220 { 46, "89272 < BS <= 109774"},
1221 { 47, "109774 < BS <= 134986"},
1222 { 48, "134986 < BS <= 165989"},
1223 { 49, "165989 < BS <= 204111"},
1224 { 50, "204111 < BS <= 250990"},
1225 { 51, "250990 < BS <= 308634"},
1226 { 52, "308634 < BS <= 379519"},
1227 { 53, "379519 < BS <= 466683"},
1228 { 54, "466683 < BS <= 573866"},
1229 { 55, "573866 < BS <= 705666"},
1230 { 56, "705666 < BS <= 867737"},
1231 { 57, "867737 < BS <= 1067031"},
1232 { 58, "1067031 < BS <= 1312097"},
1233 { 59, "1312097 < BS <= 1613447"},
1234 { 60, "1613447 < BS <= 1984009"},
1235 { 61, "1984009 < BS <= 2439678"},
1236 { 62, "2439678 < BS <= 3000000"},
1237 { 63, "BS > 3000000"},
1238 { 0, NULL }
1240 static value_string_ext ext_buffer_size_vals_ext = VALUE_STRING_EXT_INIT(ext_buffer_size_vals);
1242 static uint32_t ext_buffer_size_median[64] = {
1243 0, /* BS = 0 */
1244 5, /* 0 < BS <= 10 */
1245 12, /* 10 < BS <= 13 */
1246 15, /* 13 < BS <= 16 */
1247 18, /* 16 < BS <= 19 */
1248 21, /* 19 < BS <= 23 */
1249 26, /* 23 < BS <= 29 */
1250 32, /* 29 < BS <= 35 */
1251 39, /* 35 < BS <= 43 */
1252 48, /* 43 < BS <= 53 */
1253 59, /* 53 < BS <= 65 */
1254 73, /* 65 < BS <= 80 */
1255 89, /* 80 < BS <= 98 */
1256 109, /* 98 < BS <= 120 */
1257 134, /* 120 < BS <= 147 */
1258 164, /* 147 < BS <= 181 */
1259 202, /* 181 < BS <= 223 */
1260 249, /* 223 < BS <= 274 */
1261 306, /* 274 < BS <= 337 */
1262 376, /* 337 < BS <= 414 */
1263 462, /* 414 < BS <= 509 */
1264 567, /* 509 < BS <= 625 */
1265 697, /* 625 < BS <= 769 */
1266 857, /* 769 < BS <= 945 */
1267 1054, /* 945 < BS <= 1162 */
1268 1296, /* 1162 < BS <= 1429 */
1269 1593, /* 1429 < BS <= 1757 */
1270 1959, /* 1757 < BS <= 2161 */
1271 2409, /* 2161 < BS <= 2657 */
1272 2962, /* 2657 < BS <= 3267 */
1273 5142, /* 3267 < BS <= 4017 */
1274 4479, /* 4017 < BS <= 4940 */
1275 5507, /* 4940 < BS <= 6074 */
1276 6772, /* 6074 < BS <= 7469 */
1277 8327, /* 7469 < BS <= 9185 */
1278 10240, /* 9185 < BS <= 11294 */
1279 12591, /* 11294 < BS <= 13888 */
1280 15483, /* 13888 < BS <= 17077 */
1281 19038, /* 17077 < BS <= 20999 */
1282 23411, /* 20999 < BS <= 25822 */
1283 28787, /* 25822 < BS <= 31752 */
1284 35399, /* 31752 < BS <= 39045 */
1285 43529, /* 39045 < BS <= 48012 */
1286 53526, /* 48012 < BS <= 59039 */
1287 65819, /* 59039 < BS <= 72598 */
1288 80935, /* 72598 < BS <= 89272 */
1289 99523, /* 89272 < BS <= 109774 */
1290 122380, /* 109774 < BS <= 134986 */
1291 150488, /* 134986 < BS <= 165989 */
1292 185050, /* 165989 < BS <= 204111 */
1293 227551, /* 204111 < BS <= 250990 */
1294 279812, /* 250990 < BS <= 308634 */
1295 344077, /* 308634 < BS <= 379519 */
1296 423101, /* 379519 < BS <= 466683 */
1297 520275, /* 466683 < BS <= 573866 */
1298 705748, /* 573866 < BS <= 705666 */
1299 786702, /* 705666 < BS <= 867737 */
1300 967384, /* 867737 < BS <= 1067031 */
1301 1189564, /* 1067031 < BS <= 1312097 */
1302 1462772, /* 1312097 < BS <= 1613447 */
1303 1798728, /* 1613447 < BS <= 1984009 */
1304 2211844, /* 1984009 < BS <= 2439678 */
1305 2719839, /* 2439678 < BS <= 3000000 */
1306 3000001 /* BS > 3000000 */
1309 static const value_string power_headroom_vals[] =
1311 { 0, "-23 <= PH < -22"},
1312 { 1, "-22 <= PH < -21"},
1313 { 2, "-21 <= PH < -20"},
1314 { 3, "-20 <= PH < -19"},
1315 { 4, "-19 <= PH < -18"},
1316 { 5, "-18 <= PH < -17"},
1317 { 6, "-17 <= PH < -16"},
1318 { 7, "-16 <= PH < -15"},
1319 { 8, "-15 <= PH < -14"},
1320 { 9, "-14 <= PH < -13"},
1321 { 10, "-13 <= PH < -12"},
1322 { 11, "-12 <= PH < -11"},
1323 { 12, "-11 <= PH < -10"},
1324 { 13, "-10 <= PH < -9"},
1325 { 14, "-9 <= PH < -8"},
1326 { 15, "-8 <= PH < -7"},
1327 { 16, "-7 <= PH < -6"},
1328 { 17, "-6 <= PH < -5"},
1329 { 18, "-5 <= PH < -4"},
1330 { 19, "-4 <= PH < -3"},
1331 { 20, "-3 <= PH < -2"},
1332 { 21, "-2 <= PH < -1"},
1333 { 22, "-1 <= PH < 0"},
1334 { 23, "0 <= PH < 1"},
1335 { 24, "1 <= PH < 2"},
1336 { 25, "2 <= PH < 3"},
1337 { 26, "3 <= PH < 4"},
1338 { 27, "4 <= PH < 5"},
1339 { 28, "5 <= PH < 6"},
1340 { 29, "6 <= PH < 7"},
1341 { 30, "7 <= PH < 8"},
1342 { 31, "8 <= PH < 9"},
1343 { 32, "9 <= PH < 10"},
1344 { 33, "10 <= PH < 11"},
1345 { 34, "11 <= PH < 12"},
1346 { 35, "12 <= PH < 13"},
1347 { 36, "13 <= PH < 14"},
1348 { 37, "14 <= PH < 15"},
1349 { 38, "15 <= PH < 16"},
1350 { 39, "16 <= PH < 17"},
1351 { 40, "17 <= PH < 18"},
1352 { 41, "18 <= PH < 19"},
1353 { 42, "19 <= PH < 20"},
1354 { 43, "20 <= PH < 21"},
1355 { 44, "21 <= PH < 22"},
1356 { 45, "22 <= PH < 23"},
1357 { 46, "23 <= PH < 24"},
1358 { 47, "24 <= PH < 25"},
1359 { 48, "25 <= PH < 26"},
1360 { 49, "26 <= PH < 27"},
1361 { 50, "27 <= PH < 28"},
1362 { 51, "28 <= PH < 29"},
1363 { 52, "29 <= PH < 30"},
1364 { 53, "30 <= PH < 31"},
1365 { 54, "31 <= PH < 32"},
1366 { 55, "32 <= PH < 33"},
1367 { 56, "33 <= PH < 34"},
1368 { 57, "34 <= PH < 35"},
1369 { 58, "34 <= PH < 36"},
1370 { 59, "36 <= PH < 37"},
1371 { 60, "37 <= PH < 38"},
1372 { 61, "38 <= PH < 39"},
1373 { 62, "39 <= PH < 40"},
1374 { 63, "PH >= 40"},
1375 { 0, NULL }
1377 static value_string_ext power_headroom_vals_ext = VALUE_STRING_EXT_INIT(power_headroom_vals);
1379 static const value_string pcmaxc_vals[] =
1381 { 0, "Pcmax,c < -29"},
1382 { 1, "-29 <= Pcmax,c < -28"},
1383 { 2, "-28 <= Pcmax,c < -27"},
1384 { 3, "-27 <= Pcmax,c < -26"},
1385 { 4, "-26 <= Pcmax,c < -25"},
1386 { 5, "-25 <= Pcmax,c < -24"},
1387 { 6, "-24 <= Pcmax,c < -23"},
1388 { 7, "-23 <= Pcmax,c < -22"},
1389 { 8, "-22 <= Pcmax,c < -21"},
1390 { 9, "-21 <= Pcmax,c < -20"},
1391 { 10, "-20 <= Pcmax,c < -19"},
1392 { 11, "-19 <= Pcmax,c < -18"},
1393 { 12, "-18 <= Pcmax,c < -17"},
1394 { 13, "-17 <= Pcmax,c < -16"},
1395 { 14, "-16 <= Pcmax,c < -15"},
1396 { 15, "-15 <= Pcmax,c < -14"},
1397 { 16, "-14 <= Pcmax,c < -13"},
1398 { 17, "-13 <= Pcmax,c < -12"},
1399 { 18, "-12 <= Pcmax,c < -11"},
1400 { 19, "-11 <= Pcmax,c < -10"},
1401 { 20, "-10 <= Pcmax,c < -9"},
1402 { 21, "-9 <= Pcmax,c < -8"},
1403 { 22, "-8 <= Pcmax,c < -7"},
1404 { 23, "-7 <= Pcmax,c < -6"},
1405 { 24, "-6 <= Pcmax,c < -5"},
1406 { 25, "-5 <= Pcmax,c < -4"},
1407 { 26, "-4 <= Pcmax,c < -3"},
1408 { 27, "-3 <= Pcmax,c < -2"},
1409 { 28, "-2 <= Pcmax,c < -1"},
1410 { 29, "-1 <= Pcmax,c < 0"},
1411 { 30, "0 <= Pcmax,c < 1"},
1412 { 31, "1 <= Pcmax,c < 2"},
1413 { 32, "2 <= Pcmax,c < 3"},
1414 { 33, "3 <= Pcmax,c < 4"},
1415 { 34, "4 <= Pcmax,c < 5"},
1416 { 35, "5 <= Pcmax,c < 6"},
1417 { 36, "6 <= Pcmax,c < 7"},
1418 { 37, "7 <= Pcmax,c < 8"},
1419 { 38, "8 <= Pcmax,c < 9"},
1420 { 39, "9 <= Pcmax,c < 10"},
1421 { 40, "10 <= Pcmax,c < 11"},
1422 { 41, "11 <= Pcmax,c < 12"},
1423 { 42, "12 <= Pcmax,c < 13"},
1424 { 43, "13 <= Pcmax,c < 14"},
1425 { 44, "14 <= Pcmax,c < 15"},
1426 { 45, "15 <= Pcmax,c < 16"},
1427 { 46, "16 <= Pcmax,c < 17"},
1428 { 47, "17 <= Pcmax,c < 18"},
1429 { 48, "18 <= Pcmax,c < 19"},
1430 { 49, "19 <= Pcmax,c < 20"},
1431 { 50, "20 <= Pcmax,c < 21"},
1432 { 51, "21 <= Pcmax,c < 22"},
1433 { 52, "22 <= Pcmax,c < 23"},
1434 { 53, "23 <= Pcmax,c < 24"},
1435 { 54, "24 <= Pcmax,c < 25"},
1436 { 55, "25 <= Pcmax,c < 26"},
1437 { 56, "26 <= Pcmax,c < 27"},
1438 { 57, "27 <= Pcmax,c < 28"},
1439 { 58, "28 <= Pcmax,c < 29"},
1440 { 59, "29 <= Pcmax,c < 30"},
1441 { 60, "30 <= Pcmax,c < 31"},
1442 { 61, "31 <= Pcmax,c < 32"},
1443 { 62, "32 <= Pcmax,c < 33"},
1444 { 63, "33 <= Pcmax,c"},
1445 { 0, NULL }
1447 static value_string_ext pcmaxc_vals_ext = VALUE_STRING_EXT_INIT(pcmaxc_vals);
1449 static const value_string data_vol_power_headroom_level_vals[] =
1451 { 0, "POWER_HEADROOM_0"},
1452 { 1, "POWER_HEADROOM_1"},
1453 { 2, "POWER_HEADROOM_2"},
1454 { 3, "POWER_HEADROOM_3"},
1455 { 0, NULL }
1458 static const value_string data_vol_extended_power_headroom_level_vals[] =
1460 { 0, "POWER_HEADROOM_0"},
1461 { 1, "POWER_HEADROOM_1"},
1462 { 2, "POWER_HEADROOM_2"},
1463 { 3, "POWER_HEADROOM_3"},
1464 { 4, "POWER_HEADROOM_4"},
1465 { 5, "POWER_HEADROOM_5"},
1466 { 6, "POWER_HEADROOM_6"},
1467 { 7, "POWER_HEADROOM_7"},
1468 { 8, "POWER_HEADROOM_8"},
1469 { 9, "POWER_HEADROOM_9"},
1470 { 10, "POWER_HEADROOM_10"},
1471 { 11, "POWER_HEADROOM_11"},
1472 { 12, "POWER_HEADROOM_12"},
1473 { 13, "POWER_HEADROOM_13"},
1474 { 14, "POWER_HEADROOM_14"},
1475 { 15, "POWER_HEADROOM_15"},
1476 { 0, NULL }
1480 static const value_string data_vol_power_headroom_data_vol_vals[] =
1482 { 0, "DV = 0"},
1483 { 1, "0 < DV <= 10"},
1484 { 2, "10 < DV <= 14"},
1485 { 3, "14 < DV <= 19"},
1486 { 4, "19 < DV <= 26"},
1487 { 5, "26 < DV <= 36"},
1488 { 6, "36 < DV <= 49"},
1489 { 7, "49 < DV <= 67"},
1490 { 8, "67 < DV <= 91"},
1491 { 9, "91 < DV <= 125"},
1492 { 10, "125 < DV <= 171"},
1493 { 11, "171 < DV <= 234"},
1494 { 12, "234 < DV <= 321"},
1495 { 13, "321 < DV <= 768"},
1496 { 14, "768 < DV <= 1500"},
1497 { 15, "DV > 1500"},
1498 { 0, NULL }
1501 static const value_string bit_rate_vals[] =
1503 { 0, "no bit rate recommendation"},
1504 { 1, "0 kbit/s"},
1505 { 2, "8 kbit/s"},
1506 { 3, "10 kbit/s"},
1507 { 4, "12 kbit/s"},
1508 { 5, "16 kbit/s"},
1509 { 6, "20 kbit/s"},
1510 { 7, "24 kbit/s"},
1511 { 8, "28 kbit/s"},
1512 { 9, "32 kbit/s"},
1513 { 10, "36 kbit/s"},
1514 { 11, "40 kbit/s"},
1515 { 12, "48 kbit/s"},
1516 { 13, "56 kbit/s"},
1517 { 14, "72 kbit/s"},
1518 { 15, "88 kbit/s"},
1519 { 16, "104 kbit/s"},
1520 { 17, "120 kbit/s"},
1521 { 18, "140 kbit/s"},
1522 { 19, "160 kbit/s"},
1523 { 20, "180 kbit/s"},
1524 { 21, "200 kbit/s"},
1525 { 22, "220 kbit/s"},
1526 { 23, "240 kbit/s"},
1527 { 24, "260 kbit/s"},
1528 { 25, "280 kbit/s"},
1529 { 26, "300 kbit/s"},
1530 { 27, "350 kbit/s"},
1531 { 28, "400 kbit/s"},
1532 { 29, "450 kbit/s"},
1533 { 30, "500 kbit/s"},
1534 { 31, "600 kbit/s"},
1535 { 32, "700 kbit/s"},
1536 { 33, "800 kbit/s"},
1537 { 34, "900 kbit/s"},
1538 { 35, "1000 kbit/s"},
1539 { 36, "1100 kbit/s"},
1540 { 37, "1200 kbit/s"},
1541 { 38, "1300 kbit/s"},
1542 { 39, "1400 kbit/s"},
1543 { 40, "1500 kbit/s"},
1544 { 41, "1750 kbit/s"},
1545 { 42, "2000 kbit/s"},
1546 { 43, "2250 kbit/s"},
1547 { 44, "2500 kbit/s"},
1548 { 45, "2750 kbit/s"},
1549 { 46, "3000 kbit/s"},
1550 { 47, "3500 kbit/s"},
1551 { 48, "4000 kbit/s"},
1552 { 49, "4500 kbit/s"},
1553 { 50, "5000 kbit/s"},
1554 { 51, "5500 kbit/s"},
1555 { 52, "6000 kbit/s"},
1556 { 53, "6500 kbit/s"},
1557 { 54, "7000 kbit/s"},
1558 { 55, "7500 kbit/s"},
1559 { 56, "8000 kbit/s"},
1560 { 0, NULL }
1562 static value_string_ext bit_rate_vals_ext = VALUE_STRING_EXT_INIT(bit_rate_vals);
1564 static const value_string header_only_vals[] =
1566 { 0, "MAC PDU Headers and body present"},
1567 { 1, "MAC PDU Headers only"},
1568 { 0, NULL }
1571 static const value_string predefined_frame_vals[] =
1573 { 0, "Real MAC PDU present - will dissect"},
1574 { 1, "Predefined frame present - will not dissect"},
1575 { 0, NULL }
1578 static const value_string ul_retx_grant_vals[] =
1580 { 0, "PDCCH ReTx"},
1581 { 1, "PHICH NACK"},
1582 { 0, NULL }
1585 /**************************************************************************/
1586 /* Preferences state */
1587 /**************************************************************************/
1589 /* If this PDU has been NACK'd (by HARQ) more than a certain number of times,
1590 we trigger an expert warning. */
1591 static int global_mac_lte_retx_counter_trigger = 3;
1593 /* By default try to decode transparent data (BCH, PCH and CCCH) data using LTE RRC dissector */
1594 static bool global_mac_lte_attempt_rrc_decode = true;
1596 /* Whether should attempt to dissect frames failing CRC check */
1597 static bool global_mac_lte_dissect_crc_failures;
1599 /* Whether should attempt to decode lcid 1&2 SDUs as srb1/2 (i.e. AM RLC) */
1600 static bool global_mac_lte_attempt_srb_decode = true;
1602 /* Whether should attempt to decode MCH LCID 0 as MCCH */
1603 static bool global_mac_lte_attempt_mcch_decode;
1605 /* Whether should call RLC dissector to decode MTCH LCIDs */
1606 static bool global_mac_lte_call_rlc_for_mtch;
1608 /* Where to take LCID -> DRB mappings from */
1609 enum lcid_drb_source {
1610 FromStaticTable, FromConfigurationProtocol
1612 static int global_mac_lte_lcid_drb_source = (int)FromStaticTable;
1614 /* Threshold for warning in expert info about high BSR values */
1615 static int global_mac_lte_bsr_warn_threshold = 50; /* default is 19325 -> 22624 */
1617 /* Whether or not to track SRs and related frames */
1618 static bool global_mac_lte_track_sr = true;
1620 /* Which layer info to show in the info column */
1621 enum layer_to_show {
1622 ShowPHYLayer, ShowMACLayer, ShowRLCLayer
1625 /* Which layer's details to show in Info column */
1626 static int global_mac_lte_layer_to_show = (int)ShowRLCLayer;
1628 /* Whether to decode Contention Resolution body as UL CCCH */
1629 static bool global_mac_lte_decode_cr_body;
1631 /* Whether to record config and try to show DRX state for each configured UE */
1632 static bool global_mac_lte_show_drx;
1634 /* Whether to record config and try to show DRX state for each configured UE */
1635 static bool global_mac_lte_show_BSR_median;
1638 /* When showing RLC info, count PDUs so can append info column properly */
1639 static uint8_t s_number_of_rlc_pdus_shown;
1641 /***********************************************************************/
1642 /* How to dissect lcid 3-10 (presume drb logical channels) */
1644 static const value_string drb_lcid_vals[] = {
1645 { 3, "LCID 3"},
1646 { 4, "LCID 4"},
1647 { 5, "LCID 5"},
1648 { 6, "LCID 6"},
1649 { 7, "LCID 7"},
1650 { 8, "LCID 8"},
1651 { 9, "LCID 9"},
1652 { 10, "LCID 10"},
1653 { 0, NULL }
1656 typedef enum rlc_channel_type_t {
1657 rlcRaw,
1658 rlcTM,
1659 rlcUM5,
1660 rlcUM10,
1661 rlcAM,
1662 rlcAMulExtLiField,
1663 rlcAMdlExtLiField,
1664 rlcAMextLiField,
1665 rlcAMul16,
1666 rlcAMdl16,
1667 rlcAM16,
1668 rlcAMul16ulExtLiField,
1669 rlcAMdl16ulExtLiField,
1670 rlcAM16ulExtLiField,
1671 rlcAMul16dlExtLiField,
1672 rlcAMdl16dlExtLiField,
1673 rlcAM16dlExtLiField,
1674 rlcAMul16extLiField,
1675 rlcAMdl16extLiField,
1676 rlcAM16extLiField,
1677 } rlc_channel_type_t;
1679 static const value_string rlc_channel_type_vals[] = {
1680 { rlcTM , "TM"},
1681 { rlcUM5 , "UM, SN Len=5"},
1682 { rlcUM10 , "UM, SN Len=10"},
1683 { rlcAM , "AM"},
1684 { rlcAMulExtLiField , "AM, UL Extended LI Field"},
1685 { rlcAMdlExtLiField , "AM, DL Extended LI Field"},
1686 { rlcAMextLiField , "AM, UL/DL Extended LI Field"},
1687 { rlcAMul16 , "AM, UL SN Len=16"},
1688 { rlcAMdl16 , "AM, DL SN Len=16"},
1689 { rlcAM16 , "AM, SN Len=16"},
1690 { rlcAMul16ulExtLiField, "AM, UL SN Len=16, UL Extended LI Field"},
1691 { rlcAMdl16ulExtLiField, "AM, DL SN Len=16, UL Extended LI Field"},
1692 { rlcAM16ulExtLiField , "AM, SN Len=16, UL Extended LI Field"},
1693 { rlcAMul16dlExtLiField, "AM, UL SN Len=16, DL Extended LI Field"},
1694 { rlcAMdl16dlExtLiField, "AM, DL SN Len=16, DL Extended LI Field"},
1695 { rlcAM16dlExtLiField , "AM, SN Len=16, DL Extended LI Field"},
1696 { rlcAMul16extLiField , "AM, UL SN Len=16, UL/DL Extended LI Field"},
1697 { rlcAMdl16extLiField , "AM, DL SN Len=16, UL/DL Extended LI Field"},
1698 { rlcAM16extLiField , "AM, SN Len=16, UL/DL Extended LI Field"},
1699 { 0, NULL }
1703 /* Mapping type */
1704 typedef struct lcid_drb_mapping_t {
1705 uint16_t lcid;
1706 int drbid;
1707 rlc_channel_type_t channel_type;
1708 } lcid_drb_mapping_t;
1710 /* Mapping entity */
1711 static lcid_drb_mapping_t *lcid_drb_mappings;
1712 static unsigned num_lcid_drb_mappings;
1714 UAT_VS_DEF(lcid_drb_mappings, lcid, lcid_drb_mapping_t, uint16_t, 3, "LCID 3")
1715 UAT_SIGNED_DEC_CB_DEF(lcid_drb_mappings, drbid, lcid_drb_mapping_t)
1716 UAT_VS_DEF(lcid_drb_mappings, channel_type, lcid_drb_mapping_t, rlc_channel_type_t, rlcAM, "AM")
1718 /* UAT object */
1719 static uat_t* lcid_drb_mappings_uat;
1721 /* Dynamic mappings (set by configuration protocol)
1722 LCID is the index into the array of these */
1723 typedef struct dynamic_lcid_drb_mapping_t {
1724 bool valid;
1725 int drbid;
1726 rlc_channel_type_t channel_type;
1727 uint8_t ul_priority;
1728 } dynamic_lcid_drb_mapping_t;
1730 typedef struct ue_dynamic_drb_mappings_t {
1731 dynamic_lcid_drb_mapping_t mapping[39]; /* Index is LCID */
1732 uint8_t drb_to_lcid_mappings[33]; /* Also map drbid -> lcid */
1733 } ue_dynamic_drb_mappings_t;
1735 static GHashTable *mac_lte_ue_channels_hash;
1738 extern int proto_rlc_lte;
1740 /***************************************************************/
1744 /***************************************************************/
1745 /* Keeping track of Msg3 bodies so they can be compared with */
1746 /* Contention Resolution bodies. */
1748 typedef struct Msg3Data {
1749 uint8_t data[6];
1750 nstime_t msg3Time;
1751 uint32_t framenum;
1752 } Msg3Data;
1755 /* This table stores (RNTI -> Msg3Data*). Will be populated when
1756 Msg3 frames are first read. */
1757 static GHashTable *mac_lte_msg3_hash;
1759 typedef enum ContentionResolutionStatus {
1760 NoMsg3,
1761 Msg3Match,
1762 Msg3NoMatch
1763 } ContentionResolutionStatus;
1765 typedef struct ContentionResolutionResult {
1766 ContentionResolutionStatus status;
1767 unsigned msg3FrameNum;
1768 unsigned msSinceMsg3;
1769 } ContentionResolutionResult;
1772 /* This table stores (CRFrameNum -> CRResult). It is assigned during the first
1773 pass and used thereafter */
1774 static GHashTable *mac_lte_cr_result_hash;
1776 /* This table stores msg3 frame -> CR frame. It is assigned during the first pass
1777 * and shown in later passes */
1778 static GHashTable *mac_lte_msg3_cr_hash;
1780 /**************************************************************************/
1784 /****************************************************************/
1785 /* Keeping track of last DL frames per C-RNTI so can guess when */
1786 /* there has been a HARQ retransmission */
1787 /* TODO: this should be simplified now that harq-id & ndi are */
1788 /* being logged! */
1790 /* Could be bigger, but more than enough to flag suspected resends */
1791 #define MAX_EXPECTED_PDU_LENGTH 2048
1793 typedef struct LastFrameData {
1794 bool inUse;
1795 uint32_t framenum;
1796 bool ndi;
1797 nstime_t received_time;
1798 int length;
1799 uint8_t data[MAX_EXPECTED_PDU_LENGTH];
1800 } LastFrameData;
1802 typedef struct DLHarqBuffers {
1803 LastFrameData harqid[2][15]; /* 2 blocks (1 for each antenna) needed for DL */
1804 } DLHarqBuffers;
1807 /* This table stores (RNTI -> DLHARQBuffers*). Will be populated when
1808 DL frames are first read. */
1809 static GHashTable *mac_lte_dl_harq_hash;
1811 typedef struct DLHARQResult {
1812 bool previousSet, nextSet;
1813 unsigned previousFrameNum;
1814 unsigned timeSincePreviousFrame;
1815 unsigned nextFrameNum;
1816 unsigned timeToNextFrame;
1817 } DLHARQResult;
1820 /* This table stores (FrameNumber -> *DLHARQResult). It is assigned during the first
1821 pass and used thereafter */
1822 static GHashTable *mac_lte_dl_harq_result_hash;
1824 /**************************************************************************/
1827 /*****************************************************************/
1828 /* Keeping track of last UL frames per C-RNTI so can verify when */
1829 /* told that a frame is a retx */
1831 typedef struct ULHarqBuffers {
1832 LastFrameData harqid[8];
1833 } ULHarqBuffers;
1836 /* This table stores (RNTI -> ULHarqBuffers*). Will be populated when
1837 UL frames are first read. */
1838 static GHashTable *mac_lte_ul_harq_hash;
1840 typedef struct ULHARQResult {
1841 bool previousSet, nextSet;
1842 unsigned previousFrameNum;
1843 unsigned timeSincePreviousFrame;
1844 unsigned nextFrameNum;
1845 unsigned timeToNextFrame;
1846 } ULHARQResult;
1849 /* This table stores (FrameNum -> ULHARQResult). It is assigned during the first
1850 pass and used thereafter */
1851 /* TODO: add ueid/rnti to key... */
1852 static GHashTable *mac_lte_ul_harq_result_hash;
1854 /**************************************************************************/
1857 /**************************************************************************/
1858 /* Tracking of Scheduling Requests (SRs). */
1859 /* Keep track of: */
1860 /* - last grant before SR */
1861 /* - SR failures following request */
1862 /* - grant following SR */
1864 typedef enum SREvent {
1865 SR_Grant,
1866 SR_Request,
1867 SR_Failure
1868 } SREvent;
1870 static const value_string sr_event_vals[] =
1872 { SR_Grant, "Grant"},
1873 { SR_Request, "SR Request"},
1874 { SR_Failure, "SR Failure"},
1875 { 0, NULL}
1878 typedef enum SRStatus {
1879 None,
1880 SR_Outstanding,
1881 SR_Failed
1882 } SRStatus;
1884 static const value_string sr_status_vals[] =
1886 { None, "Receiving grants"},
1887 { SR_Outstanding, "SR Request outstanding"},
1888 { SR_Failed, "SR has Failed"},
1889 { 0, NULL}
1893 typedef struct SRState {
1894 SRStatus status;
1895 uint32_t lastSRFramenum;
1896 uint32_t lastGrantFramenum;
1897 nstime_t requestTime;
1898 } SRState;
1901 /* This table keeps track of the SR state for each UE.
1902 (RNTI -> SRState) */
1903 static GHashTable *mac_lte_ue_sr_state;
1906 typedef enum SRResultType {
1907 GrantAnsweringSR,
1908 FailureAnsweringSR,
1909 SRLeadingToGrant,
1910 SRLeadingToFailure,
1911 InvalidSREvent
1912 } SRResultType;
1915 typedef struct SRResult {
1916 SRResultType type;
1917 uint32_t frameNum;
1918 uint32_t timeDifference;
1920 /* These 2 are only used with InvalidSREvent */
1921 SRStatus status;
1922 SREvent event;
1923 } SRResult;
1925 /* Entries in this table are created during the first pass
1926 It maps (SRFrameNum -> SRResult) */
1927 static GHashTable *mac_lte_sr_request_hash;
1929 /**************************************************************************/
1932 typedef struct drx_running_state_t
1934 bool firstCycleStartSet;
1936 /* Cycle information */
1937 bool inShortCycle;
1939 /* Timers */
1940 nstime_t currentTime; /* absolute time of last PDU. Used to detect whole
1941 missing SFN cycle */
1943 uint64_t currentTicks;
1944 uint16_t currentSFN;
1945 uint16_t currentSF;
1947 /* These timers are absolute times when these events expire */
1948 uint64_t onDurationTimer;
1949 uint64_t inactivityTimer;
1950 uint64_t RTT[8];
1951 uint64_t retransmissionTimer[8];
1952 uint64_t shortCycleTimer;
1954 } drx_running_state_t;
1956 /* Have 2 states for each PDU. One for before the PDU/event, and one after.
1957 Only then can show if we don't think it should have been active at that point... */
1958 typedef struct drx_state_t {
1959 drx_config_t config;
1960 drx_running_state_t state_before;
1961 drx_running_state_t state_after;
1962 } drx_state_t;
1964 typedef struct ue_parameters_t
1966 bool use_ext_bsr_sizes;
1967 bool use_simult_pucch_pusch_pcell;
1968 bool use_simult_pucch_pusch_pscell;
1969 bool drx_state_valid;
1970 drx_state_t drx_state;
1971 } ue_parameters_t;
1973 /* Entries in this table are maintained during the first pass
1974 It maps (UEId -> ue_parameters_t). */
1975 static GHashTable *mac_lte_ue_parameters;
1978 /**************************************************************************/
1979 /* DRX State */
1980 /* Config for current cycle/timer state for a configured UE */
1983 typedef struct drx_state_key_t {
1984 uint32_t frameNumber;
1985 unsigned pdu_instance;
1986 } drx_state_key_t;
1988 /* Entries in this table are written during the first pass
1989 It maps (drx_state_key_t -> drx_state_t), so state at that point may be shown. */
1990 static GHashTable *mac_lte_drx_frame_result;
1992 static int mac_lte_framenum_instance_hash_equal(const void *v, const void *v2)
1994 const drx_state_key_t *p1 = (const drx_state_key_t*)v;
1995 const drx_state_key_t *p2 = (const drx_state_key_t*)v2;
1997 return ((p1->frameNumber == p2->frameNumber) &&
1998 (p1->pdu_instance == p2->pdu_instance));
2001 static unsigned mac_lte_framenum_instance_hash_func(const void *v)
2003 const drx_state_key_t *p1 = (const drx_state_key_t*)v;
2005 return p1->frameNumber + (p1->pdu_instance >> 8);
2011 /* Initialise the UE DRX state */
2012 static void init_drx_ue_state(drx_state_t *drx_state, bool at_init)
2014 int i;
2015 drx_state->state_before.inShortCycle = false;
2016 if (at_init) {
2017 drx_state->state_before.onDurationTimer = UINT64_C(0);
2019 drx_state->state_before.inactivityTimer = UINT64_C(0);
2020 for (i=0; i < 8; i++) {
2021 drx_state->state_before.RTT[i] = UINT64_C(0);
2022 drx_state->state_before.retransmissionTimer[i] = UINT64_C(0);
2024 drx_state->state_before.shortCycleTimer = UINT64_C(0);
2027 typedef enum drx_timer_type_t {
2028 drx_onduration_timer,
2029 drx_inactivity_timer,
2030 drx_rtt_timer,
2031 drx_retx_timer,
2032 drx_short_cycle_timer
2033 } drx_timer_type_t;
2035 /* Start the specified timer. Use the time period in the config */
2036 static void mac_lte_drx_start_timer(drx_state_t *p_state, drx_timer_type_t timer_type, uint8_t timer_id)
2038 /* Get current time in ms */
2039 uint64_t *pTimer;
2040 uint16_t timerLength;
2042 /* Get pointer to timer value, and fetch from config how much to add to it */
2043 switch (timer_type) {
2044 case drx_onduration_timer:
2045 pTimer = &(p_state->state_before.onDurationTimer);
2046 timerLength = p_state->config.onDurationTimer;
2047 break;
2048 case drx_inactivity_timer:
2049 pTimer = &(p_state->state_before.inactivityTimer);
2050 timerLength = p_state->config.inactivityTimer;
2051 break;
2052 case drx_rtt_timer:
2053 pTimer = &(p_state->state_before.RTT[timer_id]);
2054 timerLength = 8;
2055 break;
2056 case drx_retx_timer:
2057 pTimer = &(p_state->state_before.retransmissionTimer[timer_id]);
2058 timerLength = p_state->config.retransmissionTimer;
2059 break;
2060 case drx_short_cycle_timer:
2061 default:
2062 pTimer = &(p_state->state_before.shortCycleTimer);
2063 timerLength = p_state->config.shortCycle * p_state->config.shortCycleTimer;
2064 break;
2067 /* Set timer */
2068 *pTimer = p_state->state_before.currentTicks + timerLength;
2071 /* Stop the specified timer. */
2072 static void mac_lte_drx_stop_timer(drx_state_t *p_state, drx_timer_type_t timer_type, uint8_t timer_id)
2074 /* Set indicated timer value to 0 */
2075 switch (timer_type) {
2076 case drx_onduration_timer:
2077 p_state->state_before.onDurationTimer = UINT64_C(0);
2078 break;
2079 case drx_inactivity_timer:
2080 p_state->state_before.inactivityTimer = UINT64_C(0);
2081 break;
2082 case drx_rtt_timer:
2083 p_state->state_before.RTT[timer_id] = UINT64_C(0);
2084 break;
2085 case drx_retx_timer:
2086 p_state->state_before.retransmissionTimer[timer_id] = UINT64_C(0);
2087 break;
2088 case drx_short_cycle_timer:
2089 p_state->state_before.shortCycleTimer = UINT64_C(0);
2090 break;
2094 /* Has the specified timer expired? */
2095 static bool mac_lte_drx_has_timer_expired(drx_state_t *p_state, drx_timer_type_t timer_type, uint8_t timer_id,
2096 bool before_event,
2097 uint64_t *time_until_expires)
2099 uint64_t *pTimer = NULL;
2100 drx_running_state_t *state_to_use;
2102 if (before_event) {
2103 state_to_use = &p_state->state_before;
2105 else {
2106 state_to_use = &p_state->state_after;
2110 /* Get pointer to timer value */
2111 switch (timer_type) {
2112 case drx_onduration_timer:
2113 pTimer = &(state_to_use->onDurationTimer);
2114 break;
2115 case drx_inactivity_timer:
2116 pTimer = &(state_to_use->inactivityTimer);
2117 break;
2118 case drx_rtt_timer:
2119 pTimer = &(state_to_use->RTT[timer_id]);
2120 break;
2121 case drx_retx_timer:
2122 pTimer = &(state_to_use->retransmissionTimer[timer_id]);
2123 break;
2124 case drx_short_cycle_timer:
2125 pTimer = &(state_to_use->shortCycleTimer);
2126 break;
2128 default:
2129 return false;
2132 /* TODO: verify using SFN/SF ? */
2133 if (state_to_use->currentTicks == *pTimer) {
2134 *time_until_expires = 0;
2135 return true;
2138 if (state_to_use->currentTicks > *pTimer) {
2139 *time_until_expires = 0;
2141 else {
2142 *time_until_expires = *pTimer - state_to_use->currentTicks;
2145 return false;
2149 /* Handling of triggers that can prompt changes in state */
2151 static void mac_lte_drx_new_ulsch_data(uint16_t ueid)
2153 /* Look up state of this UE */
2154 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2155 GUINT_TO_POINTER((unsigned)ueid));
2157 /* Start inactivity timer */
2158 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2159 mac_lte_drx_start_timer(&ue_params->drx_state, drx_inactivity_timer, 0);
2163 static void mac_lte_drx_new_dlsch_data(uint16_t ueid)
2165 /* Look up state of this UE */
2166 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2167 GUINT_TO_POINTER((unsigned)ueid));
2169 /* Start retransmission timer */
2170 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2171 mac_lte_drx_start_timer(&ue_params->drx_state, drx_inactivity_timer, 0);
2175 static void mac_lte_drx_dl_crc_error(uint16_t ueid)
2177 /* Look up state of this UE */
2178 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2179 GUINT_TO_POINTER((unsigned)ueid));
2181 /* Start timer */
2182 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2183 mac_lte_drx_start_timer(&ue_params->drx_state, drx_retx_timer, 0);
2187 /* A DRX control element has been received */
2188 static void mac_lte_drx_control_element_received(uint16_t ueid)
2190 /* Look up state of this UE */
2191 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2192 GUINT_TO_POINTER((unsigned)ueid));
2194 /* Start timers */
2195 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2196 mac_lte_drx_stop_timer(&ue_params->drx_state, drx_onduration_timer, 0);
2197 mac_lte_drx_stop_timer(&ue_params->drx_state, drx_inactivity_timer, 0);
2202 /* Update the DRX state of the UE based on previous info and current time.
2203 This is called every time a UE with DRX configured has an UL or DL PDU */
2204 static void update_drx_info(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
2206 int harq_id;
2207 uint64_t time_until_expires;
2209 /* Look up state of this UE */
2210 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2211 GUINT_TO_POINTER((unsigned)p_mac_lte_info->ueid));
2213 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2214 /* We loop until we find this subframe */
2215 drx_state_t *ue_state = &ue_params->drx_state;
2216 uint16_t SFN = p_mac_lte_info->sysframeNumber;
2217 uint16_t SF = p_mac_lte_info->subframeNumber;
2219 /* Make sure the first time reference has been set */
2220 if (!ue_state->state_before.firstCycleStartSet) {
2221 /* Set current time to now */
2222 ue_state->state_before.currentSFN = SFN;
2223 ue_state->state_before.currentSF = SF;
2225 ue_state->state_before.currentTicks = SFN*10 + SF;
2227 ue_state->state_before.firstCycleStartSet = true;
2230 /* Will loop around these checks, once for each subframe between previous
2231 currentTime for this UE, and the time now!!! */
2232 /* It *should* be possible to just deal with the elapsed time all at once,
2233 but much harder to get right, so loop. */
2235 /* If > ~10s since last PDU, just zero all timers (except onDuration) */
2236 if ((pinfo->abs_ts.secs - ue_state->state_before.currentTime.secs) >= 9) {
2237 init_drx_ue_state(ue_state, false);
2240 while ((ue_state->state_before.currentSFN != SFN) || (ue_state->state_before.currentSF != SF)) {
2241 uint16_t subframes = ue_state->state_before.currentSFN*10 + ue_state->state_before.currentSF;
2243 /* Check for timers that have expired and change state accordingly */
2245 /* Short -> long transition */
2246 if (ue_state->state_before.inShortCycle) {
2247 if (mac_lte_drx_has_timer_expired(ue_state, drx_short_cycle_timer, 0, true, &time_until_expires)) {
2248 ue_state->state_before.inShortCycle = false;
2252 /* See if onDuration timer should be started */
2254 if (!ue_state->state_before.inShortCycle) {
2255 if ((subframes % ue_state->config.longCycle) == ue_state->config.cycleOffset) {
2256 mac_lte_drx_start_timer(ue_state, drx_onduration_timer, 0);
2259 else {
2260 if ((subframes % ue_state->config.shortCycle) == (ue_state->config.cycleOffset % ue_state->config.shortCycle)) {
2261 mac_lte_drx_start_timer(ue_state, drx_onduration_timer, 0);
2265 /* Check for HARQ RTT Timer expiring.
2266 In practice only one could expire in any given subframe... */
2267 for (harq_id = 0 ; harq_id < 8; harq_id++) {
2268 if (mac_lte_drx_has_timer_expired(ue_state, drx_rtt_timer, harq_id, true, &time_until_expires)) {
2269 /* Start the Retransmission timer */
2270 mac_lte_drx_start_timer(ue_state, drx_retx_timer, harq_id);
2274 /* Reception of DRX command is dealt with separately at the moment... */
2276 /* Inactivity timer expired */
2277 if (mac_lte_drx_has_timer_expired(ue_state, drx_inactivity_timer, 0, true, &time_until_expires)) {
2278 if (ue_state->config.shortCycleConfigured) {
2279 ue_state->state_before.inShortCycle = true;
2280 mac_lte_drx_start_timer(ue_state, drx_short_cycle_timer, 0);
2285 /* Move subframe along by one */
2286 if (ue_state->state_before.currentSF == 9) {
2287 ue_state->state_before.currentSF = 0;
2288 if (ue_state->state_before.currentSFN == 1023) {
2289 ue_state->state_before.currentSFN = 0;
2291 else {
2292 ue_state->state_before.currentSFN++;
2295 else {
2296 ue_state->state_before.currentSF++;
2299 ue_state->state_before.currentTicks++;
2302 /* Set current time to now */
2303 ue_state->state_before.currentTime = pinfo->abs_ts;
2307 /* Convenience function to get a pointer for the hash_func to work with */
2308 static void *get_drx_result_hash_key(uint32_t frameNumber,
2309 unsigned pdu_instance,
2310 bool do_persist)
2312 static drx_state_key_t key;
2313 drx_state_key_t *p_key;
2315 /* Only allocate a struct when will be adding entry */
2316 if (do_persist) {
2317 p_key = wmem_new0(wmem_file_scope(), drx_state_key_t);
2319 else {
2320 memset(&key, 0, sizeof(drx_state_key_t));
2321 p_key = &key;
2324 /* Fill in details, and return pointer */
2325 p_key->frameNumber = frameNumber;
2326 p_key->pdu_instance = pdu_instance;
2328 return p_key;
2332 /* Set DRX information to display for the current MAC frame.
2333 Only called on first pass through frames. */
2334 static void set_drx_info(packet_info *pinfo, mac_lte_info *p_mac_lte_info, bool before_event, unsigned pdu_instance)
2336 /* Look up state of this UE */
2337 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2338 GUINT_TO_POINTER((unsigned)p_mac_lte_info->ueid));
2339 drx_state_t *frame_result;
2341 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2342 /* Should only need to allocate frame_result and add to the result table when
2343 before PDU is processed */
2344 if (before_event) {
2345 /* Copy UE snapshot for this frame, and add to result table */
2346 frame_result = wmem_new(wmem_file_scope(), drx_state_t);
2348 /* Deep-copy this snapshot for this frame */
2349 *frame_result = ue_params->drx_state;
2351 /* And store in table */
2352 g_hash_table_insert(mac_lte_drx_frame_result, get_drx_result_hash_key(pinfo->num, pdu_instance, true), frame_result);
2354 else {
2355 /* After update, so just copy ue_state 'state' info after part of frame */
2356 frame_result = (drx_state_t*)g_hash_table_lookup(mac_lte_drx_frame_result,
2357 get_drx_result_hash_key(pinfo->num, pdu_instance, false));
2358 if (frame_result != NULL) {
2359 /* Deep-copy updated state from UE */
2360 frame_result->state_after = ue_params->drx_state.state_before;
2366 /* Show DRX information associated with this MAC frame */
2367 static void show_drx_info(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
2368 mac_lte_info *p_mac_lte_info, bool before_event, unsigned pdu_instance)
2370 drx_state_t *frame_state;
2371 drx_running_state_t *state_to_show;
2372 uint64_t time_until_expires;
2373 unsigned n;
2375 /* Look up entry by frame number in result table */
2376 frame_state = (drx_state_t *)g_hash_table_lookup(mac_lte_drx_frame_result,
2377 get_drx_result_hash_key(pinfo->num, pdu_instance, false));
2379 /* Show available information */
2380 if (frame_state != NULL) {
2381 proto_tree *drx_config_tree, *drx_state_tree;
2382 proto_item *drx_config_ti, *drx_state_ti, *ti;
2384 /* Show config only if 'before */
2385 if (before_event) {
2386 /************************************/
2387 /* Create config subtree */
2388 drx_config_ti = proto_tree_add_string_format(tree, hf_mac_lte_drx_config,
2389 tvb, 0, 0, "", "DRX Config");
2390 drx_config_tree = proto_item_add_subtree(drx_config_ti, ett_mac_lte_drx_config);
2391 proto_item_set_generated(drx_config_ti);
2393 /* Link back to configuration (RRC) frame */
2394 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_frame_num, tvb,
2395 0, 0, frame_state->config.frameNum);
2396 proto_item_set_generated(ti);
2398 /* Link back to any previous config frame (only from current config frame) */
2399 if ((frame_state->config.frameNum == pinfo->num) &&
2400 (frame_state->config.previousFrameNum != 0)) {
2401 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_previous_frame_num, tvb,
2402 0, 0, frame_state->config.previousFrameNum);
2403 proto_item_set_generated(ti);
2406 /* Config fields */
2407 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_long_cycle, tvb,
2408 0, 0, frame_state->config.longCycle);
2409 proto_item_set_generated(ti);
2410 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_cycle_offset, tvb,
2411 0, 0, frame_state->config.cycleOffset);
2412 proto_item_set_generated(ti);
2413 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_onduration_timer, tvb,
2414 0, 0, frame_state->config.onDurationTimer);
2415 proto_item_set_generated(ti);
2416 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_inactivity_timer, tvb,
2417 0, 0, frame_state->config.inactivityTimer);
2418 proto_item_set_generated(ti);
2419 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_retransmission_timer, tvb,
2420 0, 0, frame_state->config.retransmissionTimer);
2421 proto_item_set_generated(ti);
2423 if (frame_state->config.shortCycleConfigured) {
2424 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_short_cycle, tvb,
2425 0, 0, frame_state->config.shortCycle);
2426 proto_item_set_generated(ti);
2428 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_short_cycle_timer, tvb,
2429 0, 0, frame_state->config.shortCycleTimer);
2430 proto_item_set_generated(ti);
2433 proto_item_append_text(drx_config_ti, " (Long-cycle=%u cycle-offset=%u onDuration=%u)",
2434 frame_state->config.longCycle, frame_state->config.cycleOffset,
2435 frame_state->config.onDurationTimer);
2436 if (frame_state->config.shortCycleConfigured) {
2437 proto_item_append_text(drx_config_ti, " (Short-cycle=%u Short-cycle-timer=%u)",
2438 frame_state->config.shortCycle, frame_state->config.shortCycleTimer);
2442 /*************************************/
2443 /* Create state subtree */
2444 drx_state_ti = proto_tree_add_string_format(tree, hf_mac_lte_drx_state,
2445 tvb, 0, 0, "",
2446 (before_event) ? "DRX State Before" : "DRX State After");
2447 /* Get appropriate state pointer to use below */
2448 if (before_event) {
2449 state_to_show = &frame_state->state_before;
2451 else {
2452 state_to_show = &frame_state->state_after;
2455 drx_state_tree = proto_item_add_subtree(drx_state_ti, ett_mac_lte_drx_state);
2456 proto_item_set_generated(drx_state_ti);
2458 /* Show cycle information */
2460 if (!state_to_show->inShortCycle) {
2461 /* Show where we are in current long cycle */
2462 uint16_t offset_into_long_cycle = ((p_mac_lte_info->sysframeNumber*10) + p_mac_lte_info->subframeNumber) %
2463 frame_state->config.longCycle;
2464 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_long_cycle_offset, tvb,
2465 0, 0, offset_into_long_cycle);
2466 proto_item_set_generated(ti);
2468 else {
2469 /* Show where we are inside short cycle */
2470 uint16_t offset_into_short_cycle = ((p_mac_lte_info->sysframeNumber*10) + p_mac_lte_info->subframeNumber) %
2471 frame_state->config.shortCycle;
2473 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_short_cycle_offset, tvb,
2474 0, 0, offset_into_short_cycle);
2475 proto_item_set_generated(ti);
2477 /* Is short-cycle-timer running? */
2478 if (!mac_lte_drx_has_timer_expired(frame_state, drx_short_cycle_timer, 0, before_event, &time_until_expires)) {
2479 if (time_until_expires) {
2480 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_short_cycle_remaining, tvb,
2481 0, 0, (uint16_t)time_until_expires);
2482 proto_item_set_generated(ti);
2487 /* Show which timers are still running and how long they have to go.
2488 TODO: Complain if it looks like DRX looks like it should be on
2489 TODO: if PDU is a retranmission, would be good to check to see if DRX
2490 would have been on for original Tx! */
2492 /* Is onduration timer running? */
2493 if (!mac_lte_drx_has_timer_expired(frame_state, drx_onduration_timer, 0, before_event, &time_until_expires)) {
2494 if (time_until_expires) {
2495 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_onduration_remaining, tvb,
2496 0, 0, (uint16_t)time_until_expires);
2497 proto_item_set_generated(ti);
2501 /* Is inactivity timer running? */
2502 if (!mac_lte_drx_has_timer_expired(frame_state, drx_inactivity_timer, 0, before_event, &time_until_expires)) {
2503 if (time_until_expires) {
2504 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_inactivity_remaining, tvb,
2505 0, 0, (uint16_t)time_until_expires);
2506 proto_item_set_generated(ti);
2510 /* Are any of the Retransmission timers running? */
2511 for (n=0; n < 8; n++) {
2512 if (!mac_lte_drx_has_timer_expired(frame_state, drx_retx_timer, n, before_event, &time_until_expires)) {
2513 if (time_until_expires) {
2514 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_retransmission_remaining, tvb,
2515 0, 0, (uint16_t)time_until_expires);
2516 proto_item_set_generated(ti);
2517 proto_item_append_text(ti, " (harqid=%u)", n);
2522 /* Are any of the RTT timers running? */
2523 for (n=0; n < 8; n++) {
2524 if (!mac_lte_drx_has_timer_expired(frame_state, drx_rtt_timer, n, before_event, &time_until_expires)) {
2525 if (time_until_expires) {
2526 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_rtt_remaining, tvb,
2527 0, 0, (uint16_t)time_until_expires);
2528 proto_item_set_generated(ti);
2529 proto_item_append_text(ti, " (harqid=%u)", n);
2537 /**************************************************************************/
2540 /* Info we might learn from SIB2 to label RAPIDs seen in PRACH and RARs */
2541 static bool s_rapid_ranges_configured;
2542 static unsigned s_rapid_ranges_groupA;
2543 static unsigned s_rapid_ranges_RA;
2545 /* Return string description of rapid */
2546 static const char *get_mac_lte_rapid_description(uint8_t rapid)
2548 if (!s_rapid_ranges_configured) {
2549 return "";
2551 else {
2552 if (rapid < s_rapid_ranges_groupA) {
2553 return "[GroupA]";
2555 else if (rapid < s_rapid_ranges_RA) {
2556 return "[GroupB]";
2558 else {
2559 return "[Non-RA]";
2564 /**************************************************************************/
2565 /* Tracking of extended BSR sizes configuration */
2567 static void
2568 get_mac_lte_ue_ext_bsr_sizes(mac_lte_info *p_mac_lte_info)
2570 gpointer p_orig_key, p_ue_params;
2572 /* Use the _extended function to check the key presence and avoid overriding a
2573 value already set by the framing protocol while no RRC value is configured */
2574 if (g_hash_table_lookup_extended(mac_lte_ue_parameters,
2575 GUINT_TO_POINTER((unsigned)p_mac_lte_info->ueid),
2576 &p_orig_key, &p_ue_params)) {
2577 p_mac_lte_info->isExtendedBSRSizes = ((ue_parameters_t *)p_ue_params)->use_ext_bsr_sizes;
2581 /**************************************************************************/
2582 /* Tracking of simultaneous PUCCH/PUSCH configuration */
2584 static void
2585 get_mac_lte_ue_simult_pucch_pusch(mac_lte_info *p_mac_lte_info)
2587 gpointer p_orig_key, p_ue_params;
2589 /* Use the _extended function to check the key presence and avoid overriding a
2590 value already set by the framing protocol while no RRC value is configured */
2591 if (g_hash_table_lookup_extended(mac_lte_ue_parameters,
2592 GUINT_TO_POINTER((unsigned)p_mac_lte_info->ueid),
2593 &p_orig_key, &p_ue_params)) {
2594 p_mac_lte_info->isSimultPUCCHPUSCHPCell = ((ue_parameters_t *)p_ue_params)->use_simult_pucch_pusch_pcell;
2595 p_mac_lte_info->isSimultPUCCHPUSCHPSCell = ((ue_parameters_t *)p_ue_params)->use_simult_pucch_pusch_pscell;
2599 /* Forward declarations */
2600 static int dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*);
2602 static uint8_t get_mac_lte_channel_priority(uint16_t ueid _U_, uint8_t lcid,
2603 uint8_t direction);
2606 static void
2607 call_with_catch_all(dissector_handle_t handle, tvbuff_t* tvb, packet_info *pinfo, proto_tree *tree)
2609 /* Call it (catch exceptions so that stats will be updated) */
2610 if (handle) {
2611 TRY {
2612 call_dissector_only(handle, tvb, pinfo, tree, NULL);
2614 CATCH_ALL {
2616 ENDTRY
2620 /* Dissect context fields in the format described in packet-mac-lte.h.
2621 Return true if the necessary information was successfully found */
2622 bool dissect_mac_lte_context_fields(struct mac_lte_info *p_mac_lte_info, tvbuff_t *tvb,
2623 packet_info *pinfo, proto_tree *tree, int *p_offset)
2625 int offset = *p_offset;
2626 uint8_t tag = 0;
2628 /* Read fixed fields */
2629 p_mac_lte_info->radioType = tvb_get_uint8(tvb, offset++);
2630 p_mac_lte_info->direction = tvb_get_uint8(tvb, offset++);
2632 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2633 p_mac_lte_info->detailed_phy_info.ul_info.present = false;
2635 else {
2636 p_mac_lte_info->detailed_phy_info.dl_info.present = false;
2639 p_mac_lte_info->rntiType = tvb_get_uint8(tvb, offset++);
2641 p_mac_lte_info->sfnSfInfoPresent = false; /* Set this to true later if the relative tag is read */
2643 /* Initialize RNTI with a default value in case optional field is not present */
2644 switch (p_mac_lte_info->rntiType) {
2645 case SC_RNTI:
2646 p_mac_lte_info->rnti = 0xFFFB;
2647 break;
2648 case M_RNTI:
2649 p_mac_lte_info->rnti = 0xFFFD;
2650 break;
2651 case P_RNTI:
2652 p_mac_lte_info->rnti = 0xFFFE;
2653 break;
2654 case SI_RNTI:
2655 p_mac_lte_info->rnti = 0xFFFF;
2656 break;
2657 case RA_RNTI:
2658 case C_RNTI:
2659 case SPS_RNTI:
2660 case SL_RNTI:
2661 case G_RNTI:
2662 p_mac_lte_info->rnti = 0x0001;
2663 break;
2664 default:
2665 break;
2668 /* Read optional fields */
2669 while (tag != MAC_LTE_PAYLOAD_TAG) {
2670 /* Process next tag */
2671 tag = tvb_get_uint8(tvb, offset++);
2672 switch (tag) {
2673 case MAC_LTE_RNTI_TAG:
2674 p_mac_lte_info->rnti = tvb_get_ntohs(tvb, offset);
2675 offset += 2;
2676 break;
2677 case MAC_LTE_UEID_TAG:
2678 p_mac_lte_info->ueid = tvb_get_ntohs(tvb, offset);
2679 offset += 2;
2680 break;
2681 case MAC_LTE_FRAME_SUBFRAME_TAG:
2683 p_mac_lte_info->sfnSfInfoPresent = true;
2684 uint16_t sfn_sf = tvb_get_ntohs(tvb, offset);
2685 p_mac_lte_info->sysframeNumber = (sfn_sf >> 4) & 0x03ff;
2686 p_mac_lte_info->subframeNumber = sfn_sf & 0x000f;
2687 offset += 2;
2689 break;
2690 case MAC_LTE_PREDEFINED_DATA_TAG:
2691 p_mac_lte_info->isPredefinedData = tvb_get_uint8(tvb, offset);
2692 offset++;
2693 break;
2694 case MAC_LTE_RETX_TAG:
2695 p_mac_lte_info->reTxCount = tvb_get_uint8(tvb, offset);
2696 offset++;
2697 break;
2698 case MAC_LTE_CRC_STATUS_TAG:
2699 p_mac_lte_info->crcStatusValid = true;
2700 p_mac_lte_info->crcStatus =
2701 (mac_lte_crc_status)tvb_get_uint8(tvb, offset);
2702 offset++;
2703 break;
2704 case MAC_LTE_EXT_BSR_SIZES_TAG:
2705 p_mac_lte_info->isExtendedBSRSizes = true;
2706 break;
2707 case MAC_LTE_SEND_PREAMBLE_TAG:
2708 p_mac_lte_info->oob_event = ltemac_send_preamble;
2709 p_mac_lte_info->rapid = tvb_get_uint8(tvb, offset);
2710 offset++;
2711 p_mac_lte_info->rach_attempt_number = tvb_get_uint8(tvb, offset);
2712 offset++;
2713 break;
2714 case MAC_LTE_CARRIER_ID_TAG:
2715 p_mac_lte_info->carrierId =
2716 (mac_lte_carrier_id)tvb_get_uint8(tvb, offset);
2717 offset++;
2718 break;
2719 case MAC_LTE_PHY_TAG:
2721 int len, offset1;
2723 len = tvb_get_uint8(tvb, offset++);
2724 offset1 = offset;
2725 if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
2726 if (len < 10)
2727 goto next;
2728 p_mac_lte_info->detailed_phy_info.dl_info.present = true;
2729 p_mac_lte_info->detailed_phy_info.dl_info.dci_format =
2730 tvb_get_uint8(tvb, offset);
2731 offset++;
2732 p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type =
2733 tvb_get_uint8(tvb, offset);
2734 offset++;
2735 p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level =
2736 tvb_get_uint8(tvb, offset);
2737 offset++;
2738 p_mac_lte_info->detailed_phy_info.dl_info.mcs_index =
2739 tvb_get_uint8(tvb, offset);
2740 offset++;
2741 p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index =
2742 tvb_get_uint8(tvb, offset);
2743 offset++;
2744 p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length =
2745 tvb_get_uint8(tvb, offset);
2746 offset++;
2747 p_mac_lte_info->detailed_phy_info.dl_info.harq_id =
2748 tvb_get_uint8(tvb, offset);
2749 offset++;
2750 p_mac_lte_info->detailed_phy_info.dl_info.ndi =
2751 tvb_get_uint8(tvb, offset);
2752 offset++;
2753 p_mac_lte_info->detailed_phy_info.dl_info.transport_block =
2754 tvb_get_uint8(tvb, offset);
2755 offset++;
2756 p_mac_lte_info->dl_retx =
2757 (mac_lte_dl_retx)tvb_get_uint8(tvb, offset);
2758 } else {
2759 if (len < 6)
2760 goto next;
2761 p_mac_lte_info->detailed_phy_info.ul_info.present = true;
2762 p_mac_lte_info->detailed_phy_info.ul_info.modulation_type =
2763 tvb_get_uint8(tvb, offset);
2764 offset++;
2765 p_mac_lte_info->detailed_phy_info.ul_info.tbs_index =
2766 tvb_get_uint8(tvb, offset);
2767 offset++;
2768 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length =
2769 tvb_get_uint8(tvb, offset);
2770 offset++;
2771 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start =
2772 tvb_get_uint8(tvb, offset);
2773 offset++;
2774 p_mac_lte_info->detailed_phy_info.ul_info.harq_id =
2775 tvb_get_uint8(tvb, offset);
2776 offset++;
2777 p_mac_lte_info->detailed_phy_info.ul_info.ndi =
2778 tvb_get_uint8(tvb, offset);
2780 next:
2781 offset = offset1 + len;
2783 break;
2784 case MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG:
2785 p_mac_lte_info->isSimultPUCCHPUSCHPCell = true;
2786 break;
2787 case MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG:
2788 p_mac_lte_info->isSimultPUCCHPUSCHPSCell = true;
2789 break;
2790 case MAC_LTE_CE_MODE_TAG:
2791 p_mac_lte_info->ceMode =
2792 (mac_lte_ce_mode)tvb_get_uint8(tvb, offset);
2793 offset++;
2794 break;
2795 case MAC_LTE_NB_MODE_TAG:
2796 p_mac_lte_info->nbMode =
2797 (mac_lte_nb_mode)tvb_get_uint8(tvb, offset);
2798 offset++;
2799 break;
2800 case MAC_LTE_N_UL_RB_TAG:
2802 uint8_t nUlRb = tvb_get_uint8(tvb, offset);
2803 offset++;
2804 switch (nUlRb) {
2805 case 6:
2806 case 15:
2807 case 25:
2808 case 50:
2809 case 75:
2810 case 100:
2811 p_mac_lte_info->nUlRb = nUlRb;
2812 break;
2813 default:
2814 break;
2817 break;
2818 case MAC_LTE_SR_TAG:
2820 int n;
2821 // Read number of entries.
2822 uint16_t no_entries = tvb_get_ntohs(tvb, offset);
2823 offset += 2;
2824 if ((no_entries == 0) || (no_entries > MAX_SRs)) {
2825 return false;
2827 else {
2828 p_mac_lte_info->oob_event = ltemac_send_sr;
2829 p_mac_lte_info->number_of_srs = no_entries;
2832 // Read each entry.
2833 for (n=0; n < no_entries; n++) {
2834 p_mac_lte_info->oob_ueid[n] = tvb_get_ntohs(tvb, offset);
2835 offset += 2;
2836 p_mac_lte_info->oob_rnti[n] = tvb_get_ntohs(tvb, offset);
2837 offset += 2;
2840 break;
2842 case MAC_LTE_PAYLOAD_TAG:
2843 /* Have reached data, so set payload length and get out of loop */
2844 /* TODO: this is not correct if there is padding which isn't in frame */
2845 p_mac_lte_info->length= tvb_reported_length_remaining(tvb, offset);
2846 continue;
2848 default:
2849 /* It must be a recognised tag */
2851 proto_item *ti;
2852 proto_tree *subtree;
2854 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
2855 col_clear(pinfo->cinfo, COL_INFO);
2856 ti = proto_tree_add_item(tree, proto_mac_lte, tvb, offset, tvb_reported_length(tvb), ENC_NA);
2857 subtree = proto_item_add_subtree(ti, ett_mac_lte);
2858 proto_tree_add_expert(subtree, pinfo, &ei_mac_lte_unknown_udp_framing_tag,
2859 tvb, offset-1, 1);
2861 wmem_free(wmem_file_scope(), p_mac_lte_info);
2862 return false;
2866 /* Pass out where offset is now */
2867 *p_offset = offset;
2869 return true;
2872 /* Heuristic dissector looks for supported framing protocol (see wiki page) */
2873 static bool dissect_mac_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
2874 proto_tree *tree, void *data _U_)
2876 int offset = 0;
2877 struct mac_lte_info *p_mac_lte_info;
2878 tvbuff_t *mac_tvb;
2880 /* Needs to be at least as long as:
2881 - the signature string
2882 - fixed header bytes
2883 - tag for data
2884 - at least one byte of MAC PDU payload */
2885 if (tvb_captured_length_remaining(tvb, offset) < (int)(strlen(MAC_LTE_START_STRING)+3+2)) {
2886 return false;
2889 /* OK, compare with signature string */
2890 if (tvb_strneql(tvb, offset, MAC_LTE_START_STRING, strlen(MAC_LTE_START_STRING)) != 0) {
2891 return false;
2893 offset += (int)strlen(MAC_LTE_START_STRING);
2895 /* If redissecting, use previous info struct (if available) */
2896 p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
2897 if (p_mac_lte_info == NULL) {
2898 /* Allocate new info struct for this frame */
2899 p_mac_lte_info = wmem_new0(wmem_file_scope(), struct mac_lte_info);
2900 /* Dissect the fields to populate p_mac_lte */
2901 if (!dissect_mac_lte_context_fields(p_mac_lte_info, tvb, pinfo, tree, &offset)) {
2902 return true;
2904 /* Store info in packet */
2905 p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info);
2907 else {
2908 offset = tvb_reported_length(tvb) - p_mac_lte_info->length;
2911 /**************************************/
2912 /* OK, now dissect as MAC LTE */
2914 /* Create tvb that starts at actual MAC PDU */
2915 mac_tvb = tvb_new_subset_remaining(tvb, offset);
2916 dissect_mac_lte(mac_tvb, pinfo, tree, NULL);
2918 return true;
2922 /* Write the given formatted text to:
2923 - the info column (if pinfo != NULL)
2924 - 1 or 2 other labels (optional)
2926 static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2927 packet_info *pinfo, const char *format, ...) G_GNUC_PRINTF(4, 5);
2928 static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2929 packet_info *pinfo, const char *format, ...)
2931 #define MAX_INFO_BUFFER 256
2932 static char info_buffer[MAX_INFO_BUFFER];
2933 va_list ap;
2935 if ((ti1 == NULL) && (ti2 == NULL) && (pinfo == NULL)) {
2936 return;
2939 va_start(ap, format);
2940 vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
2941 va_end(ap);
2943 /* Add to indicated places */
2944 if (pinfo != NULL) {
2945 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2947 if (ti1 != NULL) {
2948 proto_item_append_text(ti1, "%s", info_buffer);
2950 if (ti2 != NULL) {
2951 proto_item_append_text(ti2, "%s", info_buffer);
2955 /* Version of function above, where no vsnprintf() call needed */
2956 static void write_pdu_label_and_info_literal(proto_item *ti1, proto_item *ti2,
2957 packet_info *pinfo, const char *info_buffer)
2959 if ((ti1 == NULL) && (ti2 == NULL) && (pinfo == NULL)) {
2960 return;
2963 /* Add to indicated places */
2964 if (pinfo != NULL) {
2965 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2967 if (ti1 != NULL) {
2968 proto_item_append_text(ti1, "%s", info_buffer);
2970 if (ti2 != NULL) {
2971 proto_item_append_text(ti2, "%s", info_buffer);
2977 /* Show extra PHY parameters (if present) */
2978 static void show_extra_phy_parameters(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
2979 struct mac_lte_info *p_mac_lte_info)
2981 proto_item *phy_ti;
2982 proto_tree *phy_tree;
2983 proto_item *ti;
2985 if (global_mac_lte_layer_to_show == ShowPHYLayer) {
2986 /* Clear the info column */
2987 col_clear(pinfo->cinfo, COL_INFO);
2990 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2991 if (p_mac_lte_info->detailed_phy_info.ul_info.present) {
2993 /* Create root */
2994 phy_ti = proto_tree_add_string_format(tree, hf_mac_lte_context_phy_ul,
2995 tvb, 0, 0, "", "UL PHY Context");
2996 phy_tree = proto_item_add_subtree(phy_ti, ett_mac_lte_phy_context);
2997 proto_item_set_generated(phy_ti);
2999 /* Add items */
3000 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_modulation_type,
3001 tvb, 0, 0,
3002 p_mac_lte_info->detailed_phy_info.ul_info.modulation_type);
3003 proto_item_set_generated(ti);
3005 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_tbs_index,
3006 tvb, 0, 0,
3007 p_mac_lte_info->detailed_phy_info.ul_info.tbs_index);
3008 proto_item_set_generated(ti);
3010 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_length,
3011 tvb, 0, 0,
3012 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length);
3013 proto_item_set_generated(ti);
3015 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_start,
3016 tvb, 0, 0,
3017 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start);
3018 proto_item_set_generated(ti);
3020 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_harq_id,
3021 tvb, 0, 0,
3022 p_mac_lte_info->detailed_phy_info.ul_info.harq_id);
3023 proto_item_set_generated(ti);
3025 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_ndi,
3026 tvb, 0, 0,
3027 p_mac_lte_info->detailed_phy_info.ul_info.ndi);
3028 proto_item_set_generated(ti);
3031 proto_item_append_text(phy_ti, " (");
3033 write_pdu_label_and_info(phy_ti, NULL,
3034 (global_mac_lte_layer_to_show == ShowPHYLayer) ? pinfo : NULL,
3035 "UL: UEId=%u RNTI=%u %s Tbs_Index=%u RB_len=%u RB_start=%u",
3036 p_mac_lte_info->ueid,
3037 p_mac_lte_info->rnti,
3038 val_to_str_const(p_mac_lte_info->detailed_phy_info.ul_info.modulation_type,
3039 modulation_type_vals, "Unknown"),
3040 p_mac_lte_info->detailed_phy_info.ul_info.tbs_index,
3041 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length,
3042 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start);
3044 proto_item_append_text(phy_ti, ")");
3046 /* Don't want columns to be replaced now */
3047 if (global_mac_lte_layer_to_show == ShowPHYLayer) {
3048 col_set_writable(pinfo->cinfo, -1, false);
3052 else {
3053 if (p_mac_lte_info->detailed_phy_info.dl_info.present) {
3055 /* Create root */
3056 phy_ti = proto_tree_add_string_format(tree, hf_mac_lte_context_phy_dl,
3057 tvb, 0, 0, "", "DL PHY Context");
3058 phy_tree = proto_item_add_subtree(phy_ti, ett_mac_lte_phy_context);
3059 proto_item_set_generated(phy_ti);
3061 /* Add items */
3062 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_dci_format,
3063 tvb, 0, 0,
3064 p_mac_lte_info->detailed_phy_info.dl_info.dci_format);
3065 proto_item_set_generated(ti);
3067 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_allocation_type,
3068 tvb, 0, 0,
3069 p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type);
3070 proto_item_set_generated(ti);
3072 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_aggregation_level,
3073 tvb, 0, 0,
3074 p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level);
3075 proto_item_set_generated(ti);
3077 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_mcs_index,
3078 tvb, 0, 0,
3079 p_mac_lte_info->detailed_phy_info.dl_info.mcs_index);
3080 proto_item_set_generated(ti);
3082 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_redundancy_version_index,
3083 tvb, 0, 0,
3084 p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index);
3085 proto_item_set_generated(ti);
3087 ti = proto_tree_add_boolean(phy_tree, hf_mac_lte_context_phy_dl_retx,
3088 tvb, 0, 0,
3089 p_mac_lte_info->dl_retx);
3090 proto_item_set_generated(ti);
3092 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_block_length,
3093 tvb, 0, 0,
3094 p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length);
3095 proto_item_set_generated(ti);
3097 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_harq_id,
3098 tvb, 0, 0,
3099 p_mac_lte_info->detailed_phy_info.dl_info.harq_id);
3100 proto_item_set_generated(ti);
3102 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_ndi,
3103 tvb, 0, 0,
3104 p_mac_lte_info->detailed_phy_info.dl_info.ndi);
3105 proto_item_set_generated(ti);
3107 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_tb,
3108 tvb, 0, 0,
3109 p_mac_lte_info->detailed_phy_info.dl_info.transport_block);
3110 proto_item_set_generated(ti);
3113 proto_item_append_text(phy_ti, " (");
3115 write_pdu_label_and_info(phy_ti, NULL,
3116 (global_mac_lte_layer_to_show == ShowPHYLayer) ? pinfo : NULL,
3117 "DL: UEId=%u RNTI=%u DCI_Format=%s Res_Alloc=%u Aggr_Level=%s MCS=%u RV=%u "
3118 "Res_Block_len=%u HARQ_id=%u NDI=%u",
3119 p_mac_lte_info->ueid,
3120 p_mac_lte_info->rnti,
3121 val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.dci_format,
3122 dci_format_vals, "Unknown"),
3123 p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type,
3124 val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level,
3125 aggregation_level_vals, "Unknown"),
3126 p_mac_lte_info->detailed_phy_info.dl_info.mcs_index,
3127 p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index,
3128 p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length,
3129 p_mac_lte_info->detailed_phy_info.dl_info.harq_id,
3130 p_mac_lte_info->detailed_phy_info.dl_info.ndi);
3131 proto_item_append_text(phy_ti, ")");
3133 /* Don't want columns to be replaced now */
3134 if (global_mac_lte_layer_to_show == ShowPHYLayer) {
3135 col_set_writable(pinfo->cinfo, -1, false);
3142 /* Dissect a single Random Access Response body */
3143 static int dissect_rar_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3144 proto_item *pdu_ti,
3145 int offset, uint8_t rapid, mac_lte_info *p_mac_lte_info)
3147 uint32_t reserved;
3148 unsigned start_body_offset = offset;
3149 proto_item *ti;
3150 proto_item *rar_body_ti;
3151 proto_tree *rar_body_tree;
3152 proto_tree *ul_grant_tree;
3153 proto_item *ul_grant_ti;
3154 uint32_t timing_advance;
3155 uint32_t ul_grant;
3156 uint32_t temp_crnti;
3157 const char *rapid_description;
3158 uint32_t bits_offset;
3160 /* Create tree for this Body */
3161 rar_body_ti = proto_tree_add_item(tree,
3162 hf_mac_lte_rar_body,
3163 tvb, offset, 0, ENC_ASCII);
3164 rar_body_tree = proto_item_add_subtree(rar_body_ti, ett_mac_lte_rar_body);
3166 /* Dissect an RAR entry */
3168 /* Check reserved bit */
3169 ti = proto_tree_add_item_ret_uint(rar_body_tree, hf_mac_lte_rar_reserved2, tvb, offset, 1,
3170 ENC_BIG_ENDIAN, &reserved);
3171 if (reserved != 0) {
3172 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero, "RAR body Reserved bit not zero (found 0x02%x)", reserved);
3175 /* Timing Advance */
3176 ti = proto_tree_add_item_ret_uint(rar_body_tree, hf_mac_lte_rar_ta, tvb, offset, 2, ENC_BIG_ENDIAN, &timing_advance);
3177 if (timing_advance != 0) {
3178 if (timing_advance <= 31) {
3179 expert_add_info_format(pinfo, ti, &ei_mac_lte_rar_timing_advance_not_zero_note,
3180 "RAR Timing advance not zero (%u)", timing_advance);
3181 } else {
3182 expert_add_info_format(pinfo, ti, &ei_mac_lte_rar_timing_advance_not_zero_warn,
3183 "RAR Timing advance not zero (%u)", timing_advance);
3186 offset++;
3188 /* UL Grant */
3189 if (p_mac_lte_info->ceMode == ce_mode_b) {
3190 ul_grant = tvb_get_ntohs(tvb, offset) & 0x0fff;
3191 ul_grant_ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ul_grant_ce_mode_b, tvb, offset, 2, ENC_BIG_ENDIAN);
3192 } else {
3193 ul_grant = (tvb_get_ntohl(tvb, offset) & 0x0fffff00) >> 8;
3194 ul_grant_ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ul_grant, tvb, offset, 3, ENC_BIG_ENDIAN);
3197 /* Break these 12/20 bits down as described in 36.213, section 6.2 */
3198 /* Create subtree for UL grant break-down */
3199 ul_grant_tree = proto_item_add_subtree(ul_grant_ti, ett_mac_lte_rar_ul_grant);
3201 if (p_mac_lte_info->nbMode == no_nb_mode) {
3202 switch (p_mac_lte_info->ceMode) {
3203 case no_ce_mode:
3204 default:
3205 /* Hopping flag (1 bit) */
3206 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_hopping,
3207 tvb, offset, 1, ENC_BIG_ENDIAN);
3209 /* Fixed sized resource block assignment (10 bits) */
3210 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_fsrba,
3211 tvb, offset, 2, ENC_BIG_ENDIAN);
3213 /* Truncated Modulation and coding scheme (4 bits) */
3214 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tmcs,
3215 tvb, offset+1, 2, ENC_BIG_ENDIAN);
3217 /* TPC command for scheduled PUSCH (3 bits) */
3218 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tcsp,
3219 tvb, offset+2, 1, ENC_BIG_ENDIAN);
3221 /* UL delay (1 bit) */
3222 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_delay,
3223 tvb, offset+2, 1, ENC_BIG_ENDIAN);
3225 /* CQI request (1 bit) */
3226 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_cqi_request,
3227 tvb, offset+2, 1, ENC_BIG_ENDIAN);
3229 offset += 3;
3230 break;
3232 case ce_mode_a:
3233 if (p_mac_lte_info->nUlRb == 0) {
3234 /* UL bandwidth is unknown; do not dissect UL grant */
3235 offset += 3;
3236 break;
3239 bits_offset = (offset<<3) + 4;
3241 /* Msg3 PUSCH narrowband index (0 to 4 bits) */
3242 if (p_mac_lte_info->nUlRb == 15) {
3243 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3244 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3245 bits_offset += 1;
3246 } else if (p_mac_lte_info->nUlRb == 25) {
3247 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3248 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3249 bits_offset += 2;
3250 } else if (p_mac_lte_info->nUlRb == 50) {
3251 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3252 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3253 bits_offset += 3;
3254 } else if ((p_mac_lte_info->nUlRb == 75) || (p_mac_lte_info->nUlRb == 100)) {
3255 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3256 tvb, bits_offset, 4, ENC_BIG_ENDIAN);
3257 bits_offset += 4;
3260 /* Msg3 PUSCH Resource allocation (4 bits) */
3261 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_a,
3262 tvb, bits_offset, 4, ENC_BIG_ENDIAN);
3263 bits_offset += 4;
3265 /* Number of Repetitions for Msg3 PUSCH (2 bits) */
3266 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a,
3267 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3268 bits_offset += 2;
3270 /* MCS (3 bits) */
3271 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_mcs_ce_mode_a,
3272 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3273 bits_offset += 3;
3275 /* TPC (3 bits) */
3276 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tpc_ce_mode_a,
3277 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3278 bits_offset += 3;
3280 /* CSI request (1 bit) */
3281 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_csi_request_ce_mode_a,
3282 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3283 bits_offset += 1;
3285 /* UL delay (1 bit) */
3286 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_delay_ce_mode_a,
3287 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3288 bits_offset += 1;
3290 /* Msg3/4 MPDCCH narrowband index (2 bits) */
3291 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx,
3292 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3293 bits_offset += 2;
3295 /* Optional padding (0 to 4 bits) to complete the 20 bits UL Grant */
3296 if (p_mac_lte_info->nUlRb == 6) {
3297 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3298 tvb, bits_offset, 4, ENC_BIG_ENDIAN);
3299 } else if (p_mac_lte_info->nUlRb == 15) {
3300 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3301 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3302 } else if (p_mac_lte_info->nUlRb == 25) {
3303 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3304 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3305 } else if (p_mac_lte_info->nUlRb == 50) {
3306 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3307 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3310 offset += 3;
3311 break;
3313 case ce_mode_b:
3314 /* Msg3 PUSCH narrowband index (2 bits) */
3315 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b,
3316 tvb, offset, 1, ENC_BIG_ENDIAN);
3318 /* Msg3 PUSCH Resource allocation (3 bits) */
3319 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_b,
3320 tvb, offset, 2, ENC_BIG_ENDIAN);
3322 /* Number of Repetitions for Msg3 PUSCH (3 bits) */
3323 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b,
3324 tvb, offset+1, 1, ENC_BIG_ENDIAN);
3326 /* TBS (2 bits) */
3327 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tbs_ce_mode_b,
3328 tvb, offset+1, 1, ENC_BIG_ENDIAN);
3330 /* Msg3/4 MPDCCH narrowband index (2 bits) */
3331 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx,
3332 tvb, ((offset+1)<<3)+6, 2, ENC_BIG_ENDIAN);
3334 offset += 2;
3335 break;
3337 } else {
3338 /* Uplink subcarrier spacing (1 bit) */
3339 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_subcarrier_spacing, tvb, offset, 1, ENC_BIG_ENDIAN);
3341 /* Subcarrier indication (6 bits) */
3342 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_subcarrier_indication, tvb, offset, 2, ENC_BIG_ENDIAN);
3344 /* Scheduling delay (2 bits) */
3345 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_scheduling_delay, tvb, offset+1, 1, ENC_BIG_ENDIAN);
3347 /* Msg3 repetition number (3 bits) */
3348 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_repetition_number, tvb, offset+1, 1, ENC_BIG_ENDIAN);
3350 /* MCS index (3 bits) */
3351 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_mcs_index, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3353 /* Padding (5 bits) */
3354 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_nb_mode, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3356 offset += 3;
3359 /* Temporary C-RNTI */
3360 proto_tree_add_item_ret_uint(rar_body_tree, hf_mac_lte_rar_temporary_crnti, tvb, offset, 2,
3361 ENC_BIG_ENDIAN, &temp_crnti);
3362 offset += 2;
3364 rapid_description = get_mac_lte_rapid_description(rapid);
3366 write_pdu_label_and_info(pdu_ti, rar_body_ti, pinfo,
3367 "(RAPID=%u%s: TA=%u, UL-Grant=%u, Temp C-RNTI=%u) ",
3368 rapid, rapid_description,
3369 timing_advance, ul_grant, temp_crnti);
3371 proto_item_set_len(rar_body_ti, offset-start_body_offset);
3373 return offset;
3377 #define MAX_RAR_PDUS 64
3378 /* Dissect Random Access Response (RAR) PDU */
3379 static void dissect_rar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *pdu_ti,
3380 int offset, mac_lte_info *p_mac_lte_info, mac_3gpp_tap_info *tap_info)
3382 unsigned number_of_rars = 0; /* No of RAR bodies expected following headers */
3383 uint8_t *rapids = (uint8_t *)wmem_alloc(pinfo->pool, MAX_RAR_PDUS * sizeof(uint8_t));
3384 uint32_t temp_rapid;
3385 bool backoff_indicator_seen = false;
3386 uint32_t backoff_indicator = 0;
3387 uint8_t extension;
3388 unsigned n;
3389 proto_tree *rar_headers_tree;
3390 proto_item *ti;
3391 proto_item *rar_headers_ti;
3392 proto_item *padding_length_ti;
3393 int start_headers_offset = offset;
3395 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3396 "RAR (RA-RNTI=%u, SFN=%-4u, SF=%u) ",
3397 p_mac_lte_info->rnti, p_mac_lte_info->sysframeNumber, p_mac_lte_info->subframeNumber);
3399 /* Create hidden 'virtual root' so can filter on mac-lte.rar */
3400 ti = proto_tree_add_item(tree, hf_mac_lte_rar, tvb, offset, -1, ENC_NA);
3401 proto_item_set_hidden(ti);
3403 /* Create headers tree */
3404 rar_headers_ti = proto_tree_add_item(tree,
3405 hf_mac_lte_rar_headers,
3406 tvb, offset, 0, ENC_ASCII);
3407 rar_headers_tree = proto_item_add_subtree(rar_headers_ti, ett_mac_lte_rar_headers);
3410 /***************************/
3411 /* Read the header entries */
3412 do {
3413 int start_header_offset = offset;
3414 proto_tree *rar_header_tree;
3415 proto_item *rar_header_ti;
3416 uint8_t type_value;
3417 uint8_t first_byte = tvb_get_uint8(tvb, offset);
3419 /* Create tree for this header */
3420 rar_header_ti = proto_tree_add_item(rar_headers_tree,
3421 hf_mac_lte_rar_header,
3422 tvb, offset, 0, ENC_ASCII);
3423 rar_header_tree = proto_item_add_subtree(rar_header_ti, ett_mac_lte_rar_header);
3425 /* Extension */
3426 extension = (first_byte & 0x80) >> 7;
3427 proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
3429 /* Type */
3430 type_value = (first_byte & 0x40) >> 6;
3431 proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_t, tvb, offset, 1, ENC_BIG_ENDIAN);
3433 if (type_value == 0) {
3434 /* Backoff Indicator (BI) case */
3436 uint32_t reserved;
3437 proto_item *tii;
3438 proto_item *bi_ti;
3440 /* 2 Reserved bits */
3441 tii = proto_tree_add_item_ret_uint(rar_header_tree, hf_mac_lte_rar_reserved, tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
3442 if (reserved != 0) {
3443 expert_add_info_format(pinfo, tii, &ei_mac_lte_reserved_not_zero,
3444 "RAR header Reserved bits not zero (found 0x%x)", reserved);
3447 /* Backoff Indicator */
3448 bi_ti = proto_tree_add_item_ret_uint(rar_header_tree, (p_mac_lte_info->nbMode == no_nb_mode) ?
3449 hf_mac_lte_rar_bi : hf_mac_lte_rar_bi_nb, tvb, offset, 1,
3450 ENC_BIG_ENDIAN, &backoff_indicator);
3452 /* As of March 2009 spec, it must be first, and may only appear once */
3453 if (backoff_indicator_seen) {
3454 expert_add_info(pinfo, bi_ti, &ei_mac_lte_rar_bi_present);
3456 backoff_indicator_seen = true;
3458 write_pdu_label_and_info(pdu_ti, rar_header_ti, pinfo,
3459 "(Backoff Indicator=%sms)",
3460 val_to_str_const(backoff_indicator, (p_mac_lte_info->nbMode == no_nb_mode) ?
3461 rar_bi_vals : rar_bi_nb_vals, "Illegal-value "));
3463 /* If present, it must be the first subheader */
3464 if (number_of_rars > 0) {
3465 expert_add_info(pinfo, bi_ti, &ei_mac_lte_rar_bi_not_first_subheader);
3469 else {
3470 /* RAPID case */
3471 /* TODO: complain if the same RAPID appears twice in same frame? */
3472 const char *rapid_description;
3474 proto_tree_add_item_ret_uint(rar_header_tree, hf_mac_lte_rar_rapid, tvb, offset, 1,
3475 ENC_BIG_ENDIAN, &temp_rapid);
3476 rapids[number_of_rars] = (uint8_t)temp_rapid;
3478 rapid_description = get_mac_lte_rapid_description(rapids[number_of_rars]);
3480 proto_item_append_text(rar_header_ti, "(RAPID=%u%s)",
3481 rapids[number_of_rars],
3482 rapid_description);
3484 number_of_rars++;
3487 offset++;
3489 /* Finalise length of header tree selection */
3490 proto_item_set_len(rar_header_ti, offset - start_header_offset);
3492 } while (extension && number_of_rars < MAX_RAR_PDUS);
3494 /* Append summary to headers root */
3495 proto_item_append_text(rar_headers_ti, " (%u RARs", number_of_rars);
3496 ti = proto_tree_add_uint(rar_headers_tree, hf_mac_lte_rar_no_of_rapids, tvb, 0, 0, number_of_rars);
3497 proto_item_set_generated(ti);
3498 if (backoff_indicator_seen) {
3499 proto_item_append_text(rar_headers_ti, ", BI=%sms)",
3500 val_to_str_const(backoff_indicator, (p_mac_lte_info->nbMode == no_nb_mode) ?
3501 rar_bi_vals : rar_bi_nb_vals, "Illegal-value "));
3503 else {
3504 proto_item_append_text(rar_headers_ti, ")");
3507 /* Set length for headers root */
3508 proto_item_set_len(rar_headers_ti, offset-start_headers_offset);
3511 /***************************/
3512 /* Read any indicated RARs */
3513 for (n=0; n < number_of_rars; n++) {
3514 offset = dissect_rar_entry(tvb, pinfo, tree, pdu_ti, offset, rapids[n], p_mac_lte_info);
3517 /* Update TAP info */
3518 tap_info->number_of_rars += number_of_rars;
3520 /* Padding may follow */
3521 if (tvb_reported_length_remaining(tvb, offset) > 0) {
3522 proto_tree_add_item(tree, hf_mac_lte_padding_data,
3523 tvb, offset, -1, ENC_NA);
3525 padding_length_ti = proto_tree_add_uint(tree, hf_mac_lte_padding_length,
3526 tvb, offset, 0,
3527 p_mac_lte_info->length - offset);
3528 proto_item_set_generated(padding_length_ti);
3530 /* Update padding bytes in stats */
3531 tap_info->padding_bytes += (p_mac_lte_info->length - offset);
3535 /* Dissect BCH PDU */
3536 static void dissect_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3537 proto_item *pdu_ti,
3538 int offset, mac_lte_info *p_mac_lte_info)
3540 proto_item *ti;
3542 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3543 "BCH PDU (%u bytes, on %s transport) ",
3544 tvb_reported_length_remaining(tvb, offset),
3545 val_to_str_const(p_mac_lte_info->rntiType,
3546 bch_transport_channel_vals,
3547 "Unknown"));
3549 /* Show which transport layer it came in on (inferred from RNTI type) */
3550 ti = proto_tree_add_uint(tree, hf_mac_lte_context_bch_transport_channel,
3551 tvb, offset, 0, p_mac_lte_info->rntiType);
3552 proto_item_set_generated(ti);
3554 /****************************************/
3555 /* Whole frame is BCH data */
3557 /* Raw data */
3558 ti = proto_tree_add_item(tree, hf_mac_lte_bch_pdu,
3559 tvb, offset, -1, ENC_NA);
3561 if (global_mac_lte_attempt_rrc_decode) {
3562 /* Attempt to decode payload using LTE RRC dissector */
3563 tvbuff_t *rrc_tvb = tvb_new_subset_remaining(tvb, offset);
3565 /* Get appropriate dissector handle */
3566 dissector_handle_t protocol_handle = 0;
3567 if (p_mac_lte_info->rntiType == SI_RNTI) {
3568 if (p_mac_lte_info->nbMode == no_nb_mode) {
3569 if (p_mac_lte_info->ceMode == no_ce_mode) {
3570 protocol_handle = lte_rrc_bcch_dl_sch_handle;
3572 else {
3573 protocol_handle = lte_rrc_bcch_dl_sch_br_handle;
3576 else {
3577 protocol_handle = lte_rrc_bcch_dl_sch_nb_handle;
3580 else {
3581 if (p_mac_lte_info->nbMode == no_nb_mode) {
3582 protocol_handle = lte_rrc_bcch_bch_handle;
3584 else {
3585 protocol_handle = lte_rrc_bcch_bch_nb_handle;
3589 /* Hide raw view of bytes */
3590 proto_item_set_hidden(ti);
3592 call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
3595 /* Check that this *is* downlink! */
3596 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
3597 expert_add_info(pinfo, ti, &ei_mac_lte_bch_pdu);
3602 /* Dissect PCH PDU */
3603 static void dissect_pch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3604 proto_item *pdu_ti, int offset,
3605 mac_lte_info *p_mac_lte_info,
3606 mac_3gpp_tap_info *tap_info)
3608 proto_item *ti;
3610 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3611 "PCH PDU (%u bytes) ",
3612 tvb_reported_length_remaining(tvb, offset));
3614 /****************************************/
3615 /* Whole frame is PCH data */
3617 /* Always show as raw data */
3618 ti = proto_tree_add_item(tree, hf_mac_lte_pch_pdu,
3619 tvb, offset, -1, ENC_NA);
3621 /* Get number of paging IDs for tap */
3622 tap_info->number_of_paging_ids = (tvb_get_uint8(tvb, offset) & 0x40) ?
3623 ((tvb_get_ntohs(tvb, offset) >> 7) & 0x000f) + 1 : 0;
3625 if (global_mac_lte_attempt_rrc_decode) {
3627 /* Attempt to decode payload using LTE RRC dissector */
3628 tvbuff_t *rrc_tvb = tvb_new_subset_remaining(tvb, offset);
3630 /* Hide raw view of bytes */
3631 proto_item_set_hidden(ti);
3633 /* Call it (catch exceptions so that stats will be updated) */
3634 if (p_mac_lte_info->nbMode == no_nb_mode) {
3635 call_with_catch_all(lte_rrc_pcch_handle, rrc_tvb, pinfo, tree);
3637 else {
3638 call_with_catch_all(lte_rrc_pcch_nb_handle, rrc_tvb, pinfo, tree);
3642 /* Check that this *is* downlink! */
3643 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
3644 expert_add_info(pinfo, ti, &ei_mac_lte_pch_pdu);
3649 /* Does this header entry correspond to a fixed-sized control element? */
3650 static bool is_fixed_sized_control_element(uint8_t lcid, uint8_t direction)
3652 if (direction == DIRECTION_UPLINK) {
3653 /* Uplink */
3654 switch (lcid) {
3655 case TIMING_ADVANCE_REPORT_LCID:
3656 case DCQR_AND_AS_RAI_LCID:
3657 case AUL_CONFIRMATION_4_OCTETS:
3658 case AUL_CONFIRMATION_1_OCTET:
3659 case RECOMMENDED_BIT_RATE_QUERY_LCID:
3660 case SPS_CONFIRMATION_LCID:
3661 case POWER_HEADROOM_REPORT_LCID:
3662 case CRNTI_LCID:
3663 case TRUNCATED_BSR_LCID:
3664 case SHORT_BSR_LCID:
3665 case LONG_BSR_LCID:
3666 return true;
3668 default:
3669 return false;
3672 else {
3673 /* Assume Downlink */
3674 switch (lcid) {
3675 case DCQR_COMMAND_LCID:
3676 case ACTIVATION_DEACTIVATION_PDCP_DUP_LCID:
3677 case HIBERNATION_1_OCTET_LCID:
3678 case HIBERNATION_4_OCTETS_LCID:
3679 case RECOMMENDED_BIT_RATE_LCID:
3680 case SC_PTM_STOP_INDICATION_LCID:
3681 case ACTIVATION_DEACTIVATION_4_BYTES_LCID:
3682 case LONG_DRX_COMMAND_LCID:
3683 case ACTIVATION_DEACTIVATION_LCID:
3684 case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
3685 case TIMING_ADVANCE_LCID:
3686 case DRX_COMMAND_LCID:
3687 return true;
3689 default:
3690 return false;
3696 /* Is this a BSR report header? */
3697 static bool is_bsr_lcid(uint8_t lcid)
3699 return ((lcid == TRUNCATED_BSR_LCID) ||
3700 (lcid == SHORT_BSR_LCID) ||
3701 (lcid == LONG_BSR_LCID));
3705 /* Helper function to call RLC dissector for SDUs (where channel params are known) */
3706 static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3707 proto_item *pdu_ti,
3708 int offset, uint16_t data_length,
3709 uint8_t mode, uint8_t direction, uint16_t ueid,
3710 uint16_t channelType, uint16_t channelId,
3711 uint8_t sequenceNumberLength,
3712 uint8_t priority, bool rlcExtLiField, mac_lte_nb_mode nbMode)
3714 tvbuff_t *rb_tvb = tvb_new_subset_length(tvb, offset, data_length);
3715 struct rlc_lte_info *p_rlc_lte_info;
3717 /* Reuse or create RLC info */
3718 p_rlc_lte_info = (rlc_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0);
3719 if (p_rlc_lte_info == NULL) {
3720 p_rlc_lte_info = wmem_new0(wmem_file_scope(), struct rlc_lte_info);
3723 /* Fill in struct details for channel */
3724 p_rlc_lte_info->rlcMode = mode;
3725 p_rlc_lte_info->direction = direction;
3726 p_rlc_lte_info->priority = priority;
3727 p_rlc_lte_info->ueid = ueid;
3728 p_rlc_lte_info->channelType = channelType;
3729 p_rlc_lte_info->channelId = channelId;
3730 p_rlc_lte_info->pduLength = data_length;
3731 p_rlc_lte_info->sequenceNumberLength = sequenceNumberLength;
3732 p_rlc_lte_info->extendedLiField = rlcExtLiField;
3733 if (nbMode == nb_mode) {
3734 p_rlc_lte_info->nbMode = rlc_nb_mode;
3735 } else {
3736 p_rlc_lte_info->nbMode = rlc_no_nb_mode;
3739 /* Store info in packet */
3740 p_add_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0, p_rlc_lte_info);
3742 if (global_mac_lte_layer_to_show != ShowRLCLayer) {
3743 /* Don't want these columns replaced */
3744 col_set_writable(pinfo->cinfo, -1, false);
3746 else {
3747 /* Clear info column before first RLC PDU */
3748 if (s_number_of_rlc_pdus_shown == 0) {
3749 col_clear(pinfo->cinfo, COL_INFO);
3751 else {
3752 /* Add a separator and protect column contents here */
3753 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, " || ");
3754 col_set_fence(pinfo->cinfo, COL_INFO);
3757 s_number_of_rlc_pdus_shown++;
3759 /* Call it (catch exceptions so that stats will be updated) */
3760 call_with_catch_all(rlc_lte_handle, rb_tvb, pinfo, tree);
3762 /* Let columns be written to again */
3763 col_set_writable(pinfo->cinfo, -1, true);
3767 /* For DL frames, look for previous Tx. Add link back if found */
3768 static void TrackReportedDLHARQResend(packet_info *pinfo, tvbuff_t *tvb, int length,
3769 proto_tree *tree, mac_lte_info *p_mac_lte_info)
3771 DLHARQResult *result = NULL;
3772 DLHARQResult *original_result = NULL;
3774 /* If don't have detailed DL PHY info, just give up */
3775 if (!p_mac_lte_info->detailed_phy_info.dl_info.present) {
3776 return;
3779 /* TDD may not work... */
3781 if (!PINFO_FD_VISITED(pinfo)) {
3782 /* First time, so set result and update DL harq table */
3783 LastFrameData *lastData = NULL;
3784 LastFrameData *thisData = NULL;
3786 DLHarqBuffers *ueData;
3788 /* Read these for convenience */
3789 uint8_t harq_id = p_mac_lte_info->detailed_phy_info.dl_info.harq_id;
3790 uint8_t transport_block = p_mac_lte_info->detailed_phy_info.dl_info.transport_block;
3792 /* Check harq-id bounds, give up if invalid */
3793 if ((harq_id >= 15) || (transport_block > 1)) {
3794 return;
3797 /* Look up entry for this UE/RNTI */
3798 ueData = (DLHarqBuffers *)g_hash_table_lookup(mac_lte_dl_harq_hash, GUINT_TO_POINTER((unsigned)p_mac_lte_info->rnti));
3800 if (ueData != NULL) {
3801 /* Get previous info for this harq-id */
3802 lastData = &(ueData->harqid[transport_block][harq_id]);
3803 if (lastData->inUse) {
3804 /* Compare time difference, ndi, data to see if this looks like a retx */
3805 if ((length == lastData->length) &&
3806 (p_mac_lte_info->detailed_phy_info.dl_info.ndi == lastData->ndi) &&
3807 tvb_memeql(tvb, 0, lastData->data, MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0) {
3809 /* Work out gap between frames */
3810 int seconds_between_packets = (int)
3811 (pinfo->abs_ts.secs - lastData->received_time.secs);
3812 int nseconds_between_packets =
3813 pinfo->abs_ts.nsecs - lastData->received_time.nsecs;
3815 /* Round difference to nearest millisecond */
3816 int total_gap = (seconds_between_packets*1000) +
3817 ((nseconds_between_packets+500000) / 1000000);
3819 /* Expect to be within (say) 8-13 subframes since previous */
3820 if ((total_gap >= 8) && (total_gap <= 13)) {
3822 /* Resend detected! Store result pointing back. */
3823 result = wmem_new0(wmem_file_scope(), DLHARQResult);
3824 result->previousSet = true;
3825 result->previousFrameNum = lastData->framenum;
3826 result->timeSincePreviousFrame = total_gap;
3827 g_hash_table_insert(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->num), result);
3829 /* Now make previous frame point forward to here */
3830 original_result = (DLHARQResult *)g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(lastData->framenum));
3831 if (original_result == NULL) {
3832 original_result = wmem_new0(wmem_file_scope(), DLHARQResult);
3833 g_hash_table_insert(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(lastData->framenum), original_result);
3835 original_result->nextSet = true;
3836 original_result->nextFrameNum = pinfo->num;
3837 original_result->timeToNextFrame = total_gap;
3842 else {
3843 /* Allocate entry in table for this UE/RNTI */
3844 ueData = wmem_new0(wmem_file_scope(), DLHarqBuffers);
3845 g_hash_table_insert(mac_lte_dl_harq_hash, GUINT_TO_POINTER((unsigned)p_mac_lte_info->rnti), ueData);
3848 /* Store this frame's details in table */
3849 thisData = &(ueData->harqid[transport_block][harq_id]);
3850 thisData->inUse = true;
3851 thisData->length = length;
3852 tvb_memcpy(tvb, thisData->data, 0, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH));
3853 thisData->ndi = p_mac_lte_info->detailed_phy_info.dl_info.ndi;
3854 thisData->framenum = pinfo->num;
3855 thisData->received_time = pinfo->abs_ts;
3857 else {
3858 /* Not first time, so just set what's already stored in result */
3859 result = (DLHARQResult *)g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->num));
3863 /***************************************************/
3864 /* Show link back to original frame (if available) */
3865 if (result != NULL) {
3866 if (result->previousSet) {
3867 proto_item *gap_ti;
3868 proto_item *original_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_original_frame,
3869 tvb, 0, 0, result->previousFrameNum);
3870 proto_item_set_generated(original_ti);
3872 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_time_since_previous_frame,
3873 tvb, 0, 0, result->timeSincePreviousFrame);
3874 proto_item_set_generated(gap_ti);
3877 if (result->nextSet) {
3878 proto_item *gap_ti;
3879 proto_item *next_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_next_frame,
3880 tvb, 0, 0, result->nextFrameNum);
3881 proto_item_set_generated(next_ti);
3883 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_time_until_next_frame,
3884 tvb, 0, 0, result->timeToNextFrame);
3885 proto_item_set_generated(gap_ti);
3892 /* Return true if the given packet is thought to be a retx */
3893 bool is_mac_lte_frame_retx(packet_info *pinfo, uint8_t direction)
3895 struct mac_lte_info *p_mac_lte_info = (struct mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
3897 if (p_mac_lte_info == NULL) {
3898 return false;
3901 if (direction == DIRECTION_UPLINK) {
3902 /* For UL, retx count is stored in per-packet struct */
3903 return (p_mac_lte_info->reTxCount > 0);
3905 else {
3906 /* Use answer if told directly */
3907 if (p_mac_lte_info->dl_retx == dl_retx_yes) {
3908 return true;
3910 else {
3911 /* Otherwise look up in table */
3912 DLHARQResult *result = (DLHARQResult *)g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->num));
3913 return ((result != NULL) && result->previousSet);
3919 /* Track UL frames, so that when a retx is indicated, we can search for
3920 the original tx. We will either find it, and provide a link back to it,
3921 or flag that we couldn't find as an expert error */
3922 static void TrackReportedULHARQResend(packet_info *pinfo, tvbuff_t *tvb, int offset,
3923 proto_tree *tree, mac_lte_info *p_mac_lte_info,
3924 proto_item *retx_ti)
3926 ULHARQResult *result = NULL;
3928 /* If don't have detailed DL PHY info, just give up */
3929 if (!p_mac_lte_info->detailed_phy_info.ul_info.present) {
3930 return;
3933 /* Give up if harqid is out of range */
3934 if (p_mac_lte_info->detailed_phy_info.ul_info.harq_id >= 8) {
3935 return;
3938 if (!PINFO_FD_VISITED(pinfo)) {
3939 /* First time, so set result and update UL harq table */
3940 LastFrameData *lastData = NULL;
3941 LastFrameData *thisData = NULL;
3943 /* Look up entry for this UE/RNTI */
3944 ULHarqBuffers *ueData = (ULHarqBuffers *)g_hash_table_lookup(
3945 mac_lte_ul_harq_hash, GUINT_TO_POINTER((unsigned)p_mac_lte_info->rnti));
3946 if (ueData != NULL) {
3947 if (p_mac_lte_info->reTxCount >= 1) {
3948 /* Looking for frame previously on this harq-id */
3949 lastData = &(ueData->harqid[p_mac_lte_info->detailed_phy_info.ul_info.harq_id]);
3950 if (lastData->inUse) {
3951 /* Compare time, sf, data to see if this looks like a retx */
3952 if ((tvb_reported_length_remaining(tvb, offset) == lastData->length) &&
3953 (p_mac_lte_info->detailed_phy_info.ul_info.ndi == lastData->ndi) &&
3954 tvb_memeql(tvb, offset, lastData->data, MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0) {
3956 /* Work out gap between frames */
3957 int seconds_between_packets = (int)
3958 (pinfo->abs_ts.secs - lastData->received_time.secs);
3959 int nseconds_between_packets =
3960 pinfo->abs_ts.nsecs - lastData->received_time.nsecs;
3962 /* Round to nearest ms */
3963 int total_gap = (seconds_between_packets*1000) +
3964 ((nseconds_between_packets+500000) / 1000000);
3966 /* Could be as many as max-tx (which we don't know) * 8ms ago.
3967 32 is the most I've seen... */
3968 /* TODO: could configure this from RRC... */
3969 if (total_gap <= 33) {
3970 ULHARQResult *original_result;
3972 /* Original detected!!! Store result pointing back */
3973 result = wmem_new0(wmem_file_scope(), ULHARQResult);
3974 result->previousSet = true;
3975 result->previousFrameNum = lastData->framenum;
3976 result->timeSincePreviousFrame = total_gap;
3977 g_hash_table_insert(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->num), result);
3979 /* Now make previous frame point forward to here */
3980 original_result = (ULHARQResult *)g_hash_table_lookup(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(lastData->framenum));
3981 if (original_result == NULL) {
3982 original_result = wmem_new0(wmem_file_scope(), ULHARQResult);
3983 g_hash_table_insert(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(lastData->framenum), original_result);
3985 original_result->nextSet = true;
3986 original_result->nextFrameNum = pinfo->num;
3987 original_result->timeToNextFrame = total_gap;
3993 else {
3994 /* Allocate entry in table for this UE/RNTI */
3995 ueData = wmem_new0(wmem_file_scope(), ULHarqBuffers);
3996 g_hash_table_insert(mac_lte_ul_harq_hash, GUINT_TO_POINTER((unsigned)p_mac_lte_info->rnti), ueData);
3999 /* Store this frame's details in table */
4000 thisData = &(ueData->harqid[p_mac_lte_info->detailed_phy_info.ul_info.harq_id]);
4001 thisData->inUse = true;
4002 thisData->length = tvb_reported_length_remaining(tvb, offset);
4003 tvb_memcpy(tvb, thisData->data, offset, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH));
4004 thisData->ndi = p_mac_lte_info->detailed_phy_info.ul_info.ndi;
4005 thisData->framenum = pinfo->num;
4006 thisData->received_time = pinfo->abs_ts;
4008 else {
4009 /* Not first time, so just get what's already stored in result */
4010 result = (ULHARQResult *)g_hash_table_lookup(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->num));
4013 /* Show any link back to previous Tx */
4014 if (retx_ti != NULL) {
4015 if (result != NULL) {
4016 if (result->previousSet) {
4017 proto_item *original_ti, *gap_ti;
4019 original_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_original_frame,
4020 tvb, 0, 0, result->previousFrameNum);
4021 proto_item_set_generated(original_ti);
4023 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_time_since_previous_frame,
4024 tvb, 0, 0, result->timeSincePreviousFrame);
4025 proto_item_set_generated(gap_ti);
4028 else {
4029 expert_add_info_format(pinfo, retx_ti, &ei_mac_lte_orig_tx_ul_frame_not_found,
4030 "Original Tx of UL frame not found (UE %u) !!", p_mac_lte_info->ueid);
4034 /* Show link forward to any known next Tx */
4035 if ((result != NULL) && result->nextSet) {
4036 proto_item *next_ti, *gap_ti;
4038 next_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_next_frame,
4039 tvb, 0, 0, result->nextFrameNum);
4040 expert_add_info_format(pinfo, next_ti, &ei_mac_lte_ul_harq_resend_next_frame,
4041 "UL MAC PDU (UE %u) needed to be retransmitted", p_mac_lte_info->ueid);
4043 proto_item_set_generated(next_ti);
4045 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_time_until_next_frame,
4046 tvb, 0, 0, result->timeToNextFrame);
4047 proto_item_set_generated(gap_ti);
4052 /* Look up SRResult associated with a given frame. Will create one if necessary
4053 if can_create is set */
4054 static SRResult *GetSRResult(uint32_t frameNum, bool can_create)
4056 SRResult *result;
4057 result = (SRResult *)g_hash_table_lookup(mac_lte_sr_request_hash, GUINT_TO_POINTER(frameNum));
4059 if ((result == NULL) && can_create) {
4060 result = wmem_new0(wmem_file_scope(), SRResult);
4061 g_hash_table_insert(mac_lte_sr_request_hash, GUINT_TO_POINTER((unsigned)frameNum), result);
4063 return result;
4067 /* Keep track of SR requests, failures and related grants, in order to show them
4068 as generated fields in these frames */
4069 static void TrackSRInfo(SREvent event, packet_info *pinfo, proto_tree *tree,
4070 tvbuff_t *tvb, mac_lte_info *p_mac_lte_info, int idx, proto_item *event_ti)
4072 SRResult *result = NULL;
4073 SRState *state;
4074 SRResult *resultForSRFrame = NULL;
4076 uint16_t rnti;
4077 uint16_t ueid;
4078 proto_item *ti;
4080 /* Get appropriate identifiers */
4081 if (event == SR_Request) {
4082 rnti = p_mac_lte_info->oob_rnti[idx];
4083 ueid = p_mac_lte_info->oob_ueid[idx];
4085 else {
4086 rnti = p_mac_lte_info->rnti;
4087 ueid = p_mac_lte_info->ueid;
4090 /* Create state for this RNTI if necessary */
4091 state = (SRState *)g_hash_table_lookup(mac_lte_ue_sr_state, GUINT_TO_POINTER((unsigned)rnti));
4092 if (state == NULL) {
4093 /* Allocate status for this RNTI */
4094 state = wmem_new(wmem_file_scope(), SRState);
4095 state->status = None;
4096 g_hash_table_insert(mac_lte_ue_sr_state, GUINT_TO_POINTER((unsigned)rnti), state);
4099 /* First time through - update state with new info */
4100 if (!PINFO_FD_VISITED(pinfo)) {
4101 uint32_t timeSinceRequest;
4103 /* Store time of request */
4104 if (event == SR_Request) {
4105 state->requestTime = pinfo->abs_ts;
4108 switch (state->status) {
4109 case None:
4110 switch (event) {
4111 case SR_Grant:
4112 /* Got another grant - fine */
4114 /* update state */
4115 state->lastGrantFramenum = pinfo->num;
4116 break;
4118 case SR_Request:
4119 /* Sent an SR - fine */
4121 /* Update state */
4122 state->status = SR_Outstanding;
4123 state->lastSRFramenum = pinfo->num;
4124 break;
4126 case SR_Failure:
4127 /* This is an error, since we hadn't send an SR... */
4128 result = GetSRResult(pinfo->num, true);
4129 result->type = InvalidSREvent;
4130 result->status = None;
4131 result->event = SR_Failure;
4132 break;
4134 break;
4136 case SR_Outstanding:
4137 timeSinceRequest = (uint32_t)(((pinfo->abs_ts.secs - state->requestTime.secs) * 1000) +
4138 ((pinfo->abs_ts.nsecs - state->requestTime.nsecs) / 1000000));
4140 switch (event) {
4141 case SR_Grant:
4142 /* Got grant we were waiting for, so state goes to None */
4144 /* Update state */
4145 state->status = None;
4147 /* Set result info */
4148 result = GetSRResult(pinfo->num, true);
4149 result->type = GrantAnsweringSR;
4150 result->frameNum = state->lastSRFramenum;
4151 result->timeDifference = timeSinceRequest;
4153 /* Also set forward link for SR */
4154 resultForSRFrame = GetSRResult(state->lastSRFramenum, true);
4155 resultForSRFrame->type = SRLeadingToGrant;
4156 resultForSRFrame->frameNum = pinfo->num;
4157 resultForSRFrame->timeDifference = timeSinceRequest;
4158 break;
4160 case SR_Request:
4161 /* Another request when already have one pending */
4162 result = GetSRResult(pinfo->num, true);
4163 result->type = InvalidSREvent;
4164 result->status = SR_Outstanding;
4165 result->event = SR_Request;
4166 break;
4168 case SR_Failure:
4169 /* We sent an SR but it failed */
4171 /* Update state */
4172 state->status = SR_Failed;
4174 /* Set result info for failure frame */
4175 result = GetSRResult(pinfo->num, true);
4176 result->type = FailureAnsweringSR;
4177 result->frameNum = state->lastSRFramenum;
4178 result->timeDifference = timeSinceRequest;
4180 /* Also set forward link for SR */
4181 resultForSRFrame = GetSRResult(state->lastSRFramenum, true);
4182 resultForSRFrame->type = SRLeadingToFailure;
4183 resultForSRFrame->frameNum = pinfo->num;
4184 resultForSRFrame->timeDifference = timeSinceRequest;
4185 break;
4187 break;
4189 case SR_Failed:
4190 switch (event) {
4191 case SR_Grant:
4192 /* Got a grant, presumably after a subsequent RACH - fine */
4194 /* Update state */
4195 state->status = None;
4196 break;
4198 case SR_Request:
4199 /* Tried another SR after previous one failed.
4200 Presumably a subsequent RACH was tried in-between... */
4202 state->status = SR_Outstanding;
4204 result = GetSRResult(pinfo->num, true);
4205 result->status = SR_Outstanding;
4206 result->event = SR_Request;
4207 break;
4209 case SR_Failure:
4210 /* 2 failures in a row.... */
4211 result = GetSRResult(pinfo->num, true);
4212 result->type = InvalidSREvent;
4213 result->status = SR_Failed;
4214 result->event = SR_Failure;
4215 break;
4217 break;
4221 /* Get stored result for this frame */
4222 result = GetSRResult(pinfo->num, false);
4223 if (result == NULL) {
4224 /* For an SR frame, there should always be either a PDCCH grant or indication
4225 that the SR has failed */
4226 if (event == SR_Request) {
4227 expert_add_info_format(pinfo, event_ti, &ei_mac_lte_sr_results_not_grant_or_failure_indication,
4228 "UE %u: SR results in neither a grant nor a failure indication",
4229 ueid);
4231 return;
4235 /* Show result info */
4236 switch (result->type) {
4237 case GrantAnsweringSR:
4238 ti = proto_tree_add_uint(tree, hf_mac_lte_grant_answering_sr,
4239 tvb, 0, 0, result->frameNum);
4240 proto_item_set_generated(ti);
4241 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_since_request,
4242 tvb, 0, 0, result->timeDifference);
4243 proto_item_set_generated(ti);
4244 break;
4246 case FailureAnsweringSR:
4247 ti = proto_tree_add_uint(tree, hf_mac_lte_failure_answering_sr,
4248 tvb, 0, 0, result->frameNum);
4249 proto_item_set_generated(ti);
4250 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_since_request,
4251 tvb, 0, 0, result->timeDifference);
4252 proto_item_set_generated(ti);
4253 break;
4255 case SRLeadingToGrant:
4256 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_leading_to_grant,
4257 tvb, 0, 0, result->frameNum);
4258 proto_item_set_generated(ti);
4259 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_until_answer,
4260 tvb, 0, 0, result->timeDifference);
4261 proto_item_set_generated(ti);
4263 break;
4265 case SRLeadingToFailure:
4266 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_leading_to_failure,
4267 tvb, 0, 0, result->frameNum);
4268 proto_item_set_generated(ti);
4269 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_until_answer,
4270 tvb, 0, 0, result->timeDifference);
4271 proto_item_set_generated(ti);
4272 break;
4274 case InvalidSREvent:
4275 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_sr_invalid_event,
4276 tvb, 0, 0, "UE %u: Invalid SR event - state=%s, event=%s",
4277 ueid,
4278 val_to_str_const(result->status, sr_status_vals, "Unknown"),
4279 val_to_str_const(result->event, sr_event_vals, "Unknown"));
4280 break;
4285 /********************************************************/
4286 /* Count number of UEs/TTI (in both directions) */
4287 /********************************************************/
4289 /* For keeping track during first pass */
4290 typedef struct tti_info_t {
4291 uint16_t subframe;
4292 nstime_t ttiStartTime;
4293 unsigned ues_in_tti;
4294 } tti_info_t;
4296 static tti_info_t UL_tti_info;
4297 static tti_info_t DL_tti_info;
4299 /* For associating with frame and displaying */
4300 typedef struct TTIInfoResult_t {
4301 unsigned ues_in_tti;
4302 } TTIInfoResult_t;
4304 /* This table stores (FrameNumber -> *TTIInfoResult_t). It is assigned during the first
4305 pass and used thereafter */
4306 static GHashTable *mac_lte_tti_info_result_hash;
4309 /* Work out which UE this is within TTI (within direction). Return answer */
4310 static uint16_t count_ues_tti(mac_lte_info *p_mac_lte_info, packet_info *pinfo)
4312 bool same_tti = false;
4313 tti_info_t *tti_info;
4315 /* Just return any previous result */
4316 TTIInfoResult_t *result = (TTIInfoResult_t *)g_hash_table_lookup(mac_lte_tti_info_result_hash, GUINT_TO_POINTER(pinfo->num));
4317 if (result != NULL) {
4318 return result->ues_in_tti;
4321 /* Set tti_info based upon direction */
4322 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4323 tti_info = &UL_tti_info;
4325 else {
4326 tti_info = &DL_tti_info;
4329 /* Work out if we are still in the same tti as before */
4330 if (tti_info->subframe == p_mac_lte_info->subframeNumber) {
4331 int seconds_between_packets = (int)
4332 (pinfo->abs_ts.secs - tti_info->ttiStartTime.secs);
4333 int nseconds_between_packets =
4334 pinfo->abs_ts.nsecs - tti_info->ttiStartTime.nsecs;
4336 /* Round difference to nearest microsecond */
4337 int total_us_gap = (seconds_between_packets*1000000) +
4338 ((nseconds_between_packets+500) / 1000);
4340 if (total_us_gap < 1000) {
4341 same_tti = true;
4345 /* Update global state */
4346 if (!same_tti) {
4347 tti_info->subframe = p_mac_lte_info->subframeNumber;
4348 tti_info->ttiStartTime = pinfo->abs_ts;
4349 tti_info->ues_in_tti = 1;
4351 else {
4352 tti_info->ues_in_tti++;
4355 /* Set result state for this frame */
4356 result = wmem_new(wmem_file_scope(), TTIInfoResult_t);
4357 result->ues_in_tti = tti_info->ues_in_tti;
4358 g_hash_table_insert(mac_lte_tti_info_result_hash,
4359 GUINT_TO_POINTER(pinfo->num), result);
4361 return tti_info->ues_in_tti;
4365 /* Show which UE this is (within direction) for this TTI */
4366 static void show_ues_tti(packet_info *pinfo, mac_lte_info *p_mac_lte_info, tvbuff_t *tvb, proto_tree *context_tree)
4368 /* Look up result */
4369 TTIInfoResult_t *result = (TTIInfoResult_t *)g_hash_table_lookup(mac_lte_tti_info_result_hash, GUINT_TO_POINTER(pinfo->num));
4370 if (result != NULL) {
4371 proto_item *ti = proto_tree_add_uint(context_tree,
4372 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4373 hf_mac_lte_ues_ul_per_tti :
4374 hf_mac_lte_ues_dl_per_tti,
4375 tvb, 0, 0, result->ues_in_tti);
4376 proto_item_set_generated(ti);
4380 static void set_rlc_seqnum_length_ext_li_field(rlc_channel_type_t rlc_channel_type,
4381 uint8_t direction,
4382 uint8_t *seqnum_length,
4383 bool *rlc_ext_li_field)
4385 switch (rlc_channel_type) {
4386 case rlcUM5:
4387 *seqnum_length = 5;
4388 break;
4389 case rlcUM10:
4390 *seqnum_length = 10;
4391 break;
4392 case rlcAMulExtLiField:
4393 *seqnum_length = 10;
4394 if (direction == DIRECTION_UPLINK) {
4395 *rlc_ext_li_field = true;
4397 break;
4398 case rlcAMdlExtLiField:
4399 *seqnum_length = 10;
4400 if (direction == DIRECTION_DOWNLINK) {
4401 *rlc_ext_li_field = true;
4403 break;
4404 case rlcAMextLiField:
4405 *seqnum_length = 10;
4406 *rlc_ext_li_field = true;
4407 break;
4408 case rlcAMul16:
4409 if (direction == DIRECTION_UPLINK) {
4410 *seqnum_length = 16;
4411 } else {
4412 *seqnum_length = 10;
4414 break;
4415 case rlcAMdl16:
4416 if (direction == DIRECTION_UPLINK) {
4417 *seqnum_length = 10;
4418 } else {
4419 *seqnum_length = 16;
4421 break;
4422 case rlcAM16:
4423 *seqnum_length = 16;
4424 break;
4425 case rlcAMul16ulExtLiField:
4426 if (direction == DIRECTION_UPLINK) {
4427 *seqnum_length = 16;
4428 *rlc_ext_li_field = true;
4429 } else {
4430 *seqnum_length = 10;
4432 break;
4433 case rlcAMdl16ulExtLiField:
4434 if (direction == DIRECTION_UPLINK) {
4435 *seqnum_length = 10;
4436 *rlc_ext_li_field = true;
4437 } else {
4438 *seqnum_length = 16;
4440 break;
4441 case rlcAM16ulExtLiField:
4442 *seqnum_length = 16;
4443 if (direction == DIRECTION_UPLINK) {
4444 *rlc_ext_li_field = true;
4446 break;
4447 case rlcAMul16dlExtLiField:
4448 if (direction == DIRECTION_UPLINK) {
4449 *seqnum_length = 16;
4450 } else {
4451 *seqnum_length = 10;
4452 *rlc_ext_li_field = true;
4454 break;
4455 case rlcAMdl16dlExtLiField:
4456 if (direction == DIRECTION_UPLINK) {
4457 *seqnum_length = 10;
4458 } else {
4459 *seqnum_length = 16;
4460 *rlc_ext_li_field = true;
4462 break;
4463 case rlcAM16dlExtLiField:
4464 *seqnum_length = 16;
4465 if (direction == DIRECTION_DOWNLINK) {
4466 *rlc_ext_li_field = true;
4468 break;
4469 case rlcAMul16extLiField:
4470 if (direction == DIRECTION_UPLINK) {
4471 *seqnum_length = 16;
4472 } else {
4473 *seqnum_length = 10;
4475 *rlc_ext_li_field = true;
4476 break;
4477 case rlcAMdl16extLiField:
4478 if (direction == DIRECTION_UPLINK) {
4479 *seqnum_length = 10;
4480 } else {
4481 *seqnum_length = 16;
4483 *rlc_ext_li_field = true;
4484 break;
4485 case rlcAM16extLiField:
4486 *seqnum_length = 16;
4487 *rlc_ext_li_field = true;
4488 break;
4489 default:
4490 break;
4494 /* Lookup channel details for lcid */
4495 static void lookup_rlc_channel_from_lcid(uint16_t ueid,
4496 uint8_t lcid,
4497 uint8_t direction,
4498 rlc_channel_type_t *rlc_channel_type,
4499 uint8_t *seqnum_length,
4500 int *drb_id,
4501 bool *rlc_ext_li_field)
4503 /* Zero params (in case no match is found) */
4504 *rlc_channel_type = rlcRaw;
4505 *seqnum_length = 0;
4506 *drb_id = 0;
4507 *rlc_ext_li_field = false;
4509 if (global_mac_lte_lcid_drb_source == (int)FromStaticTable) {
4511 /* Look up in static (UAT) table */
4512 unsigned m;
4513 for (m=0; m < num_lcid_drb_mappings; m++) {
4514 if (lcid == lcid_drb_mappings[m].lcid) {
4516 *rlc_channel_type = lcid_drb_mappings[m].channel_type;
4518 /* Set seqnum_length and rlc_ext_li_field */
4519 set_rlc_seqnum_length_ext_li_field(*rlc_channel_type, direction,
4520 seqnum_length, rlc_ext_li_field);
4522 /* Set drb_id */
4523 *drb_id = lcid_drb_mappings[m].drbid;
4524 break;
4528 else {
4529 /* Look up the dynamic mappings for this UE */
4530 ue_dynamic_drb_mappings_t *ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash, GUINT_TO_POINTER((unsigned)ueid));
4531 if (!ue_mappings) {
4532 return;
4535 /* Look up setting gleaned from configuration protocol */
4536 if (!ue_mappings->mapping[lcid].valid) {
4537 return;
4540 *rlc_channel_type = ue_mappings->mapping[lcid].channel_type;
4542 /* Set seqnum_length and rlc_ext_li_field */
4543 set_rlc_seqnum_length_ext_li_field(*rlc_channel_type, direction,
4544 seqnum_length, rlc_ext_li_field);
4546 /* Set drb_id */
4547 *drb_id = ue_mappings->mapping[lcid].drbid;
4552 /* Work out whether there are 1 or 4 bytes of C bits in Dual-Conn PHR CE */
4553 static unsigned get_dual_conn_phr_num_c_bytes(tvbuff_t *tvb, unsigned offset,
4554 bool isSimultPUCCHPUSCHPCell,
4555 bool isSimultPUCCHPUSCHPSCell,
4556 unsigned subheader_length)
4558 if (subheader_length < 4) {
4559 /* Can't be 4 */
4560 return 1;
4563 uint8_t scell_bitmap_byte = tvb_get_uint8(tvb, offset);
4564 unsigned i, byte_offset;
4566 /* Count bits set. */
4567 unsigned byte_bits_set = 0;
4568 for (i=1; i <= 7; ++i) {
4569 byte_bits_set += ((scell_bitmap_byte & (0x1 << i)) ? 1 : 0);
4572 /* Only work out length for 1-byte case (skip C byte itself). */
4573 byte_offset = offset+1;
4575 /* These 2 fields depend upon seeing correct RRC signalling.. */
4576 if (isSimultPUCCHPUSCHPCell) {
4577 if ((tvb_get_uint8(tvb, byte_offset) & 0x40) == 0) {
4578 byte_offset++;
4580 byte_offset++;
4582 if (isSimultPUCCHPUSCHPSCell) {
4583 if ((tvb_get_uint8(tvb, byte_offset) & 0x40) == 0) {
4584 byte_offset++;
4586 byte_offset++;
4589 /* Now walk number of entries set */
4590 for (i=0; i <= byte_bits_set; i++) {
4591 /* But take care to not walk past the end. */
4592 if ((byte_offset-offset) >= subheader_length) {
4593 /* Went off the end - assume 4... */
4594 return 4;
4596 if ((tvb_get_uint8(tvb, byte_offset) & 0x40) == 0) {
4597 byte_offset++;
4599 byte_offset++;
4602 /* Give verdict */
4603 if ((byte_offset-offset) == subheader_length) {
4604 return 1;
4606 else {
4607 return 4;
4612 #define MAX_HEADERS_IN_PDU 1024
4614 /* UL-SCH and DL-SCH formats have much in common, so handle them in a common
4615 function */
4616 static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4617 proto_item *pdu_ti, uint32_t offset,
4618 mac_lte_info *p_mac_lte_info, mac_3gpp_tap_info *tap_info,
4619 proto_item *retx_ti, proto_tree *context_tree,
4620 unsigned pdu_instance)
4622 uint8_t extension;
4623 uint16_t n;
4624 proto_item *truncated_ti;
4625 proto_item *padding_length_ti;
4627 /* Keep track of LCIDs and lengths as we dissect the header */
4628 uint16_t number_of_headers = 0;
4629 uint8_t lcids[MAX_HEADERS_IN_PDU];
4630 uint8_t elcids[MAX_HEADERS_IN_PDU];
4631 int32_t pdu_lengths[MAX_HEADERS_IN_PDU];
4633 proto_item *pdu_header_ti;
4634 proto_tree *pdu_header_tree;
4636 bool have_seen_data_header = false;
4637 uint8_t number_of_padding_subheaders = 0;
4638 bool have_seen_non_padding_control = false;
4639 bool have_seen_sc_mcch_sc_mtch_header = false;
4640 bool have_seen_bsr = false;
4641 bool expecting_body_data = false;
4642 uint32_t is_truncated = false;
4644 /* Maintain/show UEs/TTI count */
4645 tap_info->ueInTTI = count_ues_tti(p_mac_lte_info, pinfo);
4646 show_ues_tti(pinfo, p_mac_lte_info, tvb, context_tree);
4648 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4649 "%s: (SFN=%-4u, SF=%u) UEId=%-3u ",
4650 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
4651 p_mac_lte_info->sysframeNumber,
4652 p_mac_lte_info->subframeNumber,
4653 p_mac_lte_info->ueid);
4655 tap_info->raw_length = p_mac_lte_info->length;
4657 /******************************************************/
4658 /* DRX information */
4660 /* Update DRX state of UE */
4661 if (global_mac_lte_show_drx) {
4662 if (!PINFO_FD_VISITED(pinfo)) {
4664 /* Update UE state to this subframe (but before this event is processed) */
4665 update_drx_info(pinfo, p_mac_lte_info);
4667 /* Store 'before' snapshot of UE state for this frame */
4668 set_drx_info(pinfo, p_mac_lte_info, true, pdu_instance);
4671 /* Show current DRX state in tree as 'before' */
4672 show_drx_info(pinfo, tree, tvb, p_mac_lte_info, true, pdu_instance);
4674 /* Changes of state caused by events */
4675 if (!PINFO_FD_VISITED(pinfo)) {
4676 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4677 if (p_mac_lte_info->reTxCount == 0) {
4678 mac_lte_drx_new_ulsch_data(p_mac_lte_info->ueid);
4681 else {
4682 /* Downlink */
4683 if ((p_mac_lte_info->crcStatusValid) && (p_mac_lte_info->crcStatus != crc_success)) {
4684 mac_lte_drx_dl_crc_error(p_mac_lte_info->ueid);
4686 else if (p_mac_lte_info->dl_retx == dl_retx_no) {
4687 mac_lte_drx_new_dlsch_data(p_mac_lte_info->ueid);
4694 /* For uplink frames, if this is logged as a resend, look for original tx */
4695 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4696 TrackReportedULHARQResend(pinfo, tvb, offset, tree, p_mac_lte_info, retx_ti);
4699 /* For uplink grants, update SR status. N.B. only newTx grant should stop SR */
4700 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) && (p_mac_lte_info->reTxCount == 0) &&
4701 global_mac_lte_track_sr) {
4703 TrackSRInfo(SR_Grant, pinfo, tree, tvb, p_mac_lte_info, 0, NULL);
4706 /* Add PDU block header subtree */
4707 pdu_header_ti = proto_tree_add_string_format(tree,
4708 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4709 hf_mac_lte_ulsch_header :
4710 hf_mac_lte_dlsch_header,
4711 tvb, offset, 0,
4713 "MAC PDU Header");
4714 pdu_header_tree = proto_item_add_subtree(pdu_header_ti,
4715 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4716 ett_mac_lte_ulsch_header :
4717 ett_mac_lte_dlsch_header);
4720 /************************************************************************/
4721 /* Dissect each sub-header. */
4722 do {
4723 uint8_t reserved, format2, initial_lcid;
4724 uint64_t length = 0;
4725 proto_item *pdu_subheader_ti;
4726 proto_tree *pdu_subheader_tree;
4727 proto_item *lcid_ti;
4728 proto_item *ti;
4729 int offset_start_subheader = offset;
4730 uint8_t first_byte = tvb_get_uint8(tvb, offset);
4731 const char *lcid_str;
4733 /* Add PDU block header subtree.
4734 Default with length of 1 byte. */
4735 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
4736 hf_mac_lte_sch_subheader,
4737 tvb, offset, 1,
4739 "Sub-header");
4740 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
4741 ett_mac_lte_sch_subheader);
4743 /* Check 1st reserved bit */
4744 reserved = (first_byte & 0x80) >> 7;
4745 ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_reserved,
4746 tvb, offset, 1, ENC_BIG_ENDIAN);
4747 if (reserved != 0) {
4748 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
4749 "%cL-SCH header Reserved bit not zero",
4750 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D');
4753 /* Format2 bit */
4754 format2 = (first_byte & 0x40) >> 6;
4755 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_format2,
4756 tvb, offset, 1, ENC_BIG_ENDIAN);
4758 /* Extended bit */
4759 extension = (first_byte & 0x20) >> 5;
4760 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_extended,
4761 tvb, offset, 1, ENC_BIG_ENDIAN);
4763 /* LCID. Has different meaning depending upon direction. */
4764 lcids[number_of_headers] = first_byte & 0x1f;
4765 initial_lcid = lcids[number_of_headers];
4766 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4768 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_ulsch_lcid,
4769 tvb, offset, 1, ENC_BIG_ENDIAN);
4770 /* Also add LCID as a hidden, direction-less field */
4771 proto_item *bi_di_lcid = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_lcid, tvb, offset, 1, ENC_BIG_ENDIAN);
4772 proto_item_set_hidden(bi_di_lcid);
4774 if (lcids[number_of_headers] != EXT_LOGICAL_CHANNEL_ID_LCID) {
4775 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4776 "(%s",
4777 val_to_str_const(lcids[number_of_headers],
4778 ulsch_lcid_vals, "(Unknown LCID)"));
4779 } else {
4780 write_pdu_label_and_info(pdu_ti, NULL, pinfo, "(%u", tvb_get_uint8(tvb, offset+1) + 32);
4783 else {
4784 /* Downlink */
4785 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_dlsch_lcid,
4786 tvb, offset, 1, ENC_BIG_ENDIAN);
4787 /* Also add LCID as a hidden, direction-less field */
4788 proto_item *bi_di_lcid = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_lcid, tvb, offset, 1, ENC_BIG_ENDIAN);
4789 proto_item_set_hidden(bi_di_lcid);
4791 if (lcids[number_of_headers] != EXT_LOGICAL_CHANNEL_ID_LCID) {
4792 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4793 "(%s",
4794 val_to_str_const(lcids[number_of_headers],
4795 dlsch_lcid_vals, "(Unknown LCID)"));
4797 if ((lcids[number_of_headers] == DRX_COMMAND_LCID) ||
4798 (lcids[number_of_headers] == LONG_DRX_COMMAND_LCID)) {
4799 expert_add_info_format(pinfo, lcid_ti, &ei_mac_lte_dlsch_lcid,
4800 "%sDRX command received for UE %u (RNTI %u)",
4801 (lcids[number_of_headers] == LONG_DRX_COMMAND_LCID) ? "Long " :"",
4802 p_mac_lte_info->ueid, p_mac_lte_info->rnti);
4804 } else {
4805 write_pdu_label_and_info(pdu_ti, NULL, pinfo, "(%u", tvb_get_uint8(tvb, offset+1) + 32);
4808 offset++;
4810 /* Remember if we've seen a data subheader */
4811 if (is_data_lcid(lcids[number_of_headers], p_mac_lte_info->direction) || lcids[number_of_headers] == EXT_LOGICAL_CHANNEL_ID_LCID) {
4812 have_seen_data_header = true;
4813 expecting_body_data = true;
4815 if ((p_mac_lte_info->direction == DIRECTION_DOWNLINK) && (lcids[number_of_headers] == SC_MCCH_SC_MTCH_LCID)) {
4816 have_seen_sc_mcch_sc_mtch_header = true;
4819 /* Show an expert item if a control subheader (except Padding) appears
4820 *after* a data PDU */
4821 if (have_seen_data_header && !is_data_lcid(lcids[number_of_headers], p_mac_lte_info->direction) &&
4822 (lcids[number_of_headers] != EXT_LOGICAL_CHANNEL_ID_LCID) && (lcids[number_of_headers] != PADDING_LCID))
4824 expert_add_info_format(pinfo, lcid_ti, &ei_mac_lte_control_subheader_after_data_subheader,
4825 "%cL-SCH control subheaders should not appear after data subheaders",
4826 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D');
4827 return;
4830 /* Show an expert item if we're seeing more then one BSR in a frame */
4831 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) && is_bsr_lcid(lcids[number_of_headers])) {
4832 if (have_seen_bsr) {
4833 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_control_bsr_multiple);
4834 return;
4836 have_seen_bsr = true;
4839 /* Should not see padding after non-padding control... */
4840 if ((lcids[number_of_headers] == PADDING_LCID) && extension)
4842 number_of_padding_subheaders++;
4843 if (number_of_padding_subheaders > 2) {
4844 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_multiple);
4847 if (have_seen_non_padding_control) {
4848 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_before_control_subheader);
4852 /* Also flag if we have final padding but also padding subheaders
4853 at the start! */
4854 if (!extension && (lcids[number_of_headers] == PADDING_LCID) &&
4855 (number_of_padding_subheaders > 0)) {
4856 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_start_and_end);
4859 /* Remember that we've seen non-padding control */
4860 if (!is_data_lcid(lcids[number_of_headers], p_mac_lte_info->direction) &&
4861 (lcids[number_of_headers] != EXT_LOGICAL_CHANNEL_ID_LCID) &&
4862 (lcids[number_of_headers] != PADDING_LCID) &&
4863 (lcids[number_of_headers] != SC_MCCH_SC_MTCH_LCID)) {
4864 have_seen_non_padding_control = true;
4867 /* Ensure that SC-MCCH or SC-MTCH header is not multiplexed with other LCID than Padding */
4868 if (have_seen_sc_mcch_sc_mtch_header && (have_seen_data_header || have_seen_non_padding_control)) {
4869 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_invalid_sc_mcch_sc_mtch_subheader_multiplexing);
4870 return;
4873 if (lcids[number_of_headers] == EXT_LOGICAL_CHANNEL_ID_LCID) {
4874 uint8_t elcid;
4876 ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_reserved2,
4877 tvb, offset, 1, ENC_BIG_ENDIAN);
4878 if (reserved != 0) {
4879 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
4880 "%cL-SCH header Reserved bits not zero",
4881 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D');
4883 elcid = (tvb_get_uint8(tvb, offset) & 0x3f);
4884 elcids[number_of_headers] = elcid + 32;
4885 proto_tree_add_uint_format_value(pdu_subheader_tree, hf_mac_lte_sch_elcid, tvb, offset,
4886 1, elcid, "%u (%u)", elcids[number_of_headers], elcid);
4887 /* Also add hidden as LCID */
4888 proto_item *bi_di_lcid = proto_tree_add_uint(pdu_subheader_tree, hf_mac_lte_lcid, tvb, offset, 1, elcids[number_of_headers]);
4889 proto_item_set_hidden(bi_di_lcid);
4890 offset++;
4893 /********************************************************************/
4894 /* Length field follows if not the last header or for a fixed-sized
4895 control element */
4896 if (!extension) {
4897 /* Last one... */
4898 if (is_fixed_sized_control_element(lcids[number_of_headers], p_mac_lte_info->direction)) {
4899 pdu_lengths[number_of_headers] = 0;
4901 else {
4902 pdu_lengths[number_of_headers] = -1;
4905 else {
4906 /* Not the last one */
4907 if (!is_fixed_sized_control_element(lcids[number_of_headers], p_mac_lte_info->direction) &&
4908 (lcids[number_of_headers] != PADDING_LCID)) {
4910 if (format2) {
4911 /* >= 32768 - use 16 bits */
4912 ti = proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
4913 tvb, offset*8, 16, &length, ENC_BIG_ENDIAN);
4914 if (length < 32768) {
4915 expert_add_info(pinfo, ti, &ei_mac_lte_sch_invalid_length);
4918 offset += 2;
4919 } else {
4920 bool format;
4922 /* F(ormat) bit tells us how long the length field is */
4923 proto_tree_add_item_ret_boolean(pdu_subheader_tree, hf_mac_lte_sch_format,
4924 tvb, offset, 1, ENC_BIG_ENDIAN, &format);
4926 /* Now read length field itself */
4927 if (format) {
4928 /* >= 128 - use 15 bits */
4929 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
4930 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
4932 offset += 2;
4934 else {
4935 /* Less than 128 - only 7 bits */
4936 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
4937 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
4938 offset++;
4941 pdu_lengths[number_of_headers] = (int32_t)length;
4943 else {
4944 pdu_lengths[number_of_headers] = 0;
4949 /* Close off description in info column */
4950 switch (pdu_lengths[number_of_headers]) {
4951 case 0:
4952 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
4953 break;
4954 case -1:
4955 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
4956 break;
4957 default:
4958 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
4959 pdu_lengths[number_of_headers]);
4960 break;
4963 if (lcids[number_of_headers] != EXT_LOGICAL_CHANNEL_ID_LCID) {
4964 lcid_str = val_to_str_const(initial_lcid, (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4965 ulsch_lcid_vals : dlsch_lcid_vals, "Unknown");
4966 } else {
4967 lcid_str = wmem_strdup_printf(pinfo->pool, "%u", elcids[number_of_headers]);
4970 /* Append summary to subheader root */
4971 proto_item_append_text(pdu_subheader_ti, " (lcid=%s", lcid_str);
4973 switch (pdu_lengths[number_of_headers]) {
4974 case -1:
4975 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
4976 proto_item_append_text(pdu_header_ti, " (%s:remainder)", lcid_str);
4977 break;
4978 case 0:
4979 proto_item_append_text(pdu_subheader_ti, ")");
4980 proto_item_append_text(pdu_header_ti, " (%s)", lcid_str);
4981 break;
4982 default:
4983 proto_item_append_text(pdu_subheader_ti, ", length=%d)",
4984 pdu_lengths[number_of_headers]);
4985 proto_item_append_text(pdu_header_ti, " (%s:%u)", lcid_str, pdu_lengths[number_of_headers]);
4986 break;
4990 /* Flag unknown lcid values in expert info */
4991 if (try_val_to_str(lcids[number_of_headers],
4992 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals) == NULL) {
4993 expert_add_info_format(pinfo, pdu_subheader_ti, &ei_mac_lte_lcid_unexpected,
4994 "%cL-SCH: Unexpected LCID received (%u)",
4995 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D',
4996 lcids[number_of_headers]);
4999 /* Set length of this subheader */
5000 proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
5002 number_of_headers++;
5003 } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
5005 /* Check that we didn't reach the end of the subheader array... */
5006 if (number_of_headers >= MAX_HEADERS_IN_PDU) {
5007 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_too_many_subheaders, tvb, offset, 1,
5008 "Reached %u subheaders - frame obviously malformed",
5009 MAX_HEADERS_IN_PDU);
5010 return;
5014 /* Append summary to overall PDU header root */
5015 proto_item_append_text(pdu_header_ti, " [%u subheaders]",
5016 number_of_headers);
5018 /* And set its length to offset */
5019 proto_item_set_len(pdu_header_ti, offset);
5022 /* For DL, see if this is a retx. Use whole PDU present (i.e. ignore padding if not logged) */
5023 if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
5024 /* Result will be added to context tree */
5025 TrackReportedDLHARQResend(pinfo, tvb, tvb_reported_length_remaining(tvb, 0), context_tree, p_mac_lte_info);
5027 tap_info->isPHYRetx = (p_mac_lte_info->dl_retx == dl_retx_yes);
5031 /************************************************************************/
5032 /* Dissect SDUs / control elements / padding. */
5033 /************************************************************************/
5035 /* Dissect control element bodies first */
5037 for (n=0; n < number_of_headers; n++) {
5038 /* Get out of loop once see any data SDU subheaders */
5039 if (is_data_lcid(lcids[n], p_mac_lte_info->direction) ||
5040 lcids[n] == EXT_LOGICAL_CHANNEL_ID_LCID ||
5041 ((p_mac_lte_info->direction == DIRECTION_DOWNLINK) && (lcids[n] == SC_MCCH_SC_MTCH_LCID))) {
5042 break;
5045 /* Process what should be a valid control PDU type */
5046 if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
5048 /****************************/
5049 /* DL-SCH Control PDUs */
5050 switch (lcids[n]) {
5051 case DCQR_COMMAND_LCID:
5052 /* Zero length */
5053 break;
5054 case ACTIVATION_DEACTIVATION_PDCP_DUP_LCID:
5056 /* Create PDCP Dup root */
5057 proto_item *ad_pdcp_dup_ti =
5058 proto_tree_add_string_format(tree,
5059 hf_mac_lte_control_activation_deactivation_pdcp_dup,
5060 tvb, offset, pdu_lengths[n],
5062 "Activation/Deactivation of PDCP Duplication");
5063 proto_tree *ad_pdcp_dup_tree = proto_item_add_subtree(ad_pdcp_dup_ti, ett_mac_lte_activation_deactivation_pdcp_dup);
5065 /* D8..D1 (6.1.3.17) */
5066 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d8,
5067 tvb, offset, 1, ENC_BIG_ENDIAN);
5068 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d7,
5069 tvb, offset, 1, ENC_BIG_ENDIAN);
5070 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d6,
5071 tvb, offset, 1, ENC_BIG_ENDIAN);
5072 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d5,
5073 tvb, offset, 1, ENC_BIG_ENDIAN);
5074 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d4,
5075 tvb, offset, 1, ENC_BIG_ENDIAN);
5076 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d3,
5077 tvb, offset, 1, ENC_BIG_ENDIAN);
5078 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d2,
5079 tvb, offset, 1, ENC_BIG_ENDIAN);
5080 proto_tree_add_item(ad_pdcp_dup_tree, hf_mac_lte_control_activation_deactivation_pdcp_dup_d1,
5081 tvb, offset, 1, ENC_BIG_ENDIAN);
5082 offset += 1;
5083 break;
5085 case HIBERNATION_1_OCTET_LCID:
5086 case HIBERNATION_4_OCTETS_LCID:
5088 /* 6.1.3.15 */
5090 /* Hibernation root */
5091 proto_item *hibernation_ti =
5092 proto_tree_add_string_format(tree,
5093 hf_mac_lte_control_hibernation,
5094 tvb, offset, pdu_lengths[n],
5096 "Hibernation");
5097 proto_tree *hibernation_tree = proto_item_add_subtree(hibernation_ti, ett_mac_lte_hibernation);
5099 /* First octet common to both LCIDs */
5100 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c7,
5101 tvb, offset, 1, ENC_BIG_ENDIAN);
5102 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c6,
5103 tvb, offset, 1, ENC_BIG_ENDIAN);
5104 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c5,
5105 tvb, offset, 1, ENC_BIG_ENDIAN);
5106 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c4,
5107 tvb, offset, 1, ENC_BIG_ENDIAN);
5108 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c3,
5109 tvb, offset, 1, ENC_BIG_ENDIAN);
5110 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c2,
5111 tvb, offset, 1, ENC_BIG_ENDIAN);
5112 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c1,
5113 tvb, offset, 1, ENC_BIG_ENDIAN);
5114 /* N.B. Last bit is reserved */
5115 proto_tree_add_item(hibernation_ti, hf_mac_lte_control_hibernation_reserved,
5116 tvb, offset, 1, ENC_BIG_ENDIAN);
5117 offset += 1;
5119 if (lcids[n] == HIBERNATION_4_OCTETS_LCID) {
5120 /* 2nd octet */
5121 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c15,
5122 tvb, offset, 1, ENC_BIG_ENDIAN);
5123 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c14,
5124 tvb, offset, 1, ENC_BIG_ENDIAN);
5125 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c13,
5126 tvb, offset, 1, ENC_BIG_ENDIAN);
5127 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c12,
5128 tvb, offset, 1, ENC_BIG_ENDIAN);
5129 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c11,
5130 tvb, offset, 1, ENC_BIG_ENDIAN);
5131 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c10,
5132 tvb, offset, 1, ENC_BIG_ENDIAN);
5133 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c9,
5134 tvb, offset, 1, ENC_BIG_ENDIAN);
5135 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c8,
5136 tvb, offset, 1, ENC_BIG_ENDIAN);
5137 offset += 1;
5139 /* 3rd octet */
5140 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c23,
5141 tvb, offset, 1, ENC_BIG_ENDIAN);
5142 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c22,
5143 tvb, offset, 1, ENC_BIG_ENDIAN);
5144 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c21,
5145 tvb, offset, 1, ENC_BIG_ENDIAN);
5146 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c20,
5147 tvb, offset, 1, ENC_BIG_ENDIAN);
5148 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c19,
5149 tvb, offset, 1, ENC_BIG_ENDIAN);
5150 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c18,
5151 tvb, offset, 1, ENC_BIG_ENDIAN);
5152 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c17,
5153 tvb, offset, 1, ENC_BIG_ENDIAN);
5154 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c16,
5155 tvb, offset, 1, ENC_BIG_ENDIAN);
5156 offset += 1;
5158 /* 4th octet */
5159 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c31,
5160 tvb, offset, 1, ENC_BIG_ENDIAN);
5161 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c30,
5162 tvb, offset, 1, ENC_BIG_ENDIAN);
5163 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c29,
5164 tvb, offset, 1, ENC_BIG_ENDIAN);
5165 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c28,
5166 tvb, offset, 1, ENC_BIG_ENDIAN);
5167 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c27,
5168 tvb, offset, 1, ENC_BIG_ENDIAN);
5169 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c26,
5170 tvb, offset, 1, ENC_BIG_ENDIAN);
5171 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c25,
5172 tvb, offset, 1, ENC_BIG_ENDIAN);
5173 proto_tree_add_item(hibernation_tree, hf_mac_lte_control_hibernation_c24,
5174 tvb, offset, 1, ENC_BIG_ENDIAN);
5175 offset += 1;
5177 break;
5180 case ACTIVATION_DEACTIVATION_CSI_RS_LCID:
5182 proto_item *ad_csi_rs_ti;
5183 proto_tree *ad_csi_rs_tree;
5184 int32_t i;
5186 if (pdu_lengths[n] == -1) {
5187 /* Control Element size is the remaining PDU */
5188 pdu_lengths[n] = (int32_t)tvb_reported_length_remaining(tvb, offset);
5190 /* Create AD CSR-RS root */
5191 ad_csi_rs_ti = proto_tree_add_string_format(tree,
5192 hf_mac_lte_control_activation_deactivation_csi_rs,
5193 tvb, offset, pdu_lengths[n],
5195 "Activation/Deactivation of CSI-RS");
5196 ad_csi_rs_tree = proto_item_add_subtree(ad_csi_rs_ti, ett_mac_lte_activation_deactivation_csi_rs);
5198 for (i = 0; i < pdu_lengths[n]; i++) {
5199 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a8,
5200 tvb, offset, 1, ENC_BIG_ENDIAN);
5201 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a7,
5202 tvb, offset, 1, ENC_BIG_ENDIAN);
5203 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a6,
5204 tvb, offset, 1, ENC_BIG_ENDIAN);
5205 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a5,
5206 tvb, offset, 1, ENC_BIG_ENDIAN);
5207 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a4,
5208 tvb, offset, 1, ENC_BIG_ENDIAN);
5209 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a3,
5210 tvb, offset, 1, ENC_BIG_ENDIAN);
5211 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a2,
5212 tvb, offset, 1, ENC_BIG_ENDIAN);
5213 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a1,
5214 tvb, offset, 1, ENC_BIG_ENDIAN);
5215 offset += 1;
5218 break;
5219 case RECOMMENDED_BIT_RATE_LCID:
5221 proto_item *br_ti;
5222 proto_tree *br_tree;
5223 proto_item *ti;
5224 uint32_t reserved;
5226 /* Create BR root */
5227 br_ti = proto_tree_add_string_format(tree,
5228 hf_mac_lte_control_recommended_bit_rate,
5229 tvb, offset, 2,
5231 "Recommended Bit Rate");
5232 br_tree = proto_item_add_subtree(br_ti, ett_mac_lte_recommended_bit_rate);
5234 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_lcid,
5235 tvb, offset, 1, ENC_BIG_ENDIAN);
5236 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_dir,
5237 tvb, offset, 1, ENC_BIG_ENDIAN);
5238 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_bit_rate,
5239 tvb, offset, 2, ENC_BIG_ENDIAN);
5240 offset += 1;
5241 ti = proto_tree_add_item_ret_uint(br_tree, hf_mac_lte_control_recommended_bit_rate_reserved,
5242 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
5243 if (reserved != 0) {
5244 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5245 "Recommended Bit Rate Reserved bits not zero");
5247 offset += 1;
5249 break;
5250 case ACTIVATION_DEACTIVATION_LCID:
5251 case ACTIVATION_DEACTIVATION_4_BYTES_LCID:
5253 proto_item *ad_ti;
5254 proto_tree *ad_tree;
5255 proto_item *ti;
5256 uint32_t reserved;
5258 /* Create AD root */
5259 ad_ti = proto_tree_add_string_format(tree,
5260 hf_mac_lte_control_activation_deactivation,
5261 tvb, offset,
5262 (lcids[n] == ACTIVATION_DEACTIVATION_4_BYTES_LCID) ? 4 : 1,
5264 "Activation/Deactivation");
5265 ad_tree = proto_item_add_subtree(ad_ti, ett_mac_lte_activation_deactivation);
5267 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c7,
5268 tvb, offset, 1, ENC_BIG_ENDIAN);
5269 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c6,
5270 tvb, offset, 1, ENC_BIG_ENDIAN);
5271 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c5,
5272 tvb, offset, 1, ENC_BIG_ENDIAN);
5273 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c4,
5274 tvb, offset, 1, ENC_BIG_ENDIAN);
5275 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c3,
5276 tvb, offset, 1, ENC_BIG_ENDIAN);
5277 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c2,
5278 tvb, offset, 1, ENC_BIG_ENDIAN);
5279 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c1,
5280 tvb, offset, 1, ENC_BIG_ENDIAN);
5281 ti = proto_tree_add_item_ret_uint(ad_tree, hf_mac_lte_control_activation_deactivation_reserved,
5282 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
5283 if (reserved != 0) {
5284 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5285 "Activation/Deactivation Reserved bit not zero");
5287 offset++;
5288 if (lcids[n] == ACTIVATION_DEACTIVATION_4_BYTES_LCID) {
5289 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c15,
5290 tvb, offset, 1, ENC_BIG_ENDIAN);
5291 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c14,
5292 tvb, offset, 1, ENC_BIG_ENDIAN);
5293 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c13,
5294 tvb, offset, 1, ENC_BIG_ENDIAN);
5295 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c12,
5296 tvb, offset, 1, ENC_BIG_ENDIAN);
5297 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c11,
5298 tvb, offset, 1, ENC_BIG_ENDIAN);
5299 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c10,
5300 tvb, offset, 1, ENC_BIG_ENDIAN);
5301 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c9,
5302 tvb, offset, 1, ENC_BIG_ENDIAN);
5303 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c8,
5304 tvb, offset, 1, ENC_BIG_ENDIAN);
5305 offset++;
5306 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c23,
5307 tvb, offset, 1, ENC_BIG_ENDIAN);
5308 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c22,
5309 tvb, offset, 1, ENC_BIG_ENDIAN);
5310 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c21,
5311 tvb, offset, 1, ENC_BIG_ENDIAN);
5312 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c20,
5313 tvb, offset, 1, ENC_BIG_ENDIAN);
5314 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c19,
5315 tvb, offset, 1, ENC_BIG_ENDIAN);
5316 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c18,
5317 tvb, offset, 1, ENC_BIG_ENDIAN);
5318 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c17,
5319 tvb, offset, 1, ENC_BIG_ENDIAN);
5320 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c16,
5321 tvb, offset, 1, ENC_BIG_ENDIAN);
5322 offset++;
5323 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c31,
5324 tvb, offset, 1, ENC_BIG_ENDIAN);
5325 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c30,
5326 tvb, offset, 1, ENC_BIG_ENDIAN);
5327 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c29,
5328 tvb, offset, 1, ENC_BIG_ENDIAN);
5329 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c28,
5330 tvb, offset, 1, ENC_BIG_ENDIAN);
5331 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c27,
5332 tvb, offset, 1, ENC_BIG_ENDIAN);
5333 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c26,
5334 tvb, offset, 1, ENC_BIG_ENDIAN);
5335 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c25,
5336 tvb, offset, 1, ENC_BIG_ENDIAN);
5337 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c24,
5338 tvb, offset, 1, ENC_BIG_ENDIAN);
5339 offset++;
5342 break;
5343 case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
5345 proto_item *cr_ti;
5346 proto_tree *cr_tree;
5347 proto_item *ti;
5348 ContentionResolutionResult *crResult;
5350 /* Create CR root */
5351 cr_ti = proto_tree_add_string_format(tree,
5352 hf_mac_lte_control_ue_contention_resolution,
5353 tvb, offset, 6,
5355 "Contention Resolution");
5356 cr_tree = proto_item_add_subtree(cr_ti, ett_mac_lte_contention_resolution);
5358 /* Contention resolution body */
5359 proto_tree_add_item(cr_tree, hf_mac_lte_control_ue_contention_resolution_identity,
5360 tvb, offset, 6, ENC_NA);
5361 if (global_mac_lte_decode_cr_body) {
5362 tvbuff_t *cr_body_tvb = tvb_new_subset_length(tvb, offset, 6);
5363 if (lte_rrc_ul_ccch_handle != 0) {
5364 call_with_catch_all(lte_rrc_ul_ccch_handle, cr_body_tvb, pinfo, cr_tree);
5368 /* Get pointer to result struct for this frame */
5369 crResult = (ContentionResolutionResult *)g_hash_table_lookup(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->num));
5370 if (crResult == NULL) {
5372 /* Need to set result by looking for and comparing with Msg3 */
5373 Msg3Data *msg3Data;
5374 unsigned msg3Key = p_mac_lte_info->rnti;
5376 /* Allocate result and add it to the table */
5377 crResult = wmem_new(wmem_file_scope(), ContentionResolutionResult);
5378 g_hash_table_insert(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->num), crResult);
5380 /* Look for Msg3 */
5381 msg3Data = (Msg3Data *)g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(msg3Key));
5383 /* Compare CCCH bytes */
5384 if (msg3Data != NULL) {
5385 crResult->msSinceMsg3 = (uint32_t)(((pinfo->abs_ts.secs - msg3Data->msg3Time.secs) * 1000) +
5386 ((pinfo->abs_ts.nsecs - msg3Data->msg3Time.nsecs) / 1000000));
5387 crResult->msg3FrameNum = msg3Data->framenum;
5389 /* Compare the 6 bytes */
5390 if (tvb_memeql(tvb, offset, msg3Data->data, 6) == 0) {
5391 crResult->status = Msg3Match;
5393 else {
5394 crResult->status = Msg3NoMatch;
5397 else {
5398 crResult->status = NoMsg3;
5402 /* Now show CR result in tree */
5403 switch (crResult->status) {
5404 case NoMsg3:
5405 proto_item_append_text(cr_ti, " (no corresponding Msg3 found!)");
5406 break;
5408 case Msg3Match:
5409 /* Point back to msg3 frame */
5410 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
5411 tvb, 0, 0, crResult->msg3FrameNum);
5412 proto_item_set_generated(ti);
5413 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
5414 tvb, 0, 0, crResult->msSinceMsg3);
5415 proto_item_set_generated(ti);
5417 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
5418 tvb, 0, 0, true);
5419 proto_item_set_generated(ti);
5420 proto_item_append_text(cr_ti, " (matches Msg3 from frame %u, %ums ago)",
5421 crResult->msg3FrameNum, crResult->msSinceMsg3);
5423 if (!PINFO_FD_VISITED(pinfo)) {
5424 /* Add reverse mapping so can link forward from Msg3 frame */
5425 g_hash_table_insert(mac_lte_msg3_cr_hash, GUINT_TO_POINTER(crResult->msg3FrameNum),
5426 GUINT_TO_POINTER(pinfo->num));
5428 break;
5430 case Msg3NoMatch:
5431 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
5432 tvb, 0, 0, crResult->msg3FrameNum);
5433 proto_item_set_generated(ti);
5434 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
5435 tvb, 0, 0, crResult->msSinceMsg3);
5436 proto_item_set_generated(ti);
5438 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
5439 tvb, 0, 0, false);
5440 expert_add_info_format(pinfo, ti, &ei_mac_lte_control_ue_contention_resolution_msg3_matched,
5441 "CR body in Msg4 doesn't match Msg3 CCCH in frame %u",
5442 crResult->msg3FrameNum);
5443 proto_item_set_generated(ti);
5444 proto_item_append_text(cr_ti, " (doesn't match Msg3 from frame %u, %u ago)",
5445 crResult->msg3FrameNum, crResult->msSinceMsg3);
5446 break;
5449 offset += 6;
5451 break;
5452 case TIMING_ADVANCE_LCID:
5454 proto_item *ta_ti;
5455 proto_item *ta_value_ti;
5456 proto_tree *ta_tree;
5457 uint32_t ta_value;
5459 /* Create TA root */
5460 ta_ti = proto_tree_add_string_format(tree,
5461 hf_mac_lte_control_timing_advance,
5462 tvb, offset, 1,
5464 "Timing Advance");
5465 ta_tree = proto_item_add_subtree(ta_ti, ett_mac_lte_timing_advance);
5467 /* TAG Id */
5468 proto_tree_add_item(ta_tree, hf_mac_lte_control_timing_advance_group_id,
5469 tvb, offset, 1, ENC_BIG_ENDIAN);
5471 /* TA value */
5472 ta_value_ti = proto_tree_add_item_ret_uint(ta_tree, hf_mac_lte_control_timing_advance_command,
5473 tvb, offset, 1, ENC_BIG_ENDIAN, &ta_value);
5475 if (ta_value == 31) {
5476 expert_add_info(pinfo, ta_value_ti, &ei_mac_lte_control_timing_advance_command_no_correction);
5478 else {
5479 expert_add_info_format(pinfo, ta_value_ti, &ei_mac_lte_control_timing_advance_command_correction_needed,
5480 "Timing Advance control element received (%u) %s correction needed",
5481 ta_value,
5482 (ta_value < 31) ? "-ve" : "+ve");
5484 offset++;
5486 break;
5487 case DRX_COMMAND_LCID:
5488 case LONG_DRX_COMMAND_LCID:
5489 /* No payload */
5490 mac_lte_drx_control_element_received(p_mac_lte_info->ueid);
5491 break;
5492 case PADDING_LCID:
5493 /* No payload (in this position) */
5494 tap_info->padding_bytes++;
5495 break;
5497 default:
5498 break;
5501 else {
5503 /**********************************/
5504 /* UL-SCH Control PDUs */
5505 switch (lcids[n]) {
5506 case TIMING_ADVANCE_REPORT_LCID:
5507 /* 6.1.3.20 */
5508 /* R R */
5509 proto_tree_add_item(tree, hf_mac_lte_control_timing_advance_value_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
5510 /* Timing Advance */
5511 proto_tree_add_item(tree, hf_mac_lte_control_timing_advance_value, tvb, offset, 2, ENC_BIG_ENDIAN);
5512 offset += 2;
5513 break;
5515 case DCQR_AND_AS_RAI_LCID:
5516 /* TODO: 6.1.3.19 */
5517 /* AS RAI */
5518 proto_tree_add_item(tree, hf_mac_lte_control_as_rai, tvb, offset, 1, ENC_BIG_ENDIAN);
5519 /* R R */
5520 proto_tree_add_item(tree, hf_mac_lte_control_as_rai_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
5521 /* Quality Report */
5522 proto_tree_add_item(tree, hf_mac_lte_control_as_rai_quality_report, tvb, offset, 1, ENC_BIG_ENDIAN);
5523 offset += 1;
5524 break;
5526 case AUL_CONFIRMATION_1_OCTET:
5527 case AUL_CONFIRMATION_4_OCTETS:
5529 /* 6.1.3.16 */
5531 /* AUL confirmation root */
5532 proto_item *aul_conf_ti =
5533 proto_tree_add_string_format(tree,
5534 hf_mac_lte_control_aul_confirmation,
5535 tvb, offset, pdu_lengths[n],
5537 "AUL Confirmation");
5538 proto_tree *aul_conf_tree = proto_item_add_subtree(aul_conf_ti, ett_mac_lte_aul_confirmation);
5540 /* First octet common to both LCIDs */
5541 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c7,
5542 tvb, offset, 1, ENC_BIG_ENDIAN);
5543 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c6,
5544 tvb, offset, 1, ENC_BIG_ENDIAN);
5545 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c5,
5546 tvb, offset, 1, ENC_BIG_ENDIAN);
5547 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c4,
5548 tvb, offset, 1, ENC_BIG_ENDIAN);
5549 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c3,
5550 tvb, offset, 1, ENC_BIG_ENDIAN);
5551 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c2,
5552 tvb, offset, 1, ENC_BIG_ENDIAN);
5553 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c1,
5554 tvb, offset, 1, ENC_BIG_ENDIAN);
5555 /* N.B. Last bit is reserved */
5556 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_reserved,
5557 tvb, offset, 1, ENC_BIG_ENDIAN);
5558 offset += 1;
5560 if (lcids[n] == AUL_CONFIRMATION_4_OCTETS) {
5561 /* 2nd octet */
5562 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c15,
5563 tvb, offset, 1, ENC_BIG_ENDIAN);
5564 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c14,
5565 tvb, offset, 1, ENC_BIG_ENDIAN);
5566 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c13,
5567 tvb, offset, 1, ENC_BIG_ENDIAN);
5568 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c12,
5569 tvb, offset, 1, ENC_BIG_ENDIAN);
5570 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c11,
5571 tvb, offset, 1, ENC_BIG_ENDIAN);
5572 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c10,
5573 tvb, offset, 1, ENC_BIG_ENDIAN);
5574 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c9,
5575 tvb, offset, 1, ENC_BIG_ENDIAN);
5576 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c8,
5577 tvb, offset, 1, ENC_BIG_ENDIAN);
5578 offset += 1;
5580 /* 3rd octet */
5581 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c23,
5582 tvb, offset, 1, ENC_BIG_ENDIAN);
5583 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c22,
5584 tvb, offset, 1, ENC_BIG_ENDIAN);
5585 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c21,
5586 tvb, offset, 1, ENC_BIG_ENDIAN);
5587 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c20,
5588 tvb, offset, 1, ENC_BIG_ENDIAN);
5589 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c19,
5590 tvb, offset, 1, ENC_BIG_ENDIAN);
5591 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c18,
5592 tvb, offset, 1, ENC_BIG_ENDIAN);
5593 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c17,
5594 tvb, offset, 1, ENC_BIG_ENDIAN);
5595 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c16,
5596 tvb, offset, 1, ENC_BIG_ENDIAN);
5597 offset += 1;
5599 /* 4th octet */
5600 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c31,
5601 tvb, offset, 1, ENC_BIG_ENDIAN);
5602 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c30,
5603 tvb, offset, 1, ENC_BIG_ENDIAN);
5604 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c29,
5605 tvb, offset, 1, ENC_BIG_ENDIAN);
5606 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c28,
5607 tvb, offset, 1, ENC_BIG_ENDIAN);
5608 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c27,
5609 tvb, offset, 1, ENC_BIG_ENDIAN);
5610 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c26,
5611 tvb, offset, 1, ENC_BIG_ENDIAN);
5612 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c25,
5613 tvb, offset, 1, ENC_BIG_ENDIAN);
5614 proto_tree_add_item(aul_conf_tree, hf_mac_lte_control_aul_confirmation_c24,
5615 tvb, offset, 1, ENC_BIG_ENDIAN);
5616 offset += 1;
5618 break;
5621 case RECOMMENDED_BIT_RATE_QUERY_LCID:
5623 proto_item *br_ti;
5624 proto_tree *br_tree;
5625 proto_item *ti;
5626 uint32_t reserved;
5628 /* Create BR root */
5629 br_ti = proto_tree_add_string_format(tree,
5630 hf_mac_lte_control_recommended_bit_rate_query,
5631 tvb, offset, 2,
5633 "Recommended Bit Rate Query");
5634 br_tree = proto_item_add_subtree(br_ti, ett_mac_lte_recommended_bit_rate_query);
5636 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_query_lcid,
5637 tvb, offset, 1, ENC_BIG_ENDIAN);
5638 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_query_dir,
5639 tvb, offset, 1, ENC_BIG_ENDIAN);
5640 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_query_bit_rate,
5641 tvb, offset, 2, ENC_BIG_ENDIAN);
5642 offset += 1;
5643 ti = proto_tree_add_item_ret_uint(br_tree, hf_mac_lte_control_recommended_bit_rate_query_reserved,
5644 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
5645 if (reserved != 0) {
5646 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5647 "Recommended Bit Rate Reserved bits not zero");
5649 offset += 1;
5651 break;
5652 case TRUNCATED_SIDELINK_BSR_LCID:
5653 case SIDELINK_BSR_LCID:
5655 proto_item *slbsr_ti;
5656 proto_tree *slbsr_tree;
5657 uint32_t curr_offset = offset;
5659 if (pdu_lengths[n] == -1) {
5660 /* Control Element size is the remaining PDU */
5661 pdu_lengths[n] = (int32_t)tvb_reported_length_remaining(tvb, curr_offset);
5663 /* Create SLBSR root */
5664 if (lcids[n] == SIDELINK_BSR_LCID) {
5665 slbsr_ti = proto_tree_add_string_format(tree,
5666 hf_mac_lte_control_sidelink_bsr,
5667 tvb, curr_offset, pdu_lengths[n],
5669 "Sidelink BSR");
5670 } else {
5671 slbsr_ti = proto_tree_add_string_format(tree,
5672 hf_mac_lte_control_sidelink_bsr,
5673 tvb, curr_offset, pdu_lengths[n],
5675 "Truncated Sidelink BSR");
5677 slbsr_tree = proto_item_add_subtree(slbsr_ti, ett_mac_lte_sidelink_bsr);
5679 while ((int32_t)(curr_offset - offset) < pdu_lengths[n]) {
5680 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_destination_idx_odd,
5681 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5682 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_lcg_id_odd,
5683 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5684 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_buffer_size_odd,
5685 tvb, curr_offset, 2, ENC_BIG_ENDIAN);
5686 curr_offset++;
5687 if ((int32_t)(curr_offset - offset) < (pdu_lengths[n] - 1)) {
5688 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_destination_idx_even,
5689 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5690 curr_offset++;
5691 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_lcg_id_even,
5692 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5693 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_buffer_size_even,
5694 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5695 curr_offset++;
5696 } else {
5697 /* Check Reserved bit */
5698 uint32_t reserved;
5699 proto_item *it;
5701 it = proto_tree_add_item_ret_uint(slbsr_tree, hf_mac_lte_control_sidelink_reserved,
5702 tvb, curr_offset, 1, ENC_BIG_ENDIAN, &reserved);
5703 if (reserved) {
5704 if (lcids[n] == SIDELINK_BSR_LCID) {
5705 expert_add_info_format(pinfo, it, &ei_mac_lte_reserved_not_zero,
5706 "Sidelink BSR Reserved bits not zero");
5707 } else {
5708 expert_add_info_format(pinfo, it, &ei_mac_lte_reserved_not_zero,
5709 "Truncated Sidelink BSR Reserved bits not zero");
5712 break;
5715 offset += pdu_lengths[n];
5717 break;
5718 case DUAL_CONN_POWER_HEADROOM_REPORT_LCID:
5720 proto_item *dcphr_ti;
5721 proto_tree *dcphr_tree;
5722 proto_item *ti;
5723 proto_tree *dcphr_cell_tree;
5724 proto_item *dcphr_cell_ti;
5725 uint8_t scell_bitmap_byte;
5726 uint32_t scell_bitmap_word;
5727 uint8_t byte;
5728 unsigned i;
5729 uint32_t curr_offset = offset;
5731 if (!PINFO_FD_VISITED(pinfo)) {
5732 get_mac_lte_ue_simult_pucch_pusch(p_mac_lte_info);
5734 if (pdu_lengths[n] == -1) {
5735 /* Control Element size is the remaining PDU */
5736 pdu_lengths[n] = (int32_t)tvb_reported_length_remaining(tvb, curr_offset);
5739 /* Create DCPHR root */
5740 dcphr_ti = proto_tree_add_string_format(tree,
5741 hf_mac_lte_control_dual_conn_power_headroom,
5742 tvb, curr_offset, pdu_lengths[n],
5744 "Dual Connectivity Power Headroom Report");
5745 dcphr_tree = proto_item_add_subtree(dcphr_ti, ett_mac_lte_dual_conn_power_headroom);
5747 /* Work out (heuristically) whether we have 1 or 4 bytes of C bits.
5748 * Should be based upon highest sCellIndex and/or whether UE is in dual-connectivity,
5749 * but for now trust subheader length and see which one fits. */
5750 unsigned num_c_bytes = get_dual_conn_phr_num_c_bytes(tvb, curr_offset,
5751 p_mac_lte_info->isSimultPUCCHPUSCHPCell,
5752 p_mac_lte_info->isSimultPUCCHPUSCHPSCell,
5753 pdu_lengths[n]);
5755 scell_bitmap_byte = tvb_get_uint8(tvb, curr_offset);
5757 /* Do first byte (C1-C7) */
5758 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c7,
5759 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5760 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c6,
5761 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5762 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c5,
5763 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5764 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c4,
5765 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5766 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c3,
5767 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5768 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c2,
5769 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5770 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c1,
5771 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5772 /* Check Reserved bit */
5773 ti = proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved,
5774 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5775 if (scell_bitmap_byte & 0x01) {
5776 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5777 "Dual Connectivity Power Headroom Report Reserved bit not zero");
5779 curr_offset++;
5781 if (num_c_bytes == 4) {
5782 /* Do other 3 bytes (C8-C31) */
5783 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c15,
5784 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5785 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c14,
5786 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5787 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c13,
5788 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5789 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c12,
5790 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5791 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c11,
5792 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5793 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c10,
5794 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5795 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c9,
5796 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5797 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c8,
5798 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5799 curr_offset++;
5801 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c23,
5802 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5803 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c22,
5804 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5805 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c21,
5806 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5807 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c20,
5808 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5809 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c19,
5810 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5811 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c18,
5812 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5813 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c17,
5814 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5815 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c16,
5816 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5817 curr_offset++;
5819 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c31,
5820 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5821 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c30,
5822 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5823 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c29,
5824 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5825 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c28,
5826 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5827 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c27,
5828 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5829 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c26,
5830 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5831 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c25,
5832 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5833 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c24,
5834 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5835 curr_offset++;
5839 if (p_mac_lte_info->isSimultPUCCHPUSCHPCell) {
5840 /* PCell PH Type 2 is present */
5841 byte = tvb_get_uint8(tvb, curr_offset);
5842 dcphr_cell_tree = proto_tree_add_subtree(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5843 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "PCell PUCCH");
5844 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5845 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5846 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5847 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5848 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5849 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5850 proto_item_append_text(dcphr_cell_ti, " (%s)",
5851 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5852 curr_offset++;
5853 if ((byte & 0x40) == 0) {
5854 /* Pcmax,c field is present */
5855 byte = tvb_get_uint8(tvb, curr_offset);
5856 /* Check 2 Reserved bits */
5857 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5858 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5859 if (byte & 0xc0) {
5860 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5861 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5862 (byte & 0xc0) >> 6);
5864 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5865 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5866 proto_item_append_text(dcphr_cell_ti, " (%s)",
5867 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5868 curr_offset++;
5871 if (p_mac_lte_info->isSimultPUCCHPUSCHPSCell) {
5872 /* PSCell PH Type 2 is present */
5873 byte = tvb_get_uint8(tvb, curr_offset);
5874 dcphr_cell_tree = proto_tree_add_subtree(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5875 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "PSCell PUCCH");
5876 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5877 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5878 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5879 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5880 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5881 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5882 proto_item_append_text(dcphr_cell_ti, " (%s)",
5883 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5884 curr_offset++;
5885 if ((byte & 0x40) == 0) {
5886 /* Pcmax,c field is present */
5887 byte = tvb_get_uint8(tvb, curr_offset);
5888 /* Check 2 Reserved bits */
5889 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5890 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5891 if (byte & 0xc0) {
5892 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5893 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5894 (byte & 0xc0) >> 6);
5896 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5897 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5898 proto_item_append_text(dcphr_cell_ti, " (%s)",
5899 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5900 curr_offset++;
5903 byte = tvb_get_uint8(tvb, curr_offset);
5904 dcphr_cell_tree = proto_tree_add_subtree(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5905 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "PCell PUSCH");
5906 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5907 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5908 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5909 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5910 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5911 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5912 proto_item_append_text(dcphr_cell_ti, " (%s)",
5913 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5914 curr_offset++;
5915 if ((byte & 0x40) == 0) {
5916 /* Pcmax,c field is present */
5917 byte = tvb_get_uint8(tvb, curr_offset);
5918 /* Check 2 Reserved bits */
5919 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5920 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5921 if (byte & 0xc0) {
5922 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5923 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5924 (byte & 0xc0) >> 6);
5926 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5927 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5928 proto_item_append_text(dcphr_cell_ti, " (%s)",
5929 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5930 curr_offset++;
5933 /* Add entry for each set bit. Iterate over 32 entries regardless */
5934 if (num_c_bytes == 1) {
5935 scell_bitmap_word = scell_bitmap_byte << 24; /* least significant 3 bytes will be 0 */
5937 else {
5938 scell_bitmap_word = tvb_get_ntohl(tvb, offset);
5941 for (i=1; i < 31; i++) {
5942 /* Work out how much shift to adddress this bit */
5943 unsigned byte_shift = (31-i)/8;
5944 unsigned bit_shift = i % 8;
5945 /* Is entry for scell i present? */
5946 if (scell_bitmap_word & (0x01 << (byte_shift*8 + bit_shift))) {
5947 byte = tvb_get_uint8(tvb, curr_offset);
5948 dcphr_cell_tree = proto_tree_add_subtree_format(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5949 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "SCell Index %u PUSCH", i);
5950 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5951 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5952 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5953 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5954 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5955 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5956 proto_item_append_text(dcphr_cell_ti, " (%s)",
5957 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5958 curr_offset++;
5959 if ((byte & 0x40) == 0) {
5960 /* Pcmax,c field is present */
5961 byte = tvb_get_uint8(tvb, curr_offset);
5962 /* Check 2 Reserved bits */
5963 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5964 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5965 if (byte & 0xc0) {
5966 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5967 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5968 (byte & 0xc0) >> 6);
5970 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5971 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5972 proto_item_append_text(dcphr_cell_ti, " (%s)",
5973 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5974 curr_offset++;
5978 if ((int32_t)(curr_offset - offset) != pdu_lengths[n]) {
5979 expert_add_info_format(pinfo, dcphr_ti, &ei_mac_lte_control_element_size_invalid,
5980 "Control Element has an unexpected size (computed=%u, actual=%d)",
5981 curr_offset - offset, pdu_lengths[n]);
5983 offset += pdu_lengths[n];
5985 break;
5986 case EXTENDED_POWER_HEADROOM_REPORT_LCID:
5988 proto_item *ephr_ti;
5989 proto_tree *ephr_tree;
5990 proto_item *ti;
5991 proto_tree *ephr_cell_tree;
5992 proto_item *ephr_cell_ti;
5993 uint8_t scell_bitmap;
5994 uint8_t scell_count;
5995 uint8_t byte;
5996 unsigned i;
5997 uint32_t curr_offset = offset;
5998 uint32_t computed_header_offset;
6000 if (!PINFO_FD_VISITED(pinfo)) {
6001 get_mac_lte_ue_simult_pucch_pusch(p_mac_lte_info);
6003 if (pdu_lengths[n] == -1) {
6004 /* Control Element size is the remaining PDU */
6005 pdu_lengths[n] = (int16_t)tvb_reported_length_remaining(tvb, curr_offset);
6008 /* Create EPHR root */
6009 ephr_ti = proto_tree_add_string_format(tree,
6010 hf_mac_lte_control_ext_power_headroom,
6011 tvb, curr_offset, pdu_lengths[n],
6013 "Extended Power Headroom Report");
6014 ephr_tree = proto_item_add_subtree(ephr_ti, ett_mac_lte_extended_power_headroom);
6016 /* TODO: add support for extendedPHR2 */
6017 scell_bitmap = tvb_get_uint8(tvb, curr_offset);
6018 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c7,
6019 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6020 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c6,
6021 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6022 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c5,
6023 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6024 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c4,
6025 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6026 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c3,
6027 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6028 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c2,
6029 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6030 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c1,
6031 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6032 /* Check Reserved bit */
6033 ti = proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_reserved,
6034 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6035 if (scell_bitmap & 0x01) {
6036 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6037 "Extended Power Headroom Report Reserved bit not zero");
6039 curr_offset++;
6041 /* Compute expected header size to deduce if PH Type 2 report is present or not */
6042 /* First count the number of SCells */
6043 for (i = 0, scell_count = 0; i < 7; i++) {
6044 if (scell_bitmap & (0x80>>i)) {
6045 scell_count++;
6048 /* Now quickly parse the header */
6049 computed_header_offset = curr_offset;
6050 for (i = 0; i < (unsigned)(1 + scell_count); i++) {
6051 if ((tvb_get_uint8(tvb, computed_header_offset) & 0x40) == 0) {
6052 computed_header_offset++;
6054 computed_header_offset++;
6057 if (((int32_t)(computed_header_offset + 1 - curr_offset) != pdu_lengths[n]) ||
6058 p_mac_lte_info->isSimultPUCCHPUSCHPCell) {
6059 /* PH Type 2 might be present */
6060 if ((tvb_get_uint8(tvb, computed_header_offset) & 0x40) == 0) {
6061 computed_header_offset++;
6063 computed_header_offset++;
6064 if ((int32_t)(computed_header_offset + 1 - curr_offset) != pdu_lengths[n]) {
6065 expert_add_info_format(pinfo, ephr_ti, &ei_mac_lte_control_element_size_invalid,
6066 "Control Element has an unexpected size (computed=%u, actual=%d)",
6067 computed_header_offset + 1 - curr_offset, pdu_lengths[n]);
6068 offset += pdu_lengths[n];
6069 break;
6071 byte = tvb_get_uint8(tvb, curr_offset);
6072 ephr_cell_tree = proto_tree_add_subtree(ephr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
6073 ett_mac_lte_extended_power_headroom_cell, &ephr_cell_ti, "PCell PUCCH");
6074 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
6075 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6076 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
6077 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6078 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
6079 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6080 proto_item_append_text(ephr_cell_ti, " (%s)",
6081 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
6082 curr_offset++;
6083 if ((byte & 0x40) == 0) {
6084 /* Pcmax,c field is present */
6085 byte = tvb_get_uint8(tvb, curr_offset);
6086 /* Check 2 Reserved bits */
6087 ti = proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
6088 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6089 if (byte & 0xc0) {
6090 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6091 "Extended Power Headroom Report Reserved bits not zero (found 0x%x)",
6092 (byte & 0xc0) >> 6);
6094 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
6095 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6096 proto_item_append_text(ephr_cell_ti, " (%s)",
6097 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
6098 curr_offset++;
6101 byte = tvb_get_uint8(tvb, curr_offset);
6102 ephr_cell_tree = proto_tree_add_subtree(ephr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
6103 ett_mac_lte_extended_power_headroom_cell, &ephr_cell_ti, "PCell PUSCH");
6104 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
6105 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6106 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
6107 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6108 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
6109 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6110 proto_item_append_text(ephr_cell_ti, " (%s)",
6111 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
6112 curr_offset++;
6113 if ((byte & 0x40) == 0) {
6114 /* Pcmax,c field is present */
6115 byte = tvb_get_uint8(tvb, curr_offset);
6116 /* Check 2 Reserved bits */
6117 ti = proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
6118 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6119 if (byte & 0xc0) {
6120 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6121 "Extended Power Headroom Report Reserved bits not zero (found 0x%x)",
6122 (byte & 0xc0) >> 6);
6124 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
6125 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6126 proto_item_append_text(ephr_cell_ti, " (%s)",
6127 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
6128 curr_offset++;
6130 for (i = 1, scell_bitmap>>=1; i <= 7; i++, scell_bitmap>>=1) {
6131 if (scell_bitmap & 0x01) {
6132 byte = tvb_get_uint8(tvb, curr_offset);
6133 ephr_cell_tree = proto_tree_add_subtree_format(ephr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
6134 ett_mac_lte_extended_power_headroom_cell, &ephr_cell_ti, "SCell Index %u PUSCH", i);
6135 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
6136 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6137 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
6138 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6139 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
6140 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6141 proto_item_append_text(ephr_cell_ti, " (%s)",
6142 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
6143 curr_offset++;
6144 if ((byte & 0x40) == 0) {
6145 /* Pcmax,c field is present */
6146 byte = tvb_get_uint8(tvb, curr_offset);
6147 /* Check 2 Reserved bits */
6148 uint32_t reserved;
6149 ti = proto_tree_add_item_ret_uint(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
6150 tvb, curr_offset, 1, ENC_BIG_ENDIAN, &reserved);
6151 if (reserved != 0) {
6152 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6153 "Extended Power Headroom Report Reserved bits not zero (found 0x%x)",
6154 reserved);
6156 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
6157 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6158 proto_item_append_text(ephr_cell_ti, " (%s)",
6159 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
6160 curr_offset++;
6164 offset += pdu_lengths[n];
6166 break;
6167 case POWER_HEADROOM_REPORT_LCID:
6169 proto_item *phr_ti;
6170 proto_tree *phr_tree;
6171 proto_item *ti;
6172 uint32_t reserved;
6173 uint32_t level;
6175 /* Create PHR root */
6176 phr_ti = proto_tree_add_string_format(tree,
6177 hf_mac_lte_control_power_headroom,
6178 tvb, offset, 1,
6180 "Power Headroom Report");
6181 phr_tree = proto_item_add_subtree(phr_ti, ett_mac_lte_power_headroom);
6183 /* Check 2 Reserved bits */
6184 ti = proto_tree_add_item_ret_uint(phr_tree, hf_mac_lte_control_power_headroom_reserved,
6185 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
6186 if (reserved != 0) {
6187 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6188 "Power Headroom Report Reserved bits not zero (found 0x%x)", reserved);
6191 /* Level */
6192 proto_tree_add_item_ret_uint(phr_tree, hf_mac_lte_control_power_headroom_level,
6193 tvb, offset, 1, ENC_BIG_ENDIAN, &level);
6195 /* Show value in root label */
6196 proto_item_append_text(phr_ti, " (%s)",
6197 val_to_str_ext_const(level, &power_headroom_vals_ext, "Unknown"));
6198 offset++;
6200 break;
6201 case CRNTI_LCID:
6202 proto_tree_add_item(tree, hf_mac_lte_control_crnti,
6203 tvb, offset, 2, ENC_BIG_ENDIAN);
6204 offset += 2;
6205 break;
6206 /* TODO: treat separately */
6207 case TRUNCATED_BSR_LCID:
6208 case SHORT_BSR_LCID:
6210 proto_tree *bsr_tree;
6211 proto_item *bsr_ti;
6212 proto_item *buffer_size_ti;
6213 uint32_t lcgid;
6214 uint32_t buffer_size;
6215 int hfindex;
6216 value_string_ext *p_vs_ext;
6217 uint32_t *p_buffer_size_median;
6219 if (!PINFO_FD_VISITED(pinfo)) {
6220 get_mac_lte_ue_ext_bsr_sizes(p_mac_lte_info);
6222 if (p_mac_lte_info->isExtendedBSRSizes) {
6223 hfindex = hf_mac_lte_control_short_ext_bsr_buffer_size;
6224 p_vs_ext = &ext_buffer_size_vals_ext;
6225 p_buffer_size_median = ext_buffer_size_median;
6226 } else {
6227 hfindex = hf_mac_lte_control_short_bsr_buffer_size;
6228 p_vs_ext = &buffer_size_vals_ext;
6229 p_buffer_size_median = buffer_size_median;
6232 if (lcids[n] == SHORT_BSR_LCID) {
6233 bsr_ti = proto_tree_add_string_format(tree,
6234 hf_mac_lte_control_bsr,
6235 tvb, offset, 1,
6237 "Short BSR");
6238 } else {
6239 bsr_ti = proto_tree_add_string_format(tree,
6240 hf_mac_lte_control_bsr,
6241 tvb, offset, 1,
6243 "Truncated BSR");
6245 bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
6247 /* LCG ID */
6248 proto_tree_add_item_ret_uint(bsr_tree, hf_mac_lte_control_bsr_lcg_id,
6249 tvb, offset, 1, ENC_BIG_ENDIAN, &lcgid);
6250 /* Buffer Size */
6251 buffer_size_ti = proto_tree_add_item_ret_uint(bsr_tree, hfindex,
6252 tvb, offset, 1, ENC_BIG_ENDIAN, &buffer_size);
6253 if (global_mac_lte_show_BSR_median) {
6254 /* Add value that can be graphed */
6255 proto_item *bsr_median_ti = proto_tree_add_uint(bsr_tree, hf_mac_lte_bsr_size_median, tvb, offset, 1, p_buffer_size_median[buffer_size]);
6256 proto_item_set_generated(bsr_median_ti);
6258 offset++;
6260 if ((int)buffer_size >= global_mac_lte_bsr_warn_threshold) {
6261 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
6262 "UE %u - BSR for LCG %u exceeds threshold: %u (%s)",
6263 p_mac_lte_info->ueid,
6264 lcgid,
6265 buffer_size,
6266 val_to_str_ext_const(buffer_size, p_vs_ext, "Unknown"));
6270 proto_item_append_text(bsr_ti, " (lcgid=%u %s)",
6271 lcgid,
6272 val_to_str_ext_const(buffer_size, p_vs_ext, "Unknown"));
6274 break;
6275 case LONG_BSR_LCID:
6277 proto_tree *bsr_tree;
6278 proto_item *bsr_ti, *bsr_median_ti;
6279 proto_item *buffer_size_ti;
6280 uint32_t buffer_size[4];
6281 int hfindex[4];
6282 value_string_ext *p_vs_ext;
6283 uint32_t *p_buffer_size_median;
6285 if (!PINFO_FD_VISITED(pinfo)) {
6286 get_mac_lte_ue_ext_bsr_sizes(p_mac_lte_info);
6288 if (p_mac_lte_info->isExtendedBSRSizes) {
6289 hfindex[0] = hf_mac_lte_control_long_ext_bsr_buffer_size_0;
6290 hfindex[1] = hf_mac_lte_control_long_ext_bsr_buffer_size_1;
6291 hfindex[2] = hf_mac_lte_control_long_ext_bsr_buffer_size_2;
6292 hfindex[3] = hf_mac_lte_control_long_ext_bsr_buffer_size_3;
6293 p_vs_ext = &ext_buffer_size_vals_ext;
6294 p_buffer_size_median = ext_buffer_size_median;
6295 } else {
6296 hfindex[0] = hf_mac_lte_control_long_bsr_buffer_size_0;
6297 hfindex[1] = hf_mac_lte_control_long_bsr_buffer_size_1;
6298 hfindex[2] = hf_mac_lte_control_long_bsr_buffer_size_2;
6299 hfindex[3] = hf_mac_lte_control_long_bsr_buffer_size_3;
6300 p_vs_ext = &buffer_size_vals_ext;
6301 p_buffer_size_median = buffer_size_median;
6304 bsr_ti = proto_tree_add_string_format(tree,
6305 hf_mac_lte_control_bsr,
6306 tvb, offset, 3,
6308 "Long BSR");
6309 bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
6311 /* LCID Group 0 */
6312 buffer_size_ti = proto_tree_add_item_ret_uint(bsr_tree, hfindex[0],
6313 tvb, offset, 1,
6314 ENC_BIG_ENDIAN, &buffer_size[0]);
6316 if (global_mac_lte_show_BSR_median) {
6317 /* Add value that can be graphed */
6318 bsr_median_ti = proto_tree_add_uint(bsr_tree, hf_mac_lte_bsr_size_median, tvb, offset, 1, p_buffer_size_median[buffer_size[0]]);
6319 proto_item_set_generated(bsr_median_ti);
6322 if ((int)buffer_size[0] >= global_mac_lte_bsr_warn_threshold) {
6323 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
6324 "UE %u - BSR for LCG 0 exceeds threshold: %u (%s)",
6325 p_mac_lte_info->ueid,
6326 buffer_size[0],
6327 val_to_str_ext_const(buffer_size[0], p_vs_ext, "Unknown"));
6330 /* LCID Group 1 */
6331 buffer_size_ti = proto_tree_add_item_ret_uint(bsr_tree, hfindex[1],
6332 tvb, offset, 2,
6333 ENC_BIG_ENDIAN, &buffer_size[1]);
6335 if (global_mac_lte_show_BSR_median) {
6336 /* Add value that can be graphed */
6337 bsr_median_ti = proto_tree_add_uint(bsr_tree, hf_mac_lte_bsr_size_median, tvb, offset, 1, p_buffer_size_median[buffer_size[1]]);
6338 proto_item_set_generated(bsr_median_ti);
6341 offset++;
6342 if ((int)buffer_size[1] >= global_mac_lte_bsr_warn_threshold) {
6343 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
6344 "UE %u - BSR for LCG 1 exceeds threshold: %u (%s)",
6345 p_mac_lte_info->ueid,
6346 buffer_size[1],
6347 val_to_str_ext_const(buffer_size[1], p_vs_ext, "Unknown"));
6350 /* LCID Group 2 */
6351 buffer_size_ti = proto_tree_add_item_ret_uint(bsr_tree, hfindex[2],
6352 tvb, offset, 2,
6353 ENC_BIG_ENDIAN, &buffer_size[2]);
6355 if (global_mac_lte_show_BSR_median) {
6356 /* Add value that can be graphed */
6357 bsr_median_ti = proto_tree_add_uint(bsr_tree, hf_mac_lte_bsr_size_median, tvb, offset, 1, p_buffer_size_median[buffer_size[2]]);
6358 proto_item_set_generated(bsr_median_ti);
6361 offset++;
6362 if ((int)buffer_size[2] >= global_mac_lte_bsr_warn_threshold) {
6363 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
6364 "UE %u - BSR for LCG 2 exceeds threshold: %u (%s)",
6365 p_mac_lte_info->ueid,
6366 buffer_size[2],
6367 val_to_str_ext_const(buffer_size[2], p_vs_ext, "Unknown"));
6370 /* LCID Group 3 */
6371 buffer_size_ti = proto_tree_add_item_ret_uint(bsr_tree, hfindex[3],
6372 tvb, offset, 1,
6373 ENC_BIG_ENDIAN, &buffer_size[3]);
6375 if (global_mac_lte_show_BSR_median) {
6376 /* Add value that can be graphed */
6377 bsr_median_ti = proto_tree_add_uint(bsr_tree, hf_mac_lte_bsr_size_median, tvb, offset, 1, p_buffer_size_median[buffer_size[3]]);
6378 proto_item_set_generated(bsr_median_ti);
6381 offset++;
6382 if ((int)buffer_size[3] >= global_mac_lte_bsr_warn_threshold) {
6383 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
6384 "UE %u - BSR for LCG 3 exceeds threshold: %u (%s)",
6385 p_mac_lte_info->ueid,
6386 buffer_size[3],
6387 val_to_str_ext_const(buffer_size[3], p_vs_ext, "Unknown"));
6390 /* Append summary to parent */
6391 proto_item_append_text(bsr_ti, " 0:(%s) 1:(%s) 2:(%s) 3:(%s)",
6392 val_to_str_ext_const(buffer_size[0], p_vs_ext, "Unknown"),
6393 val_to_str_ext_const(buffer_size[1], p_vs_ext, "Unknown"),
6394 val_to_str_ext_const(buffer_size[2], p_vs_ext, "Unknown"),
6395 val_to_str_ext_const(buffer_size[3], p_vs_ext, "Unknown"));
6397 break;
6398 case PADDING_LCID:
6399 /* No payload, in this position */
6400 tap_info->padding_bytes++;
6401 break;
6403 default:
6404 break;
6409 /* There might not be any data, if only headers (plus control data) were logged */
6410 is_truncated = ((tvb_captured_length_remaining(tvb, offset) == 0) && expecting_body_data);
6411 truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_sch_header_only, tvb, 0, 0,
6412 is_truncated);
6413 if (is_truncated) {
6414 proto_item_set_generated(truncated_ti);
6415 expert_add_info(pinfo, truncated_ti, &ei_mac_lte_sch_header_only_truncated);
6416 /* Update sdu and byte count in stats */
6417 for (; n < number_of_headers; n++) {
6418 uint16_t data_length;
6419 /* Break out if meet padding */
6420 if (lcids[n] == PADDING_LCID) {
6421 break;
6423 data_length = (pdu_lengths[n] == -1) ?
6424 tvb_reported_length_remaining(tvb, offset) :
6425 pdu_lengths[n];
6426 if ((lcids[n] >= 3) && (lcids[n] <= 10)) {
6427 tap_info->sdus_for_lcid[lcids[n]]++;
6428 tap_info->bytes_for_lcid[lcids[n]] += data_length;
6429 } else if ((lcids[n] == EXT_LOGICAL_CHANNEL_ID_LCID) &&
6430 (elcids[n] >= 32) && (elcids[n] <= 38)) {
6431 tap_info->sdus_for_lcid[elcids[n]-21]++;
6432 tap_info->bytes_for_lcid[elcids[n]-21] += data_length;
6434 offset += data_length;
6436 if (lcids[number_of_headers-1] == PADDING_LCID) {
6437 /* Update padding bytes in stats */
6438 tap_info->padding_bytes += (p_mac_lte_info->length - offset);
6440 return;
6442 else {
6443 proto_item_set_hidden(truncated_ti);
6447 /* Now process remaining bodies, which should all be data */
6448 for (; n < number_of_headers; n++) {
6450 /* Data SDUs treated identically for Uplink or downlink channels */
6451 proto_item *sdu_ti;
6452 uint16_t data_length;
6453 bool rlc_called_for_sdu = false;
6455 /* Break out if meet padding */
6456 if (lcids[n] == PADDING_LCID) {
6457 break;
6460 /* Work out length */
6461 data_length = (pdu_lengths[n] == -1) ?
6462 tvb_reported_length_remaining(tvb, offset) :
6463 pdu_lengths[n];
6465 if ((lcids[n] == 0) && /* CCCH */
6466 (p_mac_lte_info->direction == DIRECTION_UPLINK) &&
6467 (p_mac_lte_info->nbMode == nb_mode) &&
6468 (data_length > 0)) {
6470 /* Dissect DPR MAC Control Element that is in front of CCCH SDU (Figure 6.1.3.10-1) */
6471 proto_item *dpr_ti;
6472 proto_tree *dpr_tree;
6473 uint32_t reserved;
6475 dpr_ti = proto_tree_add_string_format(tree,
6476 hf_mac_lte_control_data_vol_power_headroom,
6477 tvb, offset, 1,
6479 "Data Volume and Power Headroom Report");
6480 dpr_tree = proto_item_add_subtree(dpr_ti, ett_mac_lte_data_vol_power_headroom);
6481 /* R R */
6482 dpr_ti = proto_tree_add_item_ret_uint(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_reserved,
6483 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
6484 if (reserved) {
6485 expert_add_info_format(pinfo, dpr_ti, &ei_mac_lte_reserved_not_zero,
6486 "Data Volume and Power Headroom Report Reserved bits not zero");
6488 /* PH (2 bits) */
6489 proto_tree_add_item(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_level, tvb, offset, 1, ENC_BIG_ENDIAN);
6490 /* DV (4 bits) */
6491 proto_tree_add_item(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_data_vol, tvb, offset, 1, ENC_BIG_ENDIAN);
6492 offset++;
6493 if (pdu_lengths[n] == -1) {
6494 data_length--;
6498 if ((lcids[n] == 13) && /* CCCH and Extended Power Headroom Report */
6499 (p_mac_lte_info->direction == DIRECTION_UPLINK) &&
6500 (p_mac_lte_info->nbMode == nb_mode) &&
6501 (data_length > 0)) {
6503 /* Dissect DPR MAC Control Element that is in front of CCCH SDU (Figure 6.1.3.10-1a) */
6504 proto_item *dpr_ti;
6505 proto_tree *dpr_tree;
6507 dpr_ti = proto_tree_add_string_format(tree,
6508 hf_mac_lte_control_data_vol_power_headroom,
6509 tvb, offset, 1,
6511 "Data Volume and Power Headroom Report for Extended Power Headroom");
6512 dpr_tree = proto_item_add_subtree(dpr_ti, ett_mac_lte_data_vol_power_headroom);
6514 /* PH (4 bits) */
6515 proto_tree_add_item(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_level_4_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
6516 /* DV (4 bits) */
6517 proto_tree_add_item(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_data_vol, tvb, offset, 1, ENC_BIG_ENDIAN);
6518 offset++;
6519 if (pdu_lengths[n] == -1) {
6520 data_length--;
6524 /* Dissect SDU as raw bytes */
6525 sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_sch_sdu, tvb, offset, pdu_lengths[n],
6526 NULL, "SDU (%s, length=%u bytes): ",
6527 val_to_str_const(lcids[n],
6528 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
6529 ulsch_lcid_vals :
6530 dlsch_lcid_vals,
6531 "Unknown"),
6532 data_length);
6534 /* Look for Msg3 data so that it may be compared with later
6535 Contention Resolution body */
6536 /* Starting from R13, CCCH can be more than 48 bits but only the first 48 bits are used for contention resolution */
6537 if ((lcids[n] == 0) && (p_mac_lte_info->direction == DIRECTION_UPLINK) && (data_length >= 6)) {
6538 if (!PINFO_FD_VISITED(pinfo)) {
6539 unsigned key = p_mac_lte_info->rnti;
6540 Msg3Data *data = (Msg3Data *)g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(key));
6542 /* Look for previous entry for this UE */
6543 if (data == NULL) {
6544 /* Allocate space for data and add to table */
6545 data = wmem_new(wmem_file_scope(), Msg3Data);
6546 g_hash_table_insert(mac_lte_msg3_hash, GUINT_TO_POINTER(key), data);
6549 /* Fill in data details */
6550 data->framenum = pinfo->num;
6551 tvb_memcpy(tvb, data->data, offset, 6);
6552 data->msg3Time = pinfo->abs_ts;
6556 /* CCCH frames can be dissected directly by LTE RRC... */
6557 if ((lcids[n] == 0) && global_mac_lte_attempt_rrc_decode) {
6558 tvbuff_t *rrc_tvb = tvb_new_subset_length(tvb, offset, data_length);
6560 /* Get appropriate dissector handle */
6561 dissector_handle_t protocol_handle = 0;
6562 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
6563 if (p_mac_lte_info->nbMode == no_nb_mode) {
6564 protocol_handle = lte_rrc_ul_ccch_handle;
6566 else {
6567 protocol_handle = lte_rrc_ul_ccch_nb_handle;
6570 else {
6571 if (p_mac_lte_info->nbMode == no_nb_mode) {
6572 protocol_handle = lte_rrc_dl_ccch_handle;
6574 else {
6575 protocol_handle = lte_rrc_dl_ccch_nb_handle;
6579 /* Hide raw view of bytes */
6580 proto_item_set_hidden(sdu_ti);
6581 rlc_called_for_sdu = true;
6583 call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
6586 /* LCID 1 and 2 can be assumed to be srb1&2, so can dissect as RLC AM */
6587 /* LCID 3 in NB mode can be assumed to be srb1bis, so can dissect as RLC AM */
6588 else if ((lcids[n] == 1) || (lcids[n] == 2) ||
6589 (p_mac_lte_info->nbMode == nb_mode && lcids[n] == 3)) {
6590 if (global_mac_lte_attempt_srb_decode) {
6591 /* Call RLC dissector */
6592 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6593 RLC_AM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
6594 CHANNEL_TYPE_SRB, lcids[n], 0,
6595 get_mac_lte_channel_priority(p_mac_lte_info->ueid,
6596 lcids[n], p_mac_lte_info->direction),
6597 false, p_mac_lte_info->nbMode);
6599 /* Hide raw view of bytes */
6600 proto_item_set_hidden(sdu_ti);
6601 rlc_called_for_sdu = true;
6605 else if (((lcids[n] >= 3) && (lcids[n] <= 10)) || (lcids[n] == EXT_LOGICAL_CHANNEL_ID_LCID)) {
6607 /* Look for mapping for this LCID to drb channel set by UAT table or through
6608 configuration protocol. */
6609 rlc_channel_type_t rlc_channel_type;
6610 uint8_t seqnum_length;
6611 int drb_id;
6612 bool rlc_ext_li_field;
6613 uint8_t lcid = (lcids[n] == EXT_LOGICAL_CHANNEL_ID_LCID) ? elcids[n] : lcids[n];
6614 uint8_t priority = get_mac_lte_channel_priority(p_mac_lte_info->ueid,
6615 lcid, p_mac_lte_info->direction);
6617 lookup_rlc_channel_from_lcid(p_mac_lte_info->ueid,
6618 lcid,
6619 p_mac_lte_info->direction,
6620 &rlc_channel_type,
6621 &seqnum_length,
6622 &drb_id,
6623 &rlc_ext_li_field);
6625 /* Dissect according to channel type */
6626 switch (rlc_channel_type) {
6627 case rlcUM5:
6628 case rlcUM10:
6629 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6630 RLC_UM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
6631 CHANNEL_TYPE_DRB, (uint16_t)drb_id, seqnum_length,
6632 priority, false, p_mac_lte_info->nbMode);
6633 break;
6634 case rlcAM:
6635 case rlcAMulExtLiField:
6636 case rlcAMdlExtLiField:
6637 case rlcAMextLiField:
6638 case rlcAMul16:
6639 case rlcAMdl16:
6640 case rlcAM16:
6641 case rlcAMul16ulExtLiField:
6642 case rlcAMdl16ulExtLiField:
6643 case rlcAM16ulExtLiField:
6644 case rlcAMul16dlExtLiField:
6645 case rlcAMdl16dlExtLiField:
6646 case rlcAM16dlExtLiField:
6647 case rlcAMul16extLiField:
6648 case rlcAMdl16extLiField:
6649 case rlcAM16extLiField:
6650 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6651 RLC_AM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
6652 CHANNEL_TYPE_DRB, (uint16_t)drb_id, seqnum_length,
6653 priority, rlc_ext_li_field, p_mac_lte_info->nbMode);
6654 break;
6655 case rlcTM:
6656 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6657 RLC_TM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
6658 CHANNEL_TYPE_DRB, (uint16_t)drb_id, 0,
6659 priority, false, p_mac_lte_info->nbMode);
6660 break;
6661 case rlcRaw:
6662 /* Nothing to do! */
6663 break;
6666 if (rlc_channel_type != rlcRaw) {
6667 /* Hide raw view of bytes */
6668 proto_item_set_hidden(sdu_ti);
6669 rlc_called_for_sdu = true;
6674 else if ((lcids[n] == SC_MCCH_SC_MTCH_LCID) && (p_mac_lte_info->rntiType == SC_RNTI)
6675 && global_mac_lte_attempt_rrc_decode) {
6676 tvbuff_t *rrc_tvb = tvb_new_subset_length(tvb, offset, data_length);
6678 /* Hide raw view of bytes */
6679 proto_item_set_hidden(sdu_ti);
6680 rlc_called_for_sdu = true;
6682 call_with_catch_all(lte_rrc_sc_mcch_handle, rrc_tvb, pinfo, tree);
6685 /* Show bytes too, if won't be hidden (slow). There must be a nicer way of doing this! */
6686 if (!rlc_called_for_sdu) {
6687 if (pdu_lengths[n] >= 30)
6689 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(pinfo->pool, tvb, offset, 30));
6690 proto_item_append_text(sdu_ti, "...");
6692 else
6694 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(pinfo->pool, tvb, offset, data_length));
6698 offset += data_length;
6700 /* Update tap sdu and byte count for this channel */
6701 if ((lcids[n] >= 3) && (lcids[n] <= 10)) {
6702 tap_info->sdus_for_lcid[lcids[n]]++;
6703 tap_info->bytes_for_lcid[lcids[n]] += data_length;
6704 } else if ((lcids[n] == EXT_LOGICAL_CHANNEL_ID_LCID) &&
6705 (elcids[n] >= 32) && (elcids[n] <= 38)) {
6706 tap_info->sdus_for_lcid[elcids[n]-21]++;
6707 tap_info->bytes_for_lcid[elcids[n]-21] += data_length;
6711 /* Was this a Msg3 that led to a CR answer? */
6712 if (PINFO_FD_VISITED(pinfo)) {
6713 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) &&
6714 (lcids[0] == 0)) /* N.B. there has to be at least 1 lcid if we got here */ {
6716 uint32_t cr_frame = GPOINTER_TO_UINT (g_hash_table_lookup(mac_lte_msg3_cr_hash,
6717 GUINT_TO_POINTER(pinfo->num)));
6718 if (cr_frame != 0) {
6719 proto_item *cr_ti = proto_tree_add_uint(tree, hf_mac_lte_control_msg3_to_cr,
6720 tvb, 0, 0, cr_frame);
6721 proto_item_set_generated(cr_ti);
6726 /* Now padding, if present, extends to the end of the PDU */
6727 if (lcids[number_of_headers-1] == PADDING_LCID) {
6728 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6729 proto_tree_add_item(tree, hf_mac_lte_padding_data,
6730 tvb, offset, -1, ENC_NA);
6732 padding_length_ti = proto_tree_add_uint(tree, hf_mac_lte_padding_length,
6733 tvb, offset, 0,
6734 p_mac_lte_info->length - offset);
6735 proto_item_set_generated(padding_length_ti);
6737 /* Update padding bytes in stats */
6738 tap_info->padding_bytes += (p_mac_lte_info->length - offset);
6740 /* Make sure the PDU isn't bigger than reported! */
6741 if (offset > p_mac_lte_info->length) {
6742 expert_add_info_format(pinfo, padding_length_ti, &ei_mac_lte_context_length,
6743 "%s MAC PDU is longer than reported length (reported=%u, actual=%u)",
6744 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
6745 p_mac_lte_info->length, offset);
6748 else {
6749 /* There is no padding at the end of the frame */
6750 if (offset < p_mac_lte_info->length) {
6751 /* There is a problem if we haven't used all of the PDU */
6752 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6753 "%s PDU for UE %u is shorter than reported length (reported=%u, actual=%u)",
6754 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
6755 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
6758 if (offset > p_mac_lte_info->length) {
6759 /* There is a problem if the PDU is longer than reported */
6760 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6761 "%s PDU for UE %u is longer than reported length (reported=%u, actual=%u)",
6762 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
6763 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
6767 /* Can now store updated DRX info and show its info in the tree */
6768 if (global_mac_lte_show_drx) {
6769 if (!PINFO_FD_VISITED(pinfo)) {
6770 /* Store 'after' snapshot of UE state for this frame */
6771 set_drx_info(pinfo, p_mac_lte_info, false, pdu_instance);
6774 /* Show current DRX state in tree as 'after' */
6775 show_drx_info(pinfo, tree, tvb, p_mac_lte_info, false, pdu_instance);
6779 static void dissect_mch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *pdu_ti,
6780 uint32_t offset, mac_lte_info *p_mac_lte_info)
6782 uint8_t extension;
6783 uint16_t n;
6784 proto_item *truncated_ti;
6785 proto_item *padding_length_ti;
6786 proto_item *hidden_root_ti;
6788 /* Keep track of LCIDs and lengths as we dissect the header */
6789 uint16_t number_of_headers = 0;
6790 uint8_t lcids[MAX_HEADERS_IN_PDU];
6791 int32_t pdu_lengths[MAX_HEADERS_IN_PDU];
6793 proto_item *pdu_header_ti, *sched_info_ti = NULL;
6794 proto_tree *pdu_header_tree;
6796 bool have_seen_data_header = false;
6797 uint8_t number_of_padding_subheaders = 0;
6798 bool have_seen_non_padding_control = false;
6799 bool expecting_body_data = false;
6800 uint32_t is_truncated = false;
6802 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, "MCH: ");
6804 /* Add hidden item to filter on */
6805 hidden_root_ti = proto_tree_add_string_format(tree, hf_mac_lte_mch, tvb,
6806 offset, 0, "", "Hidden header");
6807 proto_item_set_hidden(hidden_root_ti);
6809 /* Add PDU block header subtree */
6810 pdu_header_ti = proto_tree_add_string_format(tree, hf_mac_lte_mch_header,
6811 tvb, offset, 0,
6813 "MAC PDU Header");
6814 pdu_header_tree = proto_item_add_subtree(pdu_header_ti, ett_mac_lte_mch_header);
6817 /************************************************************************/
6818 /* Dissect each sub-header. */
6819 do {
6820 uint8_t reserved, format2;
6821 uint64_t length = 0;
6822 proto_item *pdu_subheader_ti;
6823 proto_tree *pdu_subheader_tree;
6824 proto_item *lcid_ti;
6825 proto_item *ti;
6826 int offset_start_subheader = offset;
6827 uint8_t first_byte = tvb_get_uint8(tvb, offset);
6829 /* Add PDU block header subtree.
6830 Default with length of 1 byte. */
6831 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
6832 hf_mac_lte_mch_subheader,
6833 tvb, offset, 1,
6835 "Sub-header");
6836 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
6837 ett_mac_lte_mch_subheader);
6839 /* Check 1st reserved bit */
6840 reserved = (first_byte & 0x80) >> 7;
6841 ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_reserved,
6842 tvb, offset, 1, ENC_BIG_ENDIAN);
6843 if (reserved != 0) {
6844 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6845 "MCH header Reserved bits not zero");
6848 /* Format2 bit */
6849 format2 = (first_byte & 0x40) >> 6;
6850 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_format2,
6851 tvb, offset, 1, ENC_BIG_ENDIAN);
6853 /* Extended bit */
6854 extension = (first_byte & 0x20) >> 5;
6855 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_extended,
6856 tvb, offset, 1, ENC_BIG_ENDIAN);
6858 /* LCID */
6859 lcids[number_of_headers] = first_byte & 0x1f;
6860 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_lcid,
6861 tvb, offset, 1, ENC_BIG_ENDIAN);
6862 if (lcids[number_of_headers] == MCH_SCHEDULING_INFO_LCID) {
6863 sched_info_ti = lcid_ti;
6865 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6866 "(%s",
6867 val_to_str_const(lcids[number_of_headers],
6868 mch_lcid_vals, "(Unknown LCID)"));
6869 offset++;
6871 /* Remember if we've seen a data subheader */
6872 if (lcids[number_of_headers] <= 28) {
6873 have_seen_data_header = true;
6874 expecting_body_data = true;
6877 /* Show an expert item if a control subheader (except Padding) appears
6878 *after* a data PDU */
6879 if (have_seen_data_header &&
6880 (lcids[number_of_headers] > 28) && (lcids[number_of_headers] != PADDING_LCID)) {
6881 expert_add_info_format(pinfo, lcid_ti, &ei_mac_lte_control_subheader_after_data_subheader,
6882 "MCH Control subheaders should not appear after data subheaders");
6883 return;
6886 /* Should not see padding after non-padding control... */
6887 if ((lcids[number_of_headers] > 28) &&
6888 (lcids[number_of_headers] == PADDING_LCID) &&
6889 extension)
6891 number_of_padding_subheaders++;
6892 if (number_of_padding_subheaders > 2) {
6893 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_multiple);
6896 if (have_seen_non_padding_control) {
6897 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_before_control_subheader);
6901 /* Remember that we've seen non-padding control */
6902 if ((lcids[number_of_headers] > 28) &&
6903 (lcids[number_of_headers] != PADDING_LCID)) {
6904 have_seen_non_padding_control = true;
6909 /********************************************************************/
6910 /* Length field follows if not the last header or for a fixed-sized
6911 control element */
6912 if (!extension) {
6913 /* Last one... */
6914 pdu_lengths[number_of_headers] = -1;
6916 else {
6917 /* Not the last one */
6918 if (lcids[number_of_headers] != PADDING_LCID) {
6920 if (format2) {
6921 /* >= 32578 - use 16 bits */
6922 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
6923 tvb, offset*8, 16, &length, ENC_BIG_ENDIAN);
6924 if (length < 32768) {
6925 expert_add_info(pinfo, ti, &ei_mac_lte_mch_invalid_length);
6928 offset += 2;
6929 } else {
6930 bool format;
6932 /* F(ormat) bit tells us how long the length field is */
6933 proto_tree_add_item_ret_boolean(pdu_subheader_tree, hf_mac_lte_mch_format,
6934 tvb, offset, 1, ENC_BIG_ENDIAN, &format);
6936 /* Now read length field itself */
6937 if (format) {
6938 /* >= 128 - use 15 bits */
6939 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
6940 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
6942 offset += 2;
6944 else {
6945 /* Less than 128 - only 7 bits */
6946 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
6947 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
6948 offset++;
6951 pdu_lengths[number_of_headers] = (int32_t)length;
6953 else {
6954 pdu_lengths[number_of_headers] = 0;
6959 /* Close off description in info column */
6960 switch (pdu_lengths[number_of_headers]) {
6961 case 0:
6962 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
6963 break;
6964 case -1:
6965 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
6966 break;
6967 default:
6968 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
6969 pdu_lengths[number_of_headers]);
6970 break;
6973 /* Append summary to subheader root */
6974 proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
6975 val_to_str_const(lcids[number_of_headers],
6976 mch_lcid_vals, "Unknown"));
6978 switch (pdu_lengths[number_of_headers]) {
6979 case -1:
6980 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
6981 proto_item_append_text(pdu_header_ti, " (%s:remainder)",
6982 val_to_str_const(lcids[number_of_headers],
6983 mch_lcid_vals,
6984 "Unknown"));
6985 break;
6986 case 0:
6987 proto_item_append_text(pdu_subheader_ti, ")");
6988 proto_item_append_text(pdu_header_ti, " (%s)",
6989 val_to_str_const(lcids[number_of_headers],
6990 mch_lcid_vals,
6991 "Unknown"));
6992 break;
6993 default:
6994 proto_item_append_text(pdu_subheader_ti, ", length=%d)",
6995 pdu_lengths[number_of_headers]);
6996 proto_item_append_text(pdu_header_ti, " (%s:%d)",
6997 val_to_str_const(lcids[number_of_headers],
6998 mch_lcid_vals,
6999 "Unknown"),
7000 pdu_lengths[number_of_headers]);
7001 break;
7005 /* Flag unknown lcid values in expert info */
7006 if (try_val_to_str(lcids[number_of_headers],mch_lcid_vals) == NULL) {
7007 expert_add_info_format(pinfo, pdu_subheader_ti, &ei_mac_lte_lcid_unexpected,
7008 "MCH: Unexpected LCID received (%u)",
7009 lcids[number_of_headers]);
7012 /* Set length of this subheader */
7013 proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
7015 number_of_headers++;
7016 } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
7018 /* Check that we didn't reach the end of the subheader array... */
7019 if (number_of_headers >= MAX_HEADERS_IN_PDU) {
7020 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_too_many_subheaders, tvb, offset, 1,
7021 "Reached %u subheaders - frame obviously malformed",
7022 MAX_HEADERS_IN_PDU);
7023 return;
7027 /* Append summary to overall PDU header root */
7028 proto_item_append_text(pdu_header_ti, " (%u subheaders)",
7029 number_of_headers);
7031 /* And set its length to offset */
7032 proto_item_set_len(pdu_header_ti, offset);
7035 /************************************************************************/
7036 /* Dissect SDUs / control elements / padding. */
7037 /************************************************************************/
7039 /* Dissect control element bodies first */
7041 for (n=0; n < number_of_headers; n++) {
7042 /* Get out of loop once see any data SDU subheaders */
7043 if (lcids[n] <= 28) {
7044 break;
7047 /* Process what should be a valid control PDU type */
7048 switch (lcids[n]) {
7049 case MCH_SCHEDULING_INFO_LCID:
7051 uint32_t curr_offset = offset;
7052 int16_t i;
7053 uint32_t stop_mtch_val;
7054 proto_item *mch_sched_info_ti, *ti;
7055 proto_tree *mch_sched_info_tree;
7057 if (pdu_lengths[n] == -1) {
7058 /* Control Element size is the remaining PDU */
7059 pdu_lengths[n] = (int16_t)tvb_reported_length_remaining(tvb, curr_offset);
7061 if (pdu_lengths[n] & 0x01) {
7062 expert_add_info_format(pinfo, sched_info_ti, &ei_mac_lte_context_length,
7063 "MCH Scheduling Information MAC Control Element should have an even size");
7066 mch_sched_info_ti = proto_tree_add_string_format(tree,
7067 hf_mac_lte_control_mch_scheduling_info,
7068 tvb, curr_offset, pdu_lengths[n],
7070 "MCH Scheduling Information");
7071 mch_sched_info_tree = proto_item_add_subtree(mch_sched_info_ti, ett_mac_lte_mch_scheduling_info);
7073 for (i=0; i<(pdu_lengths[n]/2); i++) {
7074 proto_tree_add_item(mch_sched_info_tree, hf_mac_lte_control_mch_scheduling_info_lcid,
7075 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
7076 ti = proto_tree_add_item_ret_uint(mch_sched_info_tree, hf_mac_lte_control_mch_scheduling_info_stop_mtch,
7077 tvb, curr_offset, 2,
7078 ENC_BIG_ENDIAN, &stop_mtch_val);
7079 if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) {
7080 proto_item_append_text(ti, " (reserved)");
7082 else if (stop_mtch_val == 2047) {
7083 proto_item_append_text(ti, " (MTCH is not scheduled)");
7085 curr_offset += 2;
7088 offset += pdu_lengths[n];
7090 break;
7091 case PADDING_LCID:
7092 /* No payload (in this position) */
7093 break;
7095 default:
7096 break;
7101 /* There might not be any data, if only headers (plus control data) were logged */
7102 is_truncated = ((tvb_captured_length_remaining(tvb, offset) == 0) && expecting_body_data);
7103 truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_mch_header_only, tvb, 0, 0,
7104 is_truncated);
7105 if (is_truncated) {
7106 proto_item_set_generated(truncated_ti);
7107 expert_add_info(pinfo, truncated_ti, &ei_mac_lte_mch_header_only_truncated);
7108 return;
7110 else {
7111 proto_item_set_hidden(truncated_ti);
7115 /* Now process remaining bodies, which should all be data */
7116 for (; n < number_of_headers; n++) {
7118 proto_item *sdu_ti;
7119 uint16_t data_length;
7121 /* Break out if meet padding */
7122 if (lcids[n] == PADDING_LCID) {
7123 break;
7126 /* Work out length */
7127 data_length = (pdu_lengths[n] == -1) ?
7128 tvb_reported_length_remaining(tvb, offset) :
7129 pdu_lengths[n];
7131 if ((lcids[n] == 0) && global_mac_lte_attempt_mcch_decode) {
7132 /* Call RLC dissector */
7133 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
7134 RLC_UM_MODE, DIRECTION_DOWNLINK, 0,
7135 CHANNEL_TYPE_MCCH, 0, 5, 0, false, p_mac_lte_info->nbMode);
7136 } else if ((lcids[n] <= 28) && global_mac_lte_call_rlc_for_mtch) {
7137 /* Call RLC dissector */
7138 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
7139 RLC_UM_MODE, DIRECTION_DOWNLINK, 0,
7140 CHANNEL_TYPE_MTCH, 0, 5, 0, false, p_mac_lte_info->nbMode);
7141 } else {
7142 /* Dissect SDU as raw bytes */
7143 sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_mch_sdu, tvb, offset, pdu_lengths[n],
7144 NULL, "SDU (%s, length=%u bytes): ",
7145 val_to_str_const(lcids[n], mch_lcid_vals, "Unknown"),
7146 data_length);
7147 if (pdu_lengths[n] >= 30)
7149 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(pinfo->pool, tvb, offset, 30));
7150 proto_item_append_text(sdu_ti, "...");
7152 else
7154 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(pinfo->pool, tvb, offset, data_length));
7158 offset += data_length;
7161 /* Now padding, if present, extends to the end of the PDU */
7162 if (lcids[number_of_headers-1] == PADDING_LCID) {
7163 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7164 proto_tree_add_item(tree, hf_mac_lte_padding_data,
7165 tvb, offset, -1, ENC_NA);
7167 padding_length_ti = proto_tree_add_uint(tree, hf_mac_lte_padding_length,
7168 tvb, offset, 0,
7169 p_mac_lte_info->length - offset);
7170 proto_item_set_generated(padding_length_ti);
7172 /* Make sure the PDU isn't bigger than reported! */
7173 if (offset > p_mac_lte_info->length) {
7174 expert_add_info_format(pinfo, padding_length_ti, &ei_mac_lte_context_length,
7175 "MAC PDU is longer than reported length (reported=%u, actual=%u)",
7176 p_mac_lte_info->length, offset);
7179 else {
7180 /* There is no padding at the end of the frame */
7181 if (offset < p_mac_lte_info->length) {
7182 /* There is a problem if we haven't used all of the PDU */
7183 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
7184 "PDU is shorter than reported length (reported=%u, actual=%u)",
7185 p_mac_lte_info->length, offset);
7188 if (offset > p_mac_lte_info->length) {
7189 /* There is a problem if the PDU is longer than reported */
7190 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
7191 "PDU is longer than reported length (reported=%u, actual=%u)",
7192 p_mac_lte_info->length, offset);
7198 /* Dissect SL-BCH PDU */
7199 static void dissect_sl_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7200 proto_item *pdu_ti, int offset)
7202 proto_item *ti;
7204 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7205 "SL-BCH PDU (%u bytes)",
7206 tvb_reported_length_remaining(tvb, offset));
7208 /****************************************/
7209 /* Whole frame is SL-BCH data */
7211 /* Raw data */
7212 ti = proto_tree_add_item(tree, hf_mac_lte_slbch_pdu,
7213 tvb, offset, -1, ENC_NA);
7215 if (global_mac_lte_attempt_rrc_decode) {
7216 /* Attempt to decode payload using LTE RRC dissector */
7217 tvbuff_t *rrc_tvb = tvb_new_subset_remaining(tvb, offset);
7219 /* Hide raw view of bytes */
7220 proto_item_set_hidden(ti);
7222 call_with_catch_all(lte_rrc_sbcch_sl_bch_handle, rrc_tvb, pinfo, tree);
7227 /* Dissect SL-SCH PDU */
7228 static void dissect_slsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7229 proto_item *pdu_ti,
7230 int offset, mac_lte_info *p_mac_lte_info)
7232 /* Keep track of LCIDs and lengths as we dissect the header */
7233 uint16_t number_of_headers = 0, n;
7234 uint8_t lcids[MAX_HEADERS_IN_PDU], extension;
7235 int16_t pdu_lengths[MAX_HEADERS_IN_PDU];
7237 proto_item *pdu_header_ti, *pdu_subheader_ti, *ti, *truncated_ti, *padding_length_ti;
7238 proto_tree *pdu_header_tree, *pdu_subheader_tree;
7240 uint8_t number_of_padding_subheaders = 0;
7241 bool expecting_body_data = false;
7242 bool is_truncated;
7243 uint32_t reserved, version;
7245 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7246 "%s: (SFN=%-4u, SF=%u) UEId=%-3u ",
7247 "SL-SCH",
7248 p_mac_lte_info->sysframeNumber,
7249 p_mac_lte_info->subframeNumber,
7250 p_mac_lte_info->ueid);
7252 /* Add PDU block header subtree */
7253 pdu_header_ti = proto_tree_add_string_format(tree, hf_mac_lte_slsch_header,
7254 tvb, offset, 0,
7255 "", "MAC PDU Header");
7256 pdu_header_tree = proto_item_add_subtree(pdu_header_ti, ett_mac_lte_slsch_header);
7258 /* Dissect SL-SCH sub-header */
7259 proto_item_append_text(pdu_header_ti, " (SL-SCH)");
7260 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
7261 hf_mac_lte_slsch_subheader,
7262 tvb, offset, 6,
7264 "Sub-header (SL-SCH)");
7265 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
7266 ett_mac_lte_slsch_subheader);
7267 proto_tree_add_item_ret_uint(pdu_subheader_tree, hf_mac_lte_slsch_version,
7268 tvb, offset, 1, ENC_BIG_ENDIAN, &version);
7269 ti = proto_tree_add_item_ret_uint(pdu_subheader_tree, hf_mac_lte_slsch_reserved,
7270 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
7271 offset++;
7272 if (reserved) {
7273 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
7274 "SL-SCH header Reserved bits not zero");
7276 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_src_l2_id,
7277 tvb, offset, 3, ENC_BIG_ENDIAN);
7278 offset += 3;
7279 if (version == 3) {
7280 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_dst_l2_id2,
7281 tvb, offset, 3, ENC_BIG_ENDIAN);
7282 offset += 3;
7283 } else {
7284 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_dst_l2_id,
7285 tvb, offset, 2, ENC_BIG_ENDIAN);
7286 offset += 2;
7289 /* Dissect each sub-header */
7290 do {
7291 uint32_t first_byte;
7292 uint64_t length = 0;
7293 proto_item *lcid_ti;
7294 int offset_start_subheader = offset;
7296 /* Add PDU block header subtree.
7297 Default with length of 1 byte. */
7298 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
7299 hf_mac_lte_slsch_subheader,
7300 tvb, offset, 1,
7302 "Sub-header");
7303 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
7304 ett_mac_lte_slsch_subheader);
7306 /* Check 1st 2 reserved bits */
7307 ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_reserved2,
7308 tvb, offset, 1, ENC_BIG_ENDIAN);
7309 first_byte = tvb_get_uint8(tvb, offset);
7310 if ((first_byte & 0xc0) != 0) {
7311 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
7312 "SL-SCH header Reserved bits not zero");
7315 /* Extended bit */
7316 extension = (first_byte & 0x20) >> 5;
7317 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_extended,
7318 tvb, offset, 1, ENC_BIG_ENDIAN);
7320 /* LCID */
7321 lcids[number_of_headers] = first_byte & 0x1f;
7322 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_lcid,
7323 tvb, offset, 1, ENC_BIG_ENDIAN);
7324 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7325 "(%s",
7326 val_to_str_const(lcids[number_of_headers],
7327 slsch_lcid_vals, "(Unknown LCID)"));
7328 offset++;
7330 /* Remember if we've seen a data subheader */
7331 if (is_data_lcid(lcids[number_of_headers], p_mac_lte_info->direction)) {
7332 expecting_body_data = true;
7335 /* Should not see padding after non-padding control... */
7336 if ((lcids[number_of_headers] == PADDING_LCID) &&
7337 extension)
7339 number_of_padding_subheaders++;
7340 if (number_of_padding_subheaders > 2) {
7341 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_multiple);
7345 /* Also flag if we have final padding but also padding subheaders
7346 at the start! */
7347 if (!extension && (lcids[number_of_headers] == PADDING_LCID) &&
7348 (number_of_padding_subheaders > 0)) {
7349 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_start_and_end);
7352 /* Length field follows if not the last header or for a fixed-sized
7353 control element */
7354 if (!extension) {
7355 /* Last one... */
7356 pdu_lengths[number_of_headers] = -1;
7357 } else {
7358 /* Not the last one */
7359 if (lcids[number_of_headers] != PADDING_LCID) {
7360 bool format;
7362 /* F(ormat) bit tells us how long the length field is */
7363 proto_tree_add_item_ret_boolean(pdu_subheader_tree, hf_mac_lte_slsch_format,
7364 tvb, offset, 1, ENC_BIG_ENDIAN, &format);
7366 /* Now read length field itself */
7367 if (format) {
7368 /* >= 128 - use 15 bits */
7369 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_slsch_length,
7370 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
7371 offset += 2;
7372 } else {
7373 /* Less than 128 - only 7 bits */
7374 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_slsch_length,
7375 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
7376 offset++;
7378 pdu_lengths[number_of_headers] = (int16_t)length;
7379 } else {
7380 pdu_lengths[number_of_headers] = 0;
7384 /* Close off description in info column */
7385 switch (pdu_lengths[number_of_headers]) {
7386 case 0:
7387 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
7388 break;
7389 case -1:
7390 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
7391 break;
7392 default:
7393 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
7394 pdu_lengths[number_of_headers]);
7395 break;
7398 /* Append summary to subheader root */
7399 proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
7400 val_to_str_const(lcids[number_of_headers],
7401 slsch_lcid_vals, "Unknown"));
7403 switch (pdu_lengths[number_of_headers]) {
7404 case -1:
7405 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
7406 proto_item_append_text(pdu_header_ti, " (%s:remainder)",
7407 val_to_str_const(lcids[number_of_headers],
7408 slsch_lcid_vals, "Unknown"));
7409 break;
7410 case 0:
7411 proto_item_append_text(pdu_subheader_ti, ")");
7412 proto_item_append_text(pdu_header_ti, " (%s)",
7413 val_to_str_const(lcids[number_of_headers],
7414 slsch_lcid_vals, "Unknown"));
7415 break;
7416 default:
7417 proto_item_append_text(pdu_subheader_ti, ", length=%d)",
7418 pdu_lengths[number_of_headers]);
7419 proto_item_append_text(pdu_header_ti, " (%s:%d)",
7420 val_to_str_const(lcids[number_of_headers],
7421 slsch_lcid_vals, "Unknown"),
7422 pdu_lengths[number_of_headers]);
7423 break;
7426 /* Flag unknown lcid values in expert info */
7427 if (try_val_to_str(lcids[number_of_headers], slsch_lcid_vals) == NULL) {
7428 expert_add_info_format(pinfo, pdu_subheader_ti, &ei_mac_lte_lcid_unexpected,
7429 "SL-SCH: Unexpected LCID received (%u)",
7430 lcids[number_of_headers]);
7433 /* Set length of this subheader */
7434 proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
7436 number_of_headers++;
7437 } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
7439 /* Check that we didn't reach the end of the subheader array... */
7440 if (number_of_headers >= MAX_HEADERS_IN_PDU) {
7441 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_too_many_subheaders, tvb, offset, 1,
7442 "Reached %u subheaders - frame obviously malformed",
7443 MAX_HEADERS_IN_PDU);
7444 return;
7447 /* Append summary to overall PDU header root */
7448 proto_item_append_text(pdu_header_ti, " [%u subheaders]",
7449 number_of_headers);
7451 /* And set its length to offset */
7452 proto_item_set_len(pdu_header_ti, offset);
7454 /* Dissect control element bodies first */
7456 for (n = 0; n < number_of_headers; n++) {
7457 /* Get out of loop once see any data SDU subheaders */
7458 if (is_data_lcid(lcids[n], p_mac_lte_info->direction)) {
7459 break;
7462 switch (lcids[n]) {
7463 case PADDING_LCID:
7464 /* No payload (in this position) */
7465 break;
7466 default:
7467 break;
7471 /* There might not be any data, if only headers (plus control data) were logged */
7472 is_truncated = ((tvb_captured_length_remaining(tvb, offset) == 0) && expecting_body_data);
7473 truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_slsch_header_only, tvb, 0, 0,
7474 is_truncated);
7475 if (is_truncated) {
7476 proto_item_set_generated(truncated_ti);
7477 expert_add_info(pinfo, truncated_ti, &ei_mac_lte_slsch_header_only_truncated);
7478 return;
7479 } else {
7480 proto_item_set_hidden(truncated_ti);
7484 /* Now process remaining bodies, which should all be data */
7485 for (; n < number_of_headers; n++) {
7486 proto_item *sdu_ti;
7487 uint16_t data_length;
7489 /* Break out if meet padding */
7490 if (lcids[n] == PADDING_LCID) {
7491 break;
7494 /* Work out length */
7495 data_length = (pdu_lengths[n] == -1) ?
7496 tvb_reported_length_remaining(tvb, offset) :
7497 pdu_lengths[n];
7499 /* Dissect SDU as raw bytes */
7500 sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_slsch_sdu, tvb, offset, pdu_lengths[n],
7501 NULL, "SDU (%s, length=%u bytes): ",
7502 val_to_str_const(lcids[n],
7503 slsch_lcid_vals, "Unknown"),
7504 data_length);
7506 /* Show bytes too, if won't be hidden (slow). There must be a nicer way of doing this! */
7507 if (pdu_lengths[n] >= 30) {
7508 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(pinfo->pool, tvb, offset, 30));
7509 proto_item_append_text(sdu_ti, "...");
7510 } else {
7511 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(pinfo->pool, tvb, offset, data_length));
7514 offset += data_length;
7517 /* Now padding, if present, extends to the end of the PDU */
7518 if (lcids[number_of_headers-1] == PADDING_LCID) {
7519 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7520 proto_tree_add_item(tree, hf_mac_lte_padding_data,
7521 tvb, offset, -1, ENC_NA);
7523 padding_length_ti = proto_tree_add_uint(tree, hf_mac_lte_padding_length,
7524 tvb, offset, 0,
7525 p_mac_lte_info->length - offset);
7526 proto_item_set_generated(padding_length_ti);
7528 /* Make sure the PDU isn't bigger than reported! */
7529 if (offset > p_mac_lte_info->length) {
7530 expert_add_info_format(pinfo, padding_length_ti, &ei_mac_lte_context_length,
7531 "SL-SCH MAC PDU is longer than reported length (reported=%u, actual=%u)",
7532 p_mac_lte_info->length, offset);
7534 } else {
7535 /* There is no padding at the end of the frame */
7536 if (offset < p_mac_lte_info->length) {
7537 /* There is a problem if we haven't used all of the PDU */
7538 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
7539 "SL-SCH PDU for UE %u is shorter than reported length (reported=%u, actual=%d)",
7540 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
7543 if (offset > p_mac_lte_info->length) {
7544 /* There is a problem if the PDU is longer than reported */
7545 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
7546 "SL-SCH PDU for UE %u is longer than reported length (reported=%u, actual=%u)",
7547 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
7553 /*****************************/
7554 /* Main dissection function. */
7555 /* 'data' will be cast to an int, where it can then be used to differentiate
7556 multiple MAC PDUs logged in the same frame (e.g. in the LTE eNB LI API definition from
7557 the Small Cell Forum)
7559 static int dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
7561 proto_tree *mac_lte_tree;
7562 proto_item *pdu_ti;
7563 proto_tree *context_tree;
7564 proto_item *context_ti;
7565 proto_item *retx_ti = NULL;
7566 proto_item *ti;
7567 proto_item *hidden_root_ti;
7568 int offset = 0;
7569 struct mac_lte_info *p_mac_lte_info;
7570 int n;
7571 unsigned pdu_instance = GPOINTER_TO_UINT(data);
7573 /* Allocate and zero tap struct */
7574 mac_3gpp_tap_info *tap_info = wmem_new0(wmem_file_scope(), mac_3gpp_tap_info);
7575 tap_info->rat = MAC_RAT_LTE;
7577 /* Set protocol name */
7578 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
7580 /* Create protocol tree, using tvb_reported_length() as giving -1 will trigger an exception in case of oob event */
7581 pdu_ti = proto_tree_add_item(tree, proto_mac_lte, tvb, offset, tvb_reported_length(tvb), ENC_NA);
7582 proto_item_append_text(pdu_ti, " ");
7583 mac_lte_tree = proto_item_add_subtree(pdu_ti, ett_mac_lte);
7585 /* Look for packet info! */
7586 p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
7588 /* Can't dissect anything without it... */
7589 if (p_mac_lte_info == NULL) {
7590 proto_tree_add_expert(mac_lte_tree, pinfo, &ei_mac_lte_no_per_frame_data, tvb, offset, -1);
7591 return 0;
7594 /* Clear info column */
7595 col_clear(pinfo->cinfo, COL_INFO);
7598 /*****************************************/
7599 /* Show context information */
7601 /* Create context root */
7602 context_ti = proto_tree_add_string_format(mac_lte_tree, hf_mac_lte_context,
7603 tvb, offset, 0, "", "Context");
7604 context_tree = proto_item_add_subtree(context_ti, ett_mac_lte_context);
7605 proto_item_set_generated(context_ti);
7607 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_radio_type,
7608 tvb, 0, 0, p_mac_lte_info->radioType);
7609 proto_item_set_generated(ti);
7611 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_direction,
7612 tvb, 0, 0, p_mac_lte_info->direction);
7613 proto_item_set_generated(ti);
7615 if (p_mac_lte_info->ueid != 0) {
7616 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_ueid,
7617 tvb, 0, 0, p_mac_lte_info->ueid);
7618 proto_item_set_generated(ti);
7621 if(p_mac_lte_info->sfnSfInfoPresent) {
7622 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_sysframe_number,
7623 tvb, 0, 0, p_mac_lte_info->sysframeNumber);
7624 proto_item_set_generated(ti);
7625 if (p_mac_lte_info->sysframeNumber > 1023) {
7626 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_sysframe_number,
7627 "Sysframe number (%u) out of range - valid range is 0-1023",
7628 p_mac_lte_info->sysframeNumber);
7631 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_subframe_number,
7632 tvb, 0, 0, p_mac_lte_info->subframeNumber);
7633 proto_item_set_generated(ti);
7634 if (p_mac_lte_info->subframeNumber > 9) {
7635 /* N.B. if we set it to valid value, it won't trigger when we rescan
7636 (at least with DCT2000 files where the context struct isn't re-read). */
7637 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_sysframe_number,
7638 "Subframe number (%u) out of range - valid range is 0-9",
7639 p_mac_lte_info->subframeNumber);
7642 if (p_mac_lte_info->subframeNumberOfGrantPresent) {
7643 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_grant_subframe_number,
7644 tvb, 0, 0, p_mac_lte_info->subframeNumberOfGrant);
7645 proto_item_set_generated(ti);
7649 /* There are several out-of-band MAC events that may be indicated in the context info. */
7650 /* Handle them here */
7651 if (p_mac_lte_info->length == 0) {
7652 proto_item *preamble_ti;
7653 proto_tree *preamble_tree;
7654 const char *rapid_description;
7656 switch (p_mac_lte_info->oob_event) {
7657 case ltemac_send_preamble:
7658 preamble_ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_send_preamble,
7659 tvb, 0, 0, ENC_ASCII);
7660 preamble_tree = proto_item_add_subtree(preamble_ti, ett_mac_lte_oob);
7661 proto_item_set_generated(ti);
7663 ti = proto_tree_add_uint(preamble_tree, hf_mac_lte_context_rapid,
7664 tvb, 0, 0, p_mac_lte_info->rapid);
7665 proto_item_set_generated(ti);
7667 ti = proto_tree_add_uint(preamble_tree, hf_mac_lte_context_rach_attempt_number,
7668 tvb, 0, 0, p_mac_lte_info->rach_attempt_number);
7669 proto_item_set_generated(ti);
7671 rapid_description = get_mac_lte_rapid_description(p_mac_lte_info->rapid);
7673 /* Info column */
7674 write_pdu_label_and_info(pdu_ti, preamble_ti, pinfo,
7675 "RACH Preamble chosen for UE %u (RAPID=%u%s, attempt=%u)",
7676 p_mac_lte_info->ueid, p_mac_lte_info->rapid,
7677 rapid_description,
7678 p_mac_lte_info->rach_attempt_number);
7680 /* Add expert info (a note, unless attempt > 1) */
7681 expert_add_info_format(pinfo, ti,
7682 (p_mac_lte_info->rach_attempt_number > 1) ? &ei_mac_lte_rach_preamble_sent_warn : &ei_mac_lte_rach_preamble_sent_note,
7683 "RACH Preamble sent for UE %u (RAPID=%u%s, attempt=%u)",
7684 p_mac_lte_info->ueid, p_mac_lte_info->rapid,
7685 rapid_description,
7686 p_mac_lte_info->rach_attempt_number);
7687 break;
7688 case ltemac_send_sr:
7689 /* Count of SRs */
7690 ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_number_of_srs,
7691 tvb, 0, 0, p_mac_lte_info->number_of_srs);
7692 proto_item_set_generated(ti);
7695 for (n=0; n < p_mac_lte_info->number_of_srs; n++) {
7696 proto_item *sr_ti;
7697 proto_tree *sr_tree;
7699 /* SR event is subtree */
7700 sr_ti = proto_tree_add_expert_format(mac_lte_tree, pinfo, &ei_mac_lte_oob_send_sr,
7701 tvb, 0, 0,
7702 "Scheduling Request sent for UE %u (RNTI %u)", p_mac_lte_info->oob_ueid[n], p_mac_lte_info->oob_rnti[n]);
7703 sr_tree = proto_item_add_subtree(sr_ti, ett_mac_lte_oob);
7704 proto_item_set_generated(sr_ti);
7706 /* RNTI */
7707 ti = proto_tree_add_uint(sr_tree, hf_mac_lte_context_rnti,
7708 tvb, 0, 0, p_mac_lte_info->oob_rnti[n]);
7709 proto_item_set_generated(ti);
7711 /* UEID */
7712 ti = proto_tree_add_uint(sr_tree, hf_mac_lte_context_ueid,
7713 tvb, 0, 0, p_mac_lte_info->oob_ueid[n]);
7714 proto_item_set_generated(ti);
7716 /* Add summary to root. */
7717 proto_item_append_text(sr_ti, " (UE=%u C-RNTI=%u)",
7718 p_mac_lte_info->oob_ueid[n],
7719 p_mac_lte_info->oob_rnti[n]);
7721 /* Info column */
7723 if(n == 0) {
7724 if (p_mac_lte_info->sfnSfInfoPresent) {
7725 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7726 "Scheduling Requests (%u) sent (SFN=%-4u, SF=%u): (UE=%u C-RNTI=%u)",
7727 p_mac_lte_info->number_of_srs,
7728 p_mac_lte_info->sysframeNumber,
7729 p_mac_lte_info->subframeNumber,
7730 p_mac_lte_info->oob_ueid[n],
7731 p_mac_lte_info->oob_rnti[n]
7734 else {
7735 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7736 "Scheduling Requests (%u) sent: (UE=%u C-RNTI=%u)",
7737 p_mac_lte_info->number_of_srs,
7738 p_mac_lte_info->oob_ueid[n],
7739 p_mac_lte_info->oob_rnti[n]);
7742 else {
7743 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7744 " (UE=%u C-RNTI=%u)",
7745 p_mac_lte_info->oob_ueid[n],
7746 p_mac_lte_info->oob_rnti[n]);
7749 /* Update SR status for this UE */
7750 if (global_mac_lte_track_sr) {
7751 TrackSRInfo(SR_Request, pinfo, mac_lte_tree, tvb, p_mac_lte_info, n, sr_ti);
7754 break;
7755 case ltemac_sr_failure:
7756 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti,
7757 tvb, 0, 0, p_mac_lte_info->rnti);
7758 proto_item_set_generated(ti);
7760 proto_tree_add_expert_format(mac_lte_tree, pinfo, &ei_mac_lte_oob_sr_failure,
7761 tvb, 0, 0, "Scheduling Request failed for UE %u (RNTI %u)",
7762 p_mac_lte_info->ueid, p_mac_lte_info->rnti);
7763 proto_item_set_generated(ti);
7765 /* Info column */
7766 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7767 "Scheduling Request FAILED for UE %u (C-RNTI=%u)",
7768 p_mac_lte_info->ueid,
7769 p_mac_lte_info->rnti);
7771 /* Update SR status */
7772 if (global_mac_lte_track_sr) {
7773 TrackSRInfo(SR_Failure, pinfo, mac_lte_tree, tvb, p_mac_lte_info, 0, ti);
7776 break;
7779 /* Our work here is done */
7780 return -1;
7783 /* Show remaining meta information */
7784 if (p_mac_lte_info->rntiType != NO_RNTI) {
7785 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti,
7786 tvb, 0, 0, p_mac_lte_info->rnti);
7787 proto_item_set_generated(ti);
7788 proto_item_append_text(context_ti, " (RNTI=%u)", p_mac_lte_info->rnti);
7792 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti_type,
7793 tvb, 0, 0, p_mac_lte_info->rntiType);
7794 proto_item_set_generated(ti);
7796 /* Check that RNTI value is consistent with given RNTI type */
7797 switch (p_mac_lte_info->rntiType) {
7798 case M_RNTI:
7799 if (p_mac_lte_info->rnti != 0xFFFD) {
7800 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7801 "M-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
7802 p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFD);
7803 return 0;
7805 break;
7806 case P_RNTI:
7807 if (p_mac_lte_info->rnti != 0xFFFE) {
7808 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7809 "P-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
7810 p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFE);
7811 return 0;
7813 break;
7814 case SI_RNTI:
7815 if (p_mac_lte_info->rnti != 0xFFFF) {
7816 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7817 "SI-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
7818 p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFE);
7819 return 0;
7821 break;
7822 case RA_RNTI:
7823 if ((p_mac_lte_info->rnti < 0x0001) || (p_mac_lte_info->rnti > 0x0960)) {
7824 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7825 "RA_RNTI indicated, but given value %u (0x%x) is out of range",
7826 p_mac_lte_info->rnti, p_mac_lte_info->rnti);
7827 return 0;
7829 break;
7830 case C_RNTI:
7831 case SPS_RNTI:
7832 case SL_RNTI:
7833 case G_RNTI:
7834 if ((p_mac_lte_info->rnti < 0x0001) || (p_mac_lte_info->rnti > 0xFFF3)) {
7835 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7836 "%s indicated, but given value %u (0x%x) is out of range",
7837 val_to_str_const(p_mac_lte_info->rntiType, rnti_type_vals, "Unknown"),
7838 p_mac_lte_info->rnti, p_mac_lte_info->rnti);
7839 return 0;
7841 break;
7843 default:
7844 break;
7847 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_predefined_frame,
7848 tvb, 0, 0, p_mac_lte_info->isPredefinedData);
7849 if (p_mac_lte_info->isPredefinedData) {
7850 proto_item_set_generated(ti);
7852 else {
7853 proto_item_set_hidden(ti);
7856 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_length,
7857 tvb, 0, 0, p_mac_lte_info->length);
7858 proto_item_set_generated(ti);
7859 /* Infer uplink grant size */
7860 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
7861 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_ul_grant_size,
7862 tvb, 0, 0, p_mac_lte_info->length);
7863 proto_item_set_generated(ti);
7866 /* Retx count goes in top-level tree to make it more visible */
7867 if (p_mac_lte_info->reTxCount) {
7868 proto_item *retx_reason_ti;
7869 retx_ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_count,
7870 tvb, 0, 0, p_mac_lte_info->reTxCount);
7871 proto_item_set_generated(retx_ti);
7873 if (p_mac_lte_info->reTxCount >= global_mac_lte_retx_counter_trigger) {
7874 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
7875 expert_add_info_format(pinfo, retx_ti, &ei_mac_lte_ul_mac_frame_retx,
7876 "UE %u: UL MAC frame ReTX no. %u",
7877 p_mac_lte_info->ueid, p_mac_lte_info->reTxCount);
7879 else {
7880 expert_add_info_format(pinfo, retx_ti, &ei_mac_lte_ul_mac_frame_retx,
7881 "UE %u: DL MAC frame ReTX no. %u",
7882 p_mac_lte_info->ueid, p_mac_lte_info->reTxCount);
7886 retx_reason_ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_reason,
7887 tvb, 0, 0, p_mac_lte_info->isPHICHNACK);
7888 proto_item_set_generated(retx_reason_ti);
7891 if (p_mac_lte_info->crcStatusValid) {
7892 /* Set status */
7893 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_crc_status,
7894 tvb, 0, 0, p_mac_lte_info->crcStatus);
7895 proto_item_set_generated(ti);
7897 /* Report non-success */
7898 if (p_mac_lte_info->crcStatus != crc_success) {
7899 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_crc_status,
7900 "%s Frame has CRC error problem (%s)",
7901 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL",
7902 val_to_str_const(p_mac_lte_info->crcStatus,
7903 crc_status_vals,
7904 "Unknown"));
7905 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7906 "%s: <CRC %s> UEId=%u %s=%u ",
7907 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL",
7908 val_to_str_const(p_mac_lte_info->crcStatus,
7909 crc_status_vals,
7910 "Unknown"),
7911 p_mac_lte_info->ueid,
7912 val_to_str_const(p_mac_lte_info->rntiType, rnti_type_vals,
7913 "Unknown RNTI type"),
7914 p_mac_lte_info->rnti);
7918 /* Carrier Id */
7919 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_carrier_id,
7920 tvb, 0, 0, p_mac_lte_info->carrierId);
7921 proto_item_set_generated(ti);
7923 /* May also have extra Physical layer attributes set for this frame */
7924 show_extra_phy_parameters(pinfo, tvb, mac_lte_tree, p_mac_lte_info);
7926 /* Set context-info parts of tap struct */
7927 tap_info->rnti = p_mac_lte_info->rnti;
7928 tap_info->ueid = p_mac_lte_info->ueid;
7929 tap_info->rntiType = p_mac_lte_info->rntiType;
7930 tap_info->isPredefinedData = p_mac_lte_info->isPredefinedData;
7931 tap_info->isPHYRetx = (p_mac_lte_info->reTxCount >= 1);
7932 tap_info->crcStatusValid = p_mac_lte_info->crcStatusValid;
7933 tap_info->crcStatus = p_mac_lte_info->crcStatus;
7934 tap_info->direction = p_mac_lte_info->direction;
7936 tap_info->mac_time = pinfo->abs_ts;
7938 /* Add hidden item to filter on */
7939 if ((p_mac_lte_info->rntiType == C_RNTI) ||
7940 (p_mac_lte_info->rntiType == SPS_RNTI) ||
7941 (p_mac_lte_info->rntiType == SC_RNTI) ||
7942 (p_mac_lte_info->rntiType == G_RNTI)) {
7943 hidden_root_ti = proto_tree_add_string_format(tree,
7944 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
7945 hf_mac_lte_ulsch :
7946 hf_mac_lte_dlsch,
7947 tvb, offset, 0,
7949 "Hidden header");
7950 proto_item_set_hidden(hidden_root_ti);
7951 } else if (p_mac_lte_info->rntiType == SL_RNTI) {
7952 hidden_root_ti = proto_tree_add_string_format(tree,
7953 hf_mac_lte_slsch,
7954 tvb, offset, 0,
7956 "Hidden header");
7957 proto_item_set_hidden(hidden_root_ti);
7960 /* Also set total number of bytes (won't be used for UL/DL-SCH) */
7961 tap_info->single_number_of_bytes = tvb_reported_length_remaining(tvb, offset);
7963 /* If we know its predefined data, don't try to decode any further */
7964 if (p_mac_lte_info->isPredefinedData) {
7965 proto_tree_add_item(mac_lte_tree, hf_mac_lte_predefined_pdu, tvb, offset, -1, ENC_NA);
7966 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7967 "Predefined data (%u bytes%s)",
7968 p_mac_lte_info->length,
7969 (p_mac_lte_info->length > tvb_reported_length_remaining(tvb, offset) ?
7970 " - truncated" :
7971 ""));
7973 /* Queue tap info */
7974 if (!pinfo->flags.in_error_pkt) {
7975 tap_queue_packet(mac_lte_tap, pinfo, tap_info);
7978 return -1;
7981 /* IF CRC status failed, just do decode as raw bytes */
7982 if (!global_mac_lte_dissect_crc_failures &&
7983 (p_mac_lte_info->crcStatusValid &&
7984 (p_mac_lte_info->crcStatus != crc_success))) {
7986 proto_tree_add_item(mac_lte_tree, hf_mac_lte_raw_pdu, tvb, offset, -1, ENC_NA);
7987 write_pdu_label_and_info(pdu_ti, NULL, pinfo, "Raw data (%u bytes)", tvb_reported_length_remaining(tvb, offset));
7989 /* For uplink grants, update SR status. N.B. only newTx grant should stop SR */
7990 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) && (p_mac_lte_info->reTxCount == 0) &&
7991 global_mac_lte_track_sr) {
7993 TrackSRInfo(SR_Grant, pinfo, tree, tvb, p_mac_lte_info, 0, NULL);
7994 if (global_mac_lte_show_drx) {
7995 if (!PINFO_FD_VISITED(pinfo)) {
7996 /* Update UE state to this subframe (but before this event is processed) */
7997 update_drx_info(pinfo, p_mac_lte_info);
7999 /* Store 'before' snapshot of UE state for this frame */
8000 set_drx_info(pinfo, p_mac_lte_info, true, pdu_instance);
8002 /* Show current DRX state in tree as 'before' */
8003 show_drx_info(pinfo, tree, tvb, p_mac_lte_info, true, pdu_instance);
8007 /* Queue tap info.
8008 TODO: unfortunately DL retx detection won't get done if we return here... */
8009 if (!pinfo->flags.in_error_pkt) {
8010 tap_queue_packet(mac_lte_tap, pinfo, tap_info);
8013 return -1;
8016 /* Reset this counter */
8017 s_number_of_rlc_pdus_shown = 0;
8019 /* Dissect the MAC PDU itself. Format depends upon RNTI type. */
8020 switch (p_mac_lte_info->rntiType) {
8022 case P_RNTI:
8023 /* PCH PDU */
8024 dissect_pch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, tap_info);
8025 break;
8027 case RA_RNTI:
8028 /* RAR PDU */
8029 dissect_rar(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, tap_info);
8030 break;
8032 case C_RNTI:
8033 case SPS_RNTI:
8034 case SC_RNTI:
8035 case G_RNTI:
8036 /* Can be UL-SCH or DL-SCH */
8037 dissect_ulsch_or_dlsch(tvb, pinfo, mac_lte_tree, pdu_ti, offset,
8038 p_mac_lte_info, tap_info, retx_ti,
8039 context_tree, pdu_instance);
8040 break;
8042 case SI_RNTI:
8043 /* BCH over DL-SCH */
8044 dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
8045 break;
8047 case M_RNTI:
8048 /* MCH PDU */
8049 dissect_mch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
8050 break;
8052 case SL_BCH_RNTI:
8053 /* SL BCH PDU */
8054 dissect_sl_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset);
8055 break;
8057 case SL_RNTI:
8058 /* SL-SCH PDU */
8059 dissect_slsch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
8060 break;
8062 case NO_RNTI:
8063 /* Must be BCH over BCH... */
8064 dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
8065 break;
8068 default:
8069 break;
8072 /* Queue tap info */
8073 tap_queue_packet(mac_lte_tap, pinfo, tap_info);
8075 return -1;
8081 /* Initializes the hash tables each time a new
8082 * file is loaded or re-loaded in wireshark */
8083 static void mac_lte_init_protocol(void)
8085 /* Reset structs */
8086 memset(&UL_tti_info, 0, sizeof(UL_tti_info));
8087 UL_tti_info.subframe = 0xff; /* Invalid value */
8088 memset(&DL_tti_info, 0, sizeof(DL_tti_info));
8089 DL_tti_info.subframe = 0xff; /* Invalid value */
8091 mac_lte_msg3_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8092 mac_lte_cr_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8093 mac_lte_msg3_cr_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8094 mac_lte_dl_harq_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8095 mac_lte_dl_harq_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8096 mac_lte_ul_harq_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8097 mac_lte_ul_harq_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8098 mac_lte_ue_sr_state = g_hash_table_new(g_direct_hash, g_direct_equal);
8099 mac_lte_sr_request_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8100 mac_lte_tti_info_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8101 mac_lte_ue_channels_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
8102 mac_lte_ue_parameters = g_hash_table_new(g_direct_hash, g_direct_equal);
8103 mac_lte_drx_frame_result = g_hash_table_new(mac_lte_framenum_instance_hash_func, mac_lte_framenum_instance_hash_equal);
8105 /* Forget this setting */
8106 s_rapid_ranges_configured = false;
8109 static void mac_lte_cleanup_protocol(void)
8111 g_hash_table_destroy(mac_lte_msg3_hash);
8112 g_hash_table_destroy(mac_lte_cr_result_hash);
8113 g_hash_table_destroy(mac_lte_msg3_cr_hash);
8114 g_hash_table_destroy(mac_lte_dl_harq_hash);
8115 g_hash_table_destroy(mac_lte_dl_harq_result_hash);
8116 g_hash_table_destroy(mac_lte_ul_harq_hash);
8117 g_hash_table_destroy(mac_lte_ul_harq_result_hash);
8118 g_hash_table_destroy(mac_lte_ue_sr_state);
8119 g_hash_table_destroy(mac_lte_sr_request_hash);
8120 g_hash_table_destroy(mac_lte_tti_info_result_hash);
8121 g_hash_table_destroy(mac_lte_ue_channels_hash);
8122 g_hash_table_destroy(mac_lte_ue_parameters);
8123 g_hash_table_destroy(mac_lte_drx_frame_result);
8126 /* Callback used as part of configuring a channel mapping using UAT */
8127 static void* lcid_drb_mapping_copy_cb(void* dest, const void* orig, size_t len _U_)
8129 const lcid_drb_mapping_t *o = (const lcid_drb_mapping_t *)orig;
8130 lcid_drb_mapping_t *d = (lcid_drb_mapping_t *)dest;
8132 /* Copy all items over */
8133 d->lcid = o->lcid;
8134 d->drbid = o->drbid;
8135 d->channel_type = o->channel_type;
8137 return d;
8141 /*************************************************************************/
8142 /* These functions get called from outside of this module, i.e. from RRC */
8144 /* Set LCID -> RLC channel mappings from signalling protocol (i.e. RRC or similar). */
8145 void set_mac_lte_channel_mapping(drb_mapping_t *drb_mapping)
8147 ue_dynamic_drb_mappings_t *ue_mappings;
8148 uint8_t lcid = 0;
8150 /* Check lcid range */
8151 if (drb_mapping->lcid_present) {
8152 lcid = drb_mapping->lcid;
8154 /* Ignore if LCID is out of range */
8155 if ((lcid < 3) || (lcid > 10 && lcid < 32) || (lcid > 38)) {
8156 return;
8160 /* Look for existing UE entry */
8161 ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash,
8162 GUINT_TO_POINTER((unsigned)drb_mapping->ueid));
8163 if (!ue_mappings) {
8164 /* If not found, create & add to table */
8165 ue_mappings = wmem_new0(wmem_file_scope(), ue_dynamic_drb_mappings_t);
8166 g_hash_table_insert(mac_lte_ue_channels_hash,
8167 GUINT_TO_POINTER((unsigned)drb_mapping->ueid),
8168 ue_mappings);
8171 /* If lcid wasn't supplied, need to try to look up from drbid */
8172 if ((lcid == 0) && (drb_mapping->drbid < 32)) {
8173 lcid = ue_mappings->drb_to_lcid_mappings[drb_mapping->drbid];
8175 if (lcid == 0) {
8176 /* Still no lcid - give up */
8177 return;
8180 /* Set array entry */
8181 ue_mappings->mapping[lcid].valid = true;
8182 ue_mappings->mapping[lcid].drbid = drb_mapping->drbid;
8183 ue_mappings->drb_to_lcid_mappings[drb_mapping->drbid] = lcid;
8184 if (drb_mapping->ul_priority_present) {
8185 ue_mappings->mapping[lcid].ul_priority = drb_mapping->ul_priority;
8188 /* Fill in available RLC info */
8189 if (drb_mapping->rlcMode_present) {
8190 switch (drb_mapping->rlcMode) {
8191 case RLC_AM_MODE:
8192 if (drb_mapping->rlc_ul_ext_am_sn == true) {
8193 if (drb_mapping->rlc_dl_ext_am_sn == true) {
8194 if (drb_mapping->rlc_ul_ext_li_field == true) {
8195 if (drb_mapping->rlc_dl_ext_li_field == true) {
8196 ue_mappings->mapping[lcid].channel_type = rlcAM16extLiField;
8197 } else {
8198 ue_mappings->mapping[lcid].channel_type = rlcAM16ulExtLiField;
8200 } else {
8201 if (drb_mapping->rlc_dl_ext_li_field == true) {
8202 ue_mappings->mapping[lcid].channel_type = rlcAM16dlExtLiField;
8203 } else {
8204 ue_mappings->mapping[lcid].channel_type = rlcAM16;
8207 } else {
8208 if (drb_mapping->rlc_ul_ext_li_field == true) {
8209 if (drb_mapping->rlc_dl_ext_li_field == true) {
8210 ue_mappings->mapping[lcid].channel_type = rlcAMul16extLiField;
8211 } else {
8212 ue_mappings->mapping[lcid].channel_type = rlcAMul16ulExtLiField;
8214 } else {
8215 if (drb_mapping->rlc_dl_ext_li_field == true) {
8216 ue_mappings->mapping[lcid].channel_type = rlcAMul16dlExtLiField;
8217 } else {
8218 ue_mappings->mapping[lcid].channel_type = rlcAMul16;
8222 } else if (drb_mapping->rlc_dl_ext_am_sn == true) {
8223 if (drb_mapping->rlc_ul_ext_li_field == true) {
8224 if (drb_mapping->rlc_dl_ext_li_field == true) {
8225 ue_mappings->mapping[lcid].channel_type = rlcAMdl16extLiField;
8226 } else {
8227 ue_mappings->mapping[lcid].channel_type = rlcAMdl16ulExtLiField;
8229 } else {
8230 if (drb_mapping->rlc_dl_ext_li_field == true) {
8231 ue_mappings->mapping[lcid].channel_type = rlcAMdl16dlExtLiField;
8232 } else {
8233 ue_mappings->mapping[lcid].channel_type = rlcAMdl16;
8236 } else if (drb_mapping->rlc_ul_ext_li_field == true) {
8237 if (drb_mapping->rlc_dl_ext_li_field == true) {
8238 ue_mappings->mapping[lcid].channel_type = rlcAMextLiField;
8239 } else {
8240 ue_mappings->mapping[lcid].channel_type = rlcAMulExtLiField;
8242 } else {
8243 if (drb_mapping->rlc_dl_ext_li_field == true) {
8244 ue_mappings->mapping[lcid].channel_type = rlcAMdlExtLiField;
8245 } else {
8246 ue_mappings->mapping[lcid].channel_type = rlcAM;
8249 break;
8250 case RLC_UM_MODE:
8251 if (drb_mapping->um_sn_length_present) {
8252 if (drb_mapping->um_sn_length == 5) {
8253 ue_mappings->mapping[lcid].channel_type = rlcUM5;
8255 else {
8256 ue_mappings->mapping[lcid].channel_type = rlcUM10;
8258 break;
8261 default:
8262 break;
8267 /* Return the configured UL priority for the channel */
8268 static uint8_t get_mac_lte_channel_priority(uint16_t ueid, uint8_t lcid,
8269 uint8_t direction)
8271 ue_dynamic_drb_mappings_t *ue_mappings;
8273 /* Priority only affects UL */
8274 if (direction == DIRECTION_DOWNLINK) {
8275 return 0;
8278 /* Look up the mappings for this UE */
8279 ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash, GUINT_TO_POINTER((unsigned)ueid));
8280 if (!ue_mappings) {
8281 return 0;
8284 /* Won't report value if channel not configured */
8285 if (!ue_mappings->mapping[lcid].valid) {
8286 return 0;
8288 else {
8289 return ue_mappings->mapping[lcid].ul_priority;
8293 /* Return mode of bearer, or 0 if not found/known */
8294 uint8_t get_mac_lte_channel_mode(uint16_t ueid, uint8_t drbid)
8296 ue_dynamic_drb_mappings_t *ue_mappings;
8298 /* Look up the mappings for this UE */
8299 ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash, GUINT_TO_POINTER((unsigned)ueid));
8300 if (!ue_mappings) {
8301 return 0;
8304 if (drbid > 32) {
8305 return 0;
8307 /* Need sensible lcid */
8308 uint8_t lcid = ue_mappings->drb_to_lcid_mappings[drbid];
8309 if (lcid < 3) {
8310 /* Not valid */
8311 return 0;
8314 /* Lcid needs ot have mapping */
8315 if (!ue_mappings->mapping[lcid].valid) {
8316 return 0;
8318 rlc_channel_type_t channel_type = ue_mappings->mapping[lcid].channel_type;
8319 /* What mode does the channel type correspond to? */
8320 if (channel_type >= rlcAM) {
8321 return RLC_AM_MODE;
8323 else {
8324 return RLC_UM_MODE;
8329 /* Configure the DRX state for this UE (from RRC) */
8330 void set_mac_lte_drx_config(uint16_t ueid, drx_config_t *drx_config, packet_info *pinfo)
8332 if (global_mac_lte_show_drx && !PINFO_FD_VISITED(pinfo)) {
8333 ue_parameters_t *ue_params;
8334 uint32_t previousFrameNum = 0;
8336 /* Find or create config struct for this UE */
8337 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((unsigned)ueid));
8338 if (ue_params == NULL) {
8339 ue_params = (ue_parameters_t *)wmem_new0(wmem_file_scope(), ue_parameters_t);
8340 g_hash_table_insert(mac_lte_ue_parameters, GUINT_TO_POINTER((unsigned)ueid), ue_params);
8342 else {
8343 previousFrameNum = ue_params->drx_state.config.frameNum;
8346 ue_params->drx_state_valid = true;
8348 /* Clearing state when new config comes in... */
8349 init_drx_ue_state(&ue_params->drx_state, true);
8351 /* Copy in new config */
8352 ue_params->drx_state.config = *drx_config;
8353 /* Remember frame when current settings set */
8354 ue_params->drx_state.config.frameNum = pinfo->num;
8355 /* Also remember any previous config frame number */
8356 ue_params->drx_state.config.previousFrameNum = previousFrameNum;
8360 /* Release DRX config for this UE */
8361 void set_mac_lte_drx_config_release(uint16_t ueid, packet_info *pinfo)
8363 if (global_mac_lte_show_drx && !PINFO_FD_VISITED(pinfo)) {
8364 ue_parameters_t *ue_params;
8366 /* Find or create config struct for this UE */
8367 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((unsigned)ueid));
8368 if (ue_params != NULL) {
8369 ue_params->drx_state_valid = false;
8374 /* Configure RAPID group sizes from RRC (SIB2). Note that we currently assume
8375 that they won't change, i.e. if known we just return the last values we ever
8376 saw. */
8377 void set_mac_lte_rapid_ranges(unsigned group_A, unsigned all_RA)
8379 s_rapid_ranges_groupA = group_A;
8380 s_rapid_ranges_RA = all_RA;
8381 s_rapid_ranges_configured = true;
8384 /* Configure the BSR sizes for this UE (from RRC) */
8385 void set_mac_lte_extended_bsr_sizes(uint16_t ueid, bool use_ext_bsr_sizes, packet_info *pinfo)
8387 if (!PINFO_FD_VISITED(pinfo)) {
8388 ue_parameters_t *ue_params;
8390 /* Find or create config struct for this UE */
8391 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((unsigned)ueid));
8392 if (ue_params == NULL) {
8393 ue_params = (ue_parameters_t *)wmem_new0(wmem_file_scope(), ue_parameters_t);
8394 g_hash_table_insert(mac_lte_ue_parameters, GUINT_TO_POINTER((unsigned)ueid), ue_params);
8397 ue_params->use_ext_bsr_sizes = use_ext_bsr_sizes;
8401 /* Configure the simultaneous PUCCH/PUSCH transmission for this UE (from RRC) */
8402 void set_mac_lte_simult_pucch_pusch(uint16_t ueid, simult_pucch_pusch_cell_type cell_type, bool simult_pucch_pusch, packet_info *pinfo)
8404 if (!PINFO_FD_VISITED(pinfo)) {
8405 ue_parameters_t *ue_params;
8407 /* Find or create config struct for this UE */
8408 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((unsigned)ueid));
8409 if (ue_params == NULL) {
8410 ue_params = (ue_parameters_t *)wmem_new0(wmem_file_scope(), ue_parameters_t);
8411 g_hash_table_insert(mac_lte_ue_parameters, GUINT_TO_POINTER((unsigned)ueid), ue_params);
8414 if (cell_type == SIMULT_PUCCH_PUSCH_PCELL) {
8415 ue_params->use_simult_pucch_pusch_pcell = simult_pucch_pusch;
8416 } else {
8417 ue_params->use_simult_pucch_pusch_pscell = simult_pucch_pusch;
8422 /* Function to be called from outside this module (e.g. in a plugin) to get per-packet data */
8423 mac_lte_info *get_mac_lte_proto_data(packet_info *pinfo)
8425 return (mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
8428 /* Function to be called from outside this module (e.g. in a plugin) to set per-packet data */
8429 void set_mac_lte_proto_data(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
8431 p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info);
8434 void proto_register_mac_lte(void)
8436 static hf_register_info hf[] =
8438 /**********************************/
8439 /* Items for decoding context */
8440 { &hf_mac_lte_context,
8441 { "Context",
8442 "mac-lte.context", FT_STRING, BASE_NONE, NULL, 0x0,
8443 NULL, HFILL
8446 { &hf_mac_lte_context_radio_type,
8447 { "Radio Type",
8448 "mac-lte.radio-type", FT_UINT8, BASE_DEC, VALS(radio_type_vals), 0x0,
8449 NULL, HFILL
8452 { &hf_mac_lte_context_direction,
8453 { "Direction",
8454 "mac-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
8455 "Direction of message", HFILL
8458 { &hf_mac_lte_context_rnti,
8459 { "RNTI",
8460 "mac-lte.rnti", FT_UINT16, BASE_DEC, NULL, 0x0,
8461 "RNTI associated with message", HFILL
8464 { &hf_mac_lte_context_rnti_type,
8465 { "RNTI Type",
8466 "mac-lte.rnti-type", FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0,
8467 "Type of RNTI associated with message", HFILL
8470 { &hf_mac_lte_context_ueid,
8471 { "UEId",
8472 "mac-lte.ueid", FT_UINT16, BASE_DEC, NULL, 0x0,
8473 "User Equipment Identifier associated with message", HFILL
8476 { &hf_mac_lte_context_sysframe_number,
8477 { "System Frame Number",
8478 "mac-lte.sfn", FT_UINT16, BASE_DEC, NULL, 0x0,
8479 "System Frame Number associated with message", HFILL
8482 { &hf_mac_lte_context_subframe_number,
8483 { "Subframe",
8484 "mac-lte.subframe", FT_UINT16, BASE_DEC, NULL, 0x0,
8485 "Subframe number associated with message", HFILL
8488 { &hf_mac_lte_context_grant_subframe_number,
8489 { "Grant Subframe",
8490 "mac-lte.grant-subframe", FT_UINT16, BASE_DEC, NULL, 0x0,
8491 "Subframe when grant for this PDU was received", HFILL
8494 { &hf_mac_lte_context_predefined_frame,
8495 { "Predefined frame",
8496 "mac-lte.is-predefined-frame", FT_UINT8, BASE_DEC, VALS(predefined_frame_vals), 0x0,
8497 "Predefined test frame (or real MAC PDU)", HFILL
8500 { &hf_mac_lte_context_length,
8501 { "Length of frame",
8502 "mac-lte.length", FT_UINT8, BASE_DEC, NULL, 0x0,
8503 "Original length of frame (including SDUs and padding)", HFILL
8506 { &hf_mac_lte_context_ul_grant_size,
8507 { "Uplink grant size",
8508 "mac-lte.ul-grant-size", FT_UINT8, BASE_DEC, NULL, 0x0,
8509 "Uplink grant size (in bytes)", HFILL
8512 { &hf_mac_lte_context_bch_transport_channel,
8513 { "Transport channel",
8514 "mac-lte.bch-transport-channel", FT_UINT8, BASE_DEC, VALS(bch_transport_channel_vals), 0x0,
8515 "Transport channel BCH data was carried on", HFILL
8518 { &hf_mac_lte_context_retx_count,
8519 { "ReTX count",
8520 "mac-lte.retx-count", FT_UINT8, BASE_DEC, NULL, 0x0,
8521 "Number of times this PDU has been retransmitted", HFILL
8524 { &hf_mac_lte_context_retx_reason,
8525 { "ReTX reason",
8526 "mac-lte.retx-reason", FT_UINT8, BASE_DEC, VALS(ul_retx_grant_vals), 0x0,
8527 "Type of UL ReTx grant", HFILL
8530 { &hf_mac_lte_context_crc_status,
8531 { "CRC Status",
8532 "mac-lte.crc-status", FT_UINT8, BASE_DEC, VALS(crc_status_vals), 0x0,
8533 "CRC Status as reported by PHY", HFILL
8536 { &hf_mac_lte_context_carrier_id,
8537 { "Carrier Id",
8538 "mac-lte.carrier-id", FT_UINT8, BASE_DEC, VALS(carrier_id_vals), 0x0,
8539 NULL, HFILL
8542 { &hf_mac_lte_context_rapid,
8543 { "RAPID",
8544 "mac-lte.preamble-sent.rapid", FT_UINT8, BASE_DEC, NULL, 0x0,
8545 "RAPID sent in RACH preamble", HFILL
8548 { &hf_mac_lte_context_rach_attempt_number,
8549 { "RACH Attempt Number",
8550 "mac-lte.preamble-sent.attempt", FT_UINT8, BASE_DEC, NULL, 0x0,
8551 NULL, HFILL
8555 { &hf_mac_lte_ues_ul_per_tti,
8556 { "UL UE in TTI",
8557 "mac-lte.ul-tti-count", FT_UINT8, BASE_DEC, NULL, 0x0,
8558 "In this TTI, this is the nth UL grant", HFILL
8561 { &hf_mac_lte_ues_dl_per_tti,
8562 { "DL UE in TTI",
8563 "mac-lte.dl-tti-count", FT_UINT8, BASE_DEC, NULL, 0x0,
8564 "In this TTI, this is the nth DL PDU", HFILL
8569 /* Extra PHY context */
8570 { &hf_mac_lte_context_phy_ul,
8571 { "UL PHY attributes",
8572 "mac-lte.ul-phy", FT_STRING, BASE_NONE, NULL, 0x0,
8573 NULL, HFILL
8576 { &hf_mac_lte_context_phy_ul_modulation_type,
8577 { "Modulation type",
8578 "mac-lte.ul-phy.modulation-type", FT_UINT8, BASE_DEC, VALS(modulation_type_vals), 0x0,
8579 NULL, HFILL
8582 { &hf_mac_lte_context_phy_ul_tbs_index,
8583 { "TBs Index",
8584 "mac-lte.ul-phy.tbs-index", FT_UINT8, BASE_DEC, NULL, 0x0,
8585 NULL, HFILL
8588 { &hf_mac_lte_context_phy_ul_resource_block_length,
8589 { "Resource Block Length",
8590 "mac-lte.ul-phy.resource-block-length", FT_UINT8, BASE_DEC, NULL, 0x0,
8591 NULL, HFILL
8594 { &hf_mac_lte_context_phy_ul_resource_block_start,
8595 { "Resource Block Start",
8596 "mac-lte.ul-phy.resource-block-start", FT_UINT8, BASE_DEC, NULL, 0x0,
8597 NULL, HFILL
8600 { &hf_mac_lte_context_phy_ul_harq_id,
8601 { "HARQ Id",
8602 "mac-lte.ul-phy.harq-id", FT_UINT8, BASE_DEC, NULL, 0x0,
8603 NULL, HFILL
8606 { &hf_mac_lte_context_phy_ul_ndi,
8607 { "NDI",
8608 "mac-lte.ul-phy.ndi", FT_UINT8, BASE_DEC, NULL, 0x0,
8609 "UL New Data Indicator", HFILL
8613 { &hf_mac_lte_context_phy_dl,
8614 { "DL PHY attributes",
8615 "mac-lte.dl-phy", FT_STRING, BASE_NONE, NULL, 0x0,
8616 NULL, HFILL
8619 { &hf_mac_lte_context_phy_dl_dci_format,
8620 { "DCI format",
8621 "mac-lte.dl-phy.dci-format", FT_UINT8, BASE_DEC, VALS(dci_format_vals), 0x0,
8622 NULL, HFILL
8625 { &hf_mac_lte_context_phy_dl_resource_allocation_type,
8626 { "Resource Allocation Type",
8627 "mac-lte.dl-phy.resource-allocation-type", FT_UINT8, BASE_DEC, NULL, 0x0,
8628 NULL, HFILL
8631 { &hf_mac_lte_context_phy_dl_aggregation_level,
8632 { "Aggregation Level",
8633 "mac-lte.dl-phy.aggregation-level", FT_UINT8, BASE_DEC, VALS(aggregation_level_vals), 0x0,
8634 NULL, HFILL
8637 { &hf_mac_lte_context_phy_dl_mcs_index,
8638 { "MCS Index",
8639 "mac-lte.dl-phy.mcs-index", FT_UINT8, BASE_DEC, NULL, 0x0,
8640 NULL, HFILL
8643 { &hf_mac_lte_context_phy_dl_redundancy_version_index,
8644 { "RV Index",
8645 "mac-lte.dl-phy.rv-index", FT_UINT8, BASE_DEC, NULL, 0x0,
8646 NULL, HFILL
8649 { &hf_mac_lte_context_phy_dl_retx,
8650 { "DL Retx",
8651 "mac-lte.dl-phy.dl-retx", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
8652 NULL, HFILL
8655 { &hf_mac_lte_context_phy_dl_resource_block_length,
8656 { "RB Length",
8657 "mac-lte.dl-phy.rb-length", FT_UINT8, BASE_DEC, NULL, 0x0,
8658 NULL, HFILL
8661 { &hf_mac_lte_context_phy_dl_harq_id,
8662 { "HARQ Id",
8663 "mac-lte.dl-phy.harq-id", FT_UINT8, BASE_DEC, NULL, 0x0,
8664 NULL, HFILL
8667 { &hf_mac_lte_context_phy_dl_ndi,
8668 { "NDI",
8669 "mac-lte.dl-phy.ndi", FT_UINT8, BASE_DEC, NULL, 0x0,
8670 "New Data Indicator", HFILL
8673 { &hf_mac_lte_context_phy_dl_tb,
8674 { "TB",
8675 "mac-lte.dl-phy.tb", FT_UINT8, BASE_DEC, NULL, 0x0,
8676 "Transport Block (antenna #)", HFILL
8680 /* Out-of-band events */
8681 { &hf_mac_lte_oob_send_preamble,
8682 { "PRACH",
8683 "mac-lte.preamble-sent", FT_STRING, BASE_NONE, NULL, 0x0,
8684 NULL, HFILL
8687 { &hf_mac_lte_number_of_srs,
8688 { "Number of SRs",
8689 "mac-lte.sr-req.count", FT_UINT32, BASE_DEC, NULL, 0x0,
8690 "Number of UEs doing SR in this frame", HFILL
8694 /*******************************************/
8695 /* MAC shared channel header fields */
8696 { &hf_mac_lte_ulsch,
8697 { "UL-SCH",
8698 "mac-lte.ulsch", FT_STRING, BASE_NONE, NULL, 0x0,
8699 NULL, HFILL
8702 { &hf_mac_lte_ulsch_header,
8703 { "UL-SCH Header",
8704 "mac-lte.ulsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8705 NULL, HFILL
8708 { &hf_mac_lte_dlsch_header,
8709 { "DL-SCH Header",
8710 "mac-lte.dlsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8711 NULL, HFILL
8714 { &hf_mac_lte_dlsch,
8715 { "DL-SCH",
8716 "mac-lte.dlsch", FT_STRING, BASE_NONE, NULL, 0x0,
8717 NULL, HFILL
8720 { &hf_mac_lte_sch_subheader,
8721 { "SCH sub-header",
8722 "mac-lte.sch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8723 NULL, HFILL
8726 { &hf_mac_lte_mch,
8727 { "MCH",
8728 "mac-lte.mch", FT_STRING, BASE_NONE, NULL, 0x0,
8729 NULL, HFILL
8732 { &hf_mac_lte_mch_header,
8733 { "MCH Header",
8734 "mac-lte.mch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8735 NULL, HFILL
8738 { &hf_mac_lte_mch_subheader,
8739 { "MCH sub-header",
8740 "mac-lte.mch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8741 NULL, HFILL
8744 { &hf_mac_lte_slsch,
8745 { "SL-SCH",
8746 "mac-lte.slsch", FT_STRING, BASE_NONE, NULL, 0x0,
8747 NULL, HFILL
8750 { &hf_mac_lte_slsch_header,
8751 { "SL-SCH Header",
8752 "mac-lte.slsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8753 NULL, HFILL
8756 { &hf_mac_lte_slsch_subheader,
8757 { "SL-SCH sub-header",
8758 "mac-lte.slsch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8759 NULL, HFILL
8762 { &hf_mac_lte_sch_reserved,
8763 { "SCH reserved bit",
8764 "mac-lte.sch.reserved", FT_UINT8, BASE_HEX, NULL, 0x80,
8765 NULL, HFILL
8768 { &hf_mac_lte_sch_format2,
8769 { "Format2",
8770 "mac-lte.sch.format2", FT_BOOLEAN, 8, TFS(&format2_vals), 0x40,
8771 NULL, HFILL
8774 { &hf_mac_lte_sch_extended,
8775 { "Extension",
8776 "mac-lte.sch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8777 "Extension - i.e. further headers after this one", HFILL
8780 /* Will be hidden, but useful for bi-directional filtering */
8781 { &hf_mac_lte_lcid,
8782 { "LCID",
8783 "mac-lte.lcid", FT_UINT8, BASE_HEX, NULL, 0x1f,
8784 "Logical Channel Identifier", HFILL
8787 { &hf_mac_lte_dlsch_lcid,
8788 { "LCID",
8789 "mac-lte.dlsch.lcid", FT_UINT8, BASE_HEX, VALS(dlsch_lcid_vals), 0x1f,
8790 "DL-SCH Logical Channel Identifier", HFILL
8793 { &hf_mac_lte_ulsch_lcid,
8794 { "LCID",
8795 "mac-lte.ulsch.lcid", FT_UINT8, BASE_HEX, VALS(ulsch_lcid_vals), 0x1f,
8796 "UL-SCH Logical Channel Identifier", HFILL
8799 { &hf_mac_lte_sch_reserved2,
8800 { "SCH reserved bits",
8801 "mac-lte.sch.reserved2", FT_UINT8, BASE_HEX, NULL, 0xc0,
8802 NULL, HFILL
8805 { &hf_mac_lte_sch_elcid,
8806 { "eLCID",
8807 "mac-lte.sch.elcid", FT_UINT8, BASE_DEC, NULL, 0x3f,
8808 NULL, HFILL
8811 { &hf_mac_lte_sch_format,
8812 { "Format",
8813 "mac-lte.sch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8814 NULL, HFILL
8817 { &hf_mac_lte_sch_length,
8818 { "Length",
8819 "mac-lte.sch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8820 "Length of MAC SDU or MAC control element", HFILL
8823 { &hf_mac_lte_mch_reserved,
8824 { "MCH reserved bits",
8825 "mac-lte.mch.reserved", FT_UINT8, BASE_HEX, NULL, 0x80,
8826 NULL, HFILL
8829 { &hf_mac_lte_mch_format2,
8830 { "Format2",
8831 "mac-lte.mch.format2", FT_BOOLEAN, 8, TFS(&format2_vals), 0x40,
8832 NULL, HFILL
8835 { &hf_mac_lte_mch_extended,
8836 { "Extension",
8837 "mac-lte.mch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8838 "Extension - i.e. further headers after this one", HFILL
8841 { &hf_mac_lte_mch_lcid,
8842 { "LCID",
8843 "mac-lte.mch.lcid", FT_UINT8, BASE_HEX, VALS(mch_lcid_vals), 0x1f,
8844 "MCH Logical Channel Identifier", HFILL
8847 { &hf_mac_lte_mch_format,
8848 { "Format",
8849 "mac-lte.mch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8850 NULL, HFILL
8853 { &hf_mac_lte_mch_length,
8854 { "Length",
8855 "mac-lte.mch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8856 "Length of MAC SDU or MAC control element", HFILL
8859 { &hf_mac_lte_slsch_version,
8860 { "Version",
8861 "mac-lte.slsch.version", FT_UINT8, BASE_DEC, NULL, 0xf0,
8862 NULL, HFILL
8865 { &hf_mac_lte_slsch_reserved,
8866 { "Reserved bits",
8867 "mac-lte.slsch.reserved", FT_UINT8, BASE_HEX, NULL, 0x0f,
8868 NULL, HFILL
8871 { &hf_mac_lte_slsch_src_l2_id,
8872 { "Source Layer-2 ID",
8873 "mac-lte.slsch.src-l2-id", FT_UINT24, BASE_HEX, NULL, 0x0,
8874 NULL, HFILL
8877 { &hf_mac_lte_slsch_dst_l2_id,
8878 { "Destination Layer-2 ID",
8879 "mac-lte.slsch.dst-l2-id", FT_UINT16, BASE_HEX, NULL, 0x0,
8880 NULL, HFILL
8883 { &hf_mac_lte_slsch_dst_l2_id2,
8884 { "Destination Layer-2 ID",
8885 "mac-lte.slsch.dst-l2-id", FT_UINT24, BASE_HEX, NULL, 0x0,
8886 NULL, HFILL
8889 { &hf_mac_lte_slsch_reserved2,
8890 { "Reserved bits",
8891 "mac-lte.slsch.reserved", FT_UINT8, BASE_HEX, NULL, 0xc0,
8892 NULL, HFILL
8895 { &hf_mac_lte_slsch_extended,
8896 { "Extension",
8897 "mac-lte.slsch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8898 "Extension - i.e. further headers after this one", HFILL
8901 { &hf_mac_lte_slsch_lcid,
8902 { "LCID",
8903 "mac-lte.slsch.lcid", FT_UINT8, BASE_HEX, VALS(slsch_lcid_vals), 0x1f,
8904 "SL-SCH Logical Channel Identifier", HFILL
8907 { &hf_mac_lte_slsch_format,
8908 { "Format",
8909 "mac-lte.slsch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8910 NULL, HFILL
8913 { &hf_mac_lte_slsch_length,
8914 { "Length",
8915 "mac-lte.slsch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8916 "Length of MAC SDU or MAC control element", HFILL
8919 { &hf_mac_lte_sch_header_only,
8920 { "MAC PDU Header only",
8921 "mac-lte.sch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
8922 NULL, HFILL
8925 { &hf_mac_lte_mch_header_only,
8926 { "MAC PDU Header only",
8927 "mac-lte.mch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
8928 NULL, HFILL
8931 { &hf_mac_lte_slsch_header_only,
8932 { "MAC PDU Header only",
8933 "mac-lte.slsch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
8934 NULL, HFILL
8938 /********************************/
8939 /* Data */
8940 { &hf_mac_lte_sch_sdu,
8941 { "SDU",
8942 "mac-lte.sch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8943 "Shared channel SDU", HFILL
8946 { &hf_mac_lte_mch_sdu,
8947 { "SDU",
8948 "mac-lte.mch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8949 "Multicast channel SDU", HFILL
8952 { &hf_mac_lte_bch_pdu,
8953 { "BCH PDU",
8954 "mac-lte.bch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8955 NULL, HFILL
8958 { &hf_mac_lte_pch_pdu,
8959 { "PCH PDU",
8960 "mac-lte.pch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8961 NULL, HFILL
8964 { &hf_mac_lte_slbch_pdu,
8965 { "SL-BCH PDU",
8966 "mac-lte.slbch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8967 NULL, HFILL
8970 { &hf_mac_lte_slsch_sdu,
8971 { "SDU",
8972 "mac-lte.slsch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8973 "Sidelink shared channel SDU", HFILL
8976 { &hf_mac_lte_predefined_pdu,
8977 { "Predefined data",
8978 "mac-lte.predefined-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8979 "Predefined test data", HFILL
8982 { &hf_mac_lte_raw_pdu,
8983 { "Raw data",
8984 "mac-lte.raw-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8985 "Raw bytes of PDU (e.g. if CRC error)", HFILL
8988 { &hf_mac_lte_padding_data,
8989 { "Padding data",
8990 "mac-lte.padding-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8991 NULL, HFILL
8994 { &hf_mac_lte_padding_length,
8995 { "Padding length",
8996 "mac-lte.padding-length", FT_UINT32, BASE_DEC, NULL, 0x0,
8997 "Length of padding data not included at end of frame", HFILL
9003 /*********************************/
9004 /* RAR fields */
9005 { &hf_mac_lte_rar,
9006 { "RAR",
9007 "mac-lte.rar", FT_NONE, BASE_NONE, NULL, 0x0,
9008 NULL, HFILL
9011 { &hf_mac_lte_rar_headers,
9012 { "RAR Headers",
9013 "mac-lte.rar.headers", FT_STRING, BASE_NONE, NULL, 0x0,
9014 NULL, HFILL
9017 { &hf_mac_lte_rar_header,
9018 { "RAR Header",
9019 "mac-lte.rar.header", FT_STRING, BASE_NONE, NULL, 0x0,
9020 NULL, HFILL
9023 { &hf_mac_lte_rar_extension,
9024 { "Extension",
9025 "mac-lte.rar.e", FT_UINT8, BASE_HEX, NULL, 0x80,
9026 "Extension - i.e. further RAR headers after this one", HFILL
9029 { &hf_mac_lte_rar_t,
9030 { "Type",
9031 "mac-lte.rar.t", FT_UINT8, BASE_HEX, VALS(rar_type_vals), 0x40,
9032 "Type field indicating whether the payload is RAPID or BI", HFILL
9035 { &hf_mac_lte_rar_bi,
9036 { "BI",
9037 "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_vals), 0x0f,
9038 "Backoff Indicator (ms)", HFILL
9041 { &hf_mac_lte_rar_bi_nb,
9042 { "BI",
9043 "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_nb_vals), 0x0f,
9044 "Backoff Indicator (ms)", HFILL
9047 { &hf_mac_lte_rar_rapid,
9048 { "RAPID",
9049 "mac-lte.rar.rapid", FT_UINT8, BASE_HEX_DEC, NULL, 0x3f,
9050 "Random Access Preamble IDentifier", HFILL
9053 { &hf_mac_lte_rar_no_of_rapids,
9054 { "Number of RAPIDs",
9055 "mac-lte.rar.no-of-rapids", FT_UINT8, BASE_DEC, NULL, 0x0,
9056 "Number of RAPIDs in RAR PDU", HFILL
9059 { &hf_mac_lte_rar_reserved,
9060 { "Reserved",
9061 "mac-lte.rar.reserved", FT_UINT8, BASE_HEX, NULL, 0x30,
9062 "Reserved bits in RAR header - should be 0", HFILL
9066 { &hf_mac_lte_rar_body,
9067 { "RAR Body",
9068 "mac-lte.rar.body", FT_STRING, BASE_NONE, NULL, 0x0,
9069 NULL, HFILL
9072 { &hf_mac_lte_rar_reserved2,
9073 { "Reserved",
9074 "mac-lte.rar.reserved2", FT_UINT8, BASE_HEX, NULL, 0x80,
9075 "Reserved bit in RAR body - should be 0", HFILL
9078 { &hf_mac_lte_rar_ta,
9079 { "Timing Advance",
9080 "mac-lte.rar.ta", FT_UINT16, BASE_DEC, NULL, 0x7ff0,
9081 "Required adjustment to uplink transmission timing", HFILL
9084 { &hf_mac_lte_rar_ul_grant_ce_mode_b,
9085 { "UL Grant",
9086 "mac-lte.rar.ul-grant", FT_UINT16, BASE_DEC, NULL, 0x0fff,
9087 "Size of UL Grant", HFILL
9090 { &hf_mac_lte_rar_ul_grant,
9091 { "UL Grant",
9092 "mac-lte.rar.ul-grant", FT_UINT24, BASE_DEC, NULL, 0x0fffff,
9093 "Size of UL Grant", HFILL
9096 { &hf_mac_lte_rar_ul_grant_hopping,
9097 { "Hopping Flag",
9098 "mac-lte.rar.ul-grant.hopping", FT_UINT8, BASE_DEC, NULL, 0x08,
9099 NULL, HFILL
9102 { &hf_mac_lte_rar_ul_grant_fsrba,
9103 { "Fixed sized resource block assignment",
9104 "mac-lte.rar.ul-grant.fsrba", FT_UINT16, BASE_DEC, NULL, 0x07fe,
9105 NULL, HFILL
9108 { &hf_mac_lte_rar_ul_grant_tmcs,
9109 { "Truncated Modulation and coding scheme",
9110 "mac-lte.rar.ul-grant.tmcs", FT_UINT16, BASE_DEC, NULL, 0x01e0,
9111 NULL, HFILL
9114 { &hf_mac_lte_rar_ul_grant_tcsp,
9115 { "TPC command for scheduled PUSCH",
9116 "mac-lte.rar.ul-grant.tcsp", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_tcsp_vals), 0x1c,
9117 "PUSCH power offset in dB" , HFILL
9120 { &hf_mac_lte_rar_ul_grant_ul_delay,
9121 { "UL Delay",
9122 "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, NULL, 0x02,
9123 NULL, HFILL
9126 { &hf_mac_lte_rar_ul_grant_cqi_request,
9127 { "CQI Request",
9128 "mac-lte.rar.ul-grant.cqi-request", FT_UINT8, BASE_DEC, NULL, 0x01,
9129 NULL, HFILL
9132 { &hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
9133 { "Msg3 PUSCH narrowband index",
9134 "mac-lte.rar.ul-grant.msg3-pusch-nb-idx", FT_UINT8, BASE_DEC, NULL, 0x0,
9135 NULL, HFILL
9138 { &hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_a,
9139 { "Msg3 PUSCH Resource allocation",
9140 "mac-lte.rar.ul-grant.msg3-pusch-res-alloc", FT_UINT8, BASE_DEC, NULL, 0x0,
9141 NULL, HFILL
9144 { &hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a,
9145 { "Number of Repetitions for Msg3 PUSCH",
9146 "mac-lte.rar.ul-grant.nb-rep-msg3-pusch", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a_vals), 0x0,
9147 NULL, HFILL
9150 { &hf_mac_lte_rar_ul_grant_mcs_ce_mode_a,
9151 { "MCS",
9152 "mac-lte.rar.ul-grant.mcs", FT_UINT16, BASE_DEC, NULL, 0x0,
9153 NULL, HFILL
9156 { &hf_mac_lte_rar_ul_grant_tpc_ce_mode_a,
9157 { "TPC",
9158 "mac-lte.rar.ul-grant.tpc", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_tcsp_vals), 0x0,
9159 NULL, HFILL
9162 { &hf_mac_lte_rar_ul_grant_csi_request_ce_mode_a,
9163 { "CSI request",
9164 "mac-lte.rar.ul-grant.csi-request", FT_UINT8, BASE_DEC, NULL, 0x0,
9165 NULL, HFILL
9168 { &hf_mac_lte_rar_ul_grant_ul_delay_ce_mode_a,
9169 { "UL delay",
9170 "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
9171 NULL, HFILL
9174 { &hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx,
9175 { "Msg3/4 MPDCCH narrowband index",
9176 "mac-lte.rar.ul-grant.msg3-msg4-mpdcch-nb-idx", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_msg3_msg4_mpdcch_nb_idx_vals), 0x0,
9177 NULL, HFILL
9180 { &hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
9181 { "Padding",
9182 "mac-lte.rar.ul-grant.padding", FT_UINT8, BASE_HEX, NULL, 0x0,
9183 NULL, HFILL
9186 { &hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b,
9187 { "Msg3 PUSCH narrowband index",
9188 "mac-lte.rar.ul-grant.msg3-pusch-nb-idx", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b_vals), 0x0c,
9189 NULL, HFILL
9192 { &hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_b,
9193 { "Msg3 PUSCH resource allocation",
9194 "mac-lte.rar.ul-grant.msg3-pusch-res-alloc", FT_UINT16, BASE_DEC, NULL, 0x0380,
9195 NULL, HFILL
9198 { &hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b,
9199 { "Number of Repetitions for Msg3 PUSCH",
9200 "mac-lte.rar.ul-grant.nb-rep-msg3-pusch", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b_vals), 0x70,
9201 NULL, HFILL
9204 { &hf_mac_lte_rar_ul_grant_tbs_ce_mode_b,
9205 { "TBS",
9206 "mac-lte.rar.ul-grant.tbs", FT_UINT8, BASE_DEC, NULL, 0x0c,
9207 NULL, HFILL
9210 { &hf_mac_lte_rar_ul_grant_ul_subcarrier_spacing,
9211 { "Uplink subcarrier spacing",
9212 "mac-lte.rar.ul-grant.ul-subcarrier-spacing", FT_BOOLEAN, 8, TFS(&ul_subcarrier_spacing_val), 0x08,
9213 NULL, HFILL
9216 { &hf_mac_lte_rar_ul_grant_subcarrier_indication,
9217 { "Subcarrier indication",
9218 "mac-lte.rar.ul-grant.subcarrier-indication", FT_UINT16, BASE_DEC, NULL, 0x07e0,
9219 NULL, HFILL
9222 { &hf_mac_lte_rar_ul_grant_scheduling_delay,
9223 { "Scheduling delay",
9224 "mac-lte.rar.ul-grant.scheduling-delay", FT_UINT8, BASE_DEC, VALS(scheduling_delay_vals), 0x18,
9225 NULL, HFILL
9228 { &hf_mac_lte_rar_ul_grant_msg3_repetition_number,
9229 { "Msg3 repetition number",
9230 "mac-lte.rar.ul-grant.msg3-repetition-number", FT_UINT8, BASE_DEC, VALS(msg3_rep_nb_vals), 0x07,
9231 NULL, HFILL
9234 { &hf_mac_lte_rar_ul_grant_mcs_index,
9235 { "MCS index",
9236 "mac-lte.rar.ul-grant.mcs-index", FT_UINT8, BASE_DEC, NULL, 0xe0,
9237 NULL, HFILL
9240 { &hf_mac_lte_rar_ul_grant_padding_nb_mode,
9241 { "Padding",
9242 "mac-lte.rar.ul-grant.padding", FT_UINT8, BASE_HEX, NULL, 0x1f,
9243 NULL, HFILL
9246 { &hf_mac_lte_rar_temporary_crnti,
9247 { "Temporary C-RNTI",
9248 "mac-lte.rar.temporary-crnti", FT_UINT16, BASE_DEC, NULL, 0x0,
9249 NULL, HFILL
9253 /**********************/
9254 /* Control PDU fields */
9255 { &hf_mac_lte_control_bsr,
9256 { "BSR",
9257 "mac-lte.control.bsr", FT_STRING, BASE_NONE, NULL, 0x0,
9258 "Buffer Status Report", HFILL
9261 { &hf_mac_lte_control_bsr_lcg_id,
9262 { "Logical Channel Group ID",
9263 "mac-lte.control.bsr.lcg-id", FT_UINT8, BASE_DEC, NULL, 0xc0,
9264 NULL, HFILL
9267 { &hf_mac_lte_control_short_bsr_buffer_size,
9268 { "Buffer Size",
9269 "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
9270 "Buffer Size available in all channels in group", HFILL
9273 { &hf_mac_lte_control_long_bsr_buffer_size_0,
9274 { "Buffer Size 0",
9275 "mac-lte.control.bsr.buffer-size-0", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0xfc,
9276 "Buffer Size available in logical channel group 0", HFILL
9279 { &hf_mac_lte_control_long_bsr_buffer_size_1,
9280 { "Buffer Size 1",
9281 "mac-lte.control.bsr.buffer-size-1", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x03f0,
9282 "Buffer Size available in logical channel group 1", HFILL
9285 { &hf_mac_lte_control_long_bsr_buffer_size_2,
9286 { "Buffer Size 2",
9287 "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x0fc0,
9288 "Buffer Size available in logical channel group 2", HFILL
9291 { &hf_mac_lte_control_long_bsr_buffer_size_3,
9292 { "Buffer Size 3",
9293 "mac-lte.control.bsr.buffer-size-3", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
9294 "Buffer Size available in logical channel group 3", HFILL
9297 { &hf_mac_lte_control_short_ext_bsr_buffer_size,
9298 { "Buffer Size",
9299 "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x3f,
9300 "Buffer Size available in all channels in group", HFILL
9303 { &hf_mac_lte_control_long_ext_bsr_buffer_size_0,
9304 { "Buffer Size 0",
9305 "mac-lte.control.bsr.buffer-size-0", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0xfc,
9306 "Buffer Size available in logical channel group 0", HFILL
9309 { &hf_mac_lte_control_long_ext_bsr_buffer_size_1,
9310 { "Buffer Size 1",
9311 "mac-lte.control.bsr.buffer-size-1", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x03f0,
9312 "Buffer Size available in logical channel group 1", HFILL
9315 { &hf_mac_lte_control_long_ext_bsr_buffer_size_2,
9316 { "Buffer Size 2",
9317 "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x0fc0,
9318 "Buffer Size available in logical channel group 2", HFILL
9321 { &hf_mac_lte_control_long_ext_bsr_buffer_size_3,
9322 { "Buffer Size 3",
9323 "mac-lte.control.bsr.buffer-size-3", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x3f,
9324 "Buffer Size available in logical channel group 3", HFILL
9327 { &hf_mac_lte_bsr_size_median,
9328 { "Buffer Size Median",
9329 "mac-lte.control.bsr.buffer-size-median", FT_UINT8, BASE_DEC, NULL, 0x0,
9330 NULL, HFILL
9333 { &hf_mac_lte_control_crnti,
9334 { "C-RNTI",
9335 "mac-lte.control.crnti", FT_UINT16, BASE_DEC, NULL, 0x0,
9336 "C-RNTI for the UE", HFILL
9339 { &hf_mac_lte_control_timing_advance,
9340 { "Timing Advance",
9341 "mac-lte.control.timing-advance", FT_STRING, BASE_NONE, NULL, 0x0,
9342 NULL, HFILL
9345 { &hf_mac_lte_control_timing_advance_group_id,
9346 { "Timing Advance Group Identity",
9347 "mac-lte.control.timing-advance.group-id", FT_UINT8, BASE_DEC, NULL, 0xc0,
9348 NULL, HFILL
9351 { &hf_mac_lte_control_timing_advance_command,
9352 { "Timing Advance Command",
9353 "mac-lte.control.timing-advance.command", FT_UINT8, BASE_DEC, NULL, 0x3f,
9354 "Timing Advance (0-63 - see 36.213, 4.2.3)", HFILL
9357 { &hf_mac_lte_control_timing_advance_value_reserved,
9358 { "Reserved",
9359 "mac-lte.control.reserved", FT_UINT16, BASE_DEC, NULL, 0xc000,
9360 NULL, HFILL
9363 { &hf_mac_lte_control_timing_advance_value,
9364 { "Timing Advance",
9365 "mac-lte.control.timing-advance-value", FT_UINT16, BASE_DEC, NULL, 0x3fff,
9366 NULL, HFILL
9369 { &hf_mac_lte_control_as_rai,
9370 { "AS RAI",
9371 "mac-lte.control.as-rai", FT_UINT8, BASE_DEC, VALS(as_rai_vals), 0xc0,
9372 "Access Stratum Release Assistance Indication", HFILL
9375 { &hf_mac_lte_control_as_rai_reserved,
9376 { "Reserved",
9377 "mac-lte.control.as-rai.reserved", FT_UINT8, BASE_DEC, NULL, 0x30,
9378 NULL, HFILL
9381 /* TODO: vals from 36.133. Would need separate vals/field for NB-IoT UE? */
9382 { &hf_mac_lte_control_as_rai_quality_report,
9383 { "Quality Report",
9384 "mac-lte.control.as-rai.quality-report", FT_UINT8, BASE_DEC, NULL, 0x0f,
9385 NULL, HFILL
9388 { &hf_mac_lte_control_ue_contention_resolution,
9389 { "UE Contention Resolution",
9390 "mac-lte.control.ue-contention-resolution", FT_STRING, BASE_NONE, NULL, 0x0,
9391 NULL, HFILL
9394 { &hf_mac_lte_control_ue_contention_resolution_identity,
9395 { "UE Contention Resolution Identity",
9396 "mac-lte.control.ue-contention-resolution.identity", FT_BYTES, BASE_NONE, NULL, 0x0,
9397 NULL, HFILL
9400 { &hf_mac_lte_control_ue_contention_resolution_msg3,
9401 { "Msg3",
9402 "mac-lte.control.ue-contention-resolution.msg3", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
9403 NULL, HFILL
9406 { &hf_mac_lte_control_ue_contention_resolution_msg3_matched,
9407 { "UE Contention Resolution Matches Msg3",
9408 "mac-lte.control.ue-contention-resolution.matches-msg3", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
9409 NULL, HFILL
9412 { &hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
9413 { "Time since Msg3",
9414 "mac-lte.control.ue-contention-resolution.time-since-msg3", FT_UINT32, BASE_DEC, NULL, 0x0,
9415 "Time in ms since corresponding Msg3", HFILL
9418 { &hf_mac_lte_control_msg3_to_cr,
9419 { "CR response",
9420 "mac-lte.msg3-cr-response", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
9421 NULL, HFILL
9425 { &hf_mac_lte_control_power_headroom,
9426 { "Power Headroom Report",
9427 "mac-lte.control.power-headroom", FT_STRING, BASE_NONE, NULL, 0x0,
9428 NULL, HFILL
9431 { &hf_mac_lte_control_power_headroom_reserved,
9432 { "Reserved",
9433 "mac-lte.control.power-headroom.reserved", FT_UINT8, BASE_DEC, NULL, 0xc0,
9434 "Reserved bits, should be 0", HFILL
9437 { &hf_mac_lte_control_power_headroom_level,
9438 { "Power Headroom Level",
9439 "mac-lte.control.power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
9440 &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
9444 { &hf_mac_lte_control_dual_conn_power_headroom,
9445 { "Dual Connectivity Power Headroom Report",
9446 "mac-lte.control.dual-conn-power-headroom", FT_STRING, BASE_NONE,
9447 NULL, 0x0, NULL, HFILL
9450 { &hf_mac_lte_control_dual_conn_power_headroom_c7,
9451 { "SCell Index 7 Power Headroom",
9452 "mac-lte.control.dual-conn-power-headroom.c7", FT_BOOLEAN, 8,
9453 TFS(&scell_ph_tfs), 0x80, NULL, HFILL
9456 { &hf_mac_lte_control_dual_conn_power_headroom_c6,
9457 { "SCell Index 6 Power Headroom",
9458 "mac-lte.control.dual-conn-power-headroom.c6", FT_BOOLEAN, 8,
9459 TFS(&scell_ph_tfs), 0x40, NULL, HFILL
9462 { &hf_mac_lte_control_dual_conn_power_headroom_c5,
9463 { "SCell Index 5 Power Headroom",
9464 "mac-lte.control.dual-conn-power-headroom.c5", FT_BOOLEAN, 8,
9465 TFS(&scell_ph_tfs), 0x20, NULL, HFILL
9468 { &hf_mac_lte_control_dual_conn_power_headroom_c4,
9469 { "SCell Index 4 Power Headroom",
9470 "mac-lte.control.dual-conn-power-headroom.c4", FT_BOOLEAN, 8,
9471 TFS(&scell_ph_tfs), 0x10, NULL, HFILL
9474 { &hf_mac_lte_control_dual_conn_power_headroom_c3,
9475 { "SCell Index 3 Power Headroom",
9476 "mac-lte.control.dual-conn-power-headroom.c3", FT_BOOLEAN, 8,
9477 TFS(&scell_ph_tfs), 0x08, NULL, HFILL
9480 { &hf_mac_lte_control_dual_conn_power_headroom_c2,
9481 { "SCell Index 2 Power Headroom",
9482 "mac-lte.control.dual-conn-power-headroom.c2", FT_BOOLEAN, 8,
9483 TFS(&scell_ph_tfs), 0x04, NULL, HFILL
9486 { &hf_mac_lte_control_dual_conn_power_headroom_c1,
9487 { "SCell Index 1 Power Headroom",
9488 "mac-lte.control.dual-conn-power-headroom.c1", FT_BOOLEAN, 8,
9489 TFS(&scell_ph_tfs), 0x02, NULL, HFILL
9492 { &hf_mac_lte_control_dual_conn_power_headroom_c15,
9493 { "SCell Index 15 Power Headroom",
9494 "mac-lte.control.dual-conn-power-headroom.c15", FT_BOOLEAN, 8,
9495 TFS(&scell_ph_tfs), 0x80, NULL, HFILL
9498 { &hf_mac_lte_control_dual_conn_power_headroom_c14,
9499 { "SCell Index 14 Power Headroom",
9500 "mac-lte.control.dual-conn-power-headroom.c14", FT_BOOLEAN, 8,
9501 TFS(&scell_ph_tfs), 0x40, NULL, HFILL
9504 { &hf_mac_lte_control_dual_conn_power_headroom_c13,
9505 { "SCell Index 13 Power Headroom",
9506 "mac-lte.control.dual-conn-power-headroom.c13", FT_BOOLEAN, 8,
9507 TFS(&scell_ph_tfs), 0x20, NULL, HFILL
9510 { &hf_mac_lte_control_dual_conn_power_headroom_c12,
9511 { "SCell Index 12 Power Headroom",
9512 "mac-lte.control.dual-conn-power-headroom.c12", FT_BOOLEAN, 8,
9513 TFS(&scell_ph_tfs), 0x10, NULL, HFILL
9516 { &hf_mac_lte_control_dual_conn_power_headroom_c11,
9517 { "SCell Index 11 Power Headroom",
9518 "mac-lte.control.dual-conn-power-headroom.c11", FT_BOOLEAN, 8,
9519 TFS(&scell_ph_tfs), 0x08, NULL, HFILL
9522 { &hf_mac_lte_control_dual_conn_power_headroom_c10,
9523 { "SCell Index 10 Power Headroom",
9524 "mac-lte.control.dual-conn-power-headroom.c10", FT_BOOLEAN, 8,
9525 TFS(&scell_ph_tfs), 0x04, NULL, HFILL
9528 { &hf_mac_lte_control_dual_conn_power_headroom_c9,
9529 { "SCell Index 9 Power Headroom",
9530 "mac-lte.control.dual-conn-power-headroom.c9", FT_BOOLEAN, 8,
9531 TFS(&scell_ph_tfs), 0x02, NULL, HFILL
9534 { &hf_mac_lte_control_dual_conn_power_headroom_c8,
9535 { "SCell Index 8 Power Headroom",
9536 "mac-lte.control.dual-conn-power-headroom.c8", FT_BOOLEAN, 8,
9537 TFS(&scell_ph_tfs), 0x01, NULL, HFILL
9540 { &hf_mac_lte_control_dual_conn_power_headroom_c23,
9541 { "SCell Index 23 Power Headroom",
9542 "mac-lte.control.dual-conn-power-headroom.c23", FT_BOOLEAN, 8,
9543 TFS(&scell_ph_tfs), 0x80, NULL, HFILL
9546 { &hf_mac_lte_control_dual_conn_power_headroom_c22,
9547 { "SCell Index 22 Power Headroom",
9548 "mac-lte.control.dual-conn-power-headroom.c22", FT_BOOLEAN, 8,
9549 TFS(&scell_ph_tfs), 0x40, NULL, HFILL
9552 { &hf_mac_lte_control_dual_conn_power_headroom_c21,
9553 { "SCell Index 21 Power Headroom",
9554 "mac-lte.control.dual-conn-power-headroom.c21", FT_BOOLEAN, 8,
9555 TFS(&scell_ph_tfs), 0x20, NULL, HFILL
9558 { &hf_mac_lte_control_dual_conn_power_headroom_c20,
9559 { "SCell Index 20 Power Headroom",
9560 "mac-lte.control.dual-conn-power-headroom.c20", FT_BOOLEAN, 8,
9561 TFS(&scell_ph_tfs), 0x10, NULL, HFILL
9564 { &hf_mac_lte_control_dual_conn_power_headroom_c19,
9565 { "SCell Index 19 Power Headroom",
9566 "mac-lte.control.dual-conn-power-headroom.c19", FT_BOOLEAN, 8,
9567 TFS(&scell_ph_tfs), 0x08, NULL, HFILL
9570 { &hf_mac_lte_control_dual_conn_power_headroom_c18,
9571 { "SCell Index 18 Power Headroom",
9572 "mac-lte.control.dual-conn-power-headroom.c18", FT_BOOLEAN, 8,
9573 TFS(&scell_ph_tfs), 0x04, NULL, HFILL
9576 { &hf_mac_lte_control_dual_conn_power_headroom_c17,
9577 { "SCell Index 17 Power Headroom",
9578 "mac-lte.control.dual-conn-power-headroom.c17", FT_BOOLEAN, 8,
9579 TFS(&scell_ph_tfs), 0x02, NULL, HFILL
9582 { &hf_mac_lte_control_dual_conn_power_headroom_c16,
9583 { "SCell Index 16 Power Headroom",
9584 "mac-lte.control.dual-conn-power-headroom.c16", FT_BOOLEAN, 8,
9585 TFS(&scell_ph_tfs), 0x01, NULL, HFILL
9588 { &hf_mac_lte_control_dual_conn_power_headroom_c31,
9589 { "SCell Index 31 Power Headroom",
9590 "mac-lte.control.dual-conn-power-headroom.c31", FT_BOOLEAN, 8,
9591 TFS(&scell_ph_tfs), 0x80, NULL, HFILL
9594 { &hf_mac_lte_control_dual_conn_power_headroom_c30,
9595 { "SCell Index 30 Power Headroom",
9596 "mac-lte.control.dual-conn-power-headroom.c30", FT_BOOLEAN, 8,
9597 TFS(&scell_ph_tfs), 0x40, NULL, HFILL
9600 { &hf_mac_lte_control_dual_conn_power_headroom_c29,
9601 { "SCell Index 29 Power Headroom",
9602 "mac-lte.control.dual-conn-power-headroom.c29", FT_BOOLEAN, 8,
9603 TFS(&scell_ph_tfs), 0x20, NULL, HFILL
9606 { &hf_mac_lte_control_dual_conn_power_headroom_c28,
9607 { "SCell Index 28 Power Headroom",
9608 "mac-lte.control.dual-conn-power-headroom.c28", FT_BOOLEAN, 8,
9609 TFS(&scell_ph_tfs), 0x10, NULL, HFILL
9612 { &hf_mac_lte_control_dual_conn_power_headroom_c27,
9613 { "SCell Index 27 Power Headroom",
9614 "mac-lte.control.dual-conn-power-headroom.c27", FT_BOOLEAN, 8,
9615 TFS(&scell_ph_tfs), 0x08, NULL, HFILL
9618 { &hf_mac_lte_control_dual_conn_power_headroom_c26,
9619 { "SCell Index 26 Power Headroom",
9620 "mac-lte.control.dual-conn-power-headroom.c26", FT_BOOLEAN, 8,
9621 TFS(&scell_ph_tfs), 0x04, NULL, HFILL
9624 { &hf_mac_lte_control_dual_conn_power_headroom_c25,
9625 { "SCell Index 25 Power Headroom",
9626 "mac-lte.control.dual-conn-power-headroom.c25", FT_BOOLEAN, 8,
9627 TFS(&scell_ph_tfs), 0x02, NULL, HFILL
9630 { &hf_mac_lte_control_dual_conn_power_headroom_c24,
9631 { "SCell Index 24 Power Headroom",
9632 "mac-lte.control.dual-conn-power-headroom.c24", FT_BOOLEAN, 8,
9633 TFS(&scell_ph_tfs), 0x01, NULL, HFILL
9636 { &hf_mac_lte_control_dual_conn_power_headroom_reserved,
9637 { "Reserved",
9638 "mac-lte.control.dual-conn-power-headroom.reserved", FT_UINT8, BASE_DEC,
9639 NULL, 0x01, "Reserved bit, should be 0", HFILL
9642 { &hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
9643 { "Power Backoff",
9644 "mac-lte.control.dual-conn-power-headroom.power-backoff", FT_BOOLEAN, 8,
9645 TFS(&power_backoff_tfs), 0x80, NULL, HFILL
9648 { &hf_mac_lte_control_dual_conn_power_headroom_value,
9649 { "Power Headroom Value",
9650 "mac-lte.control.dual-conn-power-headroom.value", FT_BOOLEAN, 8,
9651 TFS(&ph_value_tfs), 0x40, NULL, HFILL
9654 { &hf_mac_lte_control_dual_conn_power_headroom_level,
9655 { "Power Headroom Level",
9656 "mac-lte.control.dual-conn-power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
9657 &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
9660 { &hf_mac_lte_control_dual_conn_power_headroom_reserved2,
9661 { "Reserved",
9662 "mac-lte.control.dual-conn-power-headroom.reserved2", FT_UINT8, BASE_DEC,
9663 NULL, 0xc0, "Reserved bits, should be 0", HFILL
9666 { &hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
9667 { "Configured UE Transmit Power",
9668 "mac-lte.control.ext-power-headroom.pcmaxc", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
9669 &pcmaxc_vals_ext, 0x3f, "Pcmax,c in dBm", HFILL
9673 { &hf_mac_lte_control_ext_power_headroom,
9674 { "Extended Power Headroom Report",
9675 "mac-lte.control.ext-power-headroom", FT_STRING, BASE_NONE,
9676 NULL, 0x0, NULL, HFILL
9679 { &hf_mac_lte_control_ext_power_headroom_c7,
9680 { "SCell Index 7 Power Headroom",
9681 "mac-lte.control.ext-power-headroom.c7", FT_BOOLEAN, 8,
9682 TFS(&scell_ph_tfs), 0x80, NULL, HFILL
9685 { &hf_mac_lte_control_ext_power_headroom_c6,
9686 { "SCell Index 6 Power Headroom",
9687 "mac-lte.control.ext-power-headroom.c6", FT_BOOLEAN, 8,
9688 TFS(&scell_ph_tfs), 0x40, NULL, HFILL
9691 { &hf_mac_lte_control_ext_power_headroom_c5,
9692 { "SCell Index 5 Power Headroom",
9693 "mac-lte.control.ext-power-headroom.c5", FT_BOOLEAN, 8,
9694 TFS(&scell_ph_tfs), 0x20, NULL, HFILL
9697 { &hf_mac_lte_control_ext_power_headroom_c4,
9698 { "SCell Index 4 Power Headroom",
9699 "mac-lte.control.ext-power-headroom.c4", FT_BOOLEAN, 8,
9700 TFS(&scell_ph_tfs), 0x10, NULL, HFILL
9703 { &hf_mac_lte_control_ext_power_headroom_c3,
9704 { "SCell Index 3 Power Headroom",
9705 "mac-lte.control.ext-power-headroom.c3", FT_BOOLEAN, 8,
9706 TFS(&scell_ph_tfs), 0x08, NULL, HFILL
9709 { &hf_mac_lte_control_ext_power_headroom_c2,
9710 { "SCell Index 2 Power Headroom",
9711 "mac-lte.control.ext-power-headroom.c2", FT_BOOLEAN, 8,
9712 TFS(&scell_ph_tfs), 0x04, NULL, HFILL
9715 { &hf_mac_lte_control_ext_power_headroom_c1,
9716 { "SCell Index 1 Power Headroom",
9717 "mac-lte.control.ext-power-headroom.c1", FT_BOOLEAN, 8,
9718 TFS(&scell_ph_tfs), 0x02, NULL, HFILL
9721 { &hf_mac_lte_control_ext_power_headroom_reserved,
9722 { "Reserved",
9723 "mac-lte.control.ext-power-headroom.reserved", FT_UINT8, BASE_DEC,
9724 NULL, 0x01, "Reserved bit, should be 0", HFILL
9727 { &hf_mac_lte_control_ext_power_headroom_power_backoff,
9728 { "Power Backoff",
9729 "mac-lte.control.ext-power-headroom.power-backoff", FT_BOOLEAN, 8,
9730 TFS(&power_backoff_tfs), 0x80, NULL, HFILL
9733 { &hf_mac_lte_control_ext_power_headroom_value,
9734 { "Power Headroom Value",
9735 "mac-lte.control.ext-power-headroom.value", FT_BOOLEAN, 8,
9736 TFS(&ph_value_tfs), 0x40, NULL, HFILL
9739 { &hf_mac_lte_control_ext_power_headroom_level,
9740 { "Power Headroom Level",
9741 "mac-lte.control.ext-power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
9742 &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
9745 { &hf_mac_lte_control_ext_power_headroom_reserved2,
9746 { "Reserved",
9747 "mac-lte.control.ext-power-headroom.reserved2", FT_UINT8, BASE_DEC,
9748 NULL, 0xc0, "Reserved bits, should be 0", HFILL
9751 { &hf_mac_lte_control_ext_power_headroom_pcmaxc,
9752 { "Configured UE Transmit Power",
9753 "mac-lte.control.ext-power-headroom.pcmaxc", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
9754 &pcmaxc_vals_ext, 0x3f, "Pcmax,c in dBm", HFILL
9758 { &hf_mac_lte_control_activation_deactivation,
9759 { "Activation/Deactivation",
9760 "mac-lte.control.activation-deactivation", FT_STRING, BASE_NONE,
9761 NULL, 0x0, NULL, HFILL
9764 { &hf_mac_lte_control_activation_deactivation_c7,
9765 { "SCell Index 7 Status",
9766 "mac-lte.control.activation-deactivation.c7", FT_BOOLEAN, 8,
9767 TFS(&tfs_activated_deactivated), 0x80, NULL, HFILL
9770 { &hf_mac_lte_control_activation_deactivation_c6,
9771 { "SCell Index 6 Status",
9772 "mac-lte.control.activation-deactivation.c6", FT_BOOLEAN, 8,
9773 TFS(&tfs_activated_deactivated), 0x40, NULL, HFILL
9776 { &hf_mac_lte_control_activation_deactivation_c5,
9777 { "SCell Index 5 Status",
9778 "mac-lte.control.activation-deactivation.c5", FT_BOOLEAN, 8,
9779 TFS(&tfs_activated_deactivated), 0x20, NULL, HFILL
9782 { &hf_mac_lte_control_activation_deactivation_c4,
9783 { "SCell Index 4 Status",
9784 "mac-lte.control.activation-deactivation.c4", FT_BOOLEAN, 8,
9785 TFS(&tfs_activated_deactivated), 0x10, NULL, HFILL
9788 { &hf_mac_lte_control_activation_deactivation_c3,
9789 { "SCell Index 3 Status",
9790 "mac-lte.control.activation-deactivation.c3", FT_BOOLEAN, 8,
9791 TFS(&tfs_activated_deactivated), 0x08, NULL, HFILL
9794 { &hf_mac_lte_control_activation_deactivation_c2,
9795 { "SCell Index 2 Status",
9796 "mac-lte.control.activation-deactivation.c2", FT_BOOLEAN, 8,
9797 TFS(&tfs_activated_deactivated), 0x04, NULL, HFILL
9800 { &hf_mac_lte_control_activation_deactivation_c1,
9801 { "SCell Index 1 Status",
9802 "mac-lte.control.activation-deactivation.c1", FT_BOOLEAN, 8,
9803 TFS(&tfs_activated_deactivated), 0x02, NULL, HFILL
9806 { &hf_mac_lte_control_activation_deactivation_reserved,
9807 { "Reserved",
9808 "mac-lte.control.activation-deactivation.reserved", FT_UINT8, BASE_DEC,
9809 NULL, 0x01, "Reserved bit, should be 0", HFILL
9812 { &hf_mac_lte_control_activation_deactivation_c15,
9813 { "SCell Index 15 Status",
9814 "mac-lte.control.activation-deactivation.c15", FT_BOOLEAN, 8,
9815 TFS(&tfs_activated_deactivated), 0x80, NULL, HFILL
9818 { &hf_mac_lte_control_activation_deactivation_c14,
9819 { "SCell Index 14 Status",
9820 "mac-lte.control.activation-deactivation.c14", FT_BOOLEAN, 8,
9821 TFS(&tfs_activated_deactivated), 0x40, NULL, HFILL
9824 { &hf_mac_lte_control_activation_deactivation_c13,
9825 { "SCell Index 13 Status",
9826 "mac-lte.control.activation-deactivation.c13", FT_BOOLEAN, 8,
9827 TFS(&tfs_activated_deactivated), 0x20, NULL, HFILL
9830 { &hf_mac_lte_control_activation_deactivation_c12,
9831 { "SCell Index 12 Status",
9832 "mac-lte.control.activation-deactivation.c12", FT_BOOLEAN, 8,
9833 TFS(&tfs_activated_deactivated), 0x10, NULL, HFILL
9836 { &hf_mac_lte_control_activation_deactivation_c11,
9837 { "SCell Index 11 Status",
9838 "mac-lte.control.activation-deactivation.c11", FT_BOOLEAN, 8,
9839 TFS(&tfs_activated_deactivated), 0x08, NULL, HFILL
9842 { &hf_mac_lte_control_activation_deactivation_c10,
9843 { "SCell Index 10 Status",
9844 "mac-lte.control.activation-deactivation.c10", FT_BOOLEAN, 8,
9845 TFS(&tfs_activated_deactivated), 0x04, NULL, HFILL
9848 { &hf_mac_lte_control_activation_deactivation_c9,
9849 { "SCell Index 9 Status",
9850 "mac-lte.control.activation-deactivation.c9", FT_BOOLEAN, 8,
9851 TFS(&tfs_activated_deactivated), 0x02, NULL, HFILL
9854 { &hf_mac_lte_control_activation_deactivation_c8,
9855 { "SCell Index 8 Status",
9856 "mac-lte.control.activation-deactivation.c8", FT_BOOLEAN, 8,
9857 TFS(&tfs_activated_deactivated), 0x01, NULL, HFILL
9860 { &hf_mac_lte_control_activation_deactivation_c23,
9861 { "SCell Index 23 Status",
9862 "mac-lte.control.activation-deactivation.c23", FT_BOOLEAN, 8,
9863 TFS(&tfs_activated_deactivated), 0x80, NULL, HFILL
9866 { &hf_mac_lte_control_activation_deactivation_c22,
9867 { "SCell Index 22 Status",
9868 "mac-lte.control.activation-deactivation.c22", FT_BOOLEAN, 8,
9869 TFS(&tfs_activated_deactivated), 0x40, NULL, HFILL
9872 { &hf_mac_lte_control_activation_deactivation_c21,
9873 { "SCell Index 21 Status",
9874 "mac-lte.control.activation-deactivation.c21", FT_BOOLEAN, 8,
9875 TFS(&tfs_activated_deactivated), 0x20, NULL, HFILL
9878 { &hf_mac_lte_control_activation_deactivation_c20,
9879 { "SCell Index 20 Status",
9880 "mac-lte.control.activation-deactivation.c20", FT_BOOLEAN, 8,
9881 TFS(&tfs_activated_deactivated), 0x10, NULL, HFILL
9884 { &hf_mac_lte_control_activation_deactivation_c19,
9885 { "SCell Index 19 Status",
9886 "mac-lte.control.activation-deactivation.c19", FT_BOOLEAN, 8,
9887 TFS(&tfs_activated_deactivated), 0x08, NULL, HFILL
9890 { &hf_mac_lte_control_activation_deactivation_c18,
9891 { "SCell Index 18 Status",
9892 "mac-lte.control.activation-deactivation.c18", FT_BOOLEAN, 8,
9893 TFS(&tfs_activated_deactivated), 0x04, NULL, HFILL
9896 { &hf_mac_lte_control_activation_deactivation_c17,
9897 { "SCell Index 17 Status",
9898 "mac-lte.control.activation-deactivation.c17", FT_BOOLEAN, 8,
9899 TFS(&tfs_activated_deactivated), 0x02, NULL, HFILL
9902 { &hf_mac_lte_control_activation_deactivation_c16,
9903 { "SCell Index 16 Status",
9904 "mac-lte.control.activation-deactivation.c16", FT_BOOLEAN, 8,
9905 TFS(&tfs_activated_deactivated), 0x01, NULL, HFILL
9908 { &hf_mac_lte_control_activation_deactivation_c31,
9909 { "SCell Index 31 Status",
9910 "mac-lte.control.activation-deactivation.c31", FT_BOOLEAN, 8,
9911 TFS(&tfs_activated_deactivated), 0x80, NULL, HFILL
9914 { &hf_mac_lte_control_activation_deactivation_c30,
9915 { "SCell Index 30 Status",
9916 "mac-lte.control.activation-deactivation.c30", FT_BOOLEAN, 8,
9917 TFS(&tfs_activated_deactivated), 0x40, NULL, HFILL
9920 { &hf_mac_lte_control_activation_deactivation_c29,
9921 { "SCell Index 29 Status",
9922 "mac-lte.control.activation-deactivation.c29", FT_BOOLEAN, 8,
9923 TFS(&tfs_activated_deactivated), 0x20, NULL, HFILL
9926 { &hf_mac_lte_control_activation_deactivation_c28,
9927 { "SCell Index 28 Status",
9928 "mac-lte.control.activation-deactivation.c28", FT_BOOLEAN, 8,
9929 TFS(&tfs_activated_deactivated), 0x10, NULL, HFILL
9932 { &hf_mac_lte_control_activation_deactivation_c27,
9933 { "SCell Index 27 Status",
9934 "mac-lte.control.activation-deactivation.c27", FT_BOOLEAN, 8,
9935 TFS(&tfs_activated_deactivated), 0x08, NULL, HFILL
9938 { &hf_mac_lte_control_activation_deactivation_c26,
9939 { "SCell Index 26 Status",
9940 "mac-lte.control.activation-deactivation.c26", FT_BOOLEAN, 8,
9941 TFS(&tfs_activated_deactivated), 0x04, NULL, HFILL
9944 { &hf_mac_lte_control_activation_deactivation_c25,
9945 { "SCell Index 25 Status",
9946 "mac-lte.control.activation-deactivation.c25", FT_BOOLEAN, 8,
9947 TFS(&tfs_activated_deactivated), 0x02, NULL, HFILL
9950 { &hf_mac_lte_control_activation_deactivation_c24,
9951 { "SCell Index 24 Status",
9952 "mac-lte.control.activation-deactivation.c24", FT_BOOLEAN, 8,
9953 TFS(&tfs_activated_deactivated), 0x01, NULL, HFILL
9957 { &hf_mac_lte_control_mch_scheduling_info,
9958 { "MCH Scheduling Information",
9959 "mac-lte.control.mch_scheduling_info", FT_STRING, BASE_NONE, NULL, 0x0,
9960 NULL, HFILL
9963 { &hf_mac_lte_control_mch_scheduling_info_lcid,
9964 { "LCID",
9965 "mac-lte.control.mch_scheduling_info.lcid", FT_UINT8, BASE_HEX, VALS(mch_lcid_vals), 0xf8,
9966 "Logical Channel ID of the MTCH", HFILL
9969 { &hf_mac_lte_control_mch_scheduling_info_stop_mtch,
9970 { "Stop MTCH",
9971 "mac-lte.control.mch_scheduling_info.stop_mtch", FT_UINT16, BASE_DEC, NULL, 0x07ff,
9972 "Ordinal number of the subframe where the corresponding MTCH stops", HFILL
9976 { &hf_mac_lte_control_sidelink_bsr,
9977 { "Sidelink BSR",
9978 "mac-lte.control.sidelink-bsr", FT_STRING, BASE_NONE, NULL, 0x0,
9979 NULL, HFILL
9982 { &hf_mac_lte_control_sidelink_bsr_destination_idx_odd,
9983 { "Destination Index",
9984 "mac-lte.control.sidelink-bsr.destination-idx", FT_UINT8, BASE_DEC, NULL, 0xf0,
9985 NULL, HFILL
9988 { &hf_mac_lte_control_sidelink_bsr_lcg_id_odd,
9989 { "Logical Channel Group ID",
9990 "mac-lte.control.sidelink-bsr.lcg-id", FT_UINT8, BASE_DEC, NULL, 0x0c,
9991 NULL, HFILL
9994 { &hf_mac_lte_control_sidelink_bsr_buffer_size_odd,
9995 { "Buffer Size",
9996 "mac-lte.control.sidelink-bsr.buffer-size", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x03f0,
9997 "Buffer Size available in all channels in group", HFILL
10000 { &hf_mac_lte_control_sidelink_bsr_destination_idx_even,
10001 { "Destination Index",
10002 "mac-lte.control.sidelink-bsr.destination-idx", FT_UINT8, BASE_DEC, NULL, 0x0f,
10003 NULL, HFILL
10006 { &hf_mac_lte_control_sidelink_bsr_lcg_id_even,
10007 { "Logical Channel Group ID",
10008 "mac-lte.control.sidelink-bsr.lcg-id", FT_UINT8, BASE_DEC, NULL, 0xc0,
10009 NULL, HFILL
10012 { &hf_mac_lte_control_sidelink_bsr_buffer_size_even,
10013 { "Buffer Size",
10014 "mac-lte.control.sidelink-bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
10015 "Buffer Size available in all channels in group", HFILL
10018 { &hf_mac_lte_control_sidelink_reserved,
10019 { "Reserved",
10020 "mac-lte.control.sidelink-bsr.reserved", FT_UINT8, BASE_DEC,
10021 NULL, 0x0f, "Reserved bits, should be 0", HFILL
10025 { &hf_mac_lte_control_data_vol_power_headroom,
10026 { "Data Volume and Power Headroom Report",
10027 "mac-lte.control.data-vol-power-headroom", FT_STRING, BASE_NONE, NULL, 0x0,
10028 NULL, HFILL
10031 { &hf_mac_lte_control_data_vol_power_headroom_reserved,
10032 { "Reserved",
10033 "mac-lte.control.data-vol-power-headroom.reserved", FT_UINT8, BASE_DEC,
10034 NULL, 0xc0, "Reserved bits, should be 0", HFILL
10037 { &hf_mac_lte_control_data_vol_power_headroom_level,
10038 { "Power Headroom Level",
10039 "mac-lte.control.data-vol-power-headroom.level", FT_UINT8, BASE_DEC,
10040 VALS(data_vol_power_headroom_level_vals), 0x30, NULL, HFILL
10043 { &hf_mac_lte_control_data_vol_power_headroom_level_4_bits,
10044 { "Power Headroom Level",
10045 "mac-lte.control.data-vol-power-headroom.level", FT_UINT8, BASE_DEC,
10046 VALS(data_vol_extended_power_headroom_level_vals), 0xf0, NULL, HFILL
10049 { &hf_mac_lte_control_data_vol_power_headroom_data_vol,
10050 { "Data Volume",
10051 "mac-lte.control.data-vol-power-headroom.data-vol", FT_UINT8, BASE_DEC,
10052 VALS(data_vol_power_headroom_data_vol_vals), 0x0f, NULL, HFILL
10056 { &hf_mac_lte_control_recommended_bit_rate,
10057 { "Recommended Bit Rate",
10058 "mac-lte.control.recommended-bit-rate", FT_STRING, BASE_NONE,
10059 NULL, 0x0, NULL, HFILL
10062 { &hf_mac_lte_control_recommended_bit_rate_lcid,
10063 { "LCID",
10064 "mac-lte.control.recommended-bit-rate.lcid", FT_UINT8, BASE_DEC,
10065 NULL, 0xf0, NULL, HFILL
10068 { &hf_mac_lte_control_recommended_bit_rate_dir,
10069 { "Direction",
10070 "mac-lte.control.recommended-bit-rate.dir", FT_BOOLEAN, 8,
10071 TFS(&tfs_uplink_downlink), 0x08, NULL, HFILL
10074 { &hf_mac_lte_control_recommended_bit_rate_bit_rate,
10075 { "Bit Rate",
10076 "mac-lte.control.recommended-bit-rate.bit-rate", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
10077 &bit_rate_vals_ext, 0x07e0, NULL, HFILL
10080 { &hf_mac_lte_control_recommended_bit_rate_reserved,
10081 { "Reserved",
10082 "mac-lte.control.recommended-bit-rate.reserved", FT_UINT8, BASE_HEX,
10083 NULL, 0x1f, "Reserved bits, should be 0", HFILL
10087 { &hf_mac_lte_control_recommended_bit_rate_query,
10088 { "Recommended Bit Rate Query",
10089 "mac-lte.control.recommended-bit-rate-query", FT_STRING, BASE_NONE,
10090 NULL, 0x0, NULL, HFILL
10093 { &hf_mac_lte_control_recommended_bit_rate_query_lcid,
10094 { "LCID",
10095 "mac-lte.control.recommended-bit-rate-query.lcid", FT_UINT8, BASE_DEC,
10096 NULL, 0xf0, NULL, HFILL
10099 { &hf_mac_lte_control_recommended_bit_rate_query_dir,
10100 { "Direction",
10101 "mac-lte.control.recommended-bit-rate-query.dir", FT_BOOLEAN, 8,
10102 TFS(&tfs_uplink_downlink), 0x08, NULL, HFILL
10105 { &hf_mac_lte_control_recommended_bit_rate_query_bit_rate,
10106 { "Bit Rate",
10107 "mac-lte.control.recommended-bit-rate-query.bit-rate", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
10108 &bit_rate_vals_ext, 0x07e0, NULL, HFILL
10111 { &hf_mac_lte_control_recommended_bit_rate_query_reserved,
10112 { "Reserved",
10113 "mac-lte.control.recommended-bit-rate-query.reserved", FT_UINT8, BASE_HEX,
10114 NULL, 0x1f, "Reserved bits, should be 0", HFILL
10118 { &hf_mac_lte_control_activation_deactivation_csi_rs,
10119 { "Activation/Deactivation of CSI-RS",
10120 "mac-lte.control.activation-deactivation-csi-rs", FT_STRING, BASE_NONE,
10121 NULL, 0x0, NULL, HFILL
10124 { &hf_mac_lte_control_activation_deactivation_csi_rs_a8,
10125 { "CSI-RS Resource Index 8",
10126 "mac-lte.control.activation-deactivation-csi-rs.a8", FT_BOOLEAN, 8,
10127 TFS(&tfs_activated_deactivated), 0x80, NULL, HFILL
10130 { &hf_mac_lte_control_activation_deactivation_csi_rs_a7,
10131 { "CSI-RS Resource Index 7",
10132 "mac-lte.control.activation-deactivation-csi-rs.a7", FT_BOOLEAN, 8,
10133 TFS(&tfs_activated_deactivated), 0x40, NULL, HFILL
10136 { &hf_mac_lte_control_activation_deactivation_csi_rs_a6,
10137 { "CSI-RS Resource Index 6",
10138 "mac-lte.control.activation-deactivation-csi-rs.a6", FT_BOOLEAN, 8,
10139 TFS(&tfs_activated_deactivated), 0x20, NULL, HFILL
10142 { &hf_mac_lte_control_activation_deactivation_csi_rs_a5,
10143 { "CSI-RS Resource Index 5",
10144 "mac-lte.control.activation-deactivation-csi-rs.a5", FT_BOOLEAN, 8,
10145 TFS(&tfs_activated_deactivated), 0x10, NULL, HFILL
10148 { &hf_mac_lte_control_activation_deactivation_csi_rs_a4,
10149 { "CSI-RS Resource Index 4",
10150 "mac-lte.control.activation-deactivation-csi-rs.a4", FT_BOOLEAN, 8,
10151 TFS(&tfs_activated_deactivated), 0x08, NULL, HFILL
10154 { &hf_mac_lte_control_activation_deactivation_csi_rs_a3,
10155 { "CSI-RS Resource Index 3",
10156 "mac-lte.control.activation-deactivation-csi-rs.a3", FT_BOOLEAN, 8,
10157 TFS(&tfs_activated_deactivated), 0x04, NULL, HFILL
10160 { &hf_mac_lte_control_activation_deactivation_csi_rs_a2,
10161 { "CSI-RS Resource Index 2",
10162 "mac-lte.control.activation-deactivation-csi-rs.a2", FT_BOOLEAN, 8,
10163 TFS(&tfs_activated_deactivated), 0x02, NULL, HFILL
10166 { &hf_mac_lte_control_activation_deactivation_csi_rs_a1,
10167 { "CSI-RS Resource Index 1",
10168 "mac-lte.control.activation-deactivation-csi-rs.a1", FT_BOOLEAN, 8,
10169 TFS(&tfs_activated_deactivated), 0x01, NULL, HFILL
10173 { &hf_mac_lte_control_activation_deactivation_pdcp_dup,
10174 { "Activation/Deactivation of PDCP Duplication",
10175 "mac-lte.control.activation-deactivation-pdcp-dup", FT_STRING, BASE_NONE,
10176 NULL, 0x0, NULL, HFILL
10179 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d8,
10180 { "PDCP Duplication for 8th established DRB",
10181 "mac-lte.control.activation-deactivation-pdcp-dup.d8", FT_BOOLEAN, 8,
10182 TFS(&tfs_activated_deactivated), 0x80, NULL, HFILL
10185 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d7,
10186 { "PDCP Duplication for 7th established DRB",
10187 "mac-lte.control.activation-deactivation-pdcp-dup.d7", FT_BOOLEAN, 8,
10188 TFS(&tfs_activated_deactivated), 0x40, NULL, HFILL
10191 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d6,
10192 { "PDCP Duplication for 6th established DRB",
10193 "mac-lte.control.activation-deactivation-pdcp-dup.d6", FT_BOOLEAN, 8,
10194 TFS(&tfs_activated_deactivated), 0x20, NULL, HFILL
10197 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d5,
10198 { "PDCP Duplication for 5th established DRB",
10199 "mac-lte.control.activation-deactivation-pdcp-dup.d5", FT_BOOLEAN, 8,
10200 TFS(&tfs_activated_deactivated), 0x10, NULL, HFILL
10203 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d4,
10204 { "PDCP Duplication for 4th established DRB",
10205 "mac-lte.control.activation-deactivation-pdcp-dup.d4", FT_BOOLEAN, 8,
10206 TFS(&tfs_activated_deactivated), 0x08, NULL, HFILL
10209 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d3,
10210 { "PDCP Duplication for 3rd established DRB",
10211 "mac-lte.control.activation-deactivation-pdcp-dup.d3", FT_BOOLEAN, 8,
10212 TFS(&tfs_activated_deactivated), 0x04, NULL, HFILL
10215 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d2,
10216 { "PDCP Duplication for 2nd established DRB",
10217 "mac-lte.control.activation-deactivation-pdcp-dup.d2", FT_BOOLEAN, 8,
10218 TFS(&tfs_activated_deactivated), 0x02, NULL, HFILL
10221 { &hf_mac_lte_control_activation_deactivation_pdcp_dup_d1,
10222 { "PDCP Duplication for 1st established DRB",
10223 "mac-lte.control.activation-deactivation-pdcp-dup.d1", FT_BOOLEAN, 8,
10224 TFS(&tfs_activated_deactivated), 0x01, NULL, HFILL
10228 { &hf_mac_lte_control_hibernation,
10229 { "Hibernation",
10230 "mac-lte.control.hibernation", FT_STRING, BASE_NONE,
10231 NULL, 0x0, NULL, HFILL
10234 { &hf_mac_lte_control_hibernation_c7,
10235 { "C7",
10236 "mac-lte.control.hibernation.c7", FT_BOOLEAN, 8,
10237 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10240 { &hf_mac_lte_control_hibernation_c6,
10241 { "C6",
10242 "mac-lte.control.hibernation.c6", FT_BOOLEAN, 8,
10243 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10246 { &hf_mac_lte_control_hibernation_c5,
10247 { "C5",
10248 "mac-lte.control.hibernation.c5", FT_BOOLEAN, 8,
10249 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10252 { &hf_mac_lte_control_hibernation_c4,
10253 { "C4",
10254 "mac-lte.control.hibernation.c4", FT_BOOLEAN, 8,
10255 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10258 { &hf_mac_lte_control_hibernation_c3,
10259 { "C3",
10260 "mac-lte.control.hibernation.c3", FT_BOOLEAN, 8,
10261 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10264 { &hf_mac_lte_control_hibernation_c2,
10265 { "C2",
10266 "mac-lte.control.hibernation.c2", FT_BOOLEAN, 8,
10267 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10270 { &hf_mac_lte_control_hibernation_c1,
10271 { "C1",
10272 "mac-lte.control.hibernation.c1", FT_BOOLEAN, 8,
10273 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10276 { &hf_mac_lte_control_hibernation_reserved,
10277 { "Reserved",
10278 "mac-lte.control.hibernation.reserved", FT_BOOLEAN, 8,
10279 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10282 { &hf_mac_lte_control_hibernation_c15,
10283 { "C15",
10284 "mac-lte.control.hibernation.c15", FT_BOOLEAN, 8,
10285 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10288 { &hf_mac_lte_control_hibernation_c14,
10289 { "C14",
10290 "mac-lte.control.hibernation.c14", FT_BOOLEAN, 8,
10291 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10294 { &hf_mac_lte_control_hibernation_c13,
10295 { "C13",
10296 "mac-lte.control.hibernation.c13", FT_BOOLEAN, 8,
10297 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10300 { &hf_mac_lte_control_hibernation_c12,
10301 { "C12",
10302 "mac-lte.control.hibernation.c12", FT_BOOLEAN, 8,
10303 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10306 { &hf_mac_lte_control_hibernation_c11,
10307 { "C11",
10308 "mac-lte.control.hibernation.c11", FT_BOOLEAN, 8,
10309 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10312 { &hf_mac_lte_control_hibernation_c10,
10313 { "C10",
10314 "mac-lte.control.hibernation.c10", FT_BOOLEAN, 8,
10315 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10318 { &hf_mac_lte_control_hibernation_c9,
10319 { "C9",
10320 "mac-lte.control.hibernation.c9", FT_BOOLEAN, 8,
10321 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10324 { &hf_mac_lte_control_hibernation_c8,
10325 { "C8",
10326 "mac-lte.control.hibernation.c8", FT_BOOLEAN, 8,
10327 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10330 { &hf_mac_lte_control_hibernation_c23,
10331 { "C23",
10332 "mac-lte.control.hibernation.c23", FT_BOOLEAN, 8,
10333 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10336 { &hf_mac_lte_control_hibernation_c22,
10337 { "C22",
10338 "mac-lte.control.hibernation.c22", FT_BOOLEAN, 8,
10339 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10342 { &hf_mac_lte_control_hibernation_c21,
10343 { "C21",
10344 "mac-lte.control.hibernation.c21", FT_BOOLEAN, 8,
10345 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10348 { &hf_mac_lte_control_hibernation_c20,
10349 { "C20",
10350 "mac-lte.control.hibernation.c20", FT_BOOLEAN, 8,
10351 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10354 { &hf_mac_lte_control_hibernation_c19,
10355 { "C19",
10356 "mac-lte.control.hibernation.c19", FT_BOOLEAN, 8,
10357 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10360 { &hf_mac_lte_control_hibernation_c18,
10361 { "C18",
10362 "mac-lte.control.hibernation.c18", FT_BOOLEAN, 8,
10363 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10366 { &hf_mac_lte_control_hibernation_c17,
10367 { "C17",
10368 "mac-lte.control.hibernation.c17", FT_BOOLEAN, 8,
10369 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10372 { &hf_mac_lte_control_hibernation_c16,
10373 { "C16",
10374 "mac-lte.control.hibernation.c16", FT_BOOLEAN, 8,
10375 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10378 { &hf_mac_lte_control_hibernation_c31,
10379 { "C31",
10380 "mac-lte.control.hibernation.c31", FT_BOOLEAN, 8,
10381 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10384 { &hf_mac_lte_control_hibernation_c30,
10385 { "C30",
10386 "mac-lte.control.hibernation.c30", FT_BOOLEAN, 8,
10387 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10390 { &hf_mac_lte_control_hibernation_c29,
10391 { "C29",
10392 "mac-lte.control.hibernation.c29", FT_BOOLEAN, 8,
10393 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10396 { &hf_mac_lte_control_hibernation_c28,
10397 { "C28",
10398 "mac-lte.control.hibernation.c28", FT_BOOLEAN, 8,
10399 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10402 { &hf_mac_lte_control_hibernation_c27,
10403 { "C27",
10404 "mac-lte.control.hibernation.c27", FT_BOOLEAN, 8,
10405 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10408 { &hf_mac_lte_control_hibernation_c26,
10409 { "C26",
10410 "mac-lte.control.hibernation.c26", FT_BOOLEAN, 8,
10411 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10414 { &hf_mac_lte_control_hibernation_c25,
10415 { "C25",
10416 "mac-lte.control.hibernation.c25", FT_BOOLEAN, 8,
10417 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10420 { &hf_mac_lte_control_hibernation_c24,
10421 { "C24",
10422 "mac-lte.control.hibernation.c24", FT_BOOLEAN, 8,
10423 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10426 { &hf_mac_lte_control_aul_confirmation,
10427 { "AUL confirmation",
10428 "mac-lte.control.aul-confirmation", FT_STRING, BASE_NONE,
10429 NULL, 0x0, NULL, HFILL
10432 { &hf_mac_lte_control_aul_confirmation_c7,
10433 { "C7",
10434 "mac-lte.control.aul-confirmation.c7", FT_BOOLEAN, 8,
10435 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10438 { &hf_mac_lte_control_aul_confirmation_c6,
10439 { "C6",
10440 "mac-lte.control.aul-confirmation.c6", FT_BOOLEAN, 8,
10441 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10444 { &hf_mac_lte_control_aul_confirmation_c5,
10445 { "C5",
10446 "mac-lte.control.aul-confirmation.c5", FT_BOOLEAN, 8,
10447 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10450 { &hf_mac_lte_control_aul_confirmation_c4,
10451 { "C4",
10452 "mac-lte.control.aul-confirmation.c4", FT_BOOLEAN, 8,
10453 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10456 { &hf_mac_lte_control_aul_confirmation_c3,
10457 { "C3",
10458 "mac-lte.control.aul-confirmation.c3", FT_BOOLEAN, 8,
10459 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10462 { &hf_mac_lte_control_aul_confirmation_c2,
10463 { "C2",
10464 "mac-lte.control.aul-confirmation.c2", FT_BOOLEAN, 8,
10465 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10468 { &hf_mac_lte_control_aul_confirmation_c1,
10469 { "C1",
10470 "mac-lte.control.aul-confirmation.c1", FT_BOOLEAN, 8,
10471 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10474 { &hf_mac_lte_control_aul_confirmation_reserved,
10475 { "Reserved",
10476 "mac-lte.control.aul-confirmation.reserved", FT_BOOLEAN, 8,
10477 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10480 { &hf_mac_lte_control_aul_confirmation_c15,
10481 { "C15",
10482 "mac-lte.control.aul-confirmation.c15", FT_BOOLEAN, 8,
10483 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10486 { &hf_mac_lte_control_aul_confirmation_c14,
10487 { "C14",
10488 "mac-lte.control.aul-confirmation.c14", FT_BOOLEAN, 8,
10489 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10492 { &hf_mac_lte_control_aul_confirmation_c13,
10493 { "C13",
10494 "mac-lte.control.aul-confirmation.c13", FT_BOOLEAN, 8,
10495 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10498 { &hf_mac_lte_control_aul_confirmation_c12,
10499 { "C12",
10500 "mac-lte.control.aul-confirmation.c12", FT_BOOLEAN, 8,
10501 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10504 { &hf_mac_lte_control_aul_confirmation_c11,
10505 { "C11",
10506 "mac-lte.control.aul-confirmation.c11", FT_BOOLEAN, 8,
10507 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10510 { &hf_mac_lte_control_aul_confirmation_c10,
10511 { "C10",
10512 "mac-lte.control.aul-confirmation.c10", FT_BOOLEAN, 8,
10513 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10516 { &hf_mac_lte_control_aul_confirmation_c9,
10517 { "C9",
10518 "mac-lte.control.aul-confirmation.c9", FT_BOOLEAN, 8,
10519 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10522 { &hf_mac_lte_control_aul_confirmation_c8,
10523 { "C8",
10524 "mac-lte.control.aul-confirmation.c8", FT_BOOLEAN, 8,
10525 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10528 { &hf_mac_lte_control_aul_confirmation_c23,
10529 { "C23",
10530 "mac-lte.control.aul-confirmation.c23", FT_BOOLEAN, 8,
10531 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10534 { &hf_mac_lte_control_aul_confirmation_c22,
10535 { "C22",
10536 "mac-lte.control.aul-confirmation.c22", FT_BOOLEAN, 8,
10537 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10540 { &hf_mac_lte_control_aul_confirmation_c21,
10541 { "C21",
10542 "mac-lte.control.aul-confirmation.c21", FT_BOOLEAN, 8,
10543 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10546 { &hf_mac_lte_control_aul_confirmation_c20,
10547 { "C20",
10548 "mac-lte.control.aul-confirmation.c20", FT_BOOLEAN, 8,
10549 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10552 { &hf_mac_lte_control_aul_confirmation_c19,
10553 { "C19",
10554 "mac-lte.control.aul-confirmation.c19", FT_BOOLEAN, 8,
10555 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10558 { &hf_mac_lte_control_aul_confirmation_c18,
10559 { "C18",
10560 "mac-lte.control.aul-confirmation.c18", FT_BOOLEAN, 8,
10561 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10564 { &hf_mac_lte_control_aul_confirmation_c17,
10565 { "C17",
10566 "mac-lte.control.aul-confirmation.c17", FT_BOOLEAN, 8,
10567 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10570 { &hf_mac_lte_control_aul_confirmation_c16,
10571 { "C16",
10572 "mac-lte.control.aul-confirmation.c16", FT_BOOLEAN, 8,
10573 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10576 { &hf_mac_lte_control_aul_confirmation_c31,
10577 { "C31",
10578 "mac-lte.control.aul-confirmation.c31", FT_BOOLEAN, 8,
10579 TFS(&dormant_activate_tfs), 0x80, NULL, HFILL
10582 { &hf_mac_lte_control_aul_confirmation_c30,
10583 { "C30",
10584 "mac-lte.control.aul-confirmation.c30", FT_BOOLEAN, 8,
10585 TFS(&dormant_activate_tfs), 0x40, NULL, HFILL
10588 { &hf_mac_lte_control_aul_confirmation_c29,
10589 { "C29",
10590 "mac-lte.control.aul-confirmation.c29", FT_BOOLEAN, 8,
10591 TFS(&dormant_activate_tfs), 0x20, NULL, HFILL
10594 { &hf_mac_lte_control_aul_confirmation_c28,
10595 { "C28",
10596 "mac-lte.control.aul-confirmation.c28", FT_BOOLEAN, 8,
10597 TFS(&dormant_activate_tfs), 0x10, NULL, HFILL
10600 { &hf_mac_lte_control_aul_confirmation_c27,
10601 { "C27",
10602 "mac-lte.control.aul-confirmation.c27", FT_BOOLEAN, 8,
10603 TFS(&dormant_activate_tfs), 0x08, NULL, HFILL
10606 { &hf_mac_lte_control_aul_confirmation_c26,
10607 { "C26",
10608 "mac-lte.control.aul-confirmation.c26", FT_BOOLEAN, 8,
10609 TFS(&dormant_activate_tfs), 0x04, NULL, HFILL
10612 { &hf_mac_lte_control_aul_confirmation_c25,
10613 { "C25",
10614 "mac-lte.control.aul-confirmation.c25", FT_BOOLEAN, 8,
10615 TFS(&dormant_activate_tfs), 0x02, NULL, HFILL
10618 { &hf_mac_lte_control_aul_confirmation_c24,
10619 { "C24",
10620 "mac-lte.control.aul-confirmation.c24", FT_BOOLEAN, 8,
10621 TFS(&dormant_activate_tfs), 0x01, NULL, HFILL
10625 /* Generated fields */
10626 { &hf_mac_lte_dl_harq_resend_original_frame,
10627 { "Frame with previous tx",
10628 "mac-lte.dlsch.retx.original-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV), 0x0,
10629 NULL, HFILL
10632 { &hf_mac_lte_dl_harq_resend_time_since_previous_frame,
10633 { "Time since previous tx (ms)",
10634 "mac-lte.dlsch.retx.time-since-previous", FT_UINT16, BASE_DEC, NULL, 0x0,
10635 NULL, HFILL
10638 { &hf_mac_lte_dl_harq_resend_next_frame,
10639 { "Frame with next tx",
10640 "mac-lte.dlsch.retx.next-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_NEXT), 0x0,
10641 NULL, HFILL
10644 { &hf_mac_lte_dl_harq_resend_time_until_next_frame,
10645 { "Time until next tx (ms)",
10646 "mac-lte.dlsch.retx.time-until-next", FT_UINT16, BASE_DEC, NULL, 0x0,
10647 NULL, HFILL
10651 { &hf_mac_lte_ul_harq_resend_original_frame,
10652 { "Frame with previous tx",
10653 "mac-lte.ulsch.retx.original-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV), 0x0,
10654 NULL, HFILL
10657 { &hf_mac_lte_ul_harq_resend_time_since_previous_frame,
10658 { "Time since previous tx (ms)",
10659 "mac-lte.ulsch.retx.time-since-previous", FT_UINT16, BASE_DEC, NULL, 0x0,
10660 NULL, HFILL
10663 { &hf_mac_lte_ul_harq_resend_next_frame,
10664 { "Frame with next tx",
10665 "mac-lte.ulsch.retx.next-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_NEXT), 0x0,
10666 NULL, HFILL
10669 { &hf_mac_lte_ul_harq_resend_time_until_next_frame,
10670 { "Time until next tx (ms)",
10671 "mac-lte.ulsch.retx.time-until-next", FT_UINT16, BASE_DEC, NULL, 0x0,
10672 NULL, HFILL
10676 { &hf_mac_lte_grant_answering_sr,
10677 { "First Grant Following SR from",
10678 "mac-lte.ulsch.grant-answering-sr", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
10679 NULL, HFILL
10682 { &hf_mac_lte_failure_answering_sr,
10683 { "SR which failed",
10684 "mac-lte.ulsch.failure-answering-sr", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
10685 NULL, HFILL
10688 { &hf_mac_lte_sr_leading_to_failure,
10689 { "This SR fails",
10690 "mac-lte.ulsch.failure-answering-sr-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
10691 NULL, HFILL
10694 { &hf_mac_lte_sr_leading_to_grant,
10695 { "This SR results in a grant here",
10696 "mac-lte.ulsch.grant-answering-sr-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
10697 NULL, HFILL
10700 { &hf_mac_lte_sr_time_since_request,
10701 { "Time since SR (ms)",
10702 "mac-lte.ulsch.time-since-sr", FT_UINT32, BASE_DEC, NULL, 0x0,
10703 NULL, HFILL
10706 { &hf_mac_lte_sr_time_until_answer,
10707 { "Time until answer (ms)",
10708 "mac-lte.ulsch.time-until-sr-answer", FT_UINT32, BASE_DEC, NULL, 0x0,
10709 NULL, HFILL
10713 { &hf_mac_lte_drx_config,
10714 { "DRX Configuration",
10715 "mac-lte.drx-config", FT_STRING, BASE_NONE,
10716 NULL, 0x0, NULL, HFILL
10719 { &hf_mac_lte_drx_config_frame_num,
10720 { "Config Frame",
10721 "mac-lte.drx-config.config-frame", FT_FRAMENUM, BASE_NONE,
10722 NULL, 0x0, NULL, HFILL
10725 { &hf_mac_lte_drx_config_previous_frame_num,
10726 { "Previous Config Frame",
10727 "mac-lte.drx-config.previous-config-frame", FT_FRAMENUM, BASE_NONE,
10728 NULL, 0x0, NULL, HFILL
10731 { &hf_mac_lte_drx_config_long_cycle,
10732 { "Long cycle",
10733 "mac-lte.drx-config.long-cycle", FT_UINT16, BASE_DEC,
10734 NULL, 0x0, NULL, HFILL
10737 { &hf_mac_lte_drx_config_cycle_offset,
10738 { "Cycle offset",
10739 "mac-lte.drx-config.cycle-offset", FT_UINT16, BASE_DEC,
10740 NULL, 0x0, NULL, HFILL
10743 { &hf_mac_lte_drx_config_onduration_timer,
10744 { "OnDuration Timer",
10745 "mac-lte.drx-config.onduration-timer", FT_UINT16, BASE_DEC,
10746 NULL, 0x0, NULL, HFILL
10749 { &hf_mac_lte_drx_config_inactivity_timer,
10750 { "Inactivity Timer",
10751 "mac-lte.drx-config.inactivity-timer", FT_UINT16, BASE_DEC,
10752 NULL, 0x0, NULL, HFILL
10755 { &hf_mac_lte_drx_config_retransmission_timer,
10756 { "Retransmission Timer",
10757 "mac-lte.drx-config.retransmission-timer", FT_UINT16, BASE_DEC,
10758 NULL, 0x0, NULL, HFILL
10761 { &hf_mac_lte_drx_config_short_cycle,
10762 { "Short cycle",
10763 "mac-lte.drx-config.short-cycle", FT_UINT16, BASE_DEC,
10764 NULL, 0x0, NULL, HFILL
10767 { &hf_mac_lte_drx_config_short_cycle_timer,
10768 { "Short cycle Timer",
10769 "mac-lte.drx-config.short-cycle-timer", FT_UINT16, BASE_DEC,
10770 NULL, 0x0, NULL, HFILL
10774 { &hf_mac_lte_drx_state,
10775 { "DRX State",
10776 "mac-lte.drx-state", FT_STRING, BASE_NONE,
10777 NULL, 0x0, NULL, HFILL
10780 { &hf_mac_lte_drx_state_long_cycle_offset,
10781 { "Long cycle offset",
10782 "mac-lte.drx-state.long-cycle-offset", FT_UINT16, BASE_DEC,
10783 NULL, 0x0, NULL, HFILL
10786 { &hf_mac_lte_drx_state_short_cycle_offset,
10787 { "Short cycle offset",
10788 "mac-lte.drx-state.short-cycle-offset", FT_UINT16, BASE_DEC,
10789 NULL, 0x0, NULL, HFILL
10792 { &hf_mac_lte_drx_state_inactivity_remaining,
10793 { "Inactivity remaining",
10794 "mac-lte.drx-state.inactivity-remaining", FT_UINT16, BASE_DEC,
10795 NULL, 0x0, NULL, HFILL
10798 { &hf_mac_lte_drx_state_onduration_remaining,
10799 { "Onduration remaining",
10800 "mac-lte.drx-state.onduration-remaining", FT_UINT16, BASE_DEC,
10801 NULL, 0x0, NULL, HFILL
10804 { &hf_mac_lte_drx_state_retransmission_remaining,
10805 { "Retransmission remaining",
10806 "mac-lte.drx-state.retransmission-remaining", FT_UINT16, BASE_DEC,
10807 NULL, 0x0, NULL, HFILL
10810 { &hf_mac_lte_drx_state_rtt_remaining,
10811 { "RTT remaining",
10812 "mac-lte.drx-state.rtt-remaining", FT_UINT16, BASE_DEC,
10813 NULL, 0x0, NULL, HFILL
10816 { &hf_mac_lte_drx_state_short_cycle_remaining,
10817 { "Short-cycle timer remaining",
10818 "mac-lte.drx-state.short-cycle-remaining", FT_UINT16, BASE_DEC,
10819 NULL, 0x0, NULL, HFILL
10824 static int *ett[] =
10826 &ett_mac_lte,
10827 &ett_mac_lte_context,
10828 &ett_mac_lte_phy_context,
10829 &ett_mac_lte_rar_headers,
10830 &ett_mac_lte_rar_header,
10831 &ett_mac_lte_rar_body,
10832 &ett_mac_lte_rar_ul_grant,
10833 &ett_mac_lte_ulsch_header,
10834 &ett_mac_lte_dlsch_header,
10835 &ett_mac_lte_mch_header,
10836 &ett_mac_lte_sch_subheader,
10837 &ett_mac_lte_mch_subheader,
10838 &ett_mac_lte_slsch_header,
10839 &ett_mac_lte_slsch_subheader,
10840 &ett_mac_lte_bch,
10841 &ett_mac_lte_bsr,
10842 &ett_mac_lte_pch,
10843 &ett_mac_lte_activation_deactivation,
10844 &ett_mac_lte_contention_resolution,
10845 &ett_mac_lte_timing_advance,
10846 &ett_mac_lte_power_headroom,
10847 &ett_mac_lte_dual_conn_power_headroom,
10848 &ett_mac_lte_dual_conn_power_headroom_cell,
10849 &ett_mac_lte_extended_power_headroom,
10850 &ett_mac_lte_extended_power_headroom_cell,
10851 &ett_mac_lte_mch_scheduling_info,
10852 &ett_mac_lte_oob,
10853 &ett_mac_lte_drx_config,
10854 &ett_mac_lte_drx_state,
10855 &ett_mac_lte_sidelink_bsr,
10856 &ett_mac_lte_data_vol_power_headroom,
10857 &ett_mac_lte_recommended_bit_rate,
10858 &ett_mac_lte_recommended_bit_rate_query,
10859 &ett_mac_lte_activation_deactivation_csi_rs,
10860 &ett_mac_lte_activation_deactivation_pdcp_dup,
10861 &ett_mac_lte_hibernation,
10862 &ett_mac_lte_aul_confirmation
10865 static ei_register_info ei[] = {
10866 { &ei_mac_lte_reserved_not_zero, { "mac-lte.reserved-not-zero", PI_MALFORMED, PI_ERROR, "Reserved bit not zero", EXPFILL }},
10867 { &ei_mac_lte_rar_timing_advance_not_zero_note, { "mac-lte.rar.ta.not-zero", PI_SEQUENCE, PI_NOTE, "RAR Timing advance not zero", EXPFILL }},
10868 { &ei_mac_lte_rar_timing_advance_not_zero_warn, { "mac-lte.rar.ta.not-zero", PI_SEQUENCE, PI_WARN, "RAR Timing advance not zero", EXPFILL }},
10869 { &ei_mac_lte_rar_bi_present, { "mac-lte.rar.bi.present", PI_MALFORMED, PI_ERROR, "MAC RAR PDU has > 1 Backoff Indicator subheader present", EXPFILL }},
10870 { &ei_mac_lte_rar_bi_not_first_subheader, { "mac-lte.rar.bi.not-first-subheader", PI_MALFORMED, PI_WARN, "Backoff Indicator must appear as first subheader", EXPFILL }},
10871 { &ei_mac_lte_bch_pdu, { "mac-lte.bch.pdu.uplink", PI_MALFORMED, PI_ERROR, "BCH data should not be received in Uplink!", EXPFILL }},
10872 { &ei_mac_lte_pch_pdu, { "mac-lte.pch.pdu.uplink", PI_MALFORMED, PI_ERROR, "PCH data should not be received in Uplink!", EXPFILL }},
10873 { &ei_mac_lte_orig_tx_ul_frame_not_found, { "mac-lte.orig-tx-ul-frame-not-found", PI_SEQUENCE, PI_ERROR, "Original Tx of UL frame not found", EXPFILL }},
10874 { &ei_mac_lte_ul_harq_resend_next_frame, { "mac-lte.ulsch.retx.next-frame.expert", PI_SEQUENCE, PI_WARN, "UL MAC PDU needed to be retransmitted", EXPFILL }},
10875 { &ei_mac_lte_sr_results_not_grant_or_failure_indication, { "mac-lte.sr_results-not-grant-or-failure-indication", PI_SEQUENCE, PI_ERROR, "SR results in neither a grant nor a failure indication", EXPFILL }},
10876 { &ei_mac_lte_sr_invalid_event, { "mac-lte.ulsch.sr-invalid-event", PI_SEQUENCE, PI_ERROR, "Invalid SR event for UE", EXPFILL }},
10877 { &ei_mac_lte_dlsch_lcid, { "mac-lte.dlsch.lcid.DRX-received", PI_SEQUENCE, PI_NOTE, "DRX command received for UE", EXPFILL }},
10878 { &ei_mac_lte_control_subheader_after_data_subheader, { "mac-lte.control-subheader-after-data-subheader", PI_MALFORMED, PI_ERROR, "?L-SCH Control subheaders should not appear after data subheaders", EXPFILL }},
10879 { &ei_mac_lte_control_bsr_multiple, { "mac-lte.control.bsr.multiple", PI_MALFORMED, PI_ERROR, "There shouldn't be > 1 BSR in a frame", EXPFILL }},
10880 { &ei_mac_lte_padding_data_multiple, { "mac-lte.padding-data.multiple", PI_MALFORMED, PI_WARN, "Should not see more than 2 padding subheaders in one frame", EXPFILL }},
10881 { &ei_mac_lte_padding_data_before_control_subheader, { "mac-lte.padding-data.before-control-subheader", PI_MALFORMED, PI_ERROR, "Padding should come before other control subheaders!", EXPFILL }},
10882 { &ei_mac_lte_padding_data_start_and_end, { "mac-lte.padding-data.start-and-end", PI_MALFORMED, PI_ERROR, "Padding subheaders at start and end!", EXPFILL }},
10883 { &ei_mac_lte_lcid_unexpected, { "mac-lte.lcid-unexpected", PI_MALFORMED, PI_ERROR, "?L-SCH: Unexpected LCID received", EXPFILL }},
10884 { &ei_mac_lte_too_many_subheaders, { "mac-lte.too-many-subheaders", PI_MALFORMED, PI_ERROR, "Reached too many subheaders - frame obviously malformed", EXPFILL }},
10885 { &ei_mac_lte_control_ue_contention_resolution_msg3_matched, { "mac-lte.control.ue-contention-resolution.matches-msg3.not", PI_SEQUENCE, PI_WARN, "CR body in Msg4 doesn't match Msg3 CCCH in frame X", EXPFILL }},
10886 { &ei_mac_lte_control_timing_advance_command_no_correction, { "mac-lte.control.timing-advance.command.no-correction", PI_SEQUENCE, PI_NOTE, "Timing Advance control element received (no correction needed)", EXPFILL }},
10887 { &ei_mac_lte_control_timing_advance_command_correction_needed, { "mac-lte.control.timing-advance.correction-needed", PI_SEQUENCE, PI_WARN, "Timing Advance control element received with correction needed", EXPFILL }},
10888 { &ei_mac_lte_control_element_size_invalid, { "mac-lte.control-element.size-invalid", PI_MALFORMED, PI_ERROR, "Control Element has an unexpected size", EXPFILL }},
10889 { &ei_mac_lte_bsr_warn_threshold_exceeded, { "mac-lte.bsr-warn-threshold-exceeded", PI_SEQUENCE, PI_WARN, "BSR for LCG X exceeds threshold", EXPFILL }},
10890 { &ei_mac_lte_sch_header_only_truncated, { "mac-lte.sch.header-only-truncated", PI_SEQUENCE, PI_NOTE, "MAC PDU SDUs have been omitted", EXPFILL }},
10891 { &ei_mac_lte_mch_header_only_truncated, { "mac-lte.mch.header-only-truncated", PI_SEQUENCE, PI_NOTE, "MAC MCH PDU SDUs have been omitted", EXPFILL }},
10892 { &ei_mac_lte_slsch_header_only_truncated, { "mac-lte.slsch.header-only-truncated", PI_SEQUENCE, PI_NOTE, "MAC PDU SDUs have been omitted", EXPFILL }},
10893 { &ei_mac_lte_context_length, { "mac-lte.length.invalid", PI_MALFORMED, PI_ERROR, "MAC PDU is longer than reported length", EXPFILL }},
10894 { &ei_mac_lte_rach_preamble_sent_warn, { "mac-lte.rach-preamble-sent", PI_SEQUENCE, PI_WARN, "RACH Preamble sent", EXPFILL }},
10895 { &ei_mac_lte_rach_preamble_sent_note, { "mac-lte.rach-preamble-sent", PI_SEQUENCE, PI_NOTE, "RACH Preamble sent", EXPFILL }},
10896 { &ei_mac_lte_oob_send_sr, { "mac-lte.sr-req", PI_SEQUENCE, PI_NOTE, "Scheduling Request sent", EXPFILL }},
10897 { &ei_mac_lte_oob_sr_failure, { "mac-lte.sr-failure", PI_SEQUENCE, PI_ERROR, "Scheduling Request failed", EXPFILL }},
10898 { &ei_mac_lte_context_sysframe_number, { "mac-lte.sfn.out-of-range", PI_MALFORMED, PI_ERROR, "Sysframe number out of range", EXPFILL }},
10899 { &ei_mac_lte_context_rnti_type, { "mac-lte.rnti-type.invalid", PI_MALFORMED, PI_ERROR, "RNTI indicated, but value is not correct", EXPFILL }},
10900 { &ei_mac_lte_ul_mac_frame_retx, { "mac-lte.ul-mac-frame-retx", PI_SEQUENCE, PI_WARN, "UL MAC frame ReTX", EXPFILL }},
10901 { &ei_mac_lte_context_crc_status, { "mac-lte.crc-status.error", PI_MALFORMED, PI_ERROR, "Frame has CRC error problem", EXPFILL }},
10902 { &ei_mac_lte_no_per_frame_data, { "mac-lte.no_per_frame_data", PI_UNDECODED, PI_WARN, "Can't dissect LTE MAC frame because no per-frame info was attached!", EXPFILL }},
10903 { &ei_mac_lte_sch_invalid_length, { "mac-lte.sch.invalid-length", PI_MALFORMED, PI_WARN, "Invalid PDU length (should be >= 32768)", EXPFILL }},
10904 { &ei_mac_lte_mch_invalid_length, { "mac-lte.mch.invalid-length", PI_MALFORMED, PI_WARN, "Invalid MCH PDU length (should be >= 32768)", EXPFILL }},
10905 { &ei_mac_lte_invalid_sc_mcch_sc_mtch_subheader_multiplexing, { "mac-lte.mch.invalid-sc-mcch-sc-mtch-subheader-multiplexing", PI_MALFORMED, PI_ERROR, "SC-MCCH/SC-MTCH header multiplexed with non padding", EXPFILL }},
10906 { &ei_mac_lte_unknown_udp_framing_tag, { "mac-lte.unknown-udp-framing-tag", PI_UNDECODED, PI_WARN, "Unknown UDP framing tag, aborting dissection", EXPFILL }}
10909 static const enum_val_t show_info_col_vals[] = {
10910 {"show-phy", "PHY Info", ShowPHYLayer},
10911 {"show-mac", "MAC Info", ShowMACLayer},
10912 {"show-rlc", "RLC Info", ShowRLCLayer},
10913 {NULL, NULL, -1}
10916 static const enum_val_t lcid_drb_source_vals[] = {
10917 {"from-static-stable", "From static table", FromStaticTable},
10918 {"from-configuration-protocol", "From configuration protocol", FromConfigurationProtocol},
10919 {NULL, NULL, -1}
10923 module_t *mac_lte_module;
10924 expert_module_t* expert_mac_lte;
10926 static uat_field_t lcid_drb_mapping_flds[] = {
10927 UAT_FLD_VS(lcid_drb_mappings, lcid, "lcid", drb_lcid_vals, "The MAC LCID"),
10928 UAT_FLD_DEC(lcid_drb_mappings, drbid,"drb id (1-32)", "Identifier of logical data channel"),
10929 UAT_FLD_VS(lcid_drb_mappings, channel_type, "RLC Channel Type", rlc_channel_type_vals, "The MAC LCID"),
10930 UAT_END_FIELDS
10933 /* Register protocol. */
10934 proto_mac_lte = proto_register_protocol("MAC-LTE", "MAC-LTE", "mac-lte");
10935 proto_register_field_array(proto_mac_lte, hf, array_length(hf));
10936 proto_register_subtree_array(ett, array_length(ett));
10937 expert_mac_lte = expert_register_protocol(proto_mac_lte);
10938 expert_register_field_array(expert_mac_lte, ei, array_length(ei));
10940 /* Allow other dissectors to find this one by name. */
10941 register_dissector("mac-lte", dissect_mac_lte, proto_mac_lte);
10943 /* Register the tap name */
10944 mac_lte_tap = register_tap("mac-3gpp");
10946 /* Preferences */
10947 mac_lte_module = prefs_register_protocol(proto_mac_lte, NULL);
10949 /* Obsolete preferences */
10950 prefs_register_obsolete_preference(mac_lte_module, "single_rar");
10951 prefs_register_obsolete_preference(mac_lte_module, "check_reserved_bits");
10952 prefs_register_obsolete_preference(mac_lte_module, "decode_rar_ul_grant");
10953 prefs_register_obsolete_preference(mac_lte_module, "show_rlc_info_column");
10954 prefs_register_obsolete_preference(mac_lte_module, "attempt_to_detect_dl_harq_resend");
10955 prefs_register_obsolete_preference(mac_lte_module, "attempt_to_track_ul_harq_resend");
10957 prefs_register_uint_preference(mac_lte_module, "retx_count_warn",
10958 "Number of Re-Transmits before expert warning triggered",
10959 "Number of Re-Transmits before expert warning triggered",
10960 10, &global_mac_lte_retx_counter_trigger);
10962 prefs_register_bool_preference(mac_lte_module, "attempt_rrc_decode",
10963 "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
10964 "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
10965 &global_mac_lte_attempt_rrc_decode);
10967 prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_crc_failures",
10968 "Dissect frames that have failed CRC check",
10969 "Attempt to dissect frames that have failed CRC check",
10970 &global_mac_lte_dissect_crc_failures);
10972 prefs_register_obsolete_preference(mac_lte_module, "heuristic_mac_lte_over_udp");
10974 prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_srb_sdus",
10975 "Attempt to dissect LCID 1&2 as srb1&2",
10976 "Will call LTE RLC dissector with standard settings as per RRC spec",
10977 &global_mac_lte_attempt_srb_decode);
10979 prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_mcch",
10980 "Attempt to dissect MCH LCID 0 as MCCH",
10981 "Will call LTE RLC dissector for MCH LCID 0",
10982 &global_mac_lte_attempt_mcch_decode);
10984 prefs_register_bool_preference(mac_lte_module, "call_rlc_for_mtch",
10985 "Call RLC dissector MTCH LCIDs",
10986 "Call RLC dissector MTCH LCIDs",
10987 &global_mac_lte_call_rlc_for_mtch);
10989 prefs_register_enum_preference(mac_lte_module, "lcid_to_drb_mapping_source",
10990 "Source of LCID -> drb channel settings",
10991 "Set whether LCID -> drb Table is taken from static table (below) or from "
10992 "info learned from control protocol (e.g. RRC)",
10993 &global_mac_lte_lcid_drb_source, lcid_drb_source_vals, false);
10995 lcid_drb_mappings_uat = uat_new("Static LCID -> drb Table",
10996 sizeof(lcid_drb_mapping_t),
10997 "drb_logchans",
10998 true,
10999 &lcid_drb_mappings,
11000 &num_lcid_drb_mappings,
11001 UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
11002 "", /* TODO: is this ref to help manual? */
11003 lcid_drb_mapping_copy_cb,
11004 NULL,
11005 NULL,
11006 NULL,
11007 NULL,
11008 lcid_drb_mapping_flds );
11010 prefs_register_uat_preference(mac_lte_module,
11011 "drb_table",
11012 "LCID -> DRB Mappings Table",
11013 "A table that maps from configurable lcids -> RLC logical channels",
11014 lcid_drb_mappings_uat);
11016 prefs_register_uint_preference(mac_lte_module, "bsr_warn_threshold",
11017 "BSR size when warning should be issued (0 - 63)",
11018 "If any BSR report is >= this number, an expert warning will be added",
11019 10, &global_mac_lte_bsr_warn_threshold);
11021 prefs_register_bool_preference(mac_lte_module, "track_sr",
11022 "Track status of SRs within UEs",
11023 "Track status of SRs, providing links between requests, failure indications and grants",
11024 &global_mac_lte_track_sr);
11026 prefs_register_enum_preference(mac_lte_module, "layer_to_show",
11027 "Which layer info to show in Info column",
11028 "Can show PHY, MAC or RLC layer info in Info column",
11029 &global_mac_lte_layer_to_show, show_info_col_vals, false);
11031 prefs_register_bool_preference(mac_lte_module, "decode_cr_body",
11032 "Decode CR body as UL CCCH",
11033 "Attempt to decode 6 bytes of Contention Resolution body as an UL CCCH PDU",
11034 &global_mac_lte_decode_cr_body);
11036 prefs_register_bool_preference(mac_lte_module, "show_drx",
11037 "Show DRX Information (Incomplete/experimental!)",
11038 "Apply DRX config and show DRX state within each UE",
11039 &global_mac_lte_show_drx);
11041 prefs_register_bool_preference(mac_lte_module, "show_bsr_median",
11042 "Show BSR Median value",
11043 "Add as a generated field the middle of the range indicated by the BSR index",
11044 &global_mac_lte_show_BSR_median);
11046 register_init_routine(&mac_lte_init_protocol);
11047 register_cleanup_routine(&mac_lte_cleanup_protocol);
11050 void proto_reg_handoff_mac_lte(void)
11052 /* Add as a heuristic UDP dissector */
11053 heur_dissector_add("udp", dissect_mac_lte_heur, "MAC-LTE over UDP", "mac_lte_udp", proto_mac_lte, HEURISTIC_DISABLE);
11055 rlc_lte_handle = find_dissector_add_dependency("rlc-lte", proto_mac_lte);
11056 lte_rrc_bcch_dl_sch_handle = find_dissector_add_dependency("lte_rrc.bcch_dl_sch", proto_mac_lte);
11057 lte_rrc_bcch_dl_sch_br_handle = find_dissector_add_dependency("lte_rrc.bcch_dl_sch_br", proto_mac_lte);
11058 lte_rrc_bcch_dl_sch_nb_handle = find_dissector_add_dependency("lte_rrc.bcch_dl_sch.nb", proto_mac_lte);
11059 lte_rrc_bcch_bch_handle = find_dissector_add_dependency("lte_rrc.bcch_bch", proto_mac_lte);
11060 lte_rrc_bcch_bch_nb_handle = find_dissector_add_dependency("lte_rrc.bcch_bch.nb", proto_mac_lte);
11061 lte_rrc_pcch_handle = find_dissector_add_dependency("lte_rrc.pcch", proto_mac_lte);
11062 lte_rrc_pcch_nb_handle = find_dissector_add_dependency("lte_rrc.pcch.nb", proto_mac_lte);
11063 lte_rrc_ul_ccch_handle = find_dissector_add_dependency("lte_rrc.ul_ccch", proto_mac_lte);
11064 lte_rrc_ul_ccch_nb_handle = find_dissector_add_dependency("lte_rrc.ul_ccch.nb", proto_mac_lte);
11065 lte_rrc_dl_ccch_handle = find_dissector_add_dependency("lte_rrc.dl_ccch", proto_mac_lte);
11066 lte_rrc_dl_ccch_nb_handle = find_dissector_add_dependency("lte_rrc.dl_ccch.nb", proto_mac_lte);
11067 lte_rrc_sbcch_sl_bch_handle = find_dissector_add_dependency("lte_rrc.sbcch_sl_bch", proto_mac_lte);
11068 lte_rrc_sc_mcch_handle = find_dissector_add_dependency("lte_rrc.sc_mcch", proto_mac_lte);
11072 * Editor modelines - https://www.wireshark.org/tools/modelines.html
11074 * Local variables:
11075 * c-basic-offset: 4
11076 * tab-width: 8
11077 * indent-tabs-mode: nil
11078 * End:
11080 * vi: set shiftwidth=4 tabstop=8 expandtab:
11081 * :indentSize=4:tabSize=8:noTabs=true: