1 /* Routines for LTE MAC disassembly
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
14 #include <epan/packet.h>
15 #include <epan/exceptions.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
20 #include <epan/proto_data.h>
21 #include "packet-mac-lte.h"
22 #include "packet-rlc-lte.h"
24 void proto_register_mac_lte(void);
25 void proto_reg_handoff_mac_lte(void);
28 * 3GPP TS 36.321 Evolved Universal Terrestrial Radio Access (E-UTRA)
29 * Medium Access Control (MAC) protocol specification v14.3.0
33 /* Initialize the protocol and registered fields. */
34 int proto_mac_lte = -1;
36 static int mac_lte_tap = -1;
38 static dissector_handle_t rlc_lte_handle;
39 static dissector_handle_t lte_rrc_bcch_dl_sch_handle;
40 static dissector_handle_t lte_rrc_bcch_dl_sch_br_handle;
41 static dissector_handle_t lte_rrc_bcch_dl_sch_nb_handle;
42 static dissector_handle_t lte_rrc_bcch_bch_handle;
43 static dissector_handle_t lte_rrc_bcch_bch_nb_handle;
44 static dissector_handle_t lte_rrc_pcch_handle;
45 static dissector_handle_t lte_rrc_pcch_nb_handle;
46 static dissector_handle_t lte_rrc_ul_ccch_handle;
47 static dissector_handle_t lte_rrc_ul_ccch_nb_handle;
48 static dissector_handle_t lte_rrc_dl_ccch_handle;
49 static dissector_handle_t lte_rrc_dl_ccch_nb_handle;
50 static dissector_handle_t lte_rrc_sbcch_sl_bch_handle;
51 static dissector_handle_t lte_rrc_sc_mcch_handle;
54 /* Decoding context */
55 static int hf_mac_lte_context = -1;
56 static int hf_mac_lte_context_radio_type = -1;
57 static int hf_mac_lte_context_direction = -1;
58 static int hf_mac_lte_context_rnti = -1;
59 static int hf_mac_lte_context_rnti_type = -1;
60 static int hf_mac_lte_context_ueid = -1;
61 static int hf_mac_lte_context_sysframe_number = -1;
62 static int hf_mac_lte_context_subframe_number = -1;
63 static int hf_mac_lte_context_grant_subframe_number = -1;
64 static int hf_mac_lte_context_predefined_frame = -1;
65 static int hf_mac_lte_context_length = -1;
66 static int hf_mac_lte_context_ul_grant_size = -1;
67 static int hf_mac_lte_context_bch_transport_channel = -1;
68 static int hf_mac_lte_context_retx_count = -1;
69 static int hf_mac_lte_context_retx_reason = -1;
70 static int hf_mac_lte_context_crc_status = -1;
71 static int hf_mac_lte_context_carrier_id = -1;
73 static int hf_mac_lte_context_rapid = -1;
74 static int hf_mac_lte_context_rach_attempt_number = -1;
76 /* Inferred context */
77 static int hf_mac_lte_ues_ul_per_tti = -1;
78 static int hf_mac_lte_ues_dl_per_tti = -1;
81 /* Extra PHY context */
82 static int hf_mac_lte_context_phy_ul = -1;
83 static int hf_mac_lte_context_phy_ul_modulation_type = -1;
84 static int hf_mac_lte_context_phy_ul_tbs_index = -1;
85 static int hf_mac_lte_context_phy_ul_resource_block_length = -1;
86 static int hf_mac_lte_context_phy_ul_resource_block_start = -1;
87 static int hf_mac_lte_context_phy_ul_harq_id = -1;
88 static int hf_mac_lte_context_phy_ul_ndi = -1;
90 static int hf_mac_lte_context_phy_dl = -1;
91 static int hf_mac_lte_context_phy_dl_dci_format = -1;
92 static int hf_mac_lte_context_phy_dl_resource_allocation_type = -1;
93 static int hf_mac_lte_context_phy_dl_aggregation_level = -1;
94 static int hf_mac_lte_context_phy_dl_mcs_index = -1;
95 static int hf_mac_lte_context_phy_dl_redundancy_version_index = -1;
96 static int hf_mac_lte_context_phy_dl_retx = -1;
97 static int hf_mac_lte_context_phy_dl_resource_block_length = -1;
98 static int hf_mac_lte_context_phy_dl_harq_id = -1;
99 static int hf_mac_lte_context_phy_dl_ndi = -1;
100 static int hf_mac_lte_context_phy_dl_tb = -1;
103 /* Out-of-band events */
104 static int hf_mac_lte_oob_send_preamble = -1;
105 static int hf_mac_lte_number_of_srs = -1;
107 /* MAC SCH/MCH header fields */
108 static int hf_mac_lte_ulsch = -1;
109 static int hf_mac_lte_ulsch_header = -1;
110 static int hf_mac_lte_dlsch = -1;
111 static int hf_mac_lte_dlsch_header = -1;
112 static int hf_mac_lte_sch_subheader = -1;
113 static int hf_mac_lte_mch = -1;
114 static int hf_mac_lte_mch_header = -1;
115 static int hf_mac_lte_mch_subheader = -1;
116 static int hf_mac_lte_slsch = -1;
117 static int hf_mac_lte_slsch_header = -1;
118 static int hf_mac_lte_slsch_subheader = -1;
120 static int hf_mac_lte_sch_reserved = -1;
121 static int hf_mac_lte_sch_format2 = -1;
122 static int hf_mac_lte_dlsch_lcid = -1;
123 static int hf_mac_lte_ulsch_lcid = -1;
124 static int hf_mac_lte_sch_extended = -1;
125 static int hf_mac_lte_sch_format = -1;
126 static int hf_mac_lte_sch_length = -1;
127 static int hf_mac_lte_mch_reserved = -1;
128 static int hf_mac_lte_mch_format2 = -1;
129 static int hf_mac_lte_mch_lcid = -1;
130 static int hf_mac_lte_mch_extended = -1;
131 static int hf_mac_lte_mch_format = -1;
132 static int hf_mac_lte_mch_length = -1;
133 static int hf_mac_lte_slsch_version = -1;
134 static int hf_mac_lte_slsch_reserved = -1;
135 static int hf_mac_lte_slsch_src_l2_id = -1;
136 static int hf_mac_lte_slsch_dst_l2_id = -1;
137 static int hf_mac_lte_slsch_dst_l2_id2 = -1;
138 static int hf_mac_lte_slsch_reserved2 = -1;
139 static int hf_mac_lte_slsch_extended = -1;
140 static int hf_mac_lte_slsch_lcid = -1;
141 static int hf_mac_lte_slsch_format = -1;
142 static int hf_mac_lte_slsch_length = -1;
144 static int hf_mac_lte_sch_header_only = -1;
145 static int hf_mac_lte_mch_header_only = -1;
146 static int hf_mac_lte_slsch_header_only = -1;
149 static int hf_mac_lte_sch_sdu = -1;
150 static int hf_mac_lte_mch_sdu = -1;
151 static int hf_mac_lte_bch_pdu = -1;
152 static int hf_mac_lte_pch_pdu = -1;
153 static int hf_mac_lte_slbch_pdu = -1;
154 static int hf_mac_lte_slsch_sdu = -1;
155 static int hf_mac_lte_predefined_pdu = -1;
156 static int hf_mac_lte_raw_pdu = -1;
157 static int hf_mac_lte_padding_data = -1;
158 static int hf_mac_lte_padding_length = -1;
162 static int hf_mac_lte_rar = -1;
163 static int hf_mac_lte_rar_headers = -1;
164 static int hf_mac_lte_rar_header = -1;
165 static int hf_mac_lte_rar_extension = -1;
166 static int hf_mac_lte_rar_t = -1;
167 static int hf_mac_lte_rar_bi = -1;
168 static int hf_mac_lte_rar_bi_nb = -1;
169 static int hf_mac_lte_rar_rapid = -1;
170 static int hf_mac_lte_rar_no_of_rapids = -1;
171 static int hf_mac_lte_rar_reserved = -1;
172 static int hf_mac_lte_rar_body = -1;
173 static int hf_mac_lte_rar_reserved2 = -1;
174 static int hf_mac_lte_rar_ta = -1;
175 static int hf_mac_lte_rar_ul_grant_ce_mode_b = -1;
176 static int hf_mac_lte_rar_ul_grant = -1;
177 static int hf_mac_lte_rar_ul_grant_hopping = -1;
178 static int hf_mac_lte_rar_ul_grant_fsrba = -1;
179 static int hf_mac_lte_rar_ul_grant_tmcs = -1;
180 static int hf_mac_lte_rar_ul_grant_tcsp = -1;
181 static int hf_mac_lte_rar_ul_grant_ul_delay = -1;
182 static int hf_mac_lte_rar_ul_grant_cqi_request = -1;
183 static int hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a = -1;
184 static int hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_a = -1;
185 static int hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a = -1;
186 static int hf_mac_lte_rar_ul_grant_mcs_ce_mode_a = -1;
187 static int hf_mac_lte_rar_ul_grant_tpc_ce_mode_a = -1;
188 static int hf_mac_lte_rar_ul_grant_csi_request_ce_mode_a = -1;
189 static int hf_mac_lte_rar_ul_grant_ul_delay_ce_mode_a = -1;
190 static int hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx = -1;
191 static int hf_mac_lte_rar_ul_grant_padding_ce_mode_a = -1;
192 static int hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b = -1;
193 static int hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_b = -1;
194 static int hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b = -1;
195 static int hf_mac_lte_rar_ul_grant_tbs_ce_mode_b = -1;
196 static int hf_mac_lte_rar_ul_grant_ul_subcarrier_spacing = -1;
197 static int hf_mac_lte_rar_ul_grant_subcarrier_indication = -1;
198 static int hf_mac_lte_rar_ul_grant_scheduling_delay = -1;
199 static int hf_mac_lte_rar_ul_grant_msg3_repetition_number = -1;
200 static int hf_mac_lte_rar_ul_grant_mcs_index = -1;
201 static int hf_mac_lte_rar_ul_grant_padding_nb_mode = -1;
202 static int hf_mac_lte_rar_temporary_crnti = -1;
204 /* Common channel control values */
205 static int hf_mac_lte_control_bsr = -1;
206 static int hf_mac_lte_control_bsr_lcg_id = -1;
207 static int hf_mac_lte_control_short_bsr_buffer_size = -1;
208 static int hf_mac_lte_control_long_bsr_buffer_size_0 = -1;
209 static int hf_mac_lte_control_long_bsr_buffer_size_1 = -1;
210 static int hf_mac_lte_control_long_bsr_buffer_size_2 = -1;
211 static int hf_mac_lte_control_long_bsr_buffer_size_3 = -1;
212 static int hf_mac_lte_control_short_ext_bsr_buffer_size = -1;
213 static int hf_mac_lte_control_long_ext_bsr_buffer_size_0 = -1;
214 static int hf_mac_lte_control_long_ext_bsr_buffer_size_1 = -1;
215 static int hf_mac_lte_control_long_ext_bsr_buffer_size_2 = -1;
216 static int hf_mac_lte_control_long_ext_bsr_buffer_size_3 = -1;
217 static int hf_mac_lte_bsr_size_median = -1;
218 static int hf_mac_lte_control_crnti = -1;
219 static int hf_mac_lte_control_timing_advance = -1;
220 static int hf_mac_lte_control_timing_advance_group_id = -1;
221 static int hf_mac_lte_control_timing_advance_command = -1;
222 static int hf_mac_lte_control_ue_contention_resolution = -1;
223 static int hf_mac_lte_control_ue_contention_resolution_identity = -1;
224 static int hf_mac_lte_control_ue_contention_resolution_msg3 = -1;
225 static int hf_mac_lte_control_ue_contention_resolution_msg3_matched = -1;
226 static int hf_mac_lte_control_ue_contention_resolution_time_since_msg3 = -1;
227 static int hf_mac_lte_control_msg3_to_cr = -1;
229 static int hf_mac_lte_control_power_headroom = -1;
230 static int hf_mac_lte_control_power_headroom_reserved = -1;
231 static int hf_mac_lte_control_power_headroom_level = -1;
232 static int hf_mac_lte_control_dual_conn_power_headroom = -1;
233 static int hf_mac_lte_control_dual_conn_power_headroom_c7 = -1;
234 static int hf_mac_lte_control_dual_conn_power_headroom_c6 = -1;
235 static int hf_mac_lte_control_dual_conn_power_headroom_c5 = -1;
236 static int hf_mac_lte_control_dual_conn_power_headroom_c4 = -1;
237 static int hf_mac_lte_control_dual_conn_power_headroom_c3 = -1;
238 static int hf_mac_lte_control_dual_conn_power_headroom_c2 = -1;
239 static int hf_mac_lte_control_dual_conn_power_headroom_c1 = -1;
240 static int hf_mac_lte_control_dual_conn_power_headroom_reserved = -1;
241 static int hf_mac_lte_control_dual_conn_power_headroom_power_backoff = -1;
242 static int hf_mac_lte_control_dual_conn_power_headroom_value = -1;
243 static int hf_mac_lte_control_dual_conn_power_headroom_level = -1;
244 static int hf_mac_lte_control_dual_conn_power_headroom_reserved2 = -1;
245 static int hf_mac_lte_control_dual_conn_power_headroom_pcmaxc = -1;
246 static int hf_mac_lte_control_ext_power_headroom = -1;
247 static int hf_mac_lte_control_ext_power_headroom_c7 = -1;
248 static int hf_mac_lte_control_ext_power_headroom_c6 = -1;
249 static int hf_mac_lte_control_ext_power_headroom_c5 = -1;
250 static int hf_mac_lte_control_ext_power_headroom_c4 = -1;
251 static int hf_mac_lte_control_ext_power_headroom_c3 = -1;
252 static int hf_mac_lte_control_ext_power_headroom_c2 = -1;
253 static int hf_mac_lte_control_ext_power_headroom_c1 = -1;
254 static int hf_mac_lte_control_ext_power_headroom_reserved = -1;
255 static int hf_mac_lte_control_ext_power_headroom_power_backoff = -1;
256 static int hf_mac_lte_control_ext_power_headroom_value = -1;
257 static int hf_mac_lte_control_ext_power_headroom_level = -1;
258 static int hf_mac_lte_control_ext_power_headroom_reserved2 = -1;
259 static int hf_mac_lte_control_ext_power_headroom_pcmaxc = -1;
260 static int hf_mac_lte_control_activation_deactivation = -1;
261 static int hf_mac_lte_control_activation_deactivation_c7 = -1;
262 static int hf_mac_lte_control_activation_deactivation_c6 = -1;
263 static int hf_mac_lte_control_activation_deactivation_c5 = -1;
264 static int hf_mac_lte_control_activation_deactivation_c4 = -1;
265 static int hf_mac_lte_control_activation_deactivation_c3 = -1;
266 static int hf_mac_lte_control_activation_deactivation_c2 = -1;
267 static int hf_mac_lte_control_activation_deactivation_c1 = -1;
268 static int hf_mac_lte_control_activation_deactivation_reserved = -1;
269 static int hf_mac_lte_control_activation_deactivation_c15 = -1;
270 static int hf_mac_lte_control_activation_deactivation_c14 = -1;
271 static int hf_mac_lte_control_activation_deactivation_c13 = -1;
272 static int hf_mac_lte_control_activation_deactivation_c12 = -1;
273 static int hf_mac_lte_control_activation_deactivation_c11 = -1;
274 static int hf_mac_lte_control_activation_deactivation_c10 = -1;
275 static int hf_mac_lte_control_activation_deactivation_c9 = -1;
276 static int hf_mac_lte_control_activation_deactivation_c8 = -1;
277 static int hf_mac_lte_control_activation_deactivation_c23 = -1;
278 static int hf_mac_lte_control_activation_deactivation_c22 = -1;
279 static int hf_mac_lte_control_activation_deactivation_c21 = -1;
280 static int hf_mac_lte_control_activation_deactivation_c20 = -1;
281 static int hf_mac_lte_control_activation_deactivation_c19 = -1;
282 static int hf_mac_lte_control_activation_deactivation_c18 = -1;
283 static int hf_mac_lte_control_activation_deactivation_c17 = -1;
284 static int hf_mac_lte_control_activation_deactivation_c16 = -1;
285 static int hf_mac_lte_control_activation_deactivation_c31 = -1;
286 static int hf_mac_lte_control_activation_deactivation_c30 = -1;
287 static int hf_mac_lte_control_activation_deactivation_c29 = -1;
288 static int hf_mac_lte_control_activation_deactivation_c28 = -1;
289 static int hf_mac_lte_control_activation_deactivation_c27 = -1;
290 static int hf_mac_lte_control_activation_deactivation_c26 = -1;
291 static int hf_mac_lte_control_activation_deactivation_c25 = -1;
292 static int hf_mac_lte_control_activation_deactivation_c24 = -1;
293 static int hf_mac_lte_control_mch_scheduling_info = -1;
294 static int hf_mac_lte_control_mch_scheduling_info_lcid = -1;
295 static int hf_mac_lte_control_mch_scheduling_info_stop_mtch = -1;
296 static int hf_mac_lte_control_sidelink_bsr = -1;
297 static int hf_mac_lte_control_sidelink_bsr_destination_idx_odd = -1;
298 static int hf_mac_lte_control_sidelink_bsr_lcg_id_odd = -1;
299 static int hf_mac_lte_control_sidelink_bsr_buffer_size_odd = -1;
300 static int hf_mac_lte_control_sidelink_bsr_destination_idx_even = -1;
301 static int hf_mac_lte_control_sidelink_bsr_lcg_id_even = -1;
302 static int hf_mac_lte_control_sidelink_bsr_buffer_size_even = -1;
303 static int hf_mac_lte_control_sidelink_reserved = -1;
304 static int hf_mac_lte_control_data_vol_power_headroom = -1;
305 static int hf_mac_lte_control_data_vol_power_headroom_reserved = -1;
306 static int hf_mac_lte_control_data_vol_power_headroom_level = -1;
307 static int hf_mac_lte_control_data_vol_power_headroom_data_vol = -1;
308 static int hf_mac_lte_control_recommended_bit_rate = -1;
309 static int hf_mac_lte_control_recommended_bit_rate_lcid = -1;
310 static int hf_mac_lte_control_recommended_bit_rate_dir = -1;
311 static int hf_mac_lte_control_recommended_bit_rate_bit_rate = -1;
312 static int hf_mac_lte_control_recommended_bit_rate_reserved = -1;
313 static int hf_mac_lte_control_recommended_bit_rate_query = -1;
314 static int hf_mac_lte_control_recommended_bit_rate_query_lcid = -1;
315 static int hf_mac_lte_control_recommended_bit_rate_query_dir = -1;
316 static int hf_mac_lte_control_recommended_bit_rate_query_bit_rate = -1;
317 static int hf_mac_lte_control_recommended_bit_rate_query_reserved = -1;
318 static int hf_mac_lte_control_activation_deactivation_csi_rs = -1;
319 static int hf_mac_lte_control_activation_deactivation_csi_rs_a8 = -1;
320 static int hf_mac_lte_control_activation_deactivation_csi_rs_a7 = -1;
321 static int hf_mac_lte_control_activation_deactivation_csi_rs_a6 = -1;
322 static int hf_mac_lte_control_activation_deactivation_csi_rs_a5 = -1;
323 static int hf_mac_lte_control_activation_deactivation_csi_rs_a4 = -1;
324 static int hf_mac_lte_control_activation_deactivation_csi_rs_a3 = -1;
325 static int hf_mac_lte_control_activation_deactivation_csi_rs_a2 = -1;
326 static int hf_mac_lte_control_activation_deactivation_csi_rs_a1 = -1;
328 static int hf_mac_lte_dl_harq_resend_original_frame = -1;
329 static int hf_mac_lte_dl_harq_resend_time_since_previous_frame = -1;
330 static int hf_mac_lte_dl_harq_resend_next_frame = -1;
331 static int hf_mac_lte_dl_harq_resend_time_until_next_frame = -1;
333 static int hf_mac_lte_ul_harq_resend_original_frame = -1;
334 static int hf_mac_lte_ul_harq_resend_time_since_previous_frame = -1;
335 static int hf_mac_lte_ul_harq_resend_next_frame = -1;
336 static int hf_mac_lte_ul_harq_resend_time_until_next_frame = -1;
338 static int hf_mac_lte_grant_answering_sr = -1;
339 static int hf_mac_lte_failure_answering_sr = -1;
340 static int hf_mac_lte_sr_leading_to_failure = -1;
341 static int hf_mac_lte_sr_leading_to_grant = -1;
342 static int hf_mac_lte_sr_time_since_request = -1;
343 static int hf_mac_lte_sr_time_until_answer = -1;
345 static int hf_mac_lte_drx_config = -1;
346 static int hf_mac_lte_drx_config_frame_num = -1;
347 static int hf_mac_lte_drx_config_previous_frame_num = -1;
348 static int hf_mac_lte_drx_config_long_cycle = -1;
349 static int hf_mac_lte_drx_config_cycle_offset = -1;
350 static int hf_mac_lte_drx_config_onduration_timer = -1;
351 static int hf_mac_lte_drx_config_inactivity_timer = -1;
352 static int hf_mac_lte_drx_config_retransmission_timer = -1;
353 static int hf_mac_lte_drx_config_short_cycle = -1;
354 static int hf_mac_lte_drx_config_short_cycle_timer = -1;
356 static int hf_mac_lte_drx_state = -1;
357 static int hf_mac_lte_drx_state_long_cycle_offset = -1;
358 /* static int hf_mac_lte_drx_state_long_cycle_on = -1; */
359 static int hf_mac_lte_drx_state_short_cycle_offset = -1;
360 /* static int hf_mac_lte_drx_state_short_cycle_on = -1; */
361 static int hf_mac_lte_drx_state_inactivity_remaining = -1;
362 static int hf_mac_lte_drx_state_onduration_remaining = -1;
363 static int hf_mac_lte_drx_state_retransmission_remaining = -1;
364 static int hf_mac_lte_drx_state_rtt_remaining = -1;
365 static int hf_mac_lte_drx_state_short_cycle_remaining = -1;
368 static int ett_mac_lte = -1;
369 static int ett_mac_lte_context = -1;
370 static int ett_mac_lte_phy_context = -1;
371 static int ett_mac_lte_ulsch_header = -1;
372 static int ett_mac_lte_dlsch_header = -1;
373 static int ett_mac_lte_mch_header = -1;
374 static int ett_mac_lte_sch_subheader = -1;
375 static int ett_mac_lte_mch_subheader = -1;
376 static int ett_mac_lte_slsch_header = -1;
377 static int ett_mac_lte_slsch_subheader = -1;
378 static int ett_mac_lte_rar_headers = -1;
379 static int ett_mac_lte_rar_header = -1;
380 static int ett_mac_lte_rar_body = -1;
381 static int ett_mac_lte_rar_ul_grant = -1;
382 static int ett_mac_lte_bsr = -1;
383 static int ett_mac_lte_bch = -1;
384 static int ett_mac_lte_pch = -1;
385 static int ett_mac_lte_activation_deactivation = -1;
386 static int ett_mac_lte_contention_resolution = -1;
387 static int ett_mac_lte_timing_advance = -1;
388 static int ett_mac_lte_power_headroom = -1;
389 static int ett_mac_lte_dual_conn_power_headroom = -1;
390 static int ett_mac_lte_dual_conn_power_headroom_cell = -1;
391 static int ett_mac_lte_extended_power_headroom = -1;
392 static int ett_mac_lte_extended_power_headroom_cell = -1;
393 static int ett_mac_lte_mch_scheduling_info = -1;
394 static int ett_mac_lte_oob = -1;
395 static int ett_mac_lte_drx_config = -1;
396 static int ett_mac_lte_drx_state = -1;
397 static int ett_mac_lte_sidelink_bsr = -1;
398 static int ett_mac_lte_data_vol_power_headroom = -1;
399 static int ett_mac_lte_recommended_bit_rate = -1;
400 static int ett_mac_lte_recommended_bit_rate_query = -1;
401 static int ett_mac_lte_activation_deactivation_csi_rs = -1;
403 static expert_field ei_mac_lte_context_rnti_type = EI_INIT;
404 static expert_field ei_mac_lte_lcid_unexpected = EI_INIT;
405 static expert_field ei_mac_lte_ul_mac_frame_retx = EI_INIT;
406 static expert_field ei_mac_lte_oob_sr_failure = EI_INIT;
407 static expert_field ei_mac_lte_control_timing_advance_command_correction_needed = EI_INIT;
408 static expert_field ei_mac_lte_sch_header_only_truncated = EI_INIT;
409 static expert_field ei_mac_lte_mch_header_only_truncated = EI_INIT;
410 static expert_field ei_mac_lte_slsch_header_only_truncated = EI_INIT;
411 static expert_field ei_mac_lte_control_timing_advance_command_no_correction = EI_INIT;
412 static expert_field ei_mac_lte_rar_timing_advance_not_zero_note = EI_INIT;
413 static expert_field ei_mac_lte_padding_data_start_and_end = EI_INIT;
414 static expert_field ei_mac_lte_bch_pdu = EI_INIT;
415 static expert_field ei_mac_lte_rach_preamble_sent_note = EI_INIT;
416 static expert_field ei_mac_lte_pch_pdu = EI_INIT;
417 static expert_field ei_mac_lte_ul_harq_resend_next_frame = EI_INIT;
418 static expert_field ei_mac_lte_control_bsr_multiple = EI_INIT;
419 static expert_field ei_mac_lte_padding_data_multiple = EI_INIT;
420 static expert_field ei_mac_lte_context_sysframe_number = EI_INIT;
421 static expert_field ei_mac_lte_rar_bi_present = EI_INIT;
422 static expert_field ei_mac_lte_control_element_size_invalid = EI_INIT;
423 static expert_field ei_mac_lte_bsr_warn_threshold_exceeded = EI_INIT;
424 static expert_field ei_mac_lte_too_many_subheaders = EI_INIT;
425 static expert_field ei_mac_lte_oob_send_sr = EI_INIT;
426 static expert_field ei_mac_lte_orig_tx_ul_frame_not_found = EI_INIT;
427 static expert_field ei_mac_lte_control_ue_contention_resolution_msg3_matched = EI_INIT;
428 static expert_field ei_mac_lte_sr_results_not_grant_or_failure_indication = EI_INIT;
429 static expert_field ei_mac_lte_context_crc_status = EI_INIT;
430 static expert_field ei_mac_lte_sr_invalid_event = EI_INIT;
431 static expert_field ei_mac_lte_control_subheader_after_data_subheader = EI_INIT;
432 static expert_field ei_mac_lte_rar_bi_not_first_subheader = EI_INIT;
433 static expert_field ei_mac_lte_context_length = EI_INIT;
434 static expert_field ei_mac_lte_reserved_not_zero = EI_INIT;
435 static expert_field ei_mac_lte_rar_timing_advance_not_zero_warn = EI_INIT;
436 static expert_field ei_mac_lte_dlsch_lcid = EI_INIT;
437 static expert_field ei_mac_lte_padding_data_before_control_subheader = EI_INIT;
438 static expert_field ei_mac_lte_rach_preamble_sent_warn = EI_INIT;
439 static expert_field ei_mac_lte_no_per_frame_data = EI_INIT;
440 static expert_field ei_mac_lte_sch_invalid_length = EI_INIT;
441 static expert_field ei_mac_lte_mch_invalid_length = EI_INIT;
442 static expert_field ei_mac_lte_invalid_sc_mcch_sc_mtch_subheader_multiplexing = EI_INIT;
443 static expert_field ei_mac_lte_unknown_udp_framing_tag = EI_INIT;
446 /* Constants and value strings */
448 static const value_string radio_type_vals[] =
456 static const value_string direction_vals[] =
458 { DIRECTION_UPLINK, "Uplink"},
459 { DIRECTION_DOWNLINK, "Downlink"},
464 static const value_string rnti_type_vals[] =
466 { NO_RNTI, "NO-RNTI"},
468 { RA_RNTI, "RA-RNTI"},
470 { SI_RNTI, "SI-RNTI"},
471 { SPS_RNTI, "SPS-RNTI"},
473 { SL_BCH_RNTI, "SL-BCH-RNTI"},
474 { SL_RNTI, "SL-RNTI"},
475 { SC_RNTI, "SC-RNTI"},
480 static const value_string bch_transport_channel_vals[] =
482 { SI_RNTI, "DL-SCH"},
487 static const value_string crc_status_vals[] =
489 { crc_success, "OK"},
490 { crc_fail, "Failed"},
491 { crc_high_code_rate, "High Code Rate"},
492 { crc_pdsch_lost, "PDSCH Lost"},
493 { crc_duplicate_nonzero_rv, "Duplicate_nonzero_rv"},
494 { crc_false_dci, "False DCI"},
498 static const value_string carrier_id_vals[] =
500 { carrier_id_primary, "Primary"},
501 { carrier_id_secondary_1, "Secondary-1"},
502 { carrier_id_secondary_2, "Secondary-2"},
503 { carrier_id_secondary_3, "Secondary-3"},
504 { carrier_id_secondary_4, "Secondary-4"},
505 { carrier_id_secondary_5, "Secondary-5"},
506 { carrier_id_secondary_6, "Secondary-6"},
507 { carrier_id_secondary_7, "Secondary-7"},
511 static const value_string dci_format_vals[] =
535 static const value_string aggregation_level_vals[] =
546 static const value_string modulation_type_vals[] =
554 static const true_false_string mac_lte_scell_ph_vals = {
559 static const true_false_string mac_lte_power_backoff_vals = {
564 static const true_false_string mac_lte_ph_value_vals = {
565 "Based on reference format",
566 "Based on real transmission"
569 static const true_false_string mac_lte_scell_status_vals = {
574 #define ACTIVATION_DEACTIVATION_CSI_RS_LCID 0x15
575 #define RECOMMENDED_BIT_RATE_LCID 0x16
576 #define SC_PTM_STOP_INDICATION_LCID 0x17
577 #define ACTIVATION_DEACTIVATION_4_BYTES_LCID 0x18
578 #define SC_MCCH_SC_MTCH_LCID 0x19
579 #define LONG_DRX_COMMAND_LCID 0x1a
580 #define ACTIVATION_DEACTIVATION_LCID 0x1b
581 #define UE_CONTENTION_RESOLUTION_IDENTITY_LCID 0x1c
582 #define TIMING_ADVANCE_LCID 0x1d
583 #define DRX_COMMAND_LCID 0x1e
584 #define PADDING_LCID 0x1f
586 static const value_string dlsch_lcid_vals[] =
599 { ACTIVATION_DEACTIVATION_CSI_RS_LCID, "Activation/Deactivation of CSI-RS"},
600 { RECOMMENDED_BIT_RATE_LCID, "Recommended Bit Rate"},
601 { SC_PTM_STOP_INDICATION_LCID, "SC-PTM Stop Indication"},
602 { ACTIVATION_DEACTIVATION_4_BYTES_LCID, "Activation/Deactivation"},
603 { SC_MCCH_SC_MTCH_LCID, "SC-MCCH/SC-MTCH"},
604 { LONG_DRX_COMMAND_LCID, "Long DRX Command"},
605 { ACTIVATION_DEACTIVATION_LCID, "Activation/Deactivation"},
606 { UE_CONTENTION_RESOLUTION_IDENTITY_LCID, "UE Contention Resolution Identity"},
607 { TIMING_ADVANCE_LCID, "Timing Advance"},
608 { DRX_COMMAND_LCID, "DRX Command"},
609 { PADDING_LCID, "Padding" },
613 #define RECOMMENDED_BIT_RATE_QUERY_LCID 0x14
614 #define SPS_CONFIRMATION_LCID 0x15
615 #define TRUNCATED_SIDELINK_BSR_LCID 0x16
616 #define SIDELINK_BSR_LCID 0x17
617 #define DUAL_CONN_POWER_HEADROOM_REPORT_LCID 0x18
618 #define EXTENDED_POWER_HEADROOM_REPORT_LCID 0x19
619 #define POWER_HEADROOM_REPORT_LCID 0x1a
620 #define CRNTI_LCID 0x1b
621 #define TRUNCATED_BSR_LCID 0x1c
622 #define SHORT_BSR_LCID 0x1d
623 #define LONG_BSR_LCID 0x1e
625 static const value_string ulsch_lcid_vals[] =
638 { 11, "CCCH (Category 0)"},
639 { 12, "CCCH (frequency hopping for unicast)"},
640 { RECOMMENDED_BIT_RATE_QUERY_LCID, "Recommended Bit Rate Query"},
641 { SPS_CONFIRMATION_LCID, "SPS Confirmation"},
642 { TRUNCATED_SIDELINK_BSR_LCID, "Truncated Sidelink BSR"},
643 { SIDELINK_BSR_LCID, "Sidelink BSR"},
644 { DUAL_CONN_POWER_HEADROOM_REPORT_LCID, "Dual Connectivity Power Headroom Report"},
645 { EXTENDED_POWER_HEADROOM_REPORT_LCID, "Extended Power Headroom Report"},
646 { POWER_HEADROOM_REPORT_LCID, "Power Headroom Report"},
647 { CRNTI_LCID, "C-RNTI"},
648 { TRUNCATED_BSR_LCID, "Truncated BSR"},
649 { SHORT_BSR_LCID, "Short BSR"},
650 { LONG_BSR_LCID, "Long BSR"},
651 { PADDING_LCID, "Padding" },
655 #define MCH_SCHEDULING_INFO_LCID 0x1e
657 static const value_string mch_lcid_vals[] =
688 { MCH_SCHEDULING_INFO_LCID, "MCH Scheduling Information"},
689 { PADDING_LCID, "Padding" },
693 static const value_string slsch_lcid_vals[] =
706 { 28, "PC5-S messages that are not protected"},
707 { 29, "PC5-S messages \"Direct Security Mode Command\" and \"Direct Security Mode Complete\""},
708 { 30, "Other PC5-S messages that are protected"},
709 { PADDING_LCID, "Padding" },
713 static const true_false_string format_vals =
715 "Data length is >= 128 bytes",
716 "Data length is < 128 bytes"
719 static const true_false_string format2_vals =
721 "Data length is >= 32768 bytes",
722 "Data length is < 32768 bytes"
725 static const value_string rar_type_vals[] =
727 { 0, "Backoff Indicator present"},
728 { 1, "RAPID present"},
733 static const value_string rar_bi_vals[] =
752 static const value_string rar_bi_nb_vals[] =
771 static const value_string rar_ul_grant_tcsp_vals[] =
785 static const value_string rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b_vals[] =
787 { 0, "NBrar mod Nnb"},
788 { 1, "(NBrar+1) mod Nnb"},
789 { 2, "(NBrar+2) mod Nnb"},
790 { 3, "(NBrar+3) mod Nnb"},
795 static const value_string rar_ul_grant_msg3_msg4_mpdcch_nb_idx_vals[] =
797 { 0, "NBrar mod Nnb2"},
798 { 1, "(NBrar+1) mod Nnb2"},
799 { 2, "(NBrar+2) mod Nnb2"},
800 { 3, "(NBrar+3) mod Nnb2"},
805 static const value_string rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a_vals[] =
815 static const value_string rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b_vals[] =
829 static const true_false_string ul_subcarrier_spacing_val =
836 static const value_string scheduling_delay_vals[]=
846 static const value_string msg3_rep_nb_vals[] =
860 static const value_string buffer_size_vals[] =
863 { 1, "0 < BS <= 10"},
864 { 2, "10 < BS <= 12"},
865 { 3, "12 < BS <= 14"},
866 { 4, "14 < BS <= 17"},
867 { 5, "17 < BS <= 19"},
868 { 6, "19 < BS <= 22"},
869 { 7, "22 < BS <= 26"},
870 { 8, "26 < BS <= 31"},
871 { 9, "31 < BS <= 36"},
872 { 10, "36 < BS <= 42"},
873 { 11, "42 < BS <= 49"},
874 { 12, "49 < BS <= 57"},
875 { 13, "57 < BS <= 67"},
876 { 14, "67 < BS <= 78"},
877 { 15, "78 < BS <= 91"},
878 { 16, "91 < BS <= 107"},
879 { 17, "107 < BS <= 125"},
880 { 18, "125 < BS <= 146"},
881 { 19, "146 < BS <= 171"},
882 { 20, "171 < BS <= 200"},
883 { 21, "200 < BS <= 234"},
884 { 22, "234 < BS <= 274"},
885 { 23, "274 < BS <= 321"},
886 { 24, "321 < BS <= 376"},
887 { 25, "376 < BS <= 440"},
888 { 26, "440 < BS <= 515"},
889 { 27, "515 < BS <= 603"},
890 { 28, "603 < BS <= 706"},
891 { 29, "706 < BS <= 826"},
892 { 30, "826 < BS <= 967"},
893 { 31, "967 < BS <= 1132"},
894 { 32, "1132 < BS <= 1326"},
895 { 33, "1326 < BS <= 1552"},
896 { 34, "1552 < BS <= 1817"},
897 { 35, "1817 < BS <= 2127"},
898 { 36, "2127 < BS <= 2490"},
899 { 37, "2490 < BS <= 2915"},
900 { 38, "2915 < BS <= 3413"},
901 { 39, "3413 < BS <= 3995"},
902 { 40, "3995 < BS <= 4677"},
903 { 41, "4677 < BS <= 5476"},
904 { 42, "5476 < BS <= 6411"},
905 { 43, "6411 < BS <= 7505"},
906 { 44, "7505 < BS <= 8787"},
907 { 45, "8787 < BS <= 10276"},
908 { 46, "10287 < BS <= 12043"},
909 { 47, "12043 < BS <= 14099"},
910 { 48, "14099 < BS <= 16507"},
911 { 49, "16507 < BS <= 19325"},
912 { 50, "19325 < BS <= 22624"},
913 { 51, "22624 < BS <= 26487"},
914 { 52, "26487 < BS <= 31009"},
915 { 53, "31009 < BS <= 36304"},
916 { 54, "36304 < BS <= 42502"},
917 { 55, "42502 < BS <= 49759"},
918 { 56, "49759 < BS <= 58255"},
919 { 57, "58255 < BS <= 68201"},
920 { 58, "68201 < BS <= 79846"},
921 { 59, "79846 < BS <= 93479"},
922 { 60, "93479 < BS <= 109439"},
923 { 61, "109439 < BS <= 128125"},
924 { 62, "128125 < BS <= 150000"},
925 { 63, "BS > 150000"},
928 static value_string_ext buffer_size_vals_ext = VALUE_STRING_EXT_INIT(buffer_size_vals);
930 static guint32 buffer_size_median[64] = {
932 5, /* 0 < BS <= 10 */
933 11, /* 10 < BS <= 12 */
934 13, /* 12 < BS <= 14 */
935 15, /* 14 < BS <= 17 */
936 18, /* 17 < BS <= 19 */
937 21, /* 19 < BS <= 22 */
938 24, /* 22 < BS <= 26 */
939 29, /* 26 < BS <= 31 */
940 34, /* 31 < BS <= 36 */
941 39, /* 36 < BS <= 42 */
942 46, /* 42 < BS <= 49 */
943 53, /* 49 < BS <= 57 */
944 62, /* 57 < BS <= 67 */
945 74, /* 67 < BS <= 78 */
946 85, /* 78 < BS <= 91 */
947 99, /* 91 < BS <= 107 */
948 116, /* 107 < BS <= 125 */
949 135, /* 125 < BS <= 146 */
950 159, /* 146 < BS <= 171 */
951 185, /* 171 < BS <= 200 */
952 217, /* 200 < BS <= 234 */
953 254, /* 234 < BS <= 274 */
954 297, /* 274 < BS <= 321 */
955 348, /* 321 < BS <= 376 */
956 408, /* 376 < BS <= 440 */
957 477, /* 440 < BS <= 515 */
958 559, /* 515 < BS <= 603 */
959 654, /* 603 < BS <= 706 */
960 766, /* 706 < BS <= 826 */
961 896, /* 826 < BS <= 967 */
962 1049, /* 967 < BS <= 1132 */
963 1229, /* 1132 < BS <= 1326 */
964 1439, /* 1326 < BS <= 1552 */
965 1684, /* 1552 < BS <= 1817 */
966 1972, /* 1817 < BS <= 2127 */
967 2308, /* 2127 < BS <= 2490 */
968 2702, /* 2490 < BS <= 2915 */
969 3164, /* 2915 < BS <= 3413 */
970 3704, /* 3413 < BS <= 3995 */
971 4336, /* 3995 < BS <= 4677 */
972 5076, /* 4677 < BS <= 5476 */
973 5943, /* 5476 < BS <= 6411 */
974 6958, /* 6411 < BS <= 7505 */
975 8146, /* 7505 < BS <= 8787 */
976 9531, /* 8787 < BS <= 10276 */
977 11165, /* 10287 < BS <= 12043 */
978 13071, /* 12043 < BS <= 14099 */
979 15303, /* 14099 < BS <= 16507 */
980 19716, /* 16507 < BS <= 19325 */
981 20974, /* 19325 < BS <= 22624 */
982 24555, /* 22624 < BS <= 26487 */
983 28748, /* 26487 < BS <= 31009 */
984 33656, /* 31009 < BS <= 36304 */
985 39403, /* 36304 < BS <= 42502 */
986 46130, /* 42502 < BS <= 49759 */
987 54007, /* 49759 < BS <= 58255 */
988 63228, /* 58255 < BS <= 68201 */
989 74023, /* 68201 < BS <= 79846 */
990 86662, /* 79846 < BS <= 93479 */
991 101459, /* 93479 < BS <= 109439 */
992 118782, /* 109439 < BS <= 128125 */
993 139062, /* 128125 < BS <= 150000 */
994 150001 /* BS > 150000 */
997 static const value_string ext_buffer_size_vals[] =
1000 { 1, "0 < BS <= 10"},
1001 { 2, "10 < BS <= 13"},
1002 { 3, "13 < BS <= 16"},
1003 { 4, "16 < BS <= 19"},
1004 { 5, "19 < BS <= 23"},
1005 { 6, "23 < BS <= 29"},
1006 { 7, "29 < BS <= 35"},
1007 { 8, "35 < BS <= 43"},
1008 { 9, "43 < BS <= 53"},
1009 { 10, "53 < BS <= 65"},
1010 { 11, "65 < BS <= 80"},
1011 { 12, "80 < BS <= 98"},
1012 { 13, "98 < BS <= 120"},
1013 { 14, "120 < BS <= 147"},
1014 { 15, "147 < BS <= 181"},
1015 { 16, "181 < BS <= 223"},
1016 { 17, "223 < BS <= 274"},
1017 { 18, "274 < BS <= 337"},
1018 { 19, "337 < BS <= 414"},
1019 { 20, "414 < BS <= 509"},
1020 { 21, "509 < BS <= 625"},
1021 { 22, "625 < BS <= 769"},
1022 { 23, "769 < BS <= 945"},
1023 { 24, "945 < BS <= 1162"},
1024 { 25, "1162 < BS <= 1429"},
1025 { 26, "1429 < BS <= 1757"},
1026 { 27, "1757 < BS <= 2161"},
1027 { 28, "2161 < BS <= 2657"},
1028 { 29, "2657 < BS <= 3267"},
1029 { 30, "3267 < BS <= 4017"},
1030 { 31, "4017 < BS <= 4940"},
1031 { 32, "4940 < BS <= 6074"},
1032 { 33, "6074 < BS <= 7469"},
1033 { 34, "7469 < BS <= 9185"},
1034 { 35, "9185 < BS <= 11294"},
1035 { 36, "11294 < BS <= 13888"},
1036 { 37, "13888 < BS <= 17077"},
1037 { 38, "17077 < BS <= 20999"},
1038 { 39, "20999 < BS <= 25822"},
1039 { 40, "25822 < BS <= 31752"},
1040 { 41, "31752 < BS <= 39045"},
1041 { 42, "39045 < BS <= 48012"},
1042 { 43, "48012 < BS <= 59039"},
1043 { 44, "59039 < BS <= 72598"},
1044 { 45, "72598 < BS <= 89272"},
1045 { 46, "89272 < BS <= 109774"},
1046 { 47, "109774 < BS <= 134986"},
1047 { 48, "134986 < BS <= 165989"},
1048 { 49, "165989 < BS <= 204111"},
1049 { 50, "204111 < BS <= 250990"},
1050 { 51, "250990 < BS <= 308634"},
1051 { 52, "308634 < BS <= 379519"},
1052 { 53, "379519 < BS <= 466683"},
1053 { 54, "466683 < BS <= 573866"},
1054 { 55, "573866 < BS <= 705666"},
1055 { 56, "705666 < BS <= 867737"},
1056 { 57, "867737 < BS <= 1067031"},
1057 { 58, "1067031 < BS <= 1312097"},
1058 { 59, "1312097 < BS <= 1613447"},
1059 { 60, "1613447 < BS <= 1984009"},
1060 { 61, "1984009 < BS <= 2439678"},
1061 { 62, "2439678 < BS <= 3000000"},
1062 { 63, "BS > 3000000"},
1065 static value_string_ext ext_buffer_size_vals_ext = VALUE_STRING_EXT_INIT(ext_buffer_size_vals);
1067 static guint32 ext_buffer_size_median[64] = {
1069 5, /* 0 < BS <= 10 */
1070 12, /* 10 < BS <= 13 */
1071 15, /* 13 < BS <= 16 */
1072 18, /* 16 < BS <= 19 */
1073 21, /* 19 < BS <= 23 */
1074 26, /* 23 < BS <= 29 */
1075 32, /* 29 < BS <= 35 */
1076 39, /* 35 < BS <= 43 */
1077 48, /* 43 < BS <= 53 */
1078 59, /* 53 < BS <= 65 */
1079 73, /* 65 < BS <= 80 */
1080 89, /* 80 < BS <= 98 */
1081 109, /* 98 < BS <= 120 */
1082 134, /* 120 < BS <= 147 */
1083 164, /* 147 < BS <= 181 */
1084 202, /* 181 < BS <= 223 */
1085 249, /* 223 < BS <= 274 */
1086 306, /* 274 < BS <= 337 */
1087 376, /* 337 < BS <= 414 */
1088 462, /* 414 < BS <= 509 */
1089 567, /* 509 < BS <= 625 */
1090 697, /* 625 < BS <= 769 */
1091 857, /* 769 < BS <= 945 */
1092 1054, /* 945 < BS <= 1162 */
1093 1296, /* 1162 < BS <= 1429 */
1094 1593, /* 1429 < BS <= 1757 */
1095 1959, /* 1757 < BS <= 2161 */
1096 2409, /* 2161 < BS <= 2657 */
1097 2962, /* 2657 < BS <= 3267 */
1098 5142, /* 3267 < BS <= 4017 */
1099 4479, /* 4017 < BS <= 4940 */
1100 5507, /* 4940 < BS <= 6074 */
1101 6772, /* 6074 < BS <= 7469 */
1102 8327, /* 7469 < BS <= 9185 */
1103 10240, /* 9185 < BS <= 11294 */
1104 12591, /* 11294 < BS <= 13888 */
1105 15483, /* 13888 < BS <= 17077 */
1106 19038, /* 17077 < BS <= 20999 */
1107 23411, /* 20999 < BS <= 25822 */
1108 28787, /* 25822 < BS <= 31752 */
1109 35399, /* 31752 < BS <= 39045 */
1110 43529, /* 39045 < BS <= 48012 */
1111 53526, /* 48012 < BS <= 59039 */
1112 65819, /* 59039 < BS <= 72598 */
1113 80935, /* 72598 < BS <= 89272 */
1114 99523, /* 89272 < BS <= 109774 */
1115 122380, /* 109774 < BS <= 134986 */
1116 150488, /* 134986 < BS <= 165989 */
1117 185050, /* 165989 < BS <= 204111 */
1118 227551, /* 204111 < BS <= 250990 */
1119 279812, /* 250990 < BS <= 308634 */
1120 344077, /* 308634 < BS <= 379519 */
1121 423101, /* 379519 < BS <= 466683 */
1122 520275, /* 466683 < BS <= 573866 */
1123 705748, /* 573866 < BS <= 705666 */
1124 786702, /* 705666 < BS <= 867737 */
1125 967384, /* 867737 < BS <= 1067031 */
1126 1189564, /* 1067031 < BS <= 1312097 */
1127 1462772, /* 1312097 < BS <= 1613447 */
1128 1798728, /* 1613447 < BS <= 1984009 */
1129 2211844, /* 1984009 < BS <= 2439678 */
1130 2719839, /* 2439678 < BS <= 3000000 */
1131 3000001 /* BS > 3000000 */
1134 static const value_string power_headroom_vals[] =
1136 { 0, "-23 <= PH < -22"},
1137 { 1, "-22 <= PH < -21"},
1138 { 2, "-21 <= PH < -20"},
1139 { 3, "-20 <= PH < -19"},
1140 { 4, "-19 <= PH < -18"},
1141 { 5, "-18 <= PH < -17"},
1142 { 6, "-17 <= PH < -16"},
1143 { 7, "-16 <= PH < -15"},
1144 { 8, "-15 <= PH < -14"},
1145 { 9, "-14 <= PH < -13"},
1146 { 10, "-13 <= PH < -12"},
1147 { 11, "-12 <= PH < -11"},
1148 { 12, "-11 <= PH < -10"},
1149 { 13, "-10 <= PH < -9"},
1150 { 14, "-9 <= PH < -8"},
1151 { 15, "-8 <= PH < -7"},
1152 { 16, "-7 <= PH < -6"},
1153 { 17, "-6 <= PH < -5"},
1154 { 18, "-5 <= PH < -4"},
1155 { 19, "-4 <= PH < -3"},
1156 { 20, "-3 <= PH < -2"},
1157 { 21, "-2 <= PH < -1"},
1158 { 22, "-1 <= PH < 0"},
1159 { 23, "0 <= PH < 1"},
1160 { 24, "1 <= PH < 2"},
1161 { 25, "2 <= PH < 3"},
1162 { 26, "3 <= PH < 4"},
1163 { 27, "4 <= PH < 5"},
1164 { 28, "5 <= PH < 6"},
1165 { 29, "6 <= PH < 7"},
1166 { 30, "7 <= PH < 8"},
1167 { 31, "8 <= PH < 9"},
1168 { 32, "9 <= PH < 10"},
1169 { 33, "10 <= PH < 11"},
1170 { 34, "11 <= PH < 12"},
1171 { 35, "12 <= PH < 13"},
1172 { 36, "13 <= PH < 14"},
1173 { 37, "14 <= PH < 15"},
1174 { 38, "15 <= PH < 16"},
1175 { 39, "16 <= PH < 17"},
1176 { 40, "17 <= PH < 18"},
1177 { 41, "18 <= PH < 19"},
1178 { 42, "19 <= PH < 20"},
1179 { 43, "20 <= PH < 21"},
1180 { 44, "21 <= PH < 22"},
1181 { 45, "22 <= PH < 23"},
1182 { 46, "23 <= PH < 24"},
1183 { 47, "24 <= PH < 25"},
1184 { 48, "25 <= PH < 26"},
1185 { 49, "26 <= PH < 27"},
1186 { 50, "27 <= PH < 28"},
1187 { 51, "28 <= PH < 29"},
1188 { 52, "29 <= PH < 30"},
1189 { 53, "30 <= PH < 31"},
1190 { 54, "31 <= PH < 32"},
1191 { 55, "32 <= PH < 33"},
1192 { 56, "33 <= PH < 34"},
1193 { 57, "34 <= PH < 35"},
1194 { 58, "34 <= PH < 36"},
1195 { 59, "36 <= PH < 37"},
1196 { 60, "37 <= PH < 38"},
1197 { 61, "38 <= PH < 39"},
1198 { 62, "39 <= PH < 40"},
1202 static value_string_ext power_headroom_vals_ext = VALUE_STRING_EXT_INIT(power_headroom_vals);
1204 static const value_string pcmaxc_vals[] =
1206 { 0, "Pcmax,c < -29"},
1207 { 1, "-29 <= Pcmax,c < -28"},
1208 { 2, "-28 <= Pcmax,c < -27"},
1209 { 3, "-27 <= Pcmax,c < -26"},
1210 { 4, "-26 <= Pcmax,c < -25"},
1211 { 5, "-25 <= Pcmax,c < -24"},
1212 { 6, "-24 <= Pcmax,c < -23"},
1213 { 7, "-23 <= Pcmax,c < -22"},
1214 { 8, "-22 <= Pcmax,c < -21"},
1215 { 9, "-21 <= Pcmax,c < -20"},
1216 { 10, "-20 <= Pcmax,c < -19"},
1217 { 11, "-19 <= Pcmax,c < -18"},
1218 { 12, "-18 <= Pcmax,c < -17"},
1219 { 13, "-17 <= Pcmax,c < -16"},
1220 { 14, "-16 <= Pcmax,c < -15"},
1221 { 15, "-15 <= Pcmax,c < -14"},
1222 { 16, "-14 <= Pcmax,c < -13"},
1223 { 17, "-13 <= Pcmax,c < -12"},
1224 { 18, "-12 <= Pcmax,c < -11"},
1225 { 19, "-11 <= Pcmax,c < -10"},
1226 { 20, "-10 <= Pcmax,c < -9"},
1227 { 21, "-9 <= Pcmax,c < -8"},
1228 { 22, "-8 <= Pcmax,c < -7"},
1229 { 23, "-7 <= Pcmax,c < -6"},
1230 { 24, "-6 <= Pcmax,c < -5"},
1231 { 25, "-5 <= Pcmax,c < -4"},
1232 { 26, "-4 <= Pcmax,c < -3"},
1233 { 27, "-3 <= Pcmax,c < -2"},
1234 { 28, "-2 <= Pcmax,c < -1"},
1235 { 29, "-1 <= Pcmax,c < 0"},
1236 { 30, "0 <= Pcmax,c < 1"},
1237 { 31, "1 <= Pcmax,c < 2"},
1238 { 32, "2 <= Pcmax,c < 3"},
1239 { 33, "3 <= Pcmax,c < 4"},
1240 { 34, "4 <= Pcmax,c < 5"},
1241 { 35, "5 <= Pcmax,c < 6"},
1242 { 36, "6 <= Pcmax,c < 7"},
1243 { 37, "7 <= Pcmax,c < 8"},
1244 { 38, "8 <= Pcmax,c < 9"},
1245 { 39, "9 <= Pcmax,c < 10"},
1246 { 40, "10 <= Pcmax,c < 11"},
1247 { 41, "11 <= Pcmax,c < 12"},
1248 { 42, "12 <= Pcmax,c < 13"},
1249 { 43, "13 <= Pcmax,c < 14"},
1250 { 44, "14 <= Pcmax,c < 15"},
1251 { 45, "15 <= Pcmax,c < 16"},
1252 { 46, "16 <= Pcmax,c < 17"},
1253 { 47, "17 <= Pcmax,c < 18"},
1254 { 48, "18 <= Pcmax,c < 19"},
1255 { 49, "19 <= Pcmax,c < 20"},
1256 { 50, "20 <= Pcmax,c < 21"},
1257 { 51, "21 <= Pcmax,c < 22"},
1258 { 52, "22 <= Pcmax,c < 23"},
1259 { 53, "23 <= Pcmax,c < 24"},
1260 { 54, "24 <= Pcmax,c < 25"},
1261 { 55, "25 <= Pcmax,c < 26"},
1262 { 56, "26 <= Pcmax,c < 27"},
1263 { 57, "27 <= Pcmax,c < 28"},
1264 { 58, "28 <= Pcmax,c < 29"},
1265 { 59, "29 <= Pcmax,c < 30"},
1266 { 60, "30 <= Pcmax,c < 31"},
1267 { 61, "31 <= Pcmax,c < 32"},
1268 { 62, "32 <= Pcmax,c < 33"},
1269 { 63, "33 <= Pcmax,c"},
1272 static value_string_ext pcmaxc_vals_ext = VALUE_STRING_EXT_INIT(pcmaxc_vals);
1274 static const value_string data_vol_power_headroom_level_vals[] =
1276 { 0, "POWER_HEADROOM_0"},
1277 { 1, "POWER_HEADROOM_1"},
1278 { 2, "POWER_HEADROOM_2"},
1279 { 3, "POWER_HEADROOM_3"},
1283 static const value_string data_vol_power_headroom_data_vol_vals[] =
1286 { 1, "0 < DV <= 10"},
1287 { 2, "10 < DV <= 14"},
1288 { 3, "14 < DV <= 19"},
1289 { 4, "19 < DV <= 26"},
1290 { 5, "26 < DV <= 36"},
1291 { 6, "36 < DV <= 49"},
1292 { 7, "49 < DV <= 67"},
1293 { 8, "67 < DV <= 91"},
1294 { 9, "91 < DV <= 125"},
1295 { 10, "125 < DV <= 171"},
1296 { 11, "171 < DV <= 234"},
1297 { 12, "234 < DV <= 321"},
1298 { 13, "321 < DV <= 768"},
1299 { 14, "768 < DV <= 1500"},
1304 static const value_string bit_rate_vals[] =
1306 { 0, "no bit rate recommendation"},
1322 { 16, "104 kbit/s"},
1323 { 17, "120 kbit/s"},
1324 { 18, "140 kbit/s"},
1325 { 19, "160 kbit/s"},
1326 { 20, "180 kbit/s"},
1327 { 21, "200 kbit/s"},
1328 { 22, "220 kbit/s"},
1329 { 23, "240 kbit/s"},
1330 { 24, "260 kbit/s"},
1331 { 25, "280 kbit/s"},
1332 { 26, "300 kbit/s"},
1333 { 27, "350 kbit/s"},
1334 { 28, "400 kbit/s"},
1335 { 29, "450 kbit/s"},
1336 { 30, "500 kbit/s"},
1337 { 31, "600 kbit/s"},
1338 { 32, "700 kbit/s"},
1339 { 33, "800 kbit/s"},
1340 { 34, "900 kbit/s"},
1341 { 35, "1000 kbit/s"},
1342 { 36, "1100 kbit/s"},
1343 { 37, "1200 kbit/s"},
1344 { 38, "1300 kbit/s"},
1345 { 39, "1400 kbit/s"},
1346 { 40, "1500 kbit/s"},
1347 { 41, "1750 kbit/s"},
1348 { 42, "2000 kbit/s"},
1349 { 43, "2250 kbit/s"},
1350 { 44, "2500 kbit/s"},
1351 { 45, "2750 kbit/s"},
1352 { 46, "3000 kbit/s"},
1353 { 47, "3500 kbit/s"},
1354 { 48, "4000 kbit/s"},
1355 { 49, "4500 kbit/s"},
1356 { 50, "5000 kbit/s"},
1357 { 51, "5500 kbit/s"},
1358 { 52, "6000 kbit/s"},
1359 { 53, "6500 kbit/s"},
1360 { 54, "7000 kbit/s"},
1361 { 55, "7500 kbit/s"},
1362 { 56, "8000 kbit/s"},
1365 static value_string_ext bit_rate_vals_ext = VALUE_STRING_EXT_INIT(bit_rate_vals);
1367 static const value_string header_only_vals[] =
1369 { 0, "MAC PDU Headers and body present"},
1370 { 1, "MAC PDU Headers only"},
1374 static const value_string predefined_frame_vals[] =
1376 { 0, "Real MAC PDU present - will dissect"},
1377 { 1, "Predefined frame present - will not dissect"},
1381 static const value_string ul_retx_grant_vals[] =
1388 /**************************************************************************/
1389 /* Preferences state */
1390 /**************************************************************************/
1392 /* If this PDU has been NACK'd (by HARQ) more than a certain number of times,
1393 we trigger an expert warning. */
1394 static gint global_mac_lte_retx_counter_trigger = 3;
1396 /* By default try to decode transparent data (BCH, PCH and CCCH) data using LTE RRC dissector */
1397 static gboolean global_mac_lte_attempt_rrc_decode = TRUE;
1399 /* Whether should attempt to dissect frames failing CRC check */
1400 static gboolean global_mac_lte_dissect_crc_failures = FALSE;
1402 /* Whether should attempt to decode lcid 1&2 SDUs as srb1/2 (i.e. AM RLC) */
1403 static gboolean global_mac_lte_attempt_srb_decode = TRUE;
1405 /* Whether should attempt to decode MCH LCID 0 as MCCH */
1406 static gboolean global_mac_lte_attempt_mcch_decode = FALSE;
1408 /* Whether should call RLC dissector to decode MTCH LCIDs */
1409 static gboolean global_mac_lte_call_rlc_for_mtch = FALSE;
1411 /* Where to take LCID -> DRB mappings from */
1412 enum lcid_drb_source {
1413 FromStaticTable, FromConfigurationProtocol
1415 static gint global_mac_lte_lcid_drb_source = (gint)FromStaticTable;
1417 /* Threshold for warning in expert info about high BSR values */
1418 static gint global_mac_lte_bsr_warn_threshold = 50; /* default is 19325 -> 22624 */
1420 /* Whether or not to track SRs and related frames */
1421 static gboolean global_mac_lte_track_sr = TRUE;
1423 /* Which layer info to show in the info column */
1424 enum layer_to_show {
1425 ShowPHYLayer, ShowMACLayer, ShowRLCLayer
1428 /* Which layer's details to show in Info column */
1429 static gint global_mac_lte_layer_to_show = (gint)ShowRLCLayer;
1431 /* Whether to decode Contention Resolution body as UL CCCH */
1432 static gboolean global_mac_lte_decode_cr_body = FALSE;
1434 /* Whether to record config and try to show DRX state for each configured UE */
1435 static gboolean global_mac_lte_show_drx = FALSE;
1437 /* Whether to record config and try to show DRX state for each configured UE */
1438 static gboolean global_mac_lte_show_BSR_median = FALSE;
1441 /* When showing RLC info, count PDUs so can append info column properly */
1442 static guint8 s_number_of_rlc_pdus_shown = 0;
1444 /***********************************************************************/
1445 /* How to dissect lcid 3-10 (presume drb logical channels) */
1447 static const value_string drb_lcid_vals[] = {
1459 typedef enum rlc_channel_type_t {
1471 rlcAMul16ulExtLiField,
1472 rlcAMdl16ulExtLiField,
1473 rlcAM16ulExtLiField,
1474 rlcAMul16dlExtLiField,
1475 rlcAMdl16dlExtLiField,
1476 rlcAM16dlExtLiField,
1477 rlcAMul16extLiField,
1478 rlcAMdl16extLiField,
1480 } rlc_channel_type_t;
1482 static const value_string rlc_channel_type_vals[] = {
1484 { rlcUM5 , "UM, SN Len=5"},
1485 { rlcUM10 , "UM, SN Len=10"},
1487 { rlcAMulExtLiField , "AM, UL Extended LI Field"},
1488 { rlcAMdlExtLiField , "AM, DL Extended LI Field"},
1489 { rlcAMextLiField , "AM, UL/DL Extended LI Field"},
1490 { rlcAMul16 , "AM, UL SN Len=16"},
1491 { rlcAMdl16 , "AM, DL SN Len=16"},
1492 { rlcAM16 , "AM, SN Len=16"},
1493 { rlcAMul16ulExtLiField, "AM, UL SN Len=16, UL Extended LI Field"},
1494 { rlcAMdl16ulExtLiField, "AM, DL SN Len=16, UL Extended LI Field"},
1495 { rlcAM16ulExtLiField , "AM, SN Len=16, UL Extended LI Field"},
1496 { rlcAMul16dlExtLiField, "AM, UL SN Len=16, DL Extended LI Field"},
1497 { rlcAMdl16dlExtLiField, "AM, DL SN Len=16, DL Extended LI Field"},
1498 { rlcAM16dlExtLiField , "AM, SN Len=16, DL Extended LI Field"},
1499 { rlcAMul16extLiField , "AM, UL SN Len=16, UL/DL Extended LI Field"},
1500 { rlcAMdl16extLiField , "AM, DL SN Len=16, UL/DL Extended LI Field"},
1501 { rlcAM16extLiField , "AM, SN Len=16, UL/DL Extended LI Field"},
1507 typedef struct lcid_drb_mapping_t {
1510 rlc_channel_type_t channel_type;
1511 } lcid_drb_mapping_t;
1513 /* Mapping entity */
1514 static lcid_drb_mapping_t *lcid_drb_mappings = NULL;
1515 static guint num_lcid_drb_mappings = 0;
1517 UAT_VS_DEF(lcid_drb_mappings, lcid, lcid_drb_mapping_t, guint16, 3, "LCID 3")
1518 UAT_SIGNED_DEC_CB_DEF(lcid_drb_mappings, drbid, lcid_drb_mapping_t)
1519 UAT_VS_DEF(lcid_drb_mappings, channel_type, lcid_drb_mapping_t, rlc_channel_type_t, rlcAM, "AM")
1522 static uat_t* lcid_drb_mappings_uat;
1524 /* Dynamic mappings (set by configuration protocol)
1525 LCID is the index into the array of these */
1526 typedef struct dynamic_lcid_drb_mapping_t {
1529 rlc_channel_type_t channel_type;
1531 } dynamic_lcid_drb_mapping_t;
1533 typedef struct ue_dynamic_drb_mappings_t {
1534 dynamic_lcid_drb_mapping_t mapping[11]; /* Index is LCID */
1535 guint8 drb_to_lcid_mappings[32]; /* Also map drbid -> lcid */
1536 } ue_dynamic_drb_mappings_t;
1538 static GHashTable *mac_lte_ue_channels_hash = NULL;
1541 extern int proto_rlc_lte;
1543 /***************************************************************/
1547 /***************************************************************/
1548 /* Keeping track of Msg3 bodies so they can be compared with */
1549 /* Contention Resolution bodies. */
1551 typedef struct Msg3Data {
1558 /* This table stores (RNTI -> Msg3Data*). Will be populated when
1559 Msg3 frames are first read. */
1560 static GHashTable *mac_lte_msg3_hash = NULL;
1562 typedef enum ContentionResolutionStatus {
1566 } ContentionResolutionStatus;
1568 typedef struct ContentionResolutionResult {
1569 ContentionResolutionStatus status;
1572 } ContentionResolutionResult;
1575 /* This table stores (CRFrameNum -> CRResult). It is assigned during the first
1576 pass and used thereafter */
1577 static GHashTable *mac_lte_cr_result_hash = NULL;
1579 /* This table stores msg3 frame -> CR frame. It is assigned during the first pass
1580 * and shown in later passes */
1581 static GHashTable *mac_lte_msg3_cr_hash = NULL;
1583 /**************************************************************************/
1587 /****************************************************************/
1588 /* Keeping track of last DL frames per C-RNTI so can guess when */
1589 /* there has been a HARQ retransmission */
1590 /* TODO: this should be simplified now that harq-id & ndi are */
1593 /* Could be bigger, but more than enough to flag suspected resends */
1594 #define MAX_EXPECTED_PDU_LENGTH 2048
1596 typedef struct LastFrameData {
1600 nstime_t received_time;
1602 guint8 data[MAX_EXPECTED_PDU_LENGTH];
1605 typedef struct DLHarqBuffers {
1606 LastFrameData harqid[2][15]; /* 2 blocks (1 for each antenna) needed for DL */
1610 /* This table stores (RNTI -> DLHARQBuffers*). Will be populated when
1611 DL frames are first read. */
1612 static GHashTable *mac_lte_dl_harq_hash = NULL;
1614 typedef struct DLHARQResult {
1615 gboolean previousSet, nextSet;
1616 guint previousFrameNum;
1617 guint timeSincePreviousFrame;
1619 guint timeToNextFrame;
1623 /* This table stores (FrameNumber -> *DLHARQResult). It is assigned during the first
1624 pass and used thereafter */
1625 static GHashTable *mac_lte_dl_harq_result_hash = NULL;
1627 /**************************************************************************/
1630 /*****************************************************************/
1631 /* Keeping track of last UL frames per C-RNTI so can verify when */
1632 /* told that a frame is a retx */
1634 typedef struct ULHarqBuffers {
1635 LastFrameData harqid[8];
1639 /* This table stores (RNTI -> ULHarqBuffers*). Will be populated when
1640 UL frames are first read. */
1641 static GHashTable *mac_lte_ul_harq_hash = NULL;
1643 typedef struct ULHARQResult {
1644 gboolean previousSet, nextSet;
1645 guint previousFrameNum;
1646 guint timeSincePreviousFrame;
1648 guint timeToNextFrame;
1652 /* This table stores (FrameNum -> ULHARQResult). It is assigned during the first
1653 pass and used thereafter */
1654 /* TODO: add ueid/rnti to key... */
1655 static GHashTable *mac_lte_ul_harq_result_hash = NULL;
1657 /**************************************************************************/
1660 /**************************************************************************/
1661 /* Tracking of Scheduling Requests (SRs). */
1662 /* Keep track of: */
1663 /* - last grant before SR */
1664 /* - SR failures following request */
1665 /* - grant following SR */
1667 typedef enum SREvent {
1673 static const value_string sr_event_vals[] =
1675 { SR_Grant, "Grant"},
1676 { SR_Request, "SR Request"},
1677 { SR_Failure, "SR Failure"},
1681 typedef enum SRStatus {
1687 static const value_string sr_status_vals[] =
1689 { None, "Receiving grants"},
1690 { SR_Outstanding, "SR Request outstanding"},
1691 { SR_Failed, "SR has Failed"},
1696 typedef struct SRState {
1698 guint32 lastSRFramenum;
1699 guint32 lastGrantFramenum;
1700 nstime_t requestTime;
1704 /* This table keeps track of the SR state for each UE.
1705 (RNTI -> SRState) */
1706 static GHashTable *mac_lte_ue_sr_state = NULL;
1709 typedef enum SRResultType {
1718 typedef struct SRResult {
1721 guint32 timeDifference;
1723 /* These 2 are only used with InvalidSREvent */
1728 /* Entries in this table are created during the first pass
1729 It maps (SRFrameNum -> SRResult) */
1730 static GHashTable *mac_lte_sr_request_hash = NULL;
1732 /**************************************************************************/
1735 typedef struct drx_running_state_t
1737 gboolean firstCycleStartSet;
1739 /* Cycle information */
1740 gboolean inShortCycle;
1743 nstime_t currentTime; /* absolute time of last PDU. Used to detect whole
1744 missing SFN cycle */
1746 guint64 currentTicks;
1750 /* These timers are absolute times when these events expire */
1751 guint64 onDurationTimer;
1752 guint64 inactivityTimer;
1754 guint64 retransmissionTimer[8];
1755 guint64 shortCycleTimer;
1757 } drx_running_state_t;
1759 /* Have 2 states for each PDU. One for before the PDU/event, and one after.
1760 Only then can show if we don't think it should have been active at that point... */
1761 typedef struct drx_state_t {
1762 drx_config_t config;
1763 drx_running_state_t state_before;
1764 drx_running_state_t state_after;
1767 typedef struct ue_parameters_t
1769 gboolean use_ext_bsr_sizes;
1770 gboolean use_simult_pucch_pusch_pcell;
1771 gboolean use_simult_pucch_pusch_pscell;
1772 gboolean drx_state_valid;
1773 drx_state_t drx_state;
1776 /* Entries in this table are maintained during the first pass
1777 It maps (UEId -> ue_parameters_t). */
1778 static GHashTable *mac_lte_ue_parameters = NULL;
1781 /**************************************************************************/
1783 /* Config for current cycle/timer state for a configured UE */
1786 typedef struct drx_state_key_t {
1787 guint32 frameNumber;
1791 /* Entries in this table are written during the first pass
1792 It maps (drx_state_key_t -> drx_state_t), so state at that point may be shown. */
1793 static GHashTable *mac_lte_drx_frame_result = NULL;
1795 static gint mac_lte_framenum_instance_hash_equal(gconstpointer v, gconstpointer v2)
1797 const drx_state_key_t *p1 = (const drx_state_key_t*)v;
1798 const drx_state_key_t *p2 = (const drx_state_key_t*)v2;
1800 return ((p1->frameNumber == p2->frameNumber) &&
1801 (p1->pdu_instance == p2->pdu_instance));
1804 static guint mac_lte_framenum_instance_hash_func(gconstpointer v)
1806 const drx_state_key_t *p1 = (const drx_state_key_t*)v;
1808 return p1->frameNumber + (p1->pdu_instance >> 8);
1814 /* Initialise the UE DRX state */
1815 static void init_drx_ue_state(drx_state_t *drx_state, gboolean at_init)
1818 drx_state->state_before.inShortCycle = FALSE;
1820 drx_state->state_before.onDurationTimer = G_GUINT64_CONSTANT(0);
1822 drx_state->state_before.inactivityTimer = G_GUINT64_CONSTANT(0);
1823 for (i=0; i < 8; i++) {
1824 drx_state->state_before.RTT[i] = G_GUINT64_CONSTANT(0);
1825 drx_state->state_before.retransmissionTimer[i] = G_GUINT64_CONSTANT(0);
1827 drx_state->state_before.shortCycleTimer = G_GUINT64_CONSTANT(0);
1830 typedef enum drx_timer_type_t {
1831 drx_onduration_timer,
1832 drx_inactivity_timer,
1835 drx_short_cycle_timer
1838 /* Start the specified timer. Use the time period in the config */
1839 static void mac_lte_drx_start_timer(drx_state_t *p_state, drx_timer_type_t timer_type, guint8 timer_id)
1841 /* Get current time in ms */
1843 guint16 timerLength;
1845 /* Get pointer to timer value, and fetch from config how much to add to it */
1846 switch (timer_type) {
1847 case drx_onduration_timer:
1848 pTimer = &(p_state->state_before.onDurationTimer);
1849 timerLength = p_state->config.onDurationTimer;
1851 case drx_inactivity_timer:
1852 pTimer = &(p_state->state_before.inactivityTimer);
1853 timerLength = p_state->config.inactivityTimer;
1856 pTimer = &(p_state->state_before.RTT[timer_id]);
1859 case drx_retx_timer:
1860 pTimer = &(p_state->state_before.retransmissionTimer[timer_id]);
1861 timerLength = p_state->config.retransmissionTimer;
1863 case drx_short_cycle_timer:
1865 pTimer = &(p_state->state_before.shortCycleTimer);
1866 timerLength = p_state->config.shortCycle * p_state->config.shortCycleTimer;
1871 *pTimer = p_state->state_before.currentTicks + timerLength;
1874 /* Stop the specified timer. */
1875 static void mac_lte_drx_stop_timer(drx_state_t *p_state, drx_timer_type_t timer_type, guint8 timer_id)
1877 /* Set indicated timer value to 0 */
1878 switch (timer_type) {
1879 case drx_onduration_timer:
1880 p_state->state_before.onDurationTimer = G_GUINT64_CONSTANT(0);
1882 case drx_inactivity_timer:
1883 p_state->state_before.inactivityTimer = G_GUINT64_CONSTANT(0);
1886 p_state->state_before.RTT[timer_id] = G_GUINT64_CONSTANT(0);
1888 case drx_retx_timer:
1889 p_state->state_before.retransmissionTimer[timer_id] = G_GUINT64_CONSTANT(0);
1891 case drx_short_cycle_timer:
1892 p_state->state_before.shortCycleTimer = G_GUINT64_CONSTANT(0);
1897 /* Has the specified timer expired? */
1898 static gboolean mac_lte_drx_has_timer_expired(drx_state_t *p_state, drx_timer_type_t timer_type, guint8 timer_id,
1899 gboolean before_event,
1900 guint64 *time_until_expires)
1902 guint64 *pTimer = NULL;
1903 drx_running_state_t *state_to_use;
1906 state_to_use = &p_state->state_before;
1909 state_to_use = &p_state->state_after;
1913 /* Get pointer to timer value */
1914 switch (timer_type) {
1915 case drx_onduration_timer:
1916 pTimer = &(state_to_use->onDurationTimer);
1918 case drx_inactivity_timer:
1919 pTimer = &(state_to_use->inactivityTimer);
1922 pTimer = &(state_to_use->RTT[timer_id]);
1924 case drx_retx_timer:
1925 pTimer = &(state_to_use->retransmissionTimer[timer_id]);
1927 case drx_short_cycle_timer:
1928 pTimer = &(state_to_use->shortCycleTimer);
1935 /* TODO: verify using SFN/SF ? */
1936 if (state_to_use->currentTicks == *pTimer) {
1937 *time_until_expires = 0;
1941 if (state_to_use->currentTicks > *pTimer) {
1942 *time_until_expires = 0;
1945 *time_until_expires = *pTimer - state_to_use->currentTicks;
1952 /* Handling of triggers that can prompt changes in state */
1954 static void mac_lte_drx_new_ulsch_data(guint16 ueid)
1956 /* Look up state of this UE */
1957 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
1958 GUINT_TO_POINTER((guint)ueid));
1960 /* Start inactivity timer */
1961 if ((ue_params != NULL) && ue_params->drx_state_valid) {
1962 mac_lte_drx_start_timer(&ue_params->drx_state, drx_inactivity_timer, 0);
1966 static void mac_lte_drx_new_dlsch_data(guint16 ueid)
1968 /* Look up state of this UE */
1969 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
1970 GUINT_TO_POINTER((guint)ueid));
1972 /* Start retransmission timer */
1973 if ((ue_params != NULL) && ue_params->drx_state_valid) {
1974 mac_lte_drx_start_timer(&ue_params->drx_state, drx_inactivity_timer, 0);
1978 static void mac_lte_drx_dl_crc_error(guint16 ueid)
1980 /* Look up state of this UE */
1981 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
1982 GUINT_TO_POINTER((guint)ueid));
1985 if ((ue_params != NULL) && ue_params->drx_state_valid) {
1986 mac_lte_drx_start_timer(&ue_params->drx_state, drx_retx_timer, 0);
1990 /* A DRX control element has been received */
1991 static void mac_lte_drx_control_element_received(guint16 ueid)
1993 /* Look up state of this UE */
1994 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
1995 GUINT_TO_POINTER((guint)ueid));
1998 if ((ue_params != NULL) && ue_params->drx_state_valid) {
1999 mac_lte_drx_stop_timer(&ue_params->drx_state, drx_onduration_timer, 0);
2000 mac_lte_drx_stop_timer(&ue_params->drx_state, drx_inactivity_timer, 0);
2005 /* Update the DRX state of the UE based on previous info and current time.
2006 This is called every time a UE with DRX configured has an UL or DL PDU */
2007 static void update_drx_info(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
2010 guint64 time_until_expires;
2012 /* Look up state of this UE */
2013 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2014 GUINT_TO_POINTER((guint)p_mac_lte_info->ueid));
2016 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2017 /* We loop until we find this subframe */
2018 drx_state_t *ue_state = &ue_params->drx_state;
2019 guint16 SFN = p_mac_lte_info->sysframeNumber;
2020 guint16 SF = p_mac_lte_info->subframeNumber;
2022 /* Make sure the first time reference has been set */
2023 if (!ue_state->state_before.firstCycleStartSet) {
2024 /* Set current time to now */
2025 ue_state->state_before.currentSFN = SFN;
2026 ue_state->state_before.currentSF = SF;
2028 ue_state->state_before.currentTicks = SFN*10 + SF;
2030 ue_state->state_before.firstCycleStartSet = TRUE;
2033 /* Will loop around these checks, once for each subframe between previous
2034 currentTime for this UE, and the time now!!! */
2035 /* It *should* be possible to just deal with the elapsed time all at once,
2036 but much harder to get right, so loop. */
2038 /* If > ~10s since last PDU, just zero all timers (except onDuration) */
2039 if ((pinfo->abs_ts.secs - ue_state->state_before.currentTime.secs) >= 9) {
2040 init_drx_ue_state(ue_state, FALSE);
2043 while ((ue_state->state_before.currentSFN != SFN) || (ue_state->state_before.currentSF != SF)) {
2044 guint16 subframes = ue_state->state_before.currentSFN*10 + ue_state->state_before.currentSF;
2046 /* Check for timers that have expired and change state accordingly */
2048 /* Short -> long transition */
2049 if (ue_state->state_before.inShortCycle) {
2050 if (mac_lte_drx_has_timer_expired(ue_state, drx_short_cycle_timer, 0, TRUE, &time_until_expires)) {
2051 ue_state->state_before.inShortCycle = FALSE;
2055 /* See if onDuration timer should be started */
2057 if (!ue_state->state_before.inShortCycle) {
2058 if ((subframes % ue_state->config.longCycle) == ue_state->config.cycleOffset) {
2059 mac_lte_drx_start_timer(ue_state, drx_onduration_timer, 0);
2063 if ((subframes % ue_state->config.shortCycle) == (ue_state->config.cycleOffset % ue_state->config.shortCycle)) {
2064 mac_lte_drx_start_timer(ue_state, drx_onduration_timer, 0);
2068 /* Check for HARQ RTT Timer expiring.
2069 In practice only one could expire in any given subframe... */
2070 for (harq_id = 0 ; harq_id < 8; harq_id++) {
2071 if (mac_lte_drx_has_timer_expired(ue_state, drx_rtt_timer, harq_id, TRUE, &time_until_expires)) {
2072 /* Start the Retransmission timer */
2073 mac_lte_drx_start_timer(ue_state, drx_retx_timer, harq_id);
2077 /* Reception of DRX command is dealt with separately at the moment... */
2079 /* Inactivity timer expired */
2080 if (mac_lte_drx_has_timer_expired(ue_state, drx_inactivity_timer, 0, TRUE, &time_until_expires)) {
2081 if (ue_state->config.shortCycleConfigured) {
2082 ue_state->state_before.inShortCycle = TRUE;
2083 mac_lte_drx_start_timer(ue_state, drx_short_cycle_timer, 0);
2088 /* Move subframe along by one */
2089 if (ue_state->state_before.currentSF == 9) {
2090 ue_state->state_before.currentSF = 0;
2091 if (ue_state->state_before.currentSFN == 1023) {
2092 ue_state->state_before.currentSFN = 0;
2095 ue_state->state_before.currentSFN++;
2099 ue_state->state_before.currentSF++;
2102 ue_state->state_before.currentTicks++;
2105 /* Set current time to now */
2106 ue_state->state_before.currentTime = pinfo->abs_ts;
2110 /* Convenience function to get a pointer for the hash_func to work with */
2111 static gpointer get_drx_result_hash_key(guint32 frameNumber,
2113 gboolean do_persist)
2115 static drx_state_key_t key;
2116 drx_state_key_t *p_key;
2118 /* Only allocate a struct when will be adding entry */
2120 p_key = wmem_new0(wmem_file_scope(), drx_state_key_t);
2123 memset(&key, 0, sizeof(drx_state_key_t));
2127 /* Fill in details, and return pointer */
2128 p_key->frameNumber = frameNumber;
2129 p_key->pdu_instance = pdu_instance;
2135 /* Set DRX information to display for the current MAC frame.
2136 Only called on first pass through frames. */
2137 static void set_drx_info(packet_info *pinfo, mac_lte_info *p_mac_lte_info, gboolean before_event, guint pdu_instance)
2139 /* Look up state of this UE */
2140 ue_parameters_t *ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters,
2141 GUINT_TO_POINTER((guint)p_mac_lte_info->ueid));
2142 drx_state_t *frame_result;
2144 if ((ue_params != NULL) && ue_params->drx_state_valid) {
2145 /* Should only need to allocate frame_result and add to the result table when
2146 before PDU is processed */
2148 /* Copy UE snapshot for this frame, and add to result table */
2149 frame_result = wmem_new(wmem_file_scope(), drx_state_t);
2151 /* Deep-copy this snapshot for this frame */
2152 *frame_result = ue_params->drx_state;
2154 /* And store in table */
2155 g_hash_table_insert(mac_lte_drx_frame_result, get_drx_result_hash_key(pinfo->num, pdu_instance, TRUE), frame_result);
2158 /* After update, so just copy ue_state 'state' info after part of frame */
2159 frame_result = (drx_state_t*)g_hash_table_lookup(mac_lte_drx_frame_result,
2160 get_drx_result_hash_key(pinfo->num, pdu_instance, FALSE));
2161 if (frame_result != NULL) {
2162 /* Deep-copy updated state from UE */
2163 frame_result->state_after = ue_params->drx_state.state_before;
2169 /* Show DRX information associated with this MAC frame */
2170 static void show_drx_info(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
2171 mac_lte_info *p_mac_lte_info, gboolean before_event, guint pdu_instance)
2173 drx_state_t *frame_state;
2174 drx_running_state_t *state_to_show;
2175 guint64 time_until_expires;
2178 /* Look up entry by frame number in result table */
2179 frame_state = (drx_state_t *)g_hash_table_lookup(mac_lte_drx_frame_result,
2180 get_drx_result_hash_key(pinfo->num, pdu_instance, FALSE));
2182 /* Show available information */
2183 if (frame_state != NULL) {
2184 proto_tree *drx_config_tree, *drx_state_tree;
2185 proto_item *drx_config_ti, *drx_state_ti, *ti;
2187 /* Show config only if 'before */
2189 /************************************/
2190 /* Create config subtree */
2191 drx_config_ti = proto_tree_add_string_format(tree, hf_mac_lte_drx_config,
2192 tvb, 0, 0, "", "DRX Config");
2193 drx_config_tree = proto_item_add_subtree(drx_config_ti, ett_mac_lte_drx_config);
2194 proto_item_set_generated(drx_config_ti);
2196 /* Link back to configuration (RRC) frame */
2197 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_frame_num, tvb,
2198 0, 0, frame_state->config.frameNum);
2199 proto_item_set_generated(ti);
2201 /* Link back to any previous config frame (only from current config frame) */
2202 if ((frame_state->config.frameNum == pinfo->num) &&
2203 (frame_state->config.previousFrameNum != 0)) {
2204 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_previous_frame_num, tvb,
2205 0, 0, frame_state->config.previousFrameNum);
2206 proto_item_set_generated(ti);
2210 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_long_cycle, tvb,
2211 0, 0, frame_state->config.longCycle);
2212 proto_item_set_generated(ti);
2213 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_cycle_offset, tvb,
2214 0, 0, frame_state->config.cycleOffset);
2215 proto_item_set_generated(ti);
2216 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_onduration_timer, tvb,
2217 0, 0, frame_state->config.onDurationTimer);
2218 proto_item_set_generated(ti);
2219 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_inactivity_timer, tvb,
2220 0, 0, frame_state->config.inactivityTimer);
2221 proto_item_set_generated(ti);
2222 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_retransmission_timer, tvb,
2223 0, 0, frame_state->config.retransmissionTimer);
2224 proto_item_set_generated(ti);
2226 if (frame_state->config.shortCycleConfigured) {
2227 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_short_cycle, tvb,
2228 0, 0, frame_state->config.shortCycle);
2229 proto_item_set_generated(ti);
2231 ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_short_cycle_timer, tvb,
2232 0, 0, frame_state->config.shortCycleTimer);
2233 proto_item_set_generated(ti);
2236 proto_item_append_text(drx_config_ti, " (Long-cycle=%u cycle-offset=%u onDuration=%u)",
2237 frame_state->config.longCycle, frame_state->config.cycleOffset,
2238 frame_state->config.onDurationTimer);
2239 if (frame_state->config.shortCycleConfigured) {
2240 proto_item_append_text(drx_config_ti, " (Short-cycle=%u Short-cycle-timer=%u)",
2241 frame_state->config.shortCycle, frame_state->config.shortCycleTimer);
2245 /*************************************/
2246 /* Create state subtree */
2247 drx_state_ti = proto_tree_add_string_format(tree, hf_mac_lte_drx_state,
2249 (before_event) ? "DRX State Before" : "DRX State After");
2250 /* Get appropriate state pointer to use below */
2252 state_to_show = &frame_state->state_before;
2255 state_to_show = &frame_state->state_after;
2258 drx_state_tree = proto_item_add_subtree(drx_state_ti, ett_mac_lte_drx_state);
2259 proto_item_set_generated(drx_state_ti);
2261 /* Show cycle information */
2263 if (!state_to_show->inShortCycle) {
2264 /* Show where we are in current long cycle */
2265 guint16 offset_into_long_cycle = ((p_mac_lte_info->sysframeNumber*10) + p_mac_lte_info->subframeNumber) %
2266 frame_state->config.longCycle;
2267 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_long_cycle_offset, tvb,
2268 0, 0, offset_into_long_cycle);
2269 proto_item_set_generated(ti);
2272 /* Show where we are inside short cycle */
2273 guint16 offset_into_short_cycle = ((p_mac_lte_info->sysframeNumber*10) + p_mac_lte_info->subframeNumber) %
2274 frame_state->config.shortCycle;
2276 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_short_cycle_offset, tvb,
2277 0, 0, offset_into_short_cycle);
2278 proto_item_set_generated(ti);
2280 /* Is short-cycle-timer running? */
2281 if (!mac_lte_drx_has_timer_expired(frame_state, drx_short_cycle_timer, 0, before_event, &time_until_expires)) {
2282 if (time_until_expires) {
2283 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_short_cycle_remaining, tvb,
2284 0, 0, (guint16)time_until_expires);
2285 proto_item_set_generated(ti);
2290 /* Show which timers are still running and how long they have to go.
2291 TODO: Complain if it looks like DRX looks like it should be on
2292 TODO: if PDU is a retranmission, would be good to check to see if DRX
2293 would have been on for original Tx! */
2295 /* Is onduration timer running? */
2296 if (!mac_lte_drx_has_timer_expired(frame_state, drx_onduration_timer, 0, before_event, &time_until_expires)) {
2297 if (time_until_expires) {
2298 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_onduration_remaining, tvb,
2299 0, 0, (guint16)time_until_expires);
2300 proto_item_set_generated(ti);
2304 /* Is inactivity timer running? */
2305 if (!mac_lte_drx_has_timer_expired(frame_state, drx_inactivity_timer, 0, before_event, &time_until_expires)) {
2306 if (time_until_expires) {
2307 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_inactivity_remaining, tvb,
2308 0, 0, (guint16)time_until_expires);
2309 proto_item_set_generated(ti);
2313 /* Are any of the Retransmission timers running? */
2314 for (n=0; n < 8; n++) {
2315 if (!mac_lte_drx_has_timer_expired(frame_state, drx_retx_timer, n, before_event, &time_until_expires)) {
2316 if (time_until_expires) {
2317 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_retransmission_remaining, tvb,
2318 0, 0, (guint16)time_until_expires);
2319 proto_item_set_generated(ti);
2320 proto_item_append_text(ti, " (harqid=%u)", n);
2325 /* Are any of the RTT timers running? */
2326 for (n=0; n < 8; n++) {
2327 if (!mac_lte_drx_has_timer_expired(frame_state, drx_rtt_timer, n, before_event, &time_until_expires)) {
2328 if (time_until_expires) {
2329 ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_rtt_remaining, tvb,
2330 0, 0, (guint16)time_until_expires);
2331 proto_item_set_generated(ti);
2332 proto_item_append_text(ti, " (harqid=%u)", n);
2340 /**************************************************************************/
2343 /* Info we might learn from SIB2 to label RAPIDs seen in PRACH and RARs */
2344 static gboolean s_rapid_ranges_configured = FALSE;
2345 static guint s_rapid_ranges_groupA;
2346 static guint s_rapid_ranges_RA;
2348 /* Return TRUE if we have been configured. Set out parameter to point at
2349 a literal string tha may be safely referenced afterwards */
2350 static const gchar *get_mac_lte_rapid_description(guint8 rapid)
2352 if (!s_rapid_ranges_configured) {
2356 if (rapid < s_rapid_ranges_groupA) {
2359 else if (rapid < s_rapid_ranges_RA) {
2368 /**************************************************************************/
2369 /* Tracking of extended BSR sizes configuration */
2372 get_mac_lte_ue_ext_bsr_sizes(mac_lte_info *p_mac_lte_info)
2374 gpointer p_orig_key, p_ue_params;
2376 /* Use the _extended function to check the key presence and avoid overriding a
2377 value already set by the framing protocol while no RRC value is configured */
2378 if (g_hash_table_lookup_extended(mac_lte_ue_parameters,
2379 GUINT_TO_POINTER((guint)p_mac_lte_info->ueid),
2380 &p_orig_key, &p_ue_params)) {
2381 p_mac_lte_info->isExtendedBSRSizes = ((ue_parameters_t *)p_ue_params)->use_ext_bsr_sizes;
2385 /**************************************************************************/
2386 /* Tracking of simultaneous PUCCH/PUSCH configuration */
2389 get_mac_lte_ue_simult_pucch_pusch(mac_lte_info *p_mac_lte_info)
2391 gpointer p_orig_key, p_ue_params;
2393 /* Use the _extended function to check the key presence and avoid overriding a
2394 value already set by the framing protocol while no RRC value is configured */
2395 if (g_hash_table_lookup_extended(mac_lte_ue_parameters,
2396 GUINT_TO_POINTER((guint)p_mac_lte_info->ueid),
2397 &p_orig_key, &p_ue_params)) {
2398 p_mac_lte_info->isSimultPUCCHPUSCHPCell = ((ue_parameters_t *)p_ue_params)->use_simult_pucch_pusch_pcell;
2399 p_mac_lte_info->isSimultPUCCHPUSCHPSCell = ((ue_parameters_t *)p_ue_params)->use_simult_pucch_pusch_pscell;
2403 /* Forward declarations */
2404 int dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*);
2406 static guint8 get_mac_lte_channel_priority(guint16 ueid _U_, guint8 lcid,
2411 call_with_catch_all(dissector_handle_t handle, tvbuff_t* tvb, packet_info *pinfo, proto_tree *tree)
2413 /* Call it (catch exceptions so that stats will be updated) */
2416 call_dissector_only(handle, tvb, pinfo, tree, NULL);
2424 /* Dissect context fields in the format described in packet-mac-lte.h.
2425 Return TRUE if the necessary information was successfully found */
2426 gboolean dissect_mac_lte_context_fields(struct mac_lte_info *p_mac_lte_info, tvbuff_t *tvb,
2427 packet_info *pinfo, proto_tree *tree, gint *p_offset)
2429 gint offset = *p_offset;
2432 /* Read fixed fields */
2433 p_mac_lte_info->radioType = tvb_get_guint8(tvb, offset++);
2434 p_mac_lte_info->direction = tvb_get_guint8(tvb, offset++);
2436 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2437 p_mac_lte_info->detailed_phy_info.ul_info.present = FALSE;
2440 p_mac_lte_info->detailed_phy_info.dl_info.present = FALSE;
2443 p_mac_lte_info->rntiType = tvb_get_guint8(tvb, offset++);
2445 p_mac_lte_info->sfnSfInfoPresent = FALSE; /* Set this to true later if the relative tag is read */
2447 /* Initialize RNTI with a default value in case optional field is not present */
2448 switch (p_mac_lte_info->rntiType) {
2450 p_mac_lte_info->rnti = 0xFFFB;
2453 p_mac_lte_info->rnti = 0xFFFD;
2456 p_mac_lte_info->rnti = 0xFFFE;
2459 p_mac_lte_info->rnti = 0xFFFF;
2466 p_mac_lte_info->rnti = 0x0001;
2472 /* Read optional fields */
2473 while (tag != MAC_LTE_PAYLOAD_TAG) {
2474 /* Process next tag */
2475 tag = tvb_get_guint8(tvb, offset++);
2477 case MAC_LTE_RNTI_TAG:
2478 p_mac_lte_info->rnti = tvb_get_ntohs(tvb, offset);
2481 case MAC_LTE_UEID_TAG:
2482 p_mac_lte_info->ueid = tvb_get_ntohs(tvb, offset);
2485 case MAC_LTE_FRAME_SUBFRAME_TAG:
2487 p_mac_lte_info->sfnSfInfoPresent = TRUE;
2488 guint16 sfn_sf = tvb_get_ntohs(tvb, offset);
2489 p_mac_lte_info->sysframeNumber = (sfn_sf >> 4) & 0x03ff;
2490 p_mac_lte_info->subframeNumber = sfn_sf & 0x000f;
2494 case MAC_LTE_PREDEFINED_DATA_TAG:
2495 p_mac_lte_info->isPredefinedData = tvb_get_guint8(tvb, offset);
2498 case MAC_LTE_RETX_TAG:
2499 p_mac_lte_info->reTxCount = tvb_get_guint8(tvb, offset);
2502 case MAC_LTE_CRC_STATUS_TAG:
2503 p_mac_lte_info->crcStatusValid = TRUE;
2504 p_mac_lte_info->crcStatus =
2505 (mac_lte_crc_status)tvb_get_guint8(tvb, offset);
2508 case MAC_LTE_EXT_BSR_SIZES_TAG:
2509 p_mac_lte_info->isExtendedBSRSizes = TRUE;
2511 case MAC_LTE_SEND_PREAMBLE_TAG:
2512 p_mac_lte_info->oob_event = ltemac_send_preamble;
2513 p_mac_lte_info->rapid = tvb_get_guint8(tvb, offset);
2515 p_mac_lte_info->rach_attempt_number = tvb_get_guint8(tvb, offset);
2518 case MAC_LTE_CARRIER_ID_TAG:
2519 p_mac_lte_info->carrierId =
2520 (mac_lte_carrier_id)tvb_get_guint8(tvb, offset);
2523 case MAC_LTE_PHY_TAG:
2527 len = tvb_get_guint8(tvb, offset++);
2529 if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
2532 p_mac_lte_info->detailed_phy_info.dl_info.present = TRUE;
2533 p_mac_lte_info->detailed_phy_info.dl_info.dci_format =
2534 tvb_get_guint8(tvb, offset);
2536 p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type =
2537 tvb_get_guint8(tvb, offset);
2539 p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level =
2540 tvb_get_guint8(tvb, offset);
2542 p_mac_lte_info->detailed_phy_info.dl_info.mcs_index =
2543 tvb_get_guint8(tvb, offset);
2545 p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index =
2546 tvb_get_guint8(tvb, offset);
2548 p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length =
2549 tvb_get_guint8(tvb, offset);
2551 p_mac_lte_info->detailed_phy_info.dl_info.harq_id =
2552 tvb_get_guint8(tvb, offset);
2554 p_mac_lte_info->detailed_phy_info.dl_info.ndi =
2555 tvb_get_guint8(tvb, offset);
2557 p_mac_lte_info->detailed_phy_info.dl_info.transport_block =
2558 tvb_get_guint8(tvb, offset);
2560 p_mac_lte_info->dl_retx =
2561 (mac_lte_dl_retx)tvb_get_guint8(tvb, offset);
2565 p_mac_lte_info->detailed_phy_info.ul_info.present = TRUE;
2566 p_mac_lte_info->detailed_phy_info.ul_info.modulation_type =
2567 tvb_get_guint8(tvb, offset);
2569 p_mac_lte_info->detailed_phy_info.ul_info.tbs_index =
2570 tvb_get_guint8(tvb, offset);
2572 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length =
2573 tvb_get_guint8(tvb, offset);
2575 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start =
2576 tvb_get_guint8(tvb, offset);
2578 p_mac_lte_info->detailed_phy_info.ul_info.harq_id =
2579 tvb_get_guint8(tvb, offset);
2581 p_mac_lte_info->detailed_phy_info.ul_info.ndi =
2582 tvb_get_guint8(tvb, offset);
2585 offset = offset1 + len;
2588 case MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG:
2589 p_mac_lte_info->isSimultPUCCHPUSCHPCell = TRUE;
2591 case MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG:
2592 p_mac_lte_info->isSimultPUCCHPUSCHPSCell = TRUE;
2594 case MAC_LTE_CE_MODE_TAG:
2595 p_mac_lte_info->ceMode =
2596 (mac_lte_ce_mode)tvb_get_guint8(tvb, offset);
2599 case MAC_LTE_NB_MODE_TAG:
2600 p_mac_lte_info->nbMode =
2601 (mac_lte_nb_mode)tvb_get_guint8(tvb, offset);
2604 case MAC_LTE_N_UL_RB_TAG:
2606 guint8 nUlRb = tvb_get_guint8(tvb, offset);
2615 p_mac_lte_info->nUlRb = nUlRb;
2622 case MAC_LTE_SR_TAG:
2625 // Read number of entries.
2626 guint16 no_entries = tvb_get_ntohs(tvb, offset);
2628 if ((no_entries == 0) || (no_entries > MAX_SRs)) {
2632 p_mac_lte_info->oob_event = ltemac_send_sr;
2633 p_mac_lte_info->number_of_srs = no_entries;
2637 for (n=0; n < no_entries; n++) {
2638 p_mac_lte_info->oob_ueid[n] = tvb_get_ntohs(tvb, offset);
2640 p_mac_lte_info->oob_rnti[n] = tvb_get_ntohs(tvb, offset);
2646 case MAC_LTE_PAYLOAD_TAG:
2647 /* Have reached data, so set payload length and get out of loop */
2648 /* TODO: this is not correct if there is padding which isn't in frame */
2649 p_mac_lte_info->length= tvb_reported_length_remaining(tvb, offset);
2653 /* It must be a recognised tag */
2656 proto_tree *subtree;
2658 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
2659 col_clear(pinfo->cinfo, COL_INFO);
2660 ti = proto_tree_add_item(tree, proto_mac_lte, tvb, offset, tvb_reported_length(tvb), ENC_NA);
2661 subtree = proto_item_add_subtree(ti, ett_mac_lte);
2662 proto_tree_add_expert(subtree, pinfo, &ei_mac_lte_unknown_udp_framing_tag,
2665 wmem_free(wmem_file_scope(), p_mac_lte_info);
2670 /* Pass out where offset is now */
2676 /* Heuristic dissector looks for supported framing protocol (see wiki page) */
2677 static gboolean dissect_mac_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
2678 proto_tree *tree, void *data _U_)
2681 struct mac_lte_info *p_mac_lte_info;
2684 /* Needs to be at least as long as:
2685 - the signature string
2686 - fixed header bytes
2688 - at least one byte of MAC PDU payload */
2689 if (tvb_captured_length_remaining(tvb, offset) < (gint)(strlen(MAC_LTE_START_STRING)+3+2)) {
2693 /* OK, compare with signature string */
2694 if (tvb_strneql(tvb, offset, MAC_LTE_START_STRING, strlen(MAC_LTE_START_STRING)) != 0) {
2697 offset += (gint)strlen(MAC_LTE_START_STRING);
2699 /* If redissecting, use previous info struct (if available) */
2700 p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
2701 if (p_mac_lte_info == NULL) {
2702 /* Allocate new info struct for this frame */
2703 p_mac_lte_info = wmem_new0(wmem_file_scope(), struct mac_lte_info);
2704 /* Dissect the fields to populate p_mac_lte */
2705 if (!dissect_mac_lte_context_fields(p_mac_lte_info, tvb, pinfo, tree, &offset)) {
2708 /* Store info in packet */
2709 p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info);
2712 offset = tvb_reported_length(tvb) - p_mac_lte_info->length;
2715 /**************************************/
2716 /* OK, now dissect as MAC LTE */
2718 /* Create tvb that starts at actual MAC PDU */
2719 mac_tvb = tvb_new_subset_remaining(tvb, offset);
2720 dissect_mac_lte(mac_tvb, pinfo, tree, NULL);
2726 /* Write the given formatted text to:
2727 - the info column (if pinfo != NULL)
2728 - 1 or 2 other labels (optional)
2730 static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2731 packet_info *pinfo, const char *format, ...)
2733 #define MAX_INFO_BUFFER 256
2734 static char info_buffer[MAX_INFO_BUFFER];
2737 if ((ti1 == NULL) && (ti2 == NULL) && (pinfo == NULL)) {
2741 va_start(ap, format);
2742 g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
2745 /* Add to indicated places */
2746 if (pinfo != NULL) {
2747 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2750 proto_item_append_text(ti1, "%s", info_buffer);
2753 proto_item_append_text(ti2, "%s", info_buffer);
2757 /* Version of function above, where no g_vsnprintf() call needed */
2758 static void write_pdu_label_and_info_literal(proto_item *ti1, proto_item *ti2,
2759 packet_info *pinfo, const char *info_buffer)
2761 if ((ti1 == NULL) && (ti2 == NULL) && (pinfo == NULL)) {
2765 /* Add to indicated places */
2766 if (pinfo != NULL) {
2767 col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2770 proto_item_append_text(ti1, "%s", info_buffer);
2773 proto_item_append_text(ti2, "%s", info_buffer);
2779 /* Show extra PHY parameters (if present) */
2780 static void show_extra_phy_parameters(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
2781 struct mac_lte_info *p_mac_lte_info)
2784 proto_tree *phy_tree;
2787 if (global_mac_lte_layer_to_show == ShowPHYLayer) {
2788 /* Clear the info column */
2789 col_clear(pinfo->cinfo, COL_INFO);
2792 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2793 if (p_mac_lte_info->detailed_phy_info.ul_info.present) {
2796 phy_ti = proto_tree_add_string_format(tree, hf_mac_lte_context_phy_ul,
2797 tvb, 0, 0, "", "UL PHY Context");
2798 phy_tree = proto_item_add_subtree(phy_ti, ett_mac_lte_phy_context);
2799 proto_item_set_generated(phy_ti);
2802 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_modulation_type,
2804 p_mac_lte_info->detailed_phy_info.ul_info.modulation_type);
2805 proto_item_set_generated(ti);
2807 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_tbs_index,
2809 p_mac_lte_info->detailed_phy_info.ul_info.tbs_index);
2810 proto_item_set_generated(ti);
2812 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_length,
2814 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length);
2815 proto_item_set_generated(ti);
2817 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_start,
2819 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start);
2820 proto_item_set_generated(ti);
2822 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_harq_id,
2824 p_mac_lte_info->detailed_phy_info.ul_info.harq_id);
2825 proto_item_set_generated(ti);
2827 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_ndi,
2829 p_mac_lte_info->detailed_phy_info.ul_info.ndi);
2830 proto_item_set_generated(ti);
2833 proto_item_append_text(phy_ti, " (");
2835 write_pdu_label_and_info(phy_ti, NULL,
2836 (global_mac_lte_layer_to_show == ShowPHYLayer) ? pinfo : NULL,
2837 "UL: UEId=%u RNTI=%u %s Tbs_Index=%u RB_len=%u RB_start=%u",
2838 p_mac_lte_info->ueid,
2839 p_mac_lte_info->rnti,
2840 val_to_str_const(p_mac_lte_info->detailed_phy_info.ul_info.modulation_type,
2841 modulation_type_vals, "Unknown"),
2842 p_mac_lte_info->detailed_phy_info.ul_info.tbs_index,
2843 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length,
2844 p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start);
2846 proto_item_append_text(phy_ti, ")");
2848 /* Don't want columns to be replaced now */
2849 if (global_mac_lte_layer_to_show == ShowPHYLayer) {
2850 col_set_writable(pinfo->cinfo, -1, FALSE);
2855 if (p_mac_lte_info->detailed_phy_info.dl_info.present) {
2858 phy_ti = proto_tree_add_string_format(tree, hf_mac_lte_context_phy_dl,
2859 tvb, 0, 0, "", "DL PHY Context");
2860 phy_tree = proto_item_add_subtree(phy_ti, ett_mac_lte_phy_context);
2861 proto_item_set_generated(phy_ti);
2864 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_dci_format,
2866 p_mac_lte_info->detailed_phy_info.dl_info.dci_format);
2867 proto_item_set_generated(ti);
2869 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_allocation_type,
2871 p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type);
2872 proto_item_set_generated(ti);
2874 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_aggregation_level,
2876 p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level);
2877 proto_item_set_generated(ti);
2879 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_mcs_index,
2881 p_mac_lte_info->detailed_phy_info.dl_info.mcs_index);
2882 proto_item_set_generated(ti);
2884 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_redundancy_version_index,
2886 p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index);
2887 proto_item_set_generated(ti);
2889 ti = proto_tree_add_boolean(phy_tree, hf_mac_lte_context_phy_dl_retx,
2891 p_mac_lte_info->dl_retx);
2892 proto_item_set_generated(ti);
2894 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_block_length,
2896 p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length);
2897 proto_item_set_generated(ti);
2899 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_harq_id,
2901 p_mac_lte_info->detailed_phy_info.dl_info.harq_id);
2902 proto_item_set_generated(ti);
2904 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_ndi,
2906 p_mac_lte_info->detailed_phy_info.dl_info.ndi);
2907 proto_item_set_generated(ti);
2909 ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_tb,
2911 p_mac_lte_info->detailed_phy_info.dl_info.transport_block);
2912 proto_item_set_generated(ti);
2915 proto_item_append_text(phy_ti, " (");
2917 write_pdu_label_and_info(phy_ti, NULL,
2918 (global_mac_lte_layer_to_show == ShowPHYLayer) ? pinfo : NULL,
2919 "DL: UEId=%u RNTI=%u DCI_Format=%s Res_Alloc=%u Aggr_Level=%s MCS=%u RV=%u "
2920 "Res_Block_len=%u HARQ_id=%u NDI=%u",
2921 p_mac_lte_info->ueid,
2922 p_mac_lte_info->rnti,
2923 val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.dci_format,
2924 dci_format_vals, "Unknown"),
2925 p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type,
2926 val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level,
2927 aggregation_level_vals, "Unknown"),
2928 p_mac_lte_info->detailed_phy_info.dl_info.mcs_index,
2929 p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index,
2930 p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length,
2931 p_mac_lte_info->detailed_phy_info.dl_info.harq_id,
2932 p_mac_lte_info->detailed_phy_info.dl_info.ndi);
2933 proto_item_append_text(phy_ti, ")");
2935 /* Don't want columns to be replaced now */
2936 if (global_mac_lte_layer_to_show == ShowPHYLayer) {
2937 col_set_writable(pinfo->cinfo, -1, FALSE);
2944 /* Dissect a single Random Access Response body */
2945 static gint dissect_rar_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2947 gint offset, guint8 rapid, mac_lte_info *p_mac_lte_info)
2950 guint start_body_offset = offset;
2952 proto_item *rar_body_ti;
2953 proto_tree *rar_body_tree;
2954 proto_tree *ul_grant_tree;
2955 proto_item *ul_grant_ti;
2956 guint16 timing_advance;
2959 const gchar *rapid_description;
2960 guint32 bits_offset;
2962 /* Create tree for this Body */
2963 rar_body_ti = proto_tree_add_item(tree,
2964 hf_mac_lte_rar_body,
2965 tvb, offset, 0, ENC_ASCII|ENC_NA);
2966 rar_body_tree = proto_item_add_subtree(rar_body_ti, ett_mac_lte_rar_body);
2968 /* Dissect an RAR entry */
2970 /* Check reserved bit */
2971 reserved = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
2972 ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_reserved2, tvb, offset, 1, ENC_BIG_ENDIAN);
2973 if (reserved != 0) {
2974 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero, "RAR body Reserved bit not zero (found 0x%x)", reserved);
2977 /* Timing Advance */
2978 timing_advance = (tvb_get_ntohs(tvb, offset) & 0x7ff0) >> 4;
2979 ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ta, tvb, offset, 2, ENC_BIG_ENDIAN);
2980 if (timing_advance != 0) {
2981 if (timing_advance <= 31) {
2982 expert_add_info_format(pinfo, ti, &ei_mac_lte_rar_timing_advance_not_zero_note,
2983 "RAR Timing advance not zero (%u)", timing_advance);
2985 expert_add_info_format(pinfo, ti, &ei_mac_lte_rar_timing_advance_not_zero_warn,
2986 "RAR Timing advance not zero (%u)", timing_advance);
2992 if (p_mac_lte_info->ceMode == ce_mode_b) {
2993 ul_grant = tvb_get_ntohs(tvb, offset) & 0x0fff;
2994 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);
2996 ul_grant = (tvb_get_ntohl(tvb, offset) & 0x0fffff00) >> 8;
2997 ul_grant_ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ul_grant, tvb, offset, 3, ENC_BIG_ENDIAN);
3000 /* Break these 12/20 bits down as described in 36.213, section 6.2 */
3001 /* Create subtree for UL grant break-down */
3002 ul_grant_tree = proto_item_add_subtree(ul_grant_ti, ett_mac_lte_rar_ul_grant);
3004 if (p_mac_lte_info->nbMode == no_nb_mode) {
3005 switch (p_mac_lte_info->ceMode) {
3008 /* Hopping flag (1 bit) */
3009 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_hopping,
3010 tvb, offset, 1, ENC_BIG_ENDIAN);
3012 /* Fixed sized resource block assignment (10 bits) */
3013 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_fsrba,
3014 tvb, offset, 2, ENC_BIG_ENDIAN);
3016 /* Truncated Modulation and coding scheme (4 bits) */
3017 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tmcs,
3018 tvb, offset+1, 2, ENC_BIG_ENDIAN);
3020 /* TPC command for scheduled PUSCH (3 bits) */
3021 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tcsp,
3022 tvb, offset+2, 1, ENC_BIG_ENDIAN);
3024 /* UL delay (1 bit) */
3025 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_delay,
3026 tvb, offset+2, 1, ENC_BIG_ENDIAN);
3028 /* CQI request (1 bit) */
3029 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_cqi_request,
3030 tvb, offset+2, 1, ENC_BIG_ENDIAN);
3036 if (p_mac_lte_info->nUlRb == 0) {
3037 /* UL bandwidth is unknown; do not dissect UL grant */
3042 bits_offset = (offset<<3) + 4;
3044 /* Msg3 PUSCH narrowband index (0 to 4 bits) */
3045 if (p_mac_lte_info->nUlRb == 15) {
3046 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3047 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3049 } else if (p_mac_lte_info->nUlRb == 25) {
3050 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3051 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3053 } else if (p_mac_lte_info->nUlRb == 50) {
3054 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3055 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3057 } else if ((p_mac_lte_info->nUlRb == 75) || (p_mac_lte_info->nUlRb == 100)) {
3058 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
3059 tvb, bits_offset, 4, ENC_BIG_ENDIAN);
3063 /* Msg3 PUSCH Resource allocation (4 bits) */
3064 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_a,
3065 tvb, bits_offset, 4, ENC_BIG_ENDIAN);
3068 /* Number of Repetitions for Msg3 PUSCH (2 bits) */
3069 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a,
3070 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3074 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_mcs_ce_mode_a,
3075 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3079 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tpc_ce_mode_a,
3080 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3083 /* CSI request (1 bit) */
3084 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_csi_request_ce_mode_a,
3085 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3088 /* UL delay (1 bit) */
3089 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_delay_ce_mode_a,
3090 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3093 /* Msg3/4 MPDCCH narrowband index (2 bits) */
3094 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx,
3095 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3098 /* Optional padding (0 to 4 bits) to complete the 20 bits UL Grant */
3099 if (p_mac_lte_info->nUlRb == 6) {
3100 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3101 tvb, bits_offset, 4, ENC_BIG_ENDIAN);
3102 } else if (p_mac_lte_info->nUlRb == 15) {
3103 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3104 tvb, bits_offset, 3, ENC_BIG_ENDIAN);
3105 } else if (p_mac_lte_info->nUlRb == 25) {
3106 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3107 tvb, bits_offset, 2, ENC_BIG_ENDIAN);
3108 } else if (p_mac_lte_info->nUlRb == 50) {
3109 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
3110 tvb, bits_offset, 1, ENC_BIG_ENDIAN);
3117 /* Msg3 PUSCH narrowband index (2 bits) */
3118 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b,
3119 tvb, offset, 1, ENC_BIG_ENDIAN);
3121 /* Msg3 PUSCH Resource allocation (3 bits) */
3122 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_b,
3123 tvb, offset, 2, ENC_BIG_ENDIAN);
3125 /* Number of Repetitions for Msg3 PUSCH (3 bits) */
3126 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b,
3127 tvb, offset+1, 1, ENC_BIG_ENDIAN);
3130 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tbs_ce_mode_b,
3131 tvb, offset+1, 1, ENC_BIG_ENDIAN);
3133 /* Msg3/4 MPDCCH narrowband index (2 bits) */
3134 proto_tree_add_bits_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx,
3135 tvb, ((offset+1)<<3)+6, 2, ENC_BIG_ENDIAN);
3141 /* Uplink subcarrier spacing (1 bit) */
3142 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_subcarrier_spacing, tvb, offset, 1, ENC_BIG_ENDIAN);
3144 /* Subcarrier indication (6 bits) */
3145 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_subcarrier_indication, tvb, offset, 2, ENC_BIG_ENDIAN);
3147 /* Scheduling delay (2 bits) */
3148 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_scheduling_delay, tvb, offset+1, 1, ENC_BIG_ENDIAN);
3150 /* Msg3 repetition number (3 bits) */
3151 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_msg3_repetition_number, tvb, offset+1, 1, ENC_BIG_ENDIAN);
3153 /* MCS index (3 bits) */
3154 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_mcs_index, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3156 /* Padding (5 bits) */
3157 proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_padding_nb_mode, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3162 /* Temporary C-RNTI */
3163 temp_crnti = tvb_get_ntohs(tvb, offset);
3164 proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_temporary_crnti, tvb, offset, 2, ENC_BIG_ENDIAN);
3167 rapid_description = get_mac_lte_rapid_description(rapid);
3169 write_pdu_label_and_info(pdu_ti, rar_body_ti, pinfo,
3170 "(RAPID=%u%s: TA=%u, UL-Grant=%u, Temp C-RNTI=%u) ",
3171 rapid, rapid_description,
3172 timing_advance, ul_grant, temp_crnti);
3174 proto_item_set_len(rar_body_ti, offset-start_body_offset);
3180 #define MAX_RAR_PDUS 64
3181 /* Dissect Random Access Response (RAR) PDU */
3182 static void dissect_rar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *pdu_ti,
3183 gint offset, mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info)
3185 gint number_of_rars = 0; /* No of RAR bodies expected following headers */
3186 guint8 *rapids = (guint8 *)wmem_alloc(wmem_packet_scope(), MAX_RAR_PDUS * sizeof(guint8));
3187 gboolean backoff_indicator_seen = FALSE;
3188 guint8 backoff_indicator = 0;
3191 proto_tree *rar_headers_tree;
3193 proto_item *rar_headers_ti;
3194 proto_item *padding_length_ti;
3195 int start_headers_offset = offset;
3197 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3198 "RAR (RA-RNTI=%u, SFN=%-4u, SF=%u) ",
3199 p_mac_lte_info->rnti, p_mac_lte_info->sysframeNumber, p_mac_lte_info->subframeNumber);
3201 /* Create hidden 'virtual root' so can filter on mac-lte.rar */
3202 ti = proto_tree_add_item(tree, hf_mac_lte_rar, tvb, offset, -1, ENC_NA);
3203 proto_item_set_hidden(ti);
3205 /* Create headers tree */
3206 rar_headers_ti = proto_tree_add_item(tree,
3207 hf_mac_lte_rar_headers,
3208 tvb, offset, 0, ENC_ASCII|ENC_NA);
3209 rar_headers_tree = proto_item_add_subtree(rar_headers_ti, ett_mac_lte_rar_headers);
3212 /***************************/
3213 /* Read the header entries */
3215 int start_header_offset = offset;
3216 proto_tree *rar_header_tree;
3217 proto_item *rar_header_ti;
3219 guint8 first_byte = tvb_get_guint8(tvb, offset);
3221 /* Create tree for this header */
3222 rar_header_ti = proto_tree_add_item(rar_headers_tree,
3223 hf_mac_lte_rar_header,
3224 tvb, offset, 0, ENC_ASCII|ENC_NA);
3225 rar_header_tree = proto_item_add_subtree(rar_header_ti, ett_mac_lte_rar_header);
3228 extension = (first_byte & 0x80) >> 7;
3229 proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
3232 type_value = (first_byte & 0x40) >> 6;
3233 proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_t, tvb, offset, 1, ENC_BIG_ENDIAN);
3235 if (type_value == 0) {
3236 /* Backoff Indicator (BI) case */
3242 /* 2 Reserved bits */
3243 reserved = (tvb_get_guint8(tvb, offset) & 0x30) >> 4;
3244 tii = proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
3245 if (reserved != 0) {
3246 expert_add_info_format(pinfo, tii, &ei_mac_lte_reserved_not_zero,
3247 "RAR header Reserved bits not zero (found 0x%x)", reserved);
3250 /* Backoff Indicator */
3251 backoff_indicator = tvb_get_guint8(tvb, offset) & 0x0f;
3252 bi_ti = proto_tree_add_item(rar_header_tree, (p_mac_lte_info->nbMode == no_nb_mode) ?
3253 hf_mac_lte_rar_bi : hf_mac_lte_rar_bi_nb, tvb, offset, 1, ENC_BIG_ENDIAN);
3255 /* As of March 2009 spec, it must be first, and may only appear once */
3256 if (backoff_indicator_seen) {
3257 expert_add_info(pinfo, bi_ti, &ei_mac_lte_rar_bi_present);
3259 backoff_indicator_seen = TRUE;
3261 write_pdu_label_and_info(pdu_ti, rar_header_ti, pinfo,
3262 "(Backoff Indicator=%sms)",
3263 val_to_str_const(backoff_indicator, (p_mac_lte_info->nbMode == no_nb_mode) ?
3264 rar_bi_vals : rar_bi_nb_vals, "Illegal-value "));
3266 /* If present, it must be the first subheader */
3267 if (number_of_rars > 0) {
3268 expert_add_info(pinfo, bi_ti, &ei_mac_lte_rar_bi_not_first_subheader);
3274 /* TODO: complain if the same RAPID appears twice in same frame? */
3275 const gchar *rapid_description;
3277 rapids[number_of_rars] = tvb_get_guint8(tvb, offset) & 0x3f;
3278 proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_rapid, tvb, offset, 1, ENC_BIG_ENDIAN);
3280 rapid_description = get_mac_lte_rapid_description(rapids[number_of_rars]);
3282 proto_item_append_text(rar_header_ti, "(RAPID=%u%s)",
3283 rapids[number_of_rars],
3291 /* Finalise length of header tree selection */
3292 proto_item_set_len(rar_header_ti, offset - start_header_offset);
3294 } while (extension && number_of_rars < MAX_RAR_PDUS);
3296 /* Append summary to headers root */
3297 proto_item_append_text(rar_headers_ti, " (%u RARs", number_of_rars);
3298 ti = proto_tree_add_uint(rar_headers_tree, hf_mac_lte_rar_no_of_rapids, tvb, 0, 0, number_of_rars);
3299 proto_item_set_generated(ti);
3300 if (backoff_indicator_seen) {
3301 proto_item_append_text(rar_headers_ti, ", BI=%sms)",
3302 val_to_str_const(backoff_indicator, (p_mac_lte_info->nbMode == no_nb_mode) ?
3303 rar_bi_vals : rar_bi_nb_vals, "Illegal-value "));
3306 proto_item_append_text(rar_headers_ti, ")");
3309 /* Set length for headers root */
3310 proto_item_set_len(rar_headers_ti, offset-start_headers_offset);
3313 /***************************/
3314 /* Read any indicated RARs */
3315 for (n=0; n < number_of_rars; n++) {
3316 offset = dissect_rar_entry(tvb, pinfo, tree, pdu_ti, offset, rapids[n], p_mac_lte_info);
3319 /* Update TAP info */
3320 tap_info->number_of_rars += number_of_rars;
3322 /* Padding may follow */
3323 if (tvb_reported_length_remaining(tvb, offset) > 0) {
3324 proto_tree_add_item(tree, hf_mac_lte_padding_data,
3325 tvb, offset, -1, ENC_NA);
3327 padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
3329 p_mac_lte_info->length - offset);
3330 proto_item_set_generated(padding_length_ti);
3332 /* Update padding bytes in stats */
3333 tap_info->padding_bytes += (p_mac_lte_info->length - offset);
3337 /* Dissect BCH PDU */
3338 static void dissect_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3340 int offset, mac_lte_info *p_mac_lte_info)
3344 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3345 "BCH PDU (%u bytes, on %s transport) ",
3346 tvb_reported_length_remaining(tvb, offset),
3347 val_to_str_const(p_mac_lte_info->rntiType,
3348 bch_transport_channel_vals,
3351 /* Show which transport layer it came in on (inferred from RNTI type) */
3352 ti = proto_tree_add_uint(tree, hf_mac_lte_context_bch_transport_channel,
3353 tvb, offset, 0, p_mac_lte_info->rntiType);
3354 proto_item_set_generated(ti);
3356 /****************************************/
3357 /* Whole frame is BCH data */
3360 ti = proto_tree_add_item(tree, hf_mac_lte_bch_pdu,
3361 tvb, offset, -1, ENC_NA);
3363 if (global_mac_lte_attempt_rrc_decode) {
3364 /* Attempt to decode payload using LTE RRC dissector */
3365 tvbuff_t *rrc_tvb = tvb_new_subset_remaining(tvb, offset);
3367 /* Get appropriate dissector handle */
3368 dissector_handle_t protocol_handle = 0;
3369 if (p_mac_lte_info->rntiType == SI_RNTI) {
3370 if (p_mac_lte_info->nbMode == no_nb_mode) {
3371 if (p_mac_lte_info->ceMode == no_ce_mode) {
3372 protocol_handle = lte_rrc_bcch_dl_sch_handle;
3375 protocol_handle = lte_rrc_bcch_dl_sch_br_handle;
3379 protocol_handle = lte_rrc_bcch_dl_sch_nb_handle;
3383 if (p_mac_lte_info->nbMode == no_nb_mode) {
3384 protocol_handle = lte_rrc_bcch_bch_handle;
3387 protocol_handle = lte_rrc_bcch_bch_nb_handle;
3391 /* Hide raw view of bytes */
3392 proto_item_set_hidden(ti);
3394 call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
3397 /* Check that this *is* downlink! */
3398 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
3399 expert_add_info(pinfo, ti, &ei_mac_lte_bch_pdu);
3404 /* Dissect PCH PDU */
3405 static void dissect_pch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3406 proto_item *pdu_ti, int offset, mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info)
3410 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3411 "PCH PDU (%u bytes) ",
3412 tvb_reported_length_remaining(tvb, offset));
3414 /****************************************/
3415 /* Whole frame is PCH data */
3417 /* Always show as raw data */
3418 ti = proto_tree_add_item(tree, hf_mac_lte_pch_pdu,
3419 tvb, offset, -1, ENC_NA);
3421 /* Get number of paging IDs for tap */
3422 tap_info->number_of_paging_ids = (tvb_get_guint8(tvb, offset) & 0x40) ?
3423 ((tvb_get_ntohs(tvb, offset) >> 7) & 0x000f) + 1 : 0;
3425 if (global_mac_lte_attempt_rrc_decode) {
3427 /* Attempt to decode payload using LTE RRC dissector */
3428 tvbuff_t *rrc_tvb = tvb_new_subset_remaining(tvb, offset);
3430 /* Hide raw view of bytes */
3431 proto_item_set_hidden(ti);
3433 /* Call it (catch exceptions so that stats will be updated) */
3434 if (p_mac_lte_info->nbMode == no_nb_mode) {
3435 call_with_catch_all(lte_rrc_pcch_handle, rrc_tvb, pinfo, tree);
3438 call_with_catch_all(lte_rrc_pcch_nb_handle, rrc_tvb, pinfo, tree);
3442 /* Check that this *is* downlink! */
3443 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
3444 expert_add_info(pinfo, ti, &ei_mac_lte_pch_pdu);
3449 /* Does this header entry correspond to a fixed-sized control element? */
3450 static int is_fixed_sized_control_element(guint8 lcid, guint8 direction)
3452 if (direction == DIRECTION_UPLINK) {
3455 case RECOMMENDED_BIT_RATE_QUERY_LCID:
3456 case SPS_CONFIRMATION_LCID:
3457 case POWER_HEADROOM_REPORT_LCID:
3459 case TRUNCATED_BSR_LCID:
3460 case SHORT_BSR_LCID:
3469 /* Assume Downlink */
3471 case RECOMMENDED_BIT_RATE_LCID:
3472 case SC_PTM_STOP_INDICATION_LCID:
3473 case ACTIVATION_DEACTIVATION_4_BYTES_LCID:
3474 case LONG_DRX_COMMAND_LCID:
3475 case ACTIVATION_DEACTIVATION_LCID:
3476 case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
3477 case TIMING_ADVANCE_LCID:
3478 case DRX_COMMAND_LCID:
3488 /* Is this a BSR report header? */
3489 static int is_bsr_lcid(guint8 lcid)
3491 return ((lcid == TRUNCATED_BSR_LCID) ||
3492 (lcid == SHORT_BSR_LCID) ||
3493 (lcid == LONG_BSR_LCID));
3497 /* Helper function to call RLC dissector for SDUs (where channel params are known) */
3498 static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3500 int offset, guint16 data_length,
3501 guint8 mode, guint8 direction, guint16 ueid,
3502 guint16 channelType, guint16 channelId,
3503 guint8 sequenceNumberLength,
3504 guint8 priority, gboolean rlcExtLiField, mac_lte_nb_mode nbMode)
3506 tvbuff_t *rb_tvb = tvb_new_subset_length(tvb, offset, data_length);
3507 struct rlc_lte_info *p_rlc_lte_info;
3509 /* Resuse or create RLC info */
3510 p_rlc_lte_info = (rlc_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0);
3511 if (p_rlc_lte_info == NULL) {
3512 p_rlc_lte_info = wmem_new0(wmem_file_scope(), struct rlc_lte_info);
3515 /* Fill in struct details for channel */
3516 p_rlc_lte_info->rlcMode = mode;
3517 p_rlc_lte_info->direction = direction;
3518 p_rlc_lte_info->priority = priority;
3519 p_rlc_lte_info->ueid = ueid;
3520 p_rlc_lte_info->channelType = channelType;
3521 p_rlc_lte_info->channelId = channelId;
3522 p_rlc_lte_info->pduLength = data_length;
3523 p_rlc_lte_info->sequenceNumberLength = sequenceNumberLength;
3524 p_rlc_lte_info->extendedLiField = rlcExtLiField;
3525 if (nbMode == nb_mode) {
3526 p_rlc_lte_info->nbMode = rlc_nb_mode;
3528 p_rlc_lte_info->nbMode = rlc_no_nb_mode;
3531 /* Store info in packet */
3532 p_add_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0, p_rlc_lte_info);
3534 if (global_mac_lte_layer_to_show != ShowRLCLayer) {
3535 /* Don't want these columns replaced */
3536 col_set_writable(pinfo->cinfo, -1, FALSE);
3539 /* Clear info column before first RLC PDU */
3540 if (s_number_of_rlc_pdus_shown == 0) {
3541 col_clear(pinfo->cinfo, COL_INFO);
3544 /* Add a separator and protect column contents here */
3545 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, " || ");
3546 col_set_fence(pinfo->cinfo, COL_INFO);
3549 s_number_of_rlc_pdus_shown++;
3551 /* Call it (catch exceptions so that stats will be updated) */
3552 call_with_catch_all(rlc_lte_handle, rb_tvb, pinfo, tree);
3554 /* Let columns be written to again */
3555 col_set_writable(pinfo->cinfo, -1, TRUE);
3559 /* For DL frames, look for previous Tx. Add link back if found */
3560 static void TrackReportedDLHARQResend(packet_info *pinfo, tvbuff_t *tvb, int length,
3561 proto_tree *tree, mac_lte_info *p_mac_lte_info)
3563 DLHARQResult *result = NULL;
3564 DLHARQResult *original_result = NULL;
3566 /* If don't have detailed DL PHY info, just give up */
3567 if (!p_mac_lte_info->detailed_phy_info.dl_info.present) {
3571 /* TDD may not work... */
3573 if (!PINFO_FD_VISITED(pinfo)) {
3574 /* First time, so set result and update DL harq table */
3575 LastFrameData *lastData = NULL;
3576 LastFrameData *thisData = NULL;
3578 DLHarqBuffers *ueData;
3580 /* Read these for convenience */
3581 guint8 harq_id = p_mac_lte_info->detailed_phy_info.dl_info.harq_id;
3582 guint8 transport_block = p_mac_lte_info->detailed_phy_info.dl_info.transport_block;
3584 /* Check harq-id bounds, give up if invalid */
3585 if ((harq_id >= 15) || (transport_block > 1)) {
3589 /* Look up entry for this UE/RNTI */
3590 ueData = (DLHarqBuffers *)g_hash_table_lookup(mac_lte_dl_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti));
3592 if (ueData != NULL) {
3593 /* Get previous info for this harq-id */
3594 lastData = &(ueData->harqid[transport_block][harq_id]);
3595 if (lastData->inUse) {
3596 /* Compare time difference, ndi, data to see if this looks like a retx */
3597 if ((length == lastData->length) &&
3598 (p_mac_lte_info->detailed_phy_info.dl_info.ndi == lastData->ndi) &&
3599 tvb_memeql(tvb, 0, lastData->data, MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0) {
3601 /* Work out gap between frames */
3602 gint seconds_between_packets = (gint)
3603 (pinfo->abs_ts.secs - lastData->received_time.secs);
3604 gint nseconds_between_packets =
3605 pinfo->abs_ts.nsecs - lastData->received_time.nsecs;
3607 /* Round difference to nearest millisecond */
3608 gint total_gap = (seconds_between_packets*1000) +
3609 ((nseconds_between_packets+500000) / 1000000);
3611 /* Expect to be within (say) 8-13 subframes since previous */
3612 if ((total_gap >= 8) && (total_gap <= 13)) {
3614 /* Resend detected! Store result pointing back. */
3615 result = wmem_new0(wmem_file_scope(), DLHARQResult);
3616 result->previousSet = TRUE;
3617 result->previousFrameNum = lastData->framenum;
3618 result->timeSincePreviousFrame = total_gap;
3619 g_hash_table_insert(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->num), result);
3621 /* Now make previous frame point forward to here */
3622 original_result = (DLHARQResult *)g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(lastData->framenum));
3623 if (original_result == NULL) {
3624 original_result = wmem_new0(wmem_file_scope(), DLHARQResult);
3625 g_hash_table_insert(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(lastData->framenum), original_result);
3627 original_result->nextSet = TRUE;
3628 original_result->nextFrameNum = pinfo->num;
3629 original_result->timeToNextFrame = total_gap;
3635 /* Allocate entry in table for this UE/RNTI */
3636 ueData = wmem_new0(wmem_file_scope(), DLHarqBuffers);
3637 g_hash_table_insert(mac_lte_dl_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti), ueData);
3640 /* Store this frame's details in table */
3641 thisData = &(ueData->harqid[transport_block][harq_id]);
3642 thisData->inUse = TRUE;
3643 thisData->length = length;
3644 tvb_memcpy(tvb, thisData->data, 0, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH));
3645 thisData->ndi = p_mac_lte_info->detailed_phy_info.dl_info.ndi;
3646 thisData->framenum = pinfo->num;
3647 thisData->received_time = pinfo->abs_ts;
3650 /* Not first time, so just set what's already stored in result */
3651 result = (DLHARQResult *)g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->num));
3655 /***************************************************/
3656 /* Show link back to original frame (if available) */
3657 if (result != NULL) {
3658 if (result->previousSet) {
3660 proto_item *original_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_original_frame,
3661 tvb, 0, 0, result->previousFrameNum);
3662 proto_item_set_generated(original_ti);
3664 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_time_since_previous_frame,
3665 tvb, 0, 0, result->timeSincePreviousFrame);
3666 proto_item_set_generated(gap_ti);
3669 if (result->nextSet) {
3671 proto_item *next_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_next_frame,
3672 tvb, 0, 0, result->nextFrameNum);
3673 proto_item_set_generated(next_ti);
3675 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_time_until_next_frame,
3676 tvb, 0, 0, result->timeToNextFrame);
3677 proto_item_set_generated(gap_ti);
3684 /* Return TRUE if the given packet is thought to be a retx */
3685 int is_mac_lte_frame_retx(packet_info *pinfo, guint8 direction)
3687 struct mac_lte_info *p_mac_lte_info = (struct mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
3689 if (p_mac_lte_info == NULL) {
3693 if (direction == DIRECTION_UPLINK) {
3694 /* For UL, retx count is stored in per-packet struct */
3695 return (p_mac_lte_info->reTxCount > 0);
3698 /* Use answer if told directly */
3699 if (p_mac_lte_info->dl_retx == dl_retx_yes) {
3703 /* Otherwise look up in table */
3704 DLHARQResult *result = (DLHARQResult *)g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->num));
3705 return ((result != NULL) && result->previousSet);
3711 /* Track UL frames, so that when a retx is indicated, we can search for
3712 the original tx. We will either find it, and provide a link back to it,
3713 or flag that we couldn't find as an expert error */
3714 static void TrackReportedULHARQResend(packet_info *pinfo, tvbuff_t *tvb, int offset,
3715 proto_tree *tree, mac_lte_info *p_mac_lte_info,
3716 proto_item *retx_ti)
3718 ULHARQResult *result = NULL;
3720 /* If don't have detailed DL PHY info, just give up */
3721 if (!p_mac_lte_info->detailed_phy_info.ul_info.present) {
3725 /* Give up if harqid is out of range */
3726 if (p_mac_lte_info->detailed_phy_info.ul_info.harq_id >= 8) {
3730 if (!PINFO_FD_VISITED(pinfo)) {
3731 /* First time, so set result and update UL harq table */
3732 LastFrameData *lastData = NULL;
3733 LastFrameData *thisData = NULL;
3735 /* Look up entry for this UE/RNTI */
3736 ULHarqBuffers *ueData = (ULHarqBuffers *)g_hash_table_lookup(
3737 mac_lte_ul_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti));
3738 if (ueData != NULL) {
3739 if (p_mac_lte_info->reTxCount >= 1) {
3740 /* Looking for frame previously on this harq-id */
3741 lastData = &(ueData->harqid[p_mac_lte_info->detailed_phy_info.ul_info.harq_id]);
3742 if (lastData->inUse) {
3743 /* Compare time, sf, data to see if this looks like a retx */
3744 if ((tvb_reported_length_remaining(tvb, offset) == lastData->length) &&
3745 (p_mac_lte_info->detailed_phy_info.ul_info.ndi == lastData->ndi) &&
3746 tvb_memeql(tvb, offset, lastData->data, MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0) {
3748 /* Work out gap between frames */
3749 gint seconds_between_packets = (gint)
3750 (pinfo->abs_ts.secs - lastData->received_time.secs);
3751 gint nseconds_between_packets =
3752 pinfo->abs_ts.nsecs - lastData->received_time.nsecs;
3754 /* Round to nearest ms */
3755 gint total_gap = (seconds_between_packets*1000) +
3756 ((nseconds_between_packets+500000) / 1000000);
3758 /* Could be as many as max-tx (which we don't know) * 8ms ago.
3759 32 is the most I've seen... */
3760 /* TODO: could configure this from RRC... */
3761 if (total_gap <= 33) {
3762 ULHARQResult *original_result;
3764 /* Original detected!!! Store result pointing back */
3765 result = wmem_new0(wmem_file_scope(), ULHARQResult);
3766 result->previousSet = TRUE;
3767 result->previousFrameNum = lastData->framenum;
3768 result->timeSincePreviousFrame = total_gap;
3769 g_hash_table_insert(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->num), result);
3771 /* Now make previous frame point forward to here */
3772 original_result = (ULHARQResult *)g_hash_table_lookup(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(lastData->framenum));
3773 if (original_result == NULL) {
3774 original_result = wmem_new0(wmem_file_scope(), ULHARQResult);
3775 g_hash_table_insert(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(lastData->framenum), original_result);
3777 original_result->nextSet = TRUE;
3778 original_result->nextFrameNum = pinfo->num;
3779 original_result->timeToNextFrame = total_gap;
3786 /* Allocate entry in table for this UE/RNTI */
3787 ueData = wmem_new0(wmem_file_scope(), ULHarqBuffers);
3788 g_hash_table_insert(mac_lte_ul_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti), ueData);
3791 /* Store this frame's details in table */
3792 thisData = &(ueData->harqid[p_mac_lte_info->detailed_phy_info.ul_info.harq_id]);
3793 thisData->inUse = TRUE;
3794 thisData->length = tvb_reported_length_remaining(tvb, offset);
3795 tvb_memcpy(tvb, thisData->data, offset, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH));
3796 thisData->ndi = p_mac_lte_info->detailed_phy_info.ul_info.ndi;
3797 thisData->framenum = pinfo->num;
3798 thisData->received_time = pinfo->abs_ts;
3801 /* Not first time, so just get what's already stored in result */
3802 result = (ULHARQResult *)g_hash_table_lookup(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->num));
3805 /* Show any link back to previous Tx */
3806 if (retx_ti != NULL) {
3807 if (result != NULL) {
3808 if (result->previousSet) {
3809 proto_item *original_ti, *gap_ti;
3811 original_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_original_frame,
3812 tvb, 0, 0, result->previousFrameNum);
3813 proto_item_set_generated(original_ti);
3815 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_time_since_previous_frame,
3816 tvb, 0, 0, result->timeSincePreviousFrame);
3817 proto_item_set_generated(gap_ti);
3821 expert_add_info_format(pinfo, retx_ti, &ei_mac_lte_orig_tx_ul_frame_not_found,
3822 "Original Tx of UL frame not found (UE %u) !!", p_mac_lte_info->ueid);
3826 /* Show link forward to any known next Tx */
3827 if ((result != NULL) && result->nextSet) {
3828 proto_item *next_ti, *gap_ti;
3830 next_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_next_frame,
3831 tvb, 0, 0, result->nextFrameNum);
3832 expert_add_info_format(pinfo, next_ti, &ei_mac_lte_ul_harq_resend_next_frame,
3833 "UL MAC PDU (UE %u) needed to be retransmitted", p_mac_lte_info->ueid);
3835 proto_item_set_generated(next_ti);
3837 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_time_until_next_frame,
3838 tvb, 0, 0, result->timeToNextFrame);
3839 proto_item_set_generated(gap_ti);
3844 /* Look up SRResult associated with a given frame. Will create one if necessary
3845 if can_create is set */
3846 static SRResult *GetSRResult(guint32 frameNum, gboolean can_create)
3849 result = (SRResult *)g_hash_table_lookup(mac_lte_sr_request_hash, GUINT_TO_POINTER(frameNum));
3851 if ((result == NULL) && can_create) {
3852 result = wmem_new0(wmem_file_scope(), SRResult);
3853 g_hash_table_insert(mac_lte_sr_request_hash, GUINT_TO_POINTER((guint)frameNum), result);
3859 /* Keep track of SR requests, failures and related grants, in order to show them
3860 as generated fields in these frames */
3861 static void TrackSRInfo(SREvent event, packet_info *pinfo, proto_tree *tree,
3862 tvbuff_t *tvb, mac_lte_info *p_mac_lte_info, gint idx, proto_item *event_ti)
3864 SRResult *result = NULL;
3866 SRResult *resultForSRFrame = NULL;
3872 /* Get appropriate identifiers */
3873 if (event == SR_Request) {
3874 rnti = p_mac_lte_info->oob_rnti[idx];
3875 ueid = p_mac_lte_info->oob_ueid[idx];
3878 rnti = p_mac_lte_info->rnti;
3879 ueid = p_mac_lte_info->ueid;
3882 /* Create state for this RNTI if necessary */
3883 state = (SRState *)g_hash_table_lookup(mac_lte_ue_sr_state, GUINT_TO_POINTER((guint)rnti));
3884 if (state == NULL) {
3885 /* Allocate status for this RNTI */
3886 state = wmem_new(wmem_file_scope(), SRState);
3887 state->status = None;
3888 g_hash_table_insert(mac_lte_ue_sr_state, GUINT_TO_POINTER((guint)rnti), state);
3891 /* First time through - update state with new info */
3892 if (!PINFO_FD_VISITED(pinfo)) {
3893 guint32 timeSinceRequest;
3895 /* Store time of request */
3896 if (event == SR_Request) {
3897 state->requestTime = pinfo->abs_ts;
3900 switch (state->status) {
3904 /* Got another grant - fine */
3907 state->lastGrantFramenum = pinfo->num;
3911 /* Sent an SR - fine */
3914 state->status = SR_Outstanding;
3915 state->lastSRFramenum = pinfo->num;
3919 /* This is an error, since we hadn't send an SR... */
3920 result = GetSRResult(pinfo->num, TRUE);
3921 result->type = InvalidSREvent;
3922 result->status = None;
3923 result->event = SR_Failure;
3928 case SR_Outstanding:
3929 timeSinceRequest = (guint32)(((pinfo->abs_ts.secs - state->requestTime.secs) * 1000) +
3930 ((pinfo->abs_ts.nsecs - state->requestTime.nsecs) / 1000000));
3934 /* Got grant we were waiting for, so state goes to None */
3937 state->status = None;
3939 /* Set result info */
3940 result = GetSRResult(pinfo->num, TRUE);
3941 result->type = GrantAnsweringSR;
3942 result->frameNum = state->lastSRFramenum;
3943 result->timeDifference = timeSinceRequest;
3945 /* Also set forward link for SR */
3946 resultForSRFrame = GetSRResult(state->lastSRFramenum, TRUE);
3947 resultForSRFrame->type = SRLeadingToGrant;
3948 resultForSRFrame->frameNum = pinfo->num;
3949 resultForSRFrame->timeDifference = timeSinceRequest;
3953 /* Another request when already have one pending */
3954 result = GetSRResult(pinfo->num, TRUE);
3955 result->type = InvalidSREvent;
3956 result->status = SR_Outstanding;
3957 result->event = SR_Request;
3961 /* We sent an SR but it failed */
3964 state->status = SR_Failed;
3966 /* Set result info for failure frame */
3967 result = GetSRResult(pinfo->num, TRUE);
3968 result->type = FailureAnsweringSR;
3969 result->frameNum = state->lastSRFramenum;
3970 result->timeDifference = timeSinceRequest;
3972 /* Also set forward link for SR */
3973 resultForSRFrame = GetSRResult(state->lastSRFramenum, TRUE);
3974 resultForSRFrame->type = SRLeadingToFailure;
3975 resultForSRFrame->frameNum = pinfo->num;
3976 resultForSRFrame->timeDifference = timeSinceRequest;
3984 /* Got a grant, presumably after a subsequent RACH - fine */
3987 state->status = None;
3991 /* Tried another SR after previous one failed.
3992 Presumably a subsequent RACH was tried in-between... */
3994 state->status = SR_Outstanding;
3996 result = GetSRResult(pinfo->num, TRUE);
3997 result->status = SR_Outstanding;
3998 result->event = SR_Request;
4002 /* 2 failures in a row.... */
4003 result = GetSRResult(pinfo->num, TRUE);
4004 result->type = InvalidSREvent;
4005 result->status = SR_Failed;
4006 result->event = SR_Failure;
4013 /* Get stored result for this frame */
4014 result = GetSRResult(pinfo->num, FALSE);
4015 if (result == NULL) {
4016 /* For an SR frame, there should always be either a PDCCH grant or indication
4017 that the SR has failed */
4018 if (event == SR_Request) {
4019 expert_add_info_format(pinfo, event_ti, &ei_mac_lte_sr_results_not_grant_or_failure_indication,
4020 "UE %u: SR results in neither a grant nor a failure indication",
4027 /* Show result info */
4028 switch (result->type) {
4029 case GrantAnsweringSR:
4030 ti = proto_tree_add_uint(tree, hf_mac_lte_grant_answering_sr,
4031 tvb, 0, 0, result->frameNum);
4032 proto_item_set_generated(ti);
4033 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_since_request,
4034 tvb, 0, 0, result->timeDifference);
4035 proto_item_set_generated(ti);
4038 case FailureAnsweringSR:
4039 ti = proto_tree_add_uint(tree, hf_mac_lte_failure_answering_sr,
4040 tvb, 0, 0, result->frameNum);
4041 proto_item_set_generated(ti);
4042 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_since_request,
4043 tvb, 0, 0, result->timeDifference);
4044 proto_item_set_generated(ti);
4047 case SRLeadingToGrant:
4048 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_leading_to_grant,
4049 tvb, 0, 0, result->frameNum);
4050 proto_item_set_generated(ti);
4051 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_until_answer,
4052 tvb, 0, 0, result->timeDifference);
4053 proto_item_set_generated(ti);
4057 case SRLeadingToFailure:
4058 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_leading_to_failure,
4059 tvb, 0, 0, result->frameNum);
4060 proto_item_set_generated(ti);
4061 ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_until_answer,
4062 tvb, 0, 0, result->timeDifference);
4063 proto_item_set_generated(ti);
4066 case InvalidSREvent:
4067 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_sr_invalid_event,
4068 tvb, 0, 0, "UE %u: Invalid SR event - state=%s, event=%s",
4070 val_to_str_const(result->status, sr_status_vals, "Unknown"),
4071 val_to_str_const(result->event, sr_event_vals, "Unknown"));
4077 /********************************************************/
4078 /* Count number of UEs/TTI (in both directions) */
4079 /********************************************************/
4081 /* For keeping track during first pass */
4082 typedef struct tti_info_t {
4084 nstime_t ttiStartTime;
4088 static tti_info_t UL_tti_info;
4089 static tti_info_t DL_tti_info;
4091 /* For associating with frame and displaying */
4092 typedef struct TTIInfoResult_t {
4096 /* This table stores (FrameNumber -> *TTIInfoResult_t). It is assigned during the first
4097 pass and used thereafter */
4098 static GHashTable *mac_lte_tti_info_result_hash = NULL;
4101 /* Work out which UE this is within TTI (within direction). Return answer */
4102 static guint16 count_ues_tti(mac_lte_info *p_mac_lte_info, packet_info *pinfo)
4104 gboolean same_tti = FALSE;
4105 tti_info_t *tti_info;
4107 /* Just return any previous result */
4108 TTIInfoResult_t *result = (TTIInfoResult_t *)g_hash_table_lookup(mac_lte_tti_info_result_hash, GUINT_TO_POINTER(pinfo->num));
4109 if (result != NULL) {
4110 return result->ues_in_tti;
4113 /* Set tti_info based upon direction */
4114 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4115 tti_info = &UL_tti_info;
4118 tti_info = &DL_tti_info;
4121 /* Work out if we are still in the same tti as before */
4122 if (tti_info->subframe == p_mac_lte_info->subframeNumber) {
4123 gint seconds_between_packets = (gint)
4124 (pinfo->abs_ts.secs - tti_info->ttiStartTime.secs);
4125 gint nseconds_between_packets =
4126 pinfo->abs_ts.nsecs - tti_info->ttiStartTime.nsecs;
4128 /* Round difference to nearest microsecond */
4129 gint total_us_gap = (seconds_between_packets*1000000) +
4130 ((nseconds_between_packets+500) / 1000);
4132 if (total_us_gap < 1000) {
4137 /* Update global state */
4139 tti_info->subframe = p_mac_lte_info->subframeNumber;
4140 tti_info->ttiStartTime = pinfo->abs_ts;
4141 tti_info->ues_in_tti = 1;
4144 tti_info->ues_in_tti++;
4147 /* Set result state for this frame */
4148 result = wmem_new(wmem_file_scope(), TTIInfoResult_t);
4149 result->ues_in_tti = tti_info->ues_in_tti;
4150 g_hash_table_insert(mac_lte_tti_info_result_hash,
4151 GUINT_TO_POINTER(pinfo->num), result);
4153 return tti_info->ues_in_tti;
4157 /* Show which UE this is (within direction) for this TTI */
4158 static void show_ues_tti(packet_info *pinfo, mac_lte_info *p_mac_lte_info, tvbuff_t *tvb, proto_tree *context_tree)
4160 /* Look up result */
4161 TTIInfoResult_t *result = (TTIInfoResult_t *)g_hash_table_lookup(mac_lte_tti_info_result_hash, GUINT_TO_POINTER(pinfo->num));
4162 if (result != NULL) {
4163 proto_item *ti = proto_tree_add_uint(context_tree,
4164 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4165 hf_mac_lte_ues_ul_per_tti :
4166 hf_mac_lte_ues_dl_per_tti,
4167 tvb, 0, 0, result->ues_in_tti);
4168 proto_item_set_generated(ti);
4172 static void set_rlc_seqnum_length_ext_li_field(rlc_channel_type_t rlc_channel_type,
4174 guint8 *seqnum_length,
4175 gboolean *rlc_ext_li_field)
4177 switch (rlc_channel_type) {
4182 *seqnum_length = 10;
4184 case rlcAMulExtLiField:
4185 *seqnum_length = 10;
4186 if (direction == DIRECTION_UPLINK) {
4187 *rlc_ext_li_field = TRUE;
4190 case rlcAMdlExtLiField:
4191 *seqnum_length = 10;
4192 if (direction == DIRECTION_DOWNLINK) {
4193 *rlc_ext_li_field = TRUE;
4196 case rlcAMextLiField:
4197 *seqnum_length = 10;
4198 *rlc_ext_li_field = TRUE;
4201 if (direction == DIRECTION_UPLINK) {
4202 *seqnum_length = 16;
4204 *seqnum_length = 10;
4208 if (direction == DIRECTION_UPLINK) {
4209 *seqnum_length = 10;
4211 *seqnum_length = 16;
4215 *seqnum_length = 16;
4217 case rlcAMul16ulExtLiField:
4218 if (direction == DIRECTION_UPLINK) {
4219 *seqnum_length = 16;
4220 *rlc_ext_li_field = TRUE;
4222 *seqnum_length = 10;
4225 case rlcAMdl16ulExtLiField:
4226 if (direction == DIRECTION_UPLINK) {
4227 *seqnum_length = 10;
4228 *rlc_ext_li_field = TRUE;
4230 *seqnum_length = 16;
4233 case rlcAM16ulExtLiField:
4234 *seqnum_length = 16;
4235 if (direction == DIRECTION_UPLINK) {
4236 *rlc_ext_li_field = TRUE;
4239 case rlcAMul16dlExtLiField:
4240 if (direction == DIRECTION_UPLINK) {
4241 *seqnum_length = 16;
4243 *seqnum_length = 10;
4244 *rlc_ext_li_field = TRUE;
4247 case rlcAMdl16dlExtLiField:
4248 if (direction == DIRECTION_UPLINK) {
4249 *seqnum_length = 10;
4251 *seqnum_length = 16;
4252 *rlc_ext_li_field = TRUE;
4255 case rlcAM16dlExtLiField:
4256 *seqnum_length = 16;
4257 if (direction == DIRECTION_DOWNLINK) {
4258 *rlc_ext_li_field = TRUE;
4261 case rlcAMul16extLiField:
4262 if (direction == DIRECTION_UPLINK) {
4263 *seqnum_length = 16;
4265 *seqnum_length = 10;
4267 *rlc_ext_li_field = TRUE;
4269 case rlcAMdl16extLiField:
4270 if (direction == DIRECTION_UPLINK) {
4271 *seqnum_length = 10;
4273 *seqnum_length = 16;
4275 *rlc_ext_li_field = TRUE;
4277 case rlcAM16extLiField:
4278 *seqnum_length = 16;
4279 *rlc_ext_li_field = TRUE;
4286 /* Lookup channel details for lcid */
4287 static void lookup_rlc_channel_from_lcid(guint16 ueid,
4290 rlc_channel_type_t *rlc_channel_type,
4291 guint8 *seqnum_length,
4293 gboolean *rlc_ext_li_field)
4295 /* Zero params (in case no match is found) */
4296 *rlc_channel_type = rlcRaw;
4299 *rlc_ext_li_field = FALSE;
4301 if (global_mac_lte_lcid_drb_source == (int)FromStaticTable) {
4303 /* Look up in static (UAT) table */
4305 for (m=0; m < num_lcid_drb_mappings; m++) {
4306 if (lcid == lcid_drb_mappings[m].lcid) {
4308 *rlc_channel_type = lcid_drb_mappings[m].channel_type;
4310 /* Set seqnum_length and rlc_ext_li_field */
4311 set_rlc_seqnum_length_ext_li_field(*rlc_channel_type, direction,
4312 seqnum_length, rlc_ext_li_field);
4315 *drb_id = lcid_drb_mappings[m].drbid;
4321 /* Look up the dynamic mappings for this UE */
4322 ue_dynamic_drb_mappings_t *ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash, GUINT_TO_POINTER((guint)ueid));
4327 /* Look up setting gleaned from configuration protocol */
4328 if (!ue_mappings->mapping[lcid].valid) {
4332 *rlc_channel_type = ue_mappings->mapping[lcid].channel_type;
4334 /* Set seqnum_length and rlc_ext_li_field */
4335 set_rlc_seqnum_length_ext_li_field(*rlc_channel_type, direction,
4336 seqnum_length, rlc_ext_li_field);
4339 *drb_id = ue_mappings->mapping[lcid].drbid;
4345 #define MAX_HEADERS_IN_PDU 1024
4347 /* UL-SCH and DL-SCH formats have much in common, so handle them in a common
4349 static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4350 proto_item *pdu_ti, guint32 offset,
4351 mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info,
4352 proto_item *retx_ti, proto_tree *context_tree,
4357 proto_item *truncated_ti;
4358 proto_item *padding_length_ti;
4360 /* Keep track of LCIDs and lengths as we dissect the header */
4361 guint16 number_of_headers = 0;
4362 guint8 lcids[MAX_HEADERS_IN_PDU];
4363 gint32 pdu_lengths[MAX_HEADERS_IN_PDU];
4365 proto_item *pdu_header_ti;
4366 proto_tree *pdu_header_tree;
4368 gboolean have_seen_data_header = FALSE;
4369 guint8 number_of_padding_subheaders = 0;
4370 gboolean have_seen_non_padding_control = FALSE;
4371 gboolean have_seen_sc_mcch_sc_mtch_header = FALSE;
4372 gboolean have_seen_bsr = FALSE;
4373 gboolean expecting_body_data = FALSE;
4374 guint32 is_truncated = FALSE;
4376 /* Maintain/show UEs/TTI count */
4377 tap_info->ueInTTI = count_ues_tti(p_mac_lte_info, pinfo);
4378 show_ues_tti(pinfo, p_mac_lte_info, tvb, context_tree);
4380 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4381 "%s: (SFN=%-4u, SF=%u) UEId=%-3u ",
4382 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
4383 p_mac_lte_info->sysframeNumber,
4384 p_mac_lte_info->subframeNumber,
4385 p_mac_lte_info->ueid);
4387 tap_info->raw_length = p_mac_lte_info->length;
4389 /******************************************************/
4390 /* DRX information */
4392 /* Update DRX state of UE */
4393 if (global_mac_lte_show_drx) {
4394 if (!PINFO_FD_VISITED(pinfo)) {
4396 /* Update UE state to this subframe (but before this event is processed) */
4397 update_drx_info(pinfo, p_mac_lte_info);
4399 /* Store 'before' snapshot of UE state for this frame */
4400 set_drx_info(pinfo, p_mac_lte_info, TRUE, pdu_instance);
4403 /* Show current DRX state in tree as 'before' */
4404 show_drx_info(pinfo, tree, tvb, p_mac_lte_info, TRUE, pdu_instance);
4406 /* Changes of state caused by events */
4407 if (!PINFO_FD_VISITED(pinfo)) {
4408 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4409 if (p_mac_lte_info->reTxCount == 0) {
4410 mac_lte_drx_new_ulsch_data(p_mac_lte_info->ueid);
4415 if ((p_mac_lte_info->crcStatusValid) && (p_mac_lte_info->crcStatus != crc_success)) {
4416 mac_lte_drx_dl_crc_error(p_mac_lte_info->ueid);
4418 else if (p_mac_lte_info->dl_retx == dl_retx_no) {
4419 mac_lte_drx_new_dlsch_data(p_mac_lte_info->ueid);
4426 /* For uplink frames, if this is logged as a resend, look for original tx */
4427 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4428 TrackReportedULHARQResend(pinfo, tvb, offset, tree, p_mac_lte_info, retx_ti);
4431 /* For uplink grants, update SR status. N.B. only newTx grant should stop SR */
4432 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) && (p_mac_lte_info->reTxCount == 0) &&
4433 global_mac_lte_track_sr) {
4435 TrackSRInfo(SR_Grant, pinfo, tree, tvb, p_mac_lte_info, 0, NULL);
4438 /* Add PDU block header subtree */
4439 pdu_header_ti = proto_tree_add_string_format(tree,
4440 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4441 hf_mac_lte_ulsch_header :
4442 hf_mac_lte_dlsch_header,
4446 pdu_header_tree = proto_item_add_subtree(pdu_header_ti,
4447 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4448 ett_mac_lte_ulsch_header :
4449 ett_mac_lte_dlsch_header);
4452 /************************************************************************/
4453 /* Dissect each sub-header. */
4455 guint8 reserved, format2, initial_lcid;
4457 proto_item *pdu_subheader_ti;
4458 proto_tree *pdu_subheader_tree;
4459 proto_item *lcid_ti;
4461 gint offset_start_subheader = offset;
4462 guint8 first_byte = tvb_get_guint8(tvb, offset);
4464 /* Add PDU block header subtree.
4465 Default with length of 1 byte. */
4466 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
4467 hf_mac_lte_sch_subheader,
4471 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
4472 ett_mac_lte_sch_subheader);
4474 /* Check 1st reserved bit */
4475 reserved = (first_byte & 0x80) >> 7;
4476 ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_reserved,
4477 tvb, offset, 1, ENC_BIG_ENDIAN);
4478 if (reserved != 0) {
4479 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
4480 "%cL-SCH header Reserved bit not zero",
4481 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D');
4485 format2 = (first_byte & 0x40) >> 6;
4486 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_format2,
4487 tvb, offset, 1, ENC_BIG_ENDIAN);
4490 extension = (first_byte & 0x20) >> 5;
4491 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_extended,
4492 tvb, offset, 1, ENC_BIG_ENDIAN);
4494 /* LCID. Has different meaning depending upon direction. */
4495 lcids[number_of_headers] = first_byte & 0x1f;
4496 initial_lcid = lcids[number_of_headers];
4497 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4499 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_ulsch_lcid,
4500 tvb, offset, 1, ENC_BIG_ENDIAN);
4501 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4503 val_to_str_const(lcids[number_of_headers],
4504 ulsch_lcid_vals, "(Unknown LCID)"));
4505 if (lcids[number_of_headers] == 11 || lcids[number_of_headers] == 12) {
4506 /* This LCID is used for CCCH by Category 0 devices / devices using frequency hopping for unicast
4507 Let's remap it to LCID 0 for statistics and other checks */
4508 lcids[number_of_headers] = 0;
4513 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_dlsch_lcid,
4514 tvb, offset, 1, ENC_BIG_ENDIAN);
4515 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4517 val_to_str_const(lcids[number_of_headers],
4518 dlsch_lcid_vals, "(Unknown LCID)"));
4520 if ((lcids[number_of_headers] == DRX_COMMAND_LCID) ||
4521 (lcids[number_of_headers] == LONG_DRX_COMMAND_LCID)) {
4522 expert_add_info_format(pinfo, lcid_ti, &ei_mac_lte_dlsch_lcid,
4523 "%sDRX command received for UE %u (RNTI %u)",
4524 (lcids[number_of_headers] == LONG_DRX_COMMAND_LCID) ? "Long " :"",
4525 p_mac_lte_info->ueid, p_mac_lte_info->rnti);
4530 /* Remember if we've seen a data subheader */
4531 if (lcids[number_of_headers] <= 10) {
4532 have_seen_data_header = TRUE;
4533 expecting_body_data = TRUE;
4535 if ((p_mac_lte_info->direction == DIRECTION_DOWNLINK) && (lcids[number_of_headers] == SC_MCCH_SC_MTCH_LCID)) {
4536 have_seen_sc_mcch_sc_mtch_header = TRUE;
4539 /* Show an expert item if a control subheader (except Padding) appears
4540 *after* a data PDU */
4541 if (have_seen_data_header && (lcids[number_of_headers] > 10) && (lcids[number_of_headers] != PADDING_LCID)) {
4542 expert_add_info_format(pinfo, lcid_ti, &ei_mac_lte_control_subheader_after_data_subheader,
4543 "%cL-SCH control subheaders should not appear after data subheaders",
4544 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D');
4548 /* Show an expert item if we're seeing more then one BSR in a frame */
4549 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) && is_bsr_lcid(lcids[number_of_headers])) {
4550 if (have_seen_bsr) {
4551 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_control_bsr_multiple);
4554 have_seen_bsr = TRUE;
4557 /* Should not see padding after non-padding control... */
4558 if ((lcids[number_of_headers] == PADDING_LCID) &&
4561 number_of_padding_subheaders++;
4562 if (number_of_padding_subheaders > 2) {
4563 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_multiple);
4566 if (have_seen_non_padding_control) {
4567 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_before_control_subheader);
4571 /* Also flag if we have final padding but also padding subheaders
4573 if (!extension && (lcids[number_of_headers] == PADDING_LCID) &&
4574 (number_of_padding_subheaders > 0)) {
4575 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_start_and_end);
4578 /* Remember that we've seen non-padding control */
4579 if ((lcids[number_of_headers] > 10) &&
4580 (lcids[number_of_headers] != PADDING_LCID) &&
4581 (lcids[number_of_headers] != SC_MCCH_SC_MTCH_LCID)) {
4582 have_seen_non_padding_control = TRUE;
4585 /* Ensure that SC-MCCH or SC-MTCH header is not multiplexed with other LCID than Padding */
4586 if (have_seen_sc_mcch_sc_mtch_header && (have_seen_data_header || have_seen_non_padding_control)) {
4587 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_invalid_sc_mcch_sc_mtch_subheader_multiplexing);
4592 /********************************************************************/
4593 /* Length field follows if not the last header or for a fixed-sized
4597 if (is_fixed_sized_control_element(lcids[number_of_headers], p_mac_lte_info->direction)) {
4598 pdu_lengths[number_of_headers] = 0;
4601 pdu_lengths[number_of_headers] = -1;
4605 /* Not the last one */
4606 if (!is_fixed_sized_control_element(lcids[number_of_headers], p_mac_lte_info->direction) &&
4607 (lcids[number_of_headers] != PADDING_LCID)) {
4610 /* >= 32768 - use 16 bits */
4611 ti = proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
4612 tvb, offset*8, 16, &length, ENC_BIG_ENDIAN);
4613 if (length < 32768) {
4614 expert_add_info(pinfo, ti, &ei_mac_lte_sch_invalid_length);
4621 /* F(ormat) bit tells us how long the length field is */
4622 format = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
4623 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_format,
4624 tvb, offset, 1, ENC_BIG_ENDIAN);
4626 /* Now read length field itself */
4628 /* >= 128 - use 15 bits */
4629 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
4630 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
4635 /* Less than 128 - only 7 bits */
4636 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
4637 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
4641 pdu_lengths[number_of_headers] = (gint32)length;
4644 pdu_lengths[number_of_headers] = 0;
4649 /* Close off description in info column */
4650 switch (pdu_lengths[number_of_headers]) {
4652 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
4655 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
4658 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
4659 pdu_lengths[number_of_headers]);
4663 /* Append summary to subheader root */
4664 proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
4665 val_to_str_const(initial_lcid,
4666 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4671 switch (pdu_lengths[number_of_headers]) {
4673 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
4674 proto_item_append_text(pdu_header_ti, " (%s:remainder)",
4675 val_to_str_const(initial_lcid,
4676 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4677 ulsch_lcid_vals : dlsch_lcid_vals,
4681 proto_item_append_text(pdu_subheader_ti, ")");
4682 proto_item_append_text(pdu_header_ti, " (%s)",
4683 val_to_str_const(initial_lcid,
4684 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4685 ulsch_lcid_vals : dlsch_lcid_vals,
4689 proto_item_append_text(pdu_subheader_ti, ", length=%u)",
4690 pdu_lengths[number_of_headers]);
4691 proto_item_append_text(pdu_header_ti, " (%s:%u)",
4692 val_to_str_const(initial_lcid,
4693 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
4694 ulsch_lcid_vals : dlsch_lcid_vals,
4696 pdu_lengths[number_of_headers]);
4701 /* Flag unknown lcid values in expert info */
4702 if (try_val_to_str(lcids[number_of_headers],
4703 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals) == NULL) {
4704 expert_add_info_format(pinfo, pdu_subheader_ti, &ei_mac_lte_lcid_unexpected,
4705 "%cL-SCH: Unexpected LCID received (%u)",
4706 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D',
4707 lcids[number_of_headers]);
4710 /* Set length of this subheader */
4711 proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
4713 number_of_headers++;
4714 } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
4716 /* Check that we didn't reach the end of the subheader array... */
4717 if (number_of_headers >= MAX_HEADERS_IN_PDU) {
4718 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_too_many_subheaders, tvb, offset, 1,
4719 "Reached %u subheaders - frame obviously malformed",
4720 MAX_HEADERS_IN_PDU);
4725 /* Append summary to overall PDU header root */
4726 proto_item_append_text(pdu_header_ti, " [%u subheaders]",
4729 /* And set its length to offset */
4730 proto_item_set_len(pdu_header_ti, offset);
4733 /* For DL, see if this is a retx. Use whole PDU present (i.e. ignore padding if not logged) */
4734 if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
4735 /* Result will be added to context tree */
4736 TrackReportedDLHARQResend(pinfo, tvb, tvb_reported_length_remaining(tvb, 0), context_tree, p_mac_lte_info);
4738 tap_info->isPHYRetx = (p_mac_lte_info->dl_retx == dl_retx_yes);
4742 /************************************************************************/
4743 /* Dissect SDUs / control elements / padding. */
4744 /************************************************************************/
4746 /* Dissect control element bodies first */
4748 for (n=0; n < number_of_headers; n++) {
4749 /* Get out of loop once see any data SDU subheaders */
4750 if ((lcids[n] <= 10) ||
4751 ((p_mac_lte_info->direction == DIRECTION_DOWNLINK) && (lcids[n] == SC_MCCH_SC_MTCH_LCID))) {
4755 /* Process what should be a valid control PDU type */
4756 if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
4758 /****************************/
4759 /* DL-SCH Control PDUs */
4761 case ACTIVATION_DEACTIVATION_CSI_RS_LCID:
4763 proto_item *ad_csi_rs_ti;
4764 proto_tree *ad_csi_rs_tree;
4767 if (pdu_lengths[n] == -1) {
4768 /* Control Element size is the remaining PDU */
4769 pdu_lengths[n] = (gint32)tvb_reported_length_remaining(tvb, offset);
4771 /* Create AD CSR-RS root */
4772 ad_csi_rs_ti = proto_tree_add_string_format(tree,
4773 hf_mac_lte_control_activation_deactivation_csi_rs,
4774 tvb, offset, pdu_lengths[n],
4776 "Activation/Deactivation of CSI-RS");
4777 ad_csi_rs_tree = proto_item_add_subtree(ad_csi_rs_ti, ett_mac_lte_activation_deactivation_csi_rs);
4779 for (i = 0; i < pdu_lengths[n]; i++) {
4780 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a8,
4781 tvb, offset, 1, ENC_BIG_ENDIAN);
4782 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a7,
4783 tvb, offset, 1, ENC_BIG_ENDIAN);
4784 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a6,
4785 tvb, offset, 1, ENC_BIG_ENDIAN);
4786 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a5,
4787 tvb, offset, 1, ENC_BIG_ENDIAN);
4788 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a4,
4789 tvb, offset, 1, ENC_BIG_ENDIAN);
4790 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a3,
4791 tvb, offset, 1, ENC_BIG_ENDIAN);
4792 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a2,
4793 tvb, offset, 1, ENC_BIG_ENDIAN);
4794 proto_tree_add_item(ad_csi_rs_tree, hf_mac_lte_control_activation_deactivation_csi_rs_a1,
4795 tvb, offset, 1, ENC_BIG_ENDIAN);
4800 case RECOMMENDED_BIT_RATE_LCID:
4803 proto_tree *br_tree;
4807 /* Create BR root */
4808 br_ti = proto_tree_add_string_format(tree,
4809 hf_mac_lte_control_recommended_bit_rate,
4812 "Recommended Bit Rate");
4813 br_tree = proto_item_add_subtree(br_ti, ett_mac_lte_recommended_bit_rate);
4815 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_lcid,
4816 tvb, offset, 1, ENC_BIG_ENDIAN);
4817 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_dir,
4818 tvb, offset, 1, ENC_BIG_ENDIAN);
4819 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_bit_rate,
4820 tvb, offset, 2, ENC_BIG_ENDIAN);
4822 ti = proto_tree_add_item_ret_uint(br_tree, hf_mac_lte_control_recommended_bit_rate_reserved,
4823 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
4824 if (reserved != 0) {
4825 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
4826 "Recommended Bit Rate Reserved bits not zero");
4831 case ACTIVATION_DEACTIVATION_LCID:
4832 case ACTIVATION_DEACTIVATION_4_BYTES_LCID:
4835 proto_tree *ad_tree;
4839 /* Create AD root */
4840 ad_ti = proto_tree_add_string_format(tree,
4841 hf_mac_lte_control_activation_deactivation,
4843 (lcids[n] == ACTIVATION_DEACTIVATION_4_BYTES_LCID) ? 4 : 1,
4845 "Activation/Deactivation");
4846 ad_tree = proto_item_add_subtree(ad_ti, ett_mac_lte_activation_deactivation);
4848 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c7,
4849 tvb, offset, 1, ENC_BIG_ENDIAN);
4850 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c6,
4851 tvb, offset, 1, ENC_BIG_ENDIAN);
4852 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c5,
4853 tvb, offset, 1, ENC_BIG_ENDIAN);
4854 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c4,
4855 tvb, offset, 1, ENC_BIG_ENDIAN);
4856 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c3,
4857 tvb, offset, 1, ENC_BIG_ENDIAN);
4858 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c2,
4859 tvb, offset, 1, ENC_BIG_ENDIAN);
4860 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c1,
4861 tvb, offset, 1, ENC_BIG_ENDIAN);
4862 ti = proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_reserved,
4863 tvb, offset, 1, ENC_BIG_ENDIAN);
4864 reserved = tvb_get_guint8(tvb, offset) & 0x01;
4865 if (reserved != 0) {
4866 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
4867 "Activation/Deactivation Reserved bit not zero");
4870 if (lcids[n] == ACTIVATION_DEACTIVATION_4_BYTES_LCID) {
4871 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c15,
4872 tvb, offset, 1, ENC_BIG_ENDIAN);
4873 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c14,
4874 tvb, offset, 1, ENC_BIG_ENDIAN);
4875 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c13,
4876 tvb, offset, 1, ENC_BIG_ENDIAN);
4877 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c12,
4878 tvb, offset, 1, ENC_BIG_ENDIAN);
4879 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c11,
4880 tvb, offset, 1, ENC_BIG_ENDIAN);
4881 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c10,
4882 tvb, offset, 1, ENC_BIG_ENDIAN);
4883 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c9,
4884 tvb, offset, 1, ENC_BIG_ENDIAN);
4885 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c8,
4886 tvb, offset, 1, ENC_BIG_ENDIAN);
4888 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c23,
4889 tvb, offset, 1, ENC_BIG_ENDIAN);
4890 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c22,
4891 tvb, offset, 1, ENC_BIG_ENDIAN);
4892 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c21,
4893 tvb, offset, 1, ENC_BIG_ENDIAN);
4894 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c20,
4895 tvb, offset, 1, ENC_BIG_ENDIAN);
4896 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c19,
4897 tvb, offset, 1, ENC_BIG_ENDIAN);
4898 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c18,
4899 tvb, offset, 1, ENC_BIG_ENDIAN);
4900 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c17,
4901 tvb, offset, 1, ENC_BIG_ENDIAN);
4902 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c16,
4903 tvb, offset, 1, ENC_BIG_ENDIAN);
4905 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c31,
4906 tvb, offset, 1, ENC_BIG_ENDIAN);
4907 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c30,
4908 tvb, offset, 1, ENC_BIG_ENDIAN);
4909 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c29,
4910 tvb, offset, 1, ENC_BIG_ENDIAN);
4911 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c28,
4912 tvb, offset, 1, ENC_BIG_ENDIAN);
4913 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c27,
4914 tvb, offset, 1, ENC_BIG_ENDIAN);
4915 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c26,
4916 tvb, offset, 1, ENC_BIG_ENDIAN);
4917 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c25,
4918 tvb, offset, 1, ENC_BIG_ENDIAN);
4919 proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c24,
4920 tvb, offset, 1, ENC_BIG_ENDIAN);
4925 case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
4928 proto_tree *cr_tree;
4930 ContentionResolutionResult *crResult;
4932 /* Create CR root */
4933 cr_ti = proto_tree_add_string_format(tree,
4934 hf_mac_lte_control_ue_contention_resolution,
4937 "Contention Resolution");
4938 cr_tree = proto_item_add_subtree(cr_ti, ett_mac_lte_contention_resolution);
4940 /* Contention resolution body */
4941 proto_tree_add_item(cr_tree, hf_mac_lte_control_ue_contention_resolution_identity,
4942 tvb, offset, 6, ENC_NA);
4943 if (global_mac_lte_decode_cr_body) {
4944 tvbuff_t *cr_body_tvb = tvb_new_subset_length(tvb, offset, 6);
4945 if (lte_rrc_ul_ccch_handle != 0) {
4946 call_with_catch_all(lte_rrc_ul_ccch_handle, cr_body_tvb, pinfo, cr_tree);
4950 /* Get pointer to result struct for this frame */
4951 crResult = (ContentionResolutionResult *)g_hash_table_lookup(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->num));
4952 if (crResult == NULL) {
4954 /* Need to set result by looking for and comparing with Msg3 */
4956 guint msg3Key = p_mac_lte_info->rnti;
4958 /* Allocate result and add it to the table */
4959 crResult = wmem_new(wmem_file_scope(), ContentionResolutionResult);
4960 g_hash_table_insert(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->num), crResult);
4963 msg3Data = (Msg3Data *)g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(msg3Key));
4965 /* Compare CCCH bytes */
4966 if (msg3Data != NULL) {
4967 crResult->msSinceMsg3 = (guint32)(((pinfo->abs_ts.secs - msg3Data->msg3Time.secs) * 1000) +
4968 ((pinfo->abs_ts.nsecs - msg3Data->msg3Time.nsecs) / 1000000));
4969 crResult->msg3FrameNum = msg3Data->framenum;
4971 /* Compare the 6 bytes */
4972 if (tvb_memeql(tvb, offset, msg3Data->data, 6) == 0) {
4973 crResult->status = Msg3Match;
4976 crResult->status = Msg3NoMatch;
4980 crResult->status = NoMsg3;
4984 /* Now show CR result in tree */
4985 switch (crResult->status) {
4987 proto_item_append_text(cr_ti, " (no corresponding Msg3 found!)");
4991 /* Point back to msg3 frame */
4992 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
4993 tvb, 0, 0, crResult->msg3FrameNum);
4994 proto_item_set_generated(ti);
4995 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
4996 tvb, 0, 0, crResult->msSinceMsg3);
4997 proto_item_set_generated(ti);
4999 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
5001 proto_item_set_generated(ti);
5002 proto_item_append_text(cr_ti, " (matches Msg3 from frame %u, %ums ago)",
5003 crResult->msg3FrameNum, crResult->msSinceMsg3);
5005 if (!PINFO_FD_VISITED(pinfo)) {
5006 /* Add reverse mapping so can link forward from Msg3 frame */
5007 g_hash_table_insert(mac_lte_msg3_cr_hash, GUINT_TO_POINTER(crResult->msg3FrameNum),
5008 GUINT_TO_POINTER(pinfo->num));
5013 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
5014 tvb, 0, 0, crResult->msg3FrameNum);
5015 proto_item_set_generated(ti);
5016 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
5017 tvb, 0, 0, crResult->msSinceMsg3);
5018 proto_item_set_generated(ti);
5020 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
5022 expert_add_info_format(pinfo, ti, &ei_mac_lte_control_ue_contention_resolution_msg3_matched,
5023 "CR body in Msg4 doesn't match Msg3 CCCH in frame %u",
5024 crResult->msg3FrameNum);
5025 proto_item_set_generated(ti);
5026 proto_item_append_text(cr_ti, " (doesn't match Msg3 from frame %u, %u ago)",
5027 crResult->msg3FrameNum, crResult->msSinceMsg3);
5034 case TIMING_ADVANCE_LCID:
5037 proto_item *ta_value_ti;
5038 proto_tree *ta_tree;
5041 /* Create TA root */
5042 ta_ti = proto_tree_add_string_format(tree,
5043 hf_mac_lte_control_timing_advance,
5047 ta_tree = proto_item_add_subtree(ta_ti, ett_mac_lte_timing_advance);
5050 proto_tree_add_item(ta_tree, hf_mac_lte_control_timing_advance_group_id,
5051 tvb, offset, 1, ENC_BIG_ENDIAN);
5054 ta_value = tvb_get_guint8(tvb, offset) & 0x3f;
5055 ta_value_ti = proto_tree_add_item(ta_tree, hf_mac_lte_control_timing_advance_command,
5056 tvb, offset, 1, ENC_BIG_ENDIAN);
5058 if (ta_value == 31) {
5059 expert_add_info(pinfo, ta_value_ti, &ei_mac_lte_control_timing_advance_command_no_correction);
5062 expert_add_info_format(pinfo, ta_value_ti, &ei_mac_lte_control_timing_advance_command_correction_needed,
5063 "Timing Advance control element received (%u) %s correction needed",
5065 (ta_value < 31) ? "-ve" : "+ve");
5070 case DRX_COMMAND_LCID:
5071 case LONG_DRX_COMMAND_LCID:
5073 mac_lte_drx_control_element_received(p_mac_lte_info->ueid);
5076 /* No payload (in this position) */
5077 tap_info->padding_bytes++;
5086 /**********************************/
5087 /* UL-SCH Control PDUs */
5089 case RECOMMENDED_BIT_RATE_QUERY_LCID:
5092 proto_tree *br_tree;
5096 /* Create BR root */
5097 br_ti = proto_tree_add_string_format(tree,
5098 hf_mac_lte_control_recommended_bit_rate_query,
5101 "Recommended Bit Rate Query");
5102 br_tree = proto_item_add_subtree(br_ti, ett_mac_lte_recommended_bit_rate_query);
5104 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_query_lcid,
5105 tvb, offset, 1, ENC_BIG_ENDIAN);
5106 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_query_dir,
5107 tvb, offset, 1, ENC_BIG_ENDIAN);
5108 proto_tree_add_item(br_tree, hf_mac_lte_control_recommended_bit_rate_query_bit_rate,
5109 tvb, offset, 2, ENC_BIG_ENDIAN);
5111 ti = proto_tree_add_item_ret_uint(br_tree, hf_mac_lte_control_recommended_bit_rate_query_reserved,
5112 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
5113 if (reserved != 0) {
5114 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5115 "Recommended Bit Rate Reserved bits not zero");
5120 case TRUNCATED_SIDELINK_BSR_LCID:
5121 case SIDELINK_BSR_LCID:
5123 proto_item *slbsr_ti;
5124 proto_tree *slbsr_tree;
5125 guint32 curr_offset = offset;
5127 if (pdu_lengths[n] == -1) {
5128 /* Control Element size is the remaining PDU */
5129 pdu_lengths[n] = (gint32)tvb_reported_length_remaining(tvb, curr_offset);
5131 /* Create SLBSR root */
5132 if (lcids[n] == SIDELINK_BSR_LCID) {
5133 slbsr_ti = proto_tree_add_string_format(tree,
5134 hf_mac_lte_control_sidelink_bsr,
5135 tvb, curr_offset, pdu_lengths[n],
5139 slbsr_ti = proto_tree_add_string_format(tree,
5140 hf_mac_lte_control_sidelink_bsr,
5141 tvb, curr_offset, pdu_lengths[n],
5143 "Truncated Sidelink BSR");
5145 slbsr_tree = proto_item_add_subtree(slbsr_ti, ett_mac_lte_sidelink_bsr);
5147 while ((gint32)(curr_offset - offset) < pdu_lengths[n]) {
5148 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_destination_idx_odd,
5149 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5150 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_lcg_id_odd,
5151 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5152 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_buffer_size_odd,
5153 tvb, curr_offset, 2, ENC_BIG_ENDIAN);
5155 if ((gint32)(curr_offset - offset) < (pdu_lengths[n] - 1)) {
5156 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_destination_idx_even,
5157 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5159 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_lcg_id_even,
5160 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5161 proto_tree_add_item(slbsr_tree, hf_mac_lte_control_sidelink_bsr_buffer_size_even,
5162 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5165 /* Check Reserved bit */
5169 it = proto_tree_add_item_ret_uint(slbsr_tree, hf_mac_lte_control_sidelink_reserved,
5170 tvb, curr_offset, 1, ENC_BIG_ENDIAN, &reserved);
5172 if (lcids[n] == SIDELINK_BSR_LCID) {
5173 expert_add_info_format(pinfo, it, &ei_mac_lte_reserved_not_zero,
5174 "Sidelink BSR Reserved bits not zero");
5176 expert_add_info_format(pinfo, it, &ei_mac_lte_reserved_not_zero,
5177 "Truncated Sidelink BSR Reserved bits not zero");
5183 offset += pdu_lengths[n];
5186 case DUAL_CONN_POWER_HEADROOM_REPORT_LCID:
5188 proto_item *dcphr_ti;
5189 proto_tree *dcphr_tree;
5191 proto_tree *dcphr_cell_tree;
5192 proto_item *dcphr_cell_ti;
5193 guint8 scell_bitmap;
5196 guint32 curr_offset = offset;
5198 if (!PINFO_FD_VISITED(pinfo)) {
5199 get_mac_lte_ue_simult_pucch_pusch(p_mac_lte_info);
5201 if (pdu_lengths[n] == -1) {
5202 /* Control Element size is the remaining PDU */
5203 pdu_lengths[n] = (gint32)tvb_reported_length_remaining(tvb, curr_offset);
5206 /* Create DCPHR root */
5207 dcphr_ti = proto_tree_add_string_format(tree,
5208 hf_mac_lte_control_dual_conn_power_headroom,
5209 tvb, curr_offset, pdu_lengths[n],
5211 "Dual Connectivity Power Headroom Report");
5212 dcphr_tree = proto_item_add_subtree(dcphr_ti, ett_mac_lte_dual_conn_power_headroom);
5214 /* TODO: add support for 4 bytes long SCell index */
5215 scell_bitmap = tvb_get_guint8(tvb, curr_offset);
5216 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c7,
5217 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5218 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c6,
5219 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5220 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c5,
5221 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5222 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c4,
5223 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5224 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c3,
5225 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5226 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c2,
5227 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5228 proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_c1,
5229 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5230 /* Check Reserved bit */
5231 ti = proto_tree_add_item(dcphr_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved,
5232 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5233 if (scell_bitmap & 0x01) {
5234 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5235 "Dual Connectivity Power Headroom Report Reserved bit not zero");
5239 if (p_mac_lte_info->isSimultPUCCHPUSCHPCell) {
5240 /* PCell PH Type 2 is present */
5241 byte = tvb_get_guint8(tvb, curr_offset);
5242 dcphr_cell_tree = proto_tree_add_subtree(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5243 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "PCell PUCCH");
5244 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5245 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5246 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5247 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5248 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5249 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5250 proto_item_append_text(dcphr_cell_ti, " (%s)",
5251 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5253 if ((byte & 0x40) == 0) {
5254 /* Pcmax,c field is present */
5255 byte = tvb_get_guint8(tvb, curr_offset);
5256 /* Check 2 Reserved bits */
5257 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5258 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5260 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5261 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5262 (byte & 0xc0) >> 6);
5264 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5265 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5266 proto_item_append_text(dcphr_cell_ti, " (%s)",
5267 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5271 if (p_mac_lte_info->isSimultPUCCHPUSCHPSCell) {
5272 /* PSCell PH Type 2 is present */
5273 byte = tvb_get_guint8(tvb, curr_offset);
5274 dcphr_cell_tree = proto_tree_add_subtree(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5275 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "PSCell PUCCH");
5276 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5277 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5278 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5279 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5280 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5281 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5282 proto_item_append_text(dcphr_cell_ti, " (%s)",
5283 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5285 if ((byte & 0x40) == 0) {
5286 /* Pcmax,c field is present */
5287 byte = tvb_get_guint8(tvb, curr_offset);
5288 /* Check 2 Reserved bits */
5289 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5290 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5292 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5293 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5294 (byte & 0xc0) >> 6);
5296 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5297 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5298 proto_item_append_text(dcphr_cell_ti, " (%s)",
5299 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5303 byte = tvb_get_guint8(tvb, curr_offset);
5304 dcphr_cell_tree = proto_tree_add_subtree(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5305 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "PCell PUSCH");
5306 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5307 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5308 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5309 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5310 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5311 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5312 proto_item_append_text(dcphr_cell_ti, " (%s)",
5313 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5315 if ((byte & 0x40) == 0) {
5316 /* Pcmax,c field is present */
5317 byte = tvb_get_guint8(tvb, curr_offset);
5318 /* Check 2 Reserved bits */
5319 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5320 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5322 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5323 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5324 (byte & 0xc0) >> 6);
5326 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5327 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5328 proto_item_append_text(dcphr_cell_ti, " (%s)",
5329 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5332 for (i = 1, scell_bitmap>>=1; i <= 7; i++, scell_bitmap>>=1) {
5333 if (scell_bitmap & 0x01) {
5334 byte = tvb_get_guint8(tvb, curr_offset);
5335 dcphr_cell_tree = proto_tree_add_subtree_format(dcphr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5336 ett_mac_lte_dual_conn_power_headroom_cell, &dcphr_cell_ti, "SCell Index %u PUSCH", i);
5337 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
5338 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5339 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_value,
5340 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5341 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_level,
5342 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5343 proto_item_append_text(dcphr_cell_ti, " (%s)",
5344 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5346 if ((byte & 0x40) == 0) {
5347 /* Pcmax,c field is present */
5348 byte = tvb_get_guint8(tvb, curr_offset);
5349 /* Check 2 Reserved bits */
5350 ti = proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_reserved2,
5351 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5353 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5354 "Dual Connectivity Power Headroom Report Reserved bits not zero (found 0x%x)",
5355 (byte & 0xc0) >> 6);
5357 proto_tree_add_item(dcphr_cell_tree, hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
5358 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5359 proto_item_append_text(dcphr_cell_ti, " (%s)",
5360 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5365 if ((gint32)(curr_offset - offset) != pdu_lengths[n]) {
5366 expert_add_info_format(pinfo, dcphr_ti, &ei_mac_lte_control_element_size_invalid,
5367 "Control Element has an unexpected size (computed=%d, actual=%d)",
5368 curr_offset - offset, pdu_lengths[n]);
5370 offset += pdu_lengths[n];
5373 case EXTENDED_POWER_HEADROOM_REPORT_LCID:
5375 proto_item *ephr_ti;
5376 proto_tree *ephr_tree;
5378 proto_tree *ephr_cell_tree;
5379 proto_item *ephr_cell_ti;
5380 guint8 scell_bitmap;
5384 guint32 curr_offset = offset;
5385 guint32 computed_header_offset;
5387 if (!PINFO_FD_VISITED(pinfo)) {
5388 get_mac_lte_ue_simult_pucch_pusch(p_mac_lte_info);
5390 if (pdu_lengths[n] == -1) {
5391 /* Control Element size is the remaining PDU */
5392 pdu_lengths[n] = (gint16)tvb_reported_length_remaining(tvb, curr_offset);
5395 /* Create EPHR root */
5396 ephr_ti = proto_tree_add_string_format(tree,
5397 hf_mac_lte_control_ext_power_headroom,
5398 tvb, curr_offset, pdu_lengths[n],
5400 "Extended Power Headroom Report");
5401 ephr_tree = proto_item_add_subtree(ephr_ti, ett_mac_lte_extended_power_headroom);
5403 /* TODO: add support for extendedPHR2 */
5404 scell_bitmap = tvb_get_guint8(tvb, curr_offset);
5405 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c7,
5406 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5407 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c6,
5408 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5409 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c5,
5410 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5411 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c4,
5412 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5413 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c3,
5414 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5415 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c2,
5416 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5417 proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c1,
5418 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5419 /* Check Reserved bit */
5420 ti = proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_reserved,
5421 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5422 if (scell_bitmap & 0x01) {
5423 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5424 "Extended Power Headroom Report Reserved bit not zero");
5428 /* Compute expected header size to deduce if PH Type 2 report is present or not */
5429 /* First count the number of SCells */
5430 for (i = 0, scell_count = 0; i < 7; i++) {
5431 if (scell_bitmap & (0x80>>i)) {
5435 /* Now quickly parse the header */
5436 computed_header_offset = curr_offset;
5437 for (i = 0; i < (guint)(1 + scell_count); i++) {
5438 if ((tvb_get_guint8(tvb, computed_header_offset) & 0x40) == 0) {
5439 computed_header_offset++;
5441 computed_header_offset++;
5444 if (((gint32)(computed_header_offset + 1 - curr_offset) != pdu_lengths[n]) ||
5445 p_mac_lte_info->isSimultPUCCHPUSCHPCell) {
5446 /* PH Type 2 might be present */
5447 if ((tvb_get_guint8(tvb, computed_header_offset) & 0x40) == 0) {
5448 computed_header_offset++;
5450 computed_header_offset++;
5451 if ((gint32)(computed_header_offset + 1 - curr_offset) != pdu_lengths[n]) {
5452 expert_add_info_format(pinfo, ephr_ti, &ei_mac_lte_control_element_size_invalid,
5453 "Control Element has an unexpected size (computed=%d, actual=%d)",
5454 computed_header_offset + 1 - curr_offset, pdu_lengths[n]);
5455 offset += pdu_lengths[n];
5458 byte = tvb_get_guint8(tvb, curr_offset);
5459 ephr_cell_tree = proto_tree_add_subtree(ephr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5460 ett_mac_lte_extended_power_headroom_cell, &ephr_cell_ti, "PCell PUCCH");
5461 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
5462 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5463 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
5464 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5465 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
5466 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5467 proto_item_append_text(ephr_cell_ti, " (%s)",
5468 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5470 if ((byte & 0x40) == 0) {
5471 /* Pcmax,c field is present */
5472 byte = tvb_get_guint8(tvb, curr_offset);
5473 /* Check 2 Reserved bits */
5474 ti = proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
5475 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5477 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5478 "Extended Power Headroom Report Reserved bits not zero (found 0x%x)",
5479 (byte & 0xc0) >> 6);
5481 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
5482 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5483 proto_item_append_text(ephr_cell_ti, " (%s)",
5484 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5488 byte = tvb_get_guint8(tvb, curr_offset);
5489 ephr_cell_tree = proto_tree_add_subtree(ephr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5490 ett_mac_lte_extended_power_headroom_cell, &ephr_cell_ti, "PCell PUSCH");
5491 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
5492 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5493 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
5494 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5495 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
5496 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5497 proto_item_append_text(ephr_cell_ti, " (%s)",
5498 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5500 if ((byte & 0x40) == 0) {
5501 /* Pcmax,c field is present */
5502 byte = tvb_get_guint8(tvb, curr_offset);
5503 /* Check 2 Reserved bits */
5504 ti = proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
5505 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5507 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5508 "Extended Power Headroom Report Reserved bits not zero (found 0x%x)",
5509 (byte & 0xc0) >> 6);
5511 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
5512 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5513 proto_item_append_text(ephr_cell_ti, " (%s)",
5514 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5517 for (i = 1, scell_bitmap>>=1; i <= 7; i++, scell_bitmap>>=1) {
5518 if (scell_bitmap & 0x01) {
5519 byte = tvb_get_guint8(tvb, curr_offset);
5520 ephr_cell_tree = proto_tree_add_subtree_format(ephr_tree, tvb, curr_offset, (!(byte&0x40)?2:1),
5521 ett_mac_lte_extended_power_headroom_cell, &ephr_cell_ti, "SCell Index %u PUSCH", i);
5522 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
5523 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5524 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
5525 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5526 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
5527 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5528 proto_item_append_text(ephr_cell_ti, " (%s)",
5529 val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
5531 if ((byte & 0x40) == 0) {
5532 /* Pcmax,c field is present */
5533 byte = tvb_get_guint8(tvb, curr_offset);
5534 /* Check 2 Reserved bits */
5535 ti = proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
5536 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5538 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5539 "Extended Power Headroom Report Reserved bits not zero (found 0x%x)",
5540 (byte & 0xc0) >> 6);
5542 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
5543 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
5544 proto_item_append_text(ephr_cell_ti, " (%s)",
5545 val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
5550 offset += pdu_lengths[n];
5553 case POWER_HEADROOM_REPORT_LCID:
5556 proto_tree *phr_tree;
5561 /* Create PHR root */
5562 phr_ti = proto_tree_add_string_format(tree,
5563 hf_mac_lte_control_power_headroom,
5566 "Power Headroom Report");
5567 phr_tree = proto_item_add_subtree(phr_ti, ett_mac_lte_power_headroom);
5569 /* Check 2 Reserved bits */
5570 reserved = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
5571 ti = proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_reserved,
5572 tvb, offset, 1, ENC_BIG_ENDIAN);
5573 if (reserved != 0) {
5574 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
5575 "Power Headroom Report Reserved bits not zero (found 0x%x)", reserved);
5579 level = tvb_get_guint8(tvb, offset) & 0x3f;
5580 proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_level,
5581 tvb, offset, 1, ENC_BIG_ENDIAN);
5583 /* Show value in root label */
5584 proto_item_append_text(phr_ti, " (%s)",
5585 val_to_str_ext_const(level, &power_headroom_vals_ext, "Unknown"));
5590 proto_tree_add_item(tree, hf_mac_lte_control_crnti,
5591 tvb, offset, 2, ENC_BIG_ENDIAN);
5594 /* TODO: treat separately */
5595 case TRUNCATED_BSR_LCID:
5596 case SHORT_BSR_LCID:
5598 proto_tree *bsr_tree;
5600 proto_item *buffer_size_ti;
5604 value_string_ext *p_vs_ext;
5605 guint32 *p_buffer_size_median;
5607 if (!PINFO_FD_VISITED(pinfo)) {
5608 get_mac_lte_ue_ext_bsr_sizes(p_mac_lte_info);
5610 if (p_mac_lte_info->isExtendedBSRSizes) {
5611 hfindex = hf_mac_lte_control_short_ext_bsr_buffer_size;
5612 p_vs_ext = &ext_buffer_size_vals_ext;
5613 p_buffer_size_median = ext_buffer_size_median;
5615 hfindex = hf_mac_lte_control_short_bsr_buffer_size;
5616 p_vs_ext = &buffer_size_vals_ext;
5617 p_buffer_size_median = buffer_size_median;
5620 if (lcids[n] == SHORT_BSR_LCID) {
5621 bsr_ti = proto_tree_add_string_format(tree,
5622 hf_mac_lte_control_bsr,
5627 bsr_ti = proto_tree_add_string_format(tree,
5628 hf_mac_lte_control_bsr,
5633 bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
5636 lcgid = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
5637 proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_lcg_id,
5638 tvb, offset, 1, ENC_BIG_ENDIAN);
5640 buffer_size = tvb_get_guint8(tvb, offset) & 0x3f;
5641 buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex,
5642 tvb, offset, 1, ENC_BIG_ENDIAN);
5643 if (global_mac_lte_show_BSR_median) {
5644 /* Add value that can be graphed */
5645 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]);
5646 proto_item_set_generated(bsr_median_ti);
5650 if (buffer_size >= global_mac_lte_bsr_warn_threshold) {
5651 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
5652 "UE %u - BSR for LCG %u exceeds threshold: %u (%s)",
5653 p_mac_lte_info->ueid,
5656 val_to_str_ext_const(buffer_size, p_vs_ext, "Unknown"));
5660 proto_item_append_text(bsr_ti, " (lcgid=%u %s)",
5662 val_to_str_ext_const(buffer_size, p_vs_ext, "Unknown"));
5667 proto_tree *bsr_tree;
5668 proto_item *bsr_ti, *bsr_median_ti;
5669 proto_item *buffer_size_ti;
5670 guint8 buffer_size[4];
5672 value_string_ext *p_vs_ext;
5673 guint32 *p_buffer_size_median;
5675 if (!PINFO_FD_VISITED(pinfo)) {
5676 get_mac_lte_ue_ext_bsr_sizes(p_mac_lte_info);
5678 if (p_mac_lte_info->isExtendedBSRSizes) {
5679 hfindex[0] = hf_mac_lte_control_long_ext_bsr_buffer_size_0;
5680 hfindex[1] = hf_mac_lte_control_long_ext_bsr_buffer_size_1;
5681 hfindex[2] = hf_mac_lte_control_long_ext_bsr_buffer_size_2;
5682 hfindex[3] = hf_mac_lte_control_long_ext_bsr_buffer_size_3;
5683 p_vs_ext = &ext_buffer_size_vals_ext;
5684 p_buffer_size_median = ext_buffer_size_median;
5686 hfindex[0] = hf_mac_lte_control_long_bsr_buffer_size_0;
5687 hfindex[1] = hf_mac_lte_control_long_bsr_buffer_size_1;
5688 hfindex[2] = hf_mac_lte_control_long_bsr_buffer_size_2;
5689 hfindex[3] = hf_mac_lte_control_long_bsr_buffer_size_3;
5690 p_vs_ext = &buffer_size_vals_ext;
5691 p_buffer_size_median = buffer_size_median;
5694 bsr_ti = proto_tree_add_string_format(tree,
5695 hf_mac_lte_control_bsr,
5699 bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
5702 buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[0],
5703 tvb, offset, 1, ENC_BIG_ENDIAN);
5704 buffer_size[0] = (tvb_get_guint8(tvb, offset) & 0xfc) >> 2;
5706 if (global_mac_lte_show_BSR_median) {
5707 /* Add value that can be graphed */
5708 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]]);
5709 proto_item_set_generated(bsr_median_ti);
5712 if (buffer_size[0] >= global_mac_lte_bsr_warn_threshold) {
5713 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
5714 "UE %u - BSR for LCG 0 exceeds threshold: %u (%s)",
5715 p_mac_lte_info->ueid,
5717 val_to_str_ext_const(buffer_size[0], p_vs_ext, "Unknown"));
5721 buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[1],
5722 tvb, offset, 2, ENC_BIG_ENDIAN);
5723 buffer_size[1] = ((tvb_get_guint8(tvb, offset) & 0x03) << 4) | ((tvb_get_guint8(tvb, offset+1) & 0xf0) >> 4);
5725 if (global_mac_lte_show_BSR_median) {
5726 /* Add value that can be graphed */
5727 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]]);
5728 proto_item_set_generated(bsr_median_ti);
5732 if (buffer_size[1] >= global_mac_lte_bsr_warn_threshold) {
5733 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
5734 "UE %u - BSR for LCG 1 exceeds threshold: %u (%s)",
5735 p_mac_lte_info->ueid,
5737 val_to_str_ext_const(buffer_size[1], p_vs_ext, "Unknown"));
5741 buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[2],
5742 tvb, offset, 2, ENC_BIG_ENDIAN);
5744 buffer_size[2] = ((tvb_get_guint8(tvb, offset) & 0x0f) << 2) | ((tvb_get_guint8(tvb, offset+1) & 0xc0) >> 6);
5746 if (global_mac_lte_show_BSR_median) {
5747 /* Add value that can be graphed */
5748 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]]);
5749 proto_item_set_generated(bsr_median_ti);
5753 if (buffer_size[2] >= global_mac_lte_bsr_warn_threshold) {
5754 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
5755 "UE %u - BSR for LCG 2 exceeds threshold: %u (%s)",
5756 p_mac_lte_info->ueid,
5758 val_to_str_ext_const(buffer_size[2], p_vs_ext, "Unknown"));
5762 buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[3],
5763 tvb, offset, 1, ENC_BIG_ENDIAN);
5764 buffer_size[3] = tvb_get_guint8(tvb, offset) & 0x3f;
5766 if (global_mac_lte_show_BSR_median) {
5767 /* Add value that can be graphed */
5768 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]]);
5769 proto_item_set_generated(bsr_median_ti);
5773 if (buffer_size[3] >= global_mac_lte_bsr_warn_threshold) {
5774 expert_add_info_format(pinfo, buffer_size_ti, &ei_mac_lte_bsr_warn_threshold_exceeded,
5775 "UE %u - BSR for LCG 3 exceeds threshold: %u (%s)",
5776 p_mac_lte_info->ueid,
5778 val_to_str_ext_const(buffer_size[3], p_vs_ext, "Unknown"));
5781 /* Append summary to parent */
5782 proto_item_append_text(bsr_ti, " 0:(%s) 1:(%s) 2:(%s) 3:(%s)",
5783 val_to_str_ext_const(buffer_size[0], p_vs_ext, "Unknown"),
5784 val_to_str_ext_const(buffer_size[1], p_vs_ext, "Unknown"),
5785 val_to_str_ext_const(buffer_size[2], p_vs_ext, "Unknown"),
5786 val_to_str_ext_const(buffer_size[3], p_vs_ext, "Unknown"));
5790 /* No payload, in this position */
5791 tap_info->padding_bytes++;
5800 /* There might not be any data, if only headers (plus control data) were logged */
5801 is_truncated = ((tvb_captured_length_remaining(tvb, offset) == 0) && expecting_body_data);
5802 truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_sch_header_only, tvb, 0, 0,
5805 proto_item_set_generated(truncated_ti);
5806 expert_add_info(pinfo, truncated_ti, &ei_mac_lte_sch_header_only_truncated);
5807 /* Update sdu and byte count in stats */
5808 for (; n < number_of_headers; n++) {
5809 guint16 data_length;
5810 /* Break out if meet padding */
5811 if (lcids[n] == PADDING_LCID) {
5814 data_length = (pdu_lengths[n] == -1) ?
5815 tvb_reported_length_remaining(tvb, offset) :
5817 tap_info->sdus_for_lcid[lcids[n]]++;
5818 tap_info->bytes_for_lcid[lcids[n]] += data_length;
5819 offset += data_length;
5821 if (lcids[number_of_headers-1] == PADDING_LCID) {
5822 /* Update padding bytes in stats */
5823 tap_info->padding_bytes += (p_mac_lte_info->length - offset);
5828 proto_item_set_hidden(truncated_ti);
5832 /* Now process remaining bodies, which should all be data */
5833 for (; n < number_of_headers; n++) {
5835 /* Data SDUs treated identically for Uplink or downlink channels */
5837 guint16 data_length;
5838 gboolean rlc_called_for_sdu = FALSE;
5840 /* Break out if meet padding */
5841 if (lcids[n] == PADDING_LCID) {
5845 /* Work out length */
5846 data_length = (pdu_lengths[n] == -1) ?
5847 tvb_reported_length_remaining(tvb, offset) :
5850 if ((lcids[n] == 0) && (p_mac_lte_info->direction == DIRECTION_UPLINK) &&
5851 (p_mac_lte_info->nbMode == nb_mode) && (data_length > 0)) {
5852 /* Dissect DPR MAC Control Element that is in front of CCCH SDU */
5854 proto_tree *dpr_tree;
5857 dpr_ti = proto_tree_add_string_format(tree,
5858 hf_mac_lte_control_data_vol_power_headroom,
5861 "Data Volume and Power Headroom Report");
5862 dpr_tree = proto_item_add_subtree(dpr_ti, ett_mac_lte_data_vol_power_headroom);
5863 dpr_ti = proto_tree_add_item_ret_uint(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_reserved,
5864 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
5866 expert_add_info_format(pinfo, dpr_ti, &ei_mac_lte_reserved_not_zero,
5867 "Data Volume and Power Headroom Report Reserved bits not zero");
5869 proto_tree_add_item(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_level, tvb, offset, 1, ENC_BIG_ENDIAN);
5870 proto_tree_add_item(dpr_tree, hf_mac_lte_control_data_vol_power_headroom_data_vol, tvb, offset, 1, ENC_BIG_ENDIAN);
5872 if (pdu_lengths[n] == -1) {
5877 /* Dissect SDU as raw bytes */
5878 sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_sch_sdu, tvb, offset, pdu_lengths[n],
5879 NULL, "SDU (%s, length=%u bytes): ",
5880 val_to_str_const(lcids[n],
5881 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
5887 /* Look for Msg3 data so that it may be compared with later
5888 Contention Resolution body */
5889 /* Starting from R13, CCCH can be more than 48 bits but only the first 48 bits are used for contention resolution */
5890 if ((lcids[n] == 0) && (p_mac_lte_info->direction == DIRECTION_UPLINK) && (data_length >= 6)) {
5891 if (!PINFO_FD_VISITED(pinfo)) {
5892 guint key = p_mac_lte_info->rnti;
5893 Msg3Data *data = (Msg3Data *)g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(key));
5895 /* Look for previous entry for this UE */
5897 /* Allocate space for data and add to table */
5898 data = wmem_new(wmem_file_scope(), Msg3Data);
5899 g_hash_table_insert(mac_lte_msg3_hash, GUINT_TO_POINTER(key), data);
5902 /* Fill in data details */
5903 data->framenum = pinfo->num;
5904 tvb_memcpy(tvb, data->data, offset, 6);
5905 data->msg3Time = pinfo->abs_ts;
5909 /* CCCH frames can be dissected directly by LTE RRC... */
5910 if ((lcids[n] == 0) && global_mac_lte_attempt_rrc_decode) {
5911 tvbuff_t *rrc_tvb = tvb_new_subset_length(tvb, offset, data_length);
5913 /* Get appropriate dissector handle */
5914 dissector_handle_t protocol_handle = 0;
5915 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
5916 if (p_mac_lte_info->nbMode == no_nb_mode) {
5917 protocol_handle = lte_rrc_ul_ccch_handle;
5920 protocol_handle = lte_rrc_ul_ccch_nb_handle;
5924 if (p_mac_lte_info->nbMode == no_nb_mode) {
5925 protocol_handle = lte_rrc_dl_ccch_handle;
5928 protocol_handle = lte_rrc_dl_ccch_nb_handle;
5932 /* Hide raw view of bytes */
5933 proto_item_set_hidden(sdu_ti);
5934 rlc_called_for_sdu = TRUE;
5936 call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
5939 /* LCID 1 and 2 can be assumed to be srb1&2, so can dissect as RLC AM */
5940 /* LCID 3 in NB mode can be assumed to be srb1bis, so can dissect as RLC AM */
5941 else if ((lcids[n] == 1) || (lcids[n] == 2) ||
5942 (p_mac_lte_info->nbMode == nb_mode && lcids[n] == 3)) {
5943 if (global_mac_lte_attempt_srb_decode) {
5944 /* Call RLC dissector */
5945 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
5946 RLC_AM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
5947 CHANNEL_TYPE_SRB, lcids[n], 0,
5948 get_mac_lte_channel_priority(p_mac_lte_info->ueid,
5949 lcids[n], p_mac_lte_info->direction),
5950 FALSE, p_mac_lte_info->nbMode);
5952 /* Hide raw view of bytes */
5953 proto_item_set_hidden(sdu_ti);
5954 rlc_called_for_sdu = TRUE;
5958 else if ((lcids[n] >= 3) && (lcids[n] <= 10)) {
5960 /* Look for mapping for this LCID to drb channel set by UAT table or through
5961 configuration protocol. */
5962 rlc_channel_type_t rlc_channel_type;
5963 guint8 seqnum_length;
5965 gboolean rlc_ext_li_field;
5966 guint8 priority = get_mac_lte_channel_priority(p_mac_lte_info->ueid,
5967 lcids[n], p_mac_lte_info->direction);
5969 lookup_rlc_channel_from_lcid(p_mac_lte_info->ueid,
5971 p_mac_lte_info->direction,
5977 /* Dissect according to channel type */
5978 switch (rlc_channel_type) {
5981 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
5982 RLC_UM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
5983 CHANNEL_TYPE_DRB, (guint16)drb_id, seqnum_length,
5984 priority, FALSE, p_mac_lte_info->nbMode);
5987 case rlcAMulExtLiField:
5988 case rlcAMdlExtLiField:
5989 case rlcAMextLiField:
5993 case rlcAMul16ulExtLiField:
5994 case rlcAMdl16ulExtLiField:
5995 case rlcAM16ulExtLiField:
5996 case rlcAMul16dlExtLiField:
5997 case rlcAMdl16dlExtLiField:
5998 case rlcAM16dlExtLiField:
5999 case rlcAMul16extLiField:
6000 case rlcAMdl16extLiField:
6001 case rlcAM16extLiField:
6002 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6003 RLC_AM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
6004 CHANNEL_TYPE_DRB, (guint16)drb_id, seqnum_length,
6005 priority, rlc_ext_li_field, p_mac_lte_info->nbMode);
6008 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6009 RLC_TM_MODE, p_mac_lte_info->direction, p_mac_lte_info->ueid,
6010 CHANNEL_TYPE_DRB, (guint16)drb_id, 0,
6011 priority, FALSE, p_mac_lte_info->nbMode);
6014 /* Nothing to do! */
6018 if (rlc_channel_type != rlcRaw) {
6019 /* Hide raw view of bytes */
6020 proto_item_set_hidden(sdu_ti);
6021 rlc_called_for_sdu = TRUE;
6026 else if ((lcids[n] == SC_MCCH_SC_MTCH_LCID) && (p_mac_lte_info->rntiType == SC_RNTI)
6027 && global_mac_lte_attempt_rrc_decode) {
6028 tvbuff_t *rrc_tvb = tvb_new_subset_length(tvb, offset, data_length);
6030 /* Hide raw view of bytes */
6031 proto_item_set_hidden(sdu_ti);
6032 rlc_called_for_sdu = TRUE;
6034 call_with_catch_all(lte_rrc_sc_mcch_handle, rrc_tvb, pinfo, tree);
6037 /* Show bytes too, if won't be hidden (slow). There must be a nicer way of doing this! */
6038 if (!rlc_called_for_sdu) {
6039 if (pdu_lengths[n] >= 30)
6041 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, 30));
6042 proto_item_append_text(sdu_ti, "...");
6046 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, data_length));
6050 offset += data_length;
6052 /* Update tap sdu and byte count for this channel */
6053 tap_info->sdus_for_lcid[lcids[n]]++;
6054 tap_info->bytes_for_lcid[lcids[n]] += data_length;
6057 /* Was this a Msg3 that led to a CR answer? */
6058 if (PINFO_FD_VISITED(pinfo)) {
6059 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) &&
6060 (number_of_headers >= 1) &&
6063 guint32 cr_frame = GPOINTER_TO_UINT (g_hash_table_lookup(mac_lte_msg3_cr_hash,
6064 GUINT_TO_POINTER(pinfo->num)));
6065 if (cr_frame != 0) {
6066 proto_item *cr_ti = proto_tree_add_uint(tree, hf_mac_lte_control_msg3_to_cr,
6067 tvb, 0, 0, cr_frame);
6068 proto_item_set_generated(cr_ti);
6073 /* Now padding, if present, extends to the end of the PDU */
6074 if (lcids[number_of_headers-1] == PADDING_LCID) {
6075 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6076 proto_tree_add_item(tree, hf_mac_lte_padding_data,
6077 tvb, offset, -1, ENC_NA);
6079 padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
6081 p_mac_lte_info->length - offset);
6082 proto_item_set_generated(padding_length_ti);
6084 /* Update padding bytes in stats */
6085 tap_info->padding_bytes += (p_mac_lte_info->length - offset);
6087 /* Make sure the PDU isn't bigger than reported! */
6088 if (offset > p_mac_lte_info->length) {
6089 expert_add_info_format(pinfo, padding_length_ti, &ei_mac_lte_context_length,
6090 "%s MAC PDU is longer than reported length (reported=%u, actual=%u)",
6091 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
6092 p_mac_lte_info->length, offset);
6096 /* There is no padding at the end of the frame */
6097 if (!is_truncated && (offset < p_mac_lte_info->length)) {
6098 /* There is a problem if we haven't used all of the PDU */
6099 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6100 "%s PDU for UE %u is shorter than reported length (reported=%u, actual=%u)",
6101 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
6102 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
6105 if (!is_truncated && (offset > p_mac_lte_info->length)) {
6106 /* There is a problem if the PDU is longer than reported */
6107 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6108 "%s PDU for UE %u is longer than reported length (reported=%u, actual=%u)",
6109 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
6110 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
6114 /* Can now store updated DRX info and show its info in the tree */
6115 if (global_mac_lte_show_drx) {
6116 if (!PINFO_FD_VISITED(pinfo)) {
6117 /* Store 'after' snapshot of UE state for this frame */
6118 set_drx_info(pinfo, p_mac_lte_info, FALSE, pdu_instance);
6121 /* Show current DRX state in tree as 'after' */
6122 show_drx_info(pinfo, tree, tvb, p_mac_lte_info, FALSE, pdu_instance);
6126 static void dissect_mch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *pdu_ti,
6127 guint32 offset, mac_lte_info *p_mac_lte_info)
6131 proto_item *truncated_ti;
6132 proto_item *padding_length_ti;
6133 proto_item *hidden_root_ti;
6135 /* Keep track of LCIDs and lengths as we dissect the header */
6136 guint16 number_of_headers = 0;
6137 guint8 lcids[MAX_HEADERS_IN_PDU];
6138 gint32 pdu_lengths[MAX_HEADERS_IN_PDU];
6140 proto_item *pdu_header_ti, *sched_info_ti = NULL;
6141 proto_tree *pdu_header_tree;
6143 gboolean have_seen_data_header = FALSE;
6144 guint8 number_of_padding_subheaders = 0;
6145 gboolean have_seen_non_padding_control = FALSE;
6146 gboolean expecting_body_data = FALSE;
6147 guint32 is_truncated = FALSE;
6149 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, "MCH: ");
6151 /* Add hidden item to filter on */
6152 hidden_root_ti = proto_tree_add_string_format(tree, hf_mac_lte_mch, tvb,
6153 offset, 0, "", "Hidden header");
6154 proto_item_set_hidden(hidden_root_ti);
6156 /* Add PDU block header subtree */
6157 pdu_header_ti = proto_tree_add_string_format(tree, hf_mac_lte_mch_header,
6161 pdu_header_tree = proto_item_add_subtree(pdu_header_ti, ett_mac_lte_mch_header);
6164 /************************************************************************/
6165 /* Dissect each sub-header. */
6167 guint8 reserved, format2;
6169 proto_item *pdu_subheader_ti;
6170 proto_tree *pdu_subheader_tree;
6171 proto_item *lcid_ti;
6173 gint offset_start_subheader = offset;
6174 guint8 first_byte = tvb_get_guint8(tvb, offset);
6176 /* Add PDU block header subtree.
6177 Default with length of 1 byte. */
6178 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
6179 hf_mac_lte_mch_subheader,
6183 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
6184 ett_mac_lte_mch_subheader);
6186 /* Check 1st reserved bit */
6187 reserved = (first_byte & 0x80) >> 7;
6188 ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_reserved,
6189 tvb, offset, 1, ENC_BIG_ENDIAN);
6190 if (reserved != 0) {
6191 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6192 "MCH header Reserved bits not zero");
6196 format2 = (first_byte & 0x40) >> 6;
6197 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_format2,
6198 tvb, offset, 1, ENC_BIG_ENDIAN);
6201 extension = (first_byte & 0x20) >> 5;
6202 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_extended,
6203 tvb, offset, 1, ENC_BIG_ENDIAN);
6206 lcids[number_of_headers] = first_byte & 0x1f;
6207 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_lcid,
6208 tvb, offset, 1, ENC_BIG_ENDIAN);
6209 if (lcids[number_of_headers] == MCH_SCHEDULING_INFO_LCID) {
6210 sched_info_ti = lcid_ti;
6212 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6214 val_to_str_const(lcids[number_of_headers],
6215 mch_lcid_vals, "(Unknown LCID)"));
6218 /* Remember if we've seen a data subheader */
6219 if (lcids[number_of_headers] <= 28) {
6220 have_seen_data_header = TRUE;
6221 expecting_body_data = TRUE;
6224 /* Show an expert item if a control subheader (except Padding) appears
6225 *after* a data PDU */
6226 if (have_seen_data_header &&
6227 (lcids[number_of_headers] > 28) && (lcids[number_of_headers] != PADDING_LCID)) {
6228 expert_add_info_format(pinfo, lcid_ti, &ei_mac_lte_control_subheader_after_data_subheader,
6229 "MCH Control subheaders should not appear after data subheaders");
6233 /* Should not see padding after non-padding control... */
6234 if ((lcids[number_of_headers] > 28) &&
6235 (lcids[number_of_headers] == PADDING_LCID) &&
6238 number_of_padding_subheaders++;
6239 if (number_of_padding_subheaders > 2) {
6240 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_multiple);
6243 if (have_seen_non_padding_control) {
6244 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_before_control_subheader);
6248 /* Remember that we've seen non-padding control */
6249 if ((lcids[number_of_headers] > 28) &&
6250 (lcids[number_of_headers] != PADDING_LCID)) {
6251 have_seen_non_padding_control = TRUE;
6256 /********************************************************************/
6257 /* Length field follows if not the last header or for a fixed-sized
6261 pdu_lengths[number_of_headers] = -1;
6264 /* Not the last one */
6265 if (lcids[number_of_headers] != PADDING_LCID) {
6268 /* >= 32578 - use 16 bits */
6269 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
6270 tvb, offset*8, 16, &length, ENC_BIG_ENDIAN);
6271 if (length < 32768) {
6272 expert_add_info(pinfo, ti, &ei_mac_lte_mch_invalid_length);
6279 /* F(ormat) bit tells us how long the length field is */
6280 format = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
6281 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_format,
6282 tvb, offset, 1, ENC_BIG_ENDIAN);
6284 /* Now read length field itself */
6286 /* >= 128 - use 15 bits */
6287 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
6288 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
6293 /* Less than 128 - only 7 bits */
6294 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
6295 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
6299 pdu_lengths[number_of_headers] = (gint32)length;
6302 pdu_lengths[number_of_headers] = 0;
6307 /* Close off description in info column */
6308 switch (pdu_lengths[number_of_headers]) {
6310 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
6313 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
6316 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
6317 pdu_lengths[number_of_headers]);
6321 /* Append summary to subheader root */
6322 proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
6323 val_to_str_const(lcids[number_of_headers],
6324 mch_lcid_vals, "Unknown"));
6326 switch (pdu_lengths[number_of_headers]) {
6328 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
6329 proto_item_append_text(pdu_header_ti, " (%s:remainder)",
6330 val_to_str_const(lcids[number_of_headers],
6335 proto_item_append_text(pdu_subheader_ti, ")");
6336 proto_item_append_text(pdu_header_ti, " (%s)",
6337 val_to_str_const(lcids[number_of_headers],
6342 proto_item_append_text(pdu_subheader_ti, ", length=%u)",
6343 pdu_lengths[number_of_headers]);
6344 proto_item_append_text(pdu_header_ti, " (%s:%u)",
6345 val_to_str_const(lcids[number_of_headers],
6348 pdu_lengths[number_of_headers]);
6353 /* Flag unknown lcid values in expert info */
6354 if (try_val_to_str(lcids[number_of_headers],mch_lcid_vals) == NULL) {
6355 expert_add_info_format(pinfo, pdu_subheader_ti, &ei_mac_lte_lcid_unexpected,
6356 "MCH: Unexpected LCID received (%u)",
6357 lcids[number_of_headers]);
6360 /* Set length of this subheader */
6361 proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
6363 number_of_headers++;
6364 } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
6366 /* Check that we didn't reach the end of the subheader array... */
6367 if (number_of_headers >= MAX_HEADERS_IN_PDU) {
6368 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_too_many_subheaders, tvb, offset, 1,
6369 "Reached %u subheaders - frame obviously malformed",
6370 MAX_HEADERS_IN_PDU);
6375 /* Append summary to overall PDU header root */
6376 proto_item_append_text(pdu_header_ti, " (%u subheaders)",
6379 /* And set its length to offset */
6380 proto_item_set_len(pdu_header_ti, offset);
6383 /************************************************************************/
6384 /* Dissect SDUs / control elements / padding. */
6385 /************************************************************************/
6387 /* Dissect control element bodies first */
6389 for (n=0; n < number_of_headers; n++) {
6390 /* Get out of loop once see any data SDU subheaders */
6391 if (lcids[n] <= 28) {
6395 /* Process what should be a valid control PDU type */
6397 case MCH_SCHEDULING_INFO_LCID:
6399 guint32 curr_offset = offset;
6401 guint16 stop_mtch_val;
6402 proto_item *mch_sched_info_ti, *ti;
6403 proto_tree *mch_sched_info_tree;
6405 if (pdu_lengths[n] == -1) {
6406 /* Control Element size is the remaining PDU */
6407 pdu_lengths[n] = (gint16)tvb_reported_length_remaining(tvb, curr_offset);
6409 if (pdu_lengths[n] & 0x01) {
6410 expert_add_info_format(pinfo, sched_info_ti, &ei_mac_lte_context_length,
6411 "MCH Scheduling Information MAC Control Element should have an even size");
6414 mch_sched_info_ti = proto_tree_add_string_format(tree,
6415 hf_mac_lte_control_mch_scheduling_info,
6416 tvb, curr_offset, pdu_lengths[n],
6418 "MCH Scheduling Information");
6419 mch_sched_info_tree = proto_item_add_subtree(mch_sched_info_ti, ett_mac_lte_mch_scheduling_info);
6421 for (i=0; i<(pdu_lengths[n]/2); i++) {
6422 proto_tree_add_item(mch_sched_info_tree, hf_mac_lte_control_mch_scheduling_info_lcid,
6423 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
6424 stop_mtch_val = tvb_get_ntohs(tvb, curr_offset) & 0x7ff;
6425 ti = proto_tree_add_item(mch_sched_info_tree, hf_mac_lte_control_mch_scheduling_info_stop_mtch,
6426 tvb, curr_offset, 2, ENC_BIG_ENDIAN);
6427 if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) {
6428 proto_item_append_text(ti, " (reserved)");
6430 else if (stop_mtch_val == 2047) {
6431 proto_item_append_text(ti, " (MTCH is not scheduled)");
6436 offset += pdu_lengths[n];
6440 /* No payload (in this position) */
6449 /* There might not be any data, if only headers (plus control data) were logged */
6450 is_truncated = ((tvb_captured_length_remaining(tvb, offset) == 0) && expecting_body_data);
6451 truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_mch_header_only, tvb, 0, 0,
6454 proto_item_set_generated(truncated_ti);
6455 expert_add_info(pinfo, truncated_ti, &ei_mac_lte_mch_header_only_truncated);
6459 proto_item_set_hidden(truncated_ti);
6463 /* Now process remaining bodies, which should all be data */
6464 for (; n < number_of_headers; n++) {
6467 guint16 data_length;
6469 /* Break out if meet padding */
6470 if (lcids[n] == PADDING_LCID) {
6474 /* Work out length */
6475 data_length = (pdu_lengths[n] == -1) ?
6476 tvb_reported_length_remaining(tvb, offset) :
6479 if ((lcids[n] == 0) && global_mac_lte_attempt_mcch_decode) {
6480 /* Call RLC dissector */
6481 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6482 RLC_UM_MODE, DIRECTION_DOWNLINK, 0,
6483 CHANNEL_TYPE_MCCH, 0, 5, 0, FALSE, p_mac_lte_info->nbMode);
6484 } else if ((lcids[n] <= 28) && global_mac_lte_call_rlc_for_mtch) {
6485 /* Call RLC dissector */
6486 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
6487 RLC_UM_MODE, DIRECTION_DOWNLINK, 0,
6488 CHANNEL_TYPE_MTCH, 0, 5, 0, FALSE, p_mac_lte_info->nbMode);
6490 /* Dissect SDU as raw bytes */
6491 sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_mch_sdu, tvb, offset, pdu_lengths[n],
6492 NULL, "SDU (%s, length=%u bytes): ",
6493 val_to_str_const(lcids[n], mch_lcid_vals, "Unknown"),
6495 if (pdu_lengths[n] >= 30)
6497 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, 30));
6498 proto_item_append_text(sdu_ti, "...");
6502 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, data_length));
6506 offset += data_length;
6509 /* Now padding, if present, extends to the end of the PDU */
6510 if (lcids[number_of_headers-1] == PADDING_LCID) {
6511 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6512 proto_tree_add_item(tree, hf_mac_lte_padding_data,
6513 tvb, offset, -1, ENC_NA);
6515 padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
6517 p_mac_lte_info->length - offset);
6518 proto_item_set_generated(padding_length_ti);
6520 /* Make sure the PDU isn't bigger than reported! */
6521 if (offset > p_mac_lte_info->length) {
6522 expert_add_info_format(pinfo, padding_length_ti, &ei_mac_lte_context_length,
6523 "MAC PDU is longer than reported length (reported=%u, actual=%u)",
6524 p_mac_lte_info->length, offset);
6528 /* There is no padding at the end of the frame */
6529 if (!is_truncated && (offset < p_mac_lte_info->length)) {
6530 /* There is a problem if we haven't used all of the PDU */
6531 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6532 "PDU is shorter than reported length (reported=%u, actual=%u)",
6533 p_mac_lte_info->length, offset);
6536 if (!is_truncated && (offset > p_mac_lte_info->length)) {
6537 /* There is a problem if the PDU is longer than reported */
6538 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6539 "PDU is longer than reported length (reported=%u, actual=%u)",
6540 p_mac_lte_info->length, offset);
6546 /* Dissect SL-BCH PDU */
6547 static void dissect_sl_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6548 proto_item *pdu_ti, int offset)
6552 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6553 "SL-BCH PDU (%u bytes)",
6554 tvb_reported_length_remaining(tvb, offset));
6556 /****************************************/
6557 /* Whole frame is SL-BCH data */
6560 ti = proto_tree_add_item(tree, hf_mac_lte_slbch_pdu,
6561 tvb, offset, -1, ENC_NA);
6563 if (global_mac_lte_attempt_rrc_decode) {
6564 /* Attempt to decode payload using LTE RRC dissector */
6565 tvbuff_t *rrc_tvb = tvb_new_subset_remaining(tvb, offset);
6567 /* Hide raw view of bytes */
6568 proto_item_set_hidden(ti);
6570 call_with_catch_all(lte_rrc_sbcch_sl_bch_handle, rrc_tvb, pinfo, tree);
6575 /* Dissect SL-SCH PDU */
6576 static void dissect_slsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6578 int offset, mac_lte_info *p_mac_lte_info)
6580 /* Keep track of LCIDs and lengths as we dissect the header */
6581 guint16 number_of_headers = 0, n;
6582 guint8 lcids[MAX_HEADERS_IN_PDU], extension;
6583 gint16 pdu_lengths[MAX_HEADERS_IN_PDU];
6585 proto_item *pdu_header_ti, *pdu_subheader_ti, *ti, *truncated_ti, *padding_length_ti;
6586 proto_tree *pdu_header_tree, *pdu_subheader_tree;
6588 guint8 number_of_padding_subheaders = 0;
6589 gboolean expecting_body_data = FALSE;
6590 gboolean is_truncated;
6591 guint32 reserved, version;
6593 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6594 "%s: (SFN=%-4u, SF=%u) UEId=%-3u ",
6596 p_mac_lte_info->sysframeNumber,
6597 p_mac_lte_info->subframeNumber,
6598 p_mac_lte_info->ueid);
6600 /* Add PDU block header subtree */
6601 pdu_header_ti = proto_tree_add_string_format(tree, hf_mac_lte_slsch_header,
6603 "", "MAC PDU Header");
6604 pdu_header_tree = proto_item_add_subtree(pdu_header_ti, ett_mac_lte_slsch_header);
6606 /* Dissect SL-SCH sub-header */
6607 proto_item_append_text(pdu_header_ti, " (SL-SCH)");
6608 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
6609 hf_mac_lte_slsch_subheader,
6612 "Sub-header (SL-SCH)");
6613 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
6614 ett_mac_lte_slsch_subheader);
6615 proto_tree_add_item_ret_uint(pdu_subheader_tree, hf_mac_lte_slsch_version,
6616 tvb, offset, 1, ENC_BIG_ENDIAN, &version);
6617 ti = proto_tree_add_item_ret_uint(pdu_subheader_tree, hf_mac_lte_slsch_reserved,
6618 tvb, offset, 1, ENC_BIG_ENDIAN, &reserved);
6621 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6622 "SL-SCH header Reserved bits not zero");
6624 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_src_l2_id,
6625 tvb, offset, 3, ENC_BIG_ENDIAN);
6628 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_dst_l2_id2,
6629 tvb, offset, 3, ENC_BIG_ENDIAN);
6632 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_dst_l2_id,
6633 tvb, offset, 2, ENC_BIG_ENDIAN);
6637 /* Dissect each sub-header */
6641 proto_item *lcid_ti;
6642 gint offset_start_subheader = offset;
6644 /* Add PDU block header subtree.
6645 Default with length of 1 byte. */
6646 pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
6647 hf_mac_lte_slsch_subheader,
6651 pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
6652 ett_mac_lte_slsch_subheader);
6654 /* Check 1st 2 reserved bits */
6655 ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_reserved2,
6656 tvb, offset, 1, ENC_BIG_ENDIAN);
6657 first_byte = tvb_get_guint8(tvb, offset);
6658 if ((first_byte & 0xc0) != 0) {
6659 expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6660 "SL-SCH header Reserved bits not zero");
6664 extension = (first_byte & 0x20) >> 5;
6665 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_extended,
6666 tvb, offset, 1, ENC_BIG_ENDIAN);
6669 lcids[number_of_headers] = first_byte & 0x1f;
6670 lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_lcid,
6671 tvb, offset, 1, ENC_BIG_ENDIAN);
6672 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6674 val_to_str_const(lcids[number_of_headers],
6675 slsch_lcid_vals, "(Unknown LCID)"));
6678 /* Remember if we've seen a data subheader */
6679 if (lcids[number_of_headers] <= 10) {
6680 expecting_body_data = TRUE;
6683 /* Should not see padding after non-padding control... */
6684 if ((lcids[number_of_headers] == PADDING_LCID) &&
6687 number_of_padding_subheaders++;
6688 if (number_of_padding_subheaders > 2) {
6689 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_multiple);
6693 /* Also flag if we have final padding but also padding subheaders
6695 if (!extension && (lcids[number_of_headers] == PADDING_LCID) &&
6696 (number_of_padding_subheaders > 0)) {
6697 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_start_and_end);
6700 /* Length field follows if not the last header or for a fixed-sized
6704 pdu_lengths[number_of_headers] = -1;
6706 /* Not the last one */
6707 if (lcids[number_of_headers] != PADDING_LCID) {
6710 /* F(ormat) bit tells us how long the length field is */
6711 proto_tree_add_item_ret_boolean(pdu_subheader_tree, hf_mac_lte_slsch_format,
6712 tvb, offset, 1, ENC_BIG_ENDIAN, &format);
6714 /* Now read length field itself */
6716 /* >= 128 - use 15 bits */
6717 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_slsch_length,
6718 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
6721 /* Less than 128 - only 7 bits */
6722 proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_slsch_length,
6723 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
6726 pdu_lengths[number_of_headers] = (gint16)length;
6728 pdu_lengths[number_of_headers] = 0;
6732 /* Close off description in info column */
6733 switch (pdu_lengths[number_of_headers]) {
6735 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
6738 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
6741 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
6742 pdu_lengths[number_of_headers]);
6746 /* Append summary to subheader root */
6747 proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
6748 val_to_str_const(lcids[number_of_headers],
6749 slsch_lcid_vals, "Unknown"));
6751 switch (pdu_lengths[number_of_headers]) {
6753 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
6754 proto_item_append_text(pdu_header_ti, " (%s:remainder)",
6755 val_to_str_const(lcids[number_of_headers],
6756 slsch_lcid_vals, "Unknown"));
6759 proto_item_append_text(pdu_subheader_ti, ")");
6760 proto_item_append_text(pdu_header_ti, " (%s)",
6761 val_to_str_const(lcids[number_of_headers],
6762 slsch_lcid_vals, "Unknown"));
6765 proto_item_append_text(pdu_subheader_ti, ", length=%u)",
6766 pdu_lengths[number_of_headers]);
6767 proto_item_append_text(pdu_header_ti, " (%s:%u)",
6768 val_to_str_const(lcids[number_of_headers],
6769 slsch_lcid_vals, "Unknown"),
6770 pdu_lengths[number_of_headers]);
6774 /* Flag unknown lcid values in expert info */
6775 if (try_val_to_str(lcids[number_of_headers], slsch_lcid_vals) == NULL) {
6776 expert_add_info_format(pinfo, pdu_subheader_ti, &ei_mac_lte_lcid_unexpected,
6777 "SL-SCH: Unexpected LCID received (%u)",
6778 lcids[number_of_headers]);
6781 /* Set length of this subheader */
6782 proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
6784 number_of_headers++;
6785 } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
6787 /* Check that we didn't reach the end of the subheader array... */
6788 if (number_of_headers >= MAX_HEADERS_IN_PDU) {
6789 proto_tree_add_expert_format(tree, pinfo, &ei_mac_lte_too_many_subheaders, tvb, offset, 1,
6790 "Reached %u subheaders - frame obviously malformed",
6791 MAX_HEADERS_IN_PDU);
6795 /* Append summary to overall PDU header root */
6796 proto_item_append_text(pdu_header_ti, " [%u subheaders]",
6799 /* And set its length to offset */
6800 proto_item_set_len(pdu_header_ti, offset);
6802 /* Dissect control element bodies first */
6804 for (n = 0; n < number_of_headers; n++) {
6805 /* Get out of loop once see any data SDU subheaders */
6806 if (lcids[n] <= 10) {
6812 /* No payload (in this position) */
6819 /* There might not be any data, if only headers (plus control data) were logged */
6820 is_truncated = ((tvb_captured_length_remaining(tvb, offset) == 0) && expecting_body_data);
6821 truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_slsch_header_only, tvb, 0, 0,
6824 proto_item_set_generated(truncated_ti);
6825 expert_add_info(pinfo, truncated_ti, &ei_mac_lte_slsch_header_only_truncated);
6828 proto_item_set_hidden(truncated_ti);
6832 /* Now process remaining bodies, which should all be data */
6833 for (; n < number_of_headers; n++) {
6835 guint16 data_length;
6837 /* Break out if meet padding */
6838 if (lcids[n] == PADDING_LCID) {
6842 /* Work out length */
6843 data_length = (pdu_lengths[n] == -1) ?
6844 tvb_reported_length_remaining(tvb, offset) :
6847 /* Dissect SDU as raw bytes */
6848 sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_slsch_sdu, tvb, offset, pdu_lengths[n],
6849 NULL, "SDU (%s, length=%u bytes): ",
6850 val_to_str_const(lcids[n],
6851 slsch_lcid_vals, "Unknown"),
6854 /* Show bytes too, if won't be hidden (slow). There must be a nicer way of doing this! */
6855 if (pdu_lengths[n] >= 30) {
6856 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, 30));
6857 proto_item_append_text(sdu_ti, "...");
6859 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, data_length));
6862 offset += data_length;
6865 /* Now padding, if present, extends to the end of the PDU */
6866 if (lcids[number_of_headers-1] == PADDING_LCID) {
6867 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6868 proto_tree_add_item(tree, hf_mac_lte_padding_data,
6869 tvb, offset, -1, ENC_NA);
6871 padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
6873 p_mac_lte_info->length - offset);
6874 proto_item_set_generated(padding_length_ti);
6876 /* Make sure the PDU isn't bigger than reported! */
6877 if (offset > p_mac_lte_info->length) {
6878 expert_add_info_format(pinfo, padding_length_ti, &ei_mac_lte_context_length,
6879 "SL-SCH MAC PDU is longer than reported length (reported=%u, actual=%u)",
6880 p_mac_lte_info->length, offset);
6883 /* There is no padding at the end of the frame */
6884 if (!is_truncated && (offset < p_mac_lte_info->length)) {
6885 /* There is a problem if we haven't used all of the PDU */
6886 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6887 "SL-SCH PDU for UE %u is shorter than reported length (reported=%u, actual=%u)",
6888 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
6891 if (!is_truncated && (offset > p_mac_lte_info->length)) {
6892 /* There is a problem if the PDU is longer than reported */
6893 expert_add_info_format(pinfo, pdu_ti, &ei_mac_lte_context_length,
6894 "SL-SCH PDU for UE %u is longer than reported length (reported=%u, actual=%u)",
6895 p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
6901 /*****************************/
6902 /* Main dissection function. */
6903 /* 'data' will be cast to an int, where it can then be used to differentiate
6904 multiple MAC PDUs logged in the same frame (e.g. in the LTE eNB LI API definition from
6905 the Small Cell Forum)
6907 int dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
6909 proto_tree *mac_lte_tree;
6911 proto_tree *context_tree;
6912 proto_item *context_ti;
6913 proto_item *retx_ti = NULL;
6915 proto_item *hidden_root_ti;
6917 struct mac_lte_info *p_mac_lte_info;
6919 guint pdu_instance = GPOINTER_TO_UINT(data);
6921 /* Allocate and zero tap struct */
6922 mac_lte_tap_info *tap_info = (mac_lte_tap_info *)wmem_alloc0(wmem_file_scope(), sizeof(mac_lte_tap_info));
6924 /* Set protocol name */
6925 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
6927 /* Create protocol tree, using tvb_reported_length() as giving -1 will trigger an exception in case of oob event */
6928 pdu_ti = proto_tree_add_item(tree, proto_mac_lte, tvb, offset, tvb_reported_length(tvb), ENC_NA);
6929 proto_item_append_text(pdu_ti, " ");
6930 mac_lte_tree = proto_item_add_subtree(pdu_ti, ett_mac_lte);
6932 /* Look for packet info! */
6933 p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
6935 /* Can't dissect anything without it... */
6936 if (p_mac_lte_info == NULL) {
6937 proto_tree_add_expert(mac_lte_tree, pinfo, &ei_mac_lte_no_per_frame_data, tvb, offset, -1);
6941 /* Clear info column */
6942 col_clear(pinfo->cinfo, COL_INFO);
6945 /*****************************************/
6946 /* Show context information */
6948 /* Create context root */
6949 context_ti = proto_tree_add_string_format(mac_lte_tree, hf_mac_lte_context,
6950 tvb, offset, 0, "", "Context");
6951 context_tree = proto_item_add_subtree(context_ti, ett_mac_lte_context);
6952 proto_item_set_generated(context_ti);
6954 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_radio_type,
6955 tvb, 0, 0, p_mac_lte_info->radioType);
6956 proto_item_set_generated(ti);
6958 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_direction,
6959 tvb, 0, 0, p_mac_lte_info->direction);
6960 proto_item_set_generated(ti);
6962 if (p_mac_lte_info->ueid != 0) {
6963 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_ueid,
6964 tvb, 0, 0, p_mac_lte_info->ueid);
6965 proto_item_set_generated(ti);
6968 if(p_mac_lte_info->sfnSfInfoPresent) {
6969 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_sysframe_number,
6970 tvb, 0, 0, p_mac_lte_info->sysframeNumber);
6971 proto_item_set_generated(ti);
6972 if (p_mac_lte_info->sysframeNumber > 1023) {
6973 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_sysframe_number,
6974 "Sysframe number (%u) out of range - valid range is 0-1023",
6975 p_mac_lte_info->sysframeNumber);
6978 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_subframe_number,
6979 tvb, 0, 0, p_mac_lte_info->subframeNumber);
6980 proto_item_set_generated(ti);
6981 if (p_mac_lte_info->subframeNumber > 9) {
6982 /* N.B. if we set it to valid value, it won't trigger when we rescan
6983 (at least with DCT2000 files where the context struct isn't re-read). */
6984 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_sysframe_number,
6985 "Subframe number (%u) out of range - valid range is 0-9",
6986 p_mac_lte_info->subframeNumber);
6989 if (p_mac_lte_info->subframeNumberOfGrantPresent) {
6990 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_grant_subframe_number,
6991 tvb, 0, 0, p_mac_lte_info->subframeNumberOfGrant);
6992 proto_item_set_generated(ti);
6996 /* There are several out-of-band MAC events that may be indicated in the context info. */
6997 /* Handle them here */
6998 if (p_mac_lte_info->length == 0) {
6999 proto_item *preamble_ti;
7000 proto_tree *preamble_tree;
7001 const gchar *rapid_description;
7003 switch (p_mac_lte_info->oob_event) {
7004 case ltemac_send_preamble:
7005 preamble_ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_send_preamble,
7006 tvb, 0, 0, ENC_ASCII|ENC_NA);
7007 preamble_tree = proto_item_add_subtree(preamble_ti, ett_mac_lte_oob);
7008 proto_item_set_generated(ti);
7010 ti = proto_tree_add_uint(preamble_tree, hf_mac_lte_context_rapid,
7011 tvb, 0, 0, p_mac_lte_info->rapid);
7012 proto_item_set_generated(ti);
7014 ti = proto_tree_add_uint(preamble_tree, hf_mac_lte_context_rach_attempt_number,
7015 tvb, 0, 0, p_mac_lte_info->rach_attempt_number);
7016 proto_item_set_generated(ti);
7018 rapid_description = get_mac_lte_rapid_description(p_mac_lte_info->rapid);
7021 write_pdu_label_and_info(pdu_ti, preamble_ti, pinfo,
7022 "RACH Preamble chosen for UE %u (RAPID=%u%s, attempt=%u)",
7023 p_mac_lte_info->ueid, p_mac_lte_info->rapid,
7025 p_mac_lte_info->rach_attempt_number);
7027 /* Add expert info (a note, unless attempt > 1) */
7028 expert_add_info_format(pinfo, ti,
7029 (p_mac_lte_info->rach_attempt_number > 1) ? &ei_mac_lte_rach_preamble_sent_warn : &ei_mac_lte_rach_preamble_sent_note,
7030 "RACH Preamble sent for UE %u (RAPID=%u%s, attempt=%u)",
7031 p_mac_lte_info->ueid, p_mac_lte_info->rapid,
7033 p_mac_lte_info->rach_attempt_number);
7035 case ltemac_send_sr:
7037 ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_number_of_srs,
7038 tvb, 0, 0, p_mac_lte_info->number_of_srs);
7039 proto_item_set_generated(ti);
7042 for (n=0; n < p_mac_lte_info->number_of_srs; n++) {
7044 proto_tree *sr_tree;
7046 /* SR event is subtree */
7047 sr_ti = proto_tree_add_expert_format(mac_lte_tree, pinfo, &ei_mac_lte_oob_send_sr,
7049 "Scheduling Request sent for UE %u (RNTI %u)", p_mac_lte_info->oob_ueid[n], p_mac_lte_info->oob_rnti[n]);
7050 sr_tree = proto_item_add_subtree(sr_ti, ett_mac_lte_oob);
7051 proto_item_set_generated(sr_ti);
7054 ti = proto_tree_add_uint(sr_tree, hf_mac_lte_context_rnti,
7055 tvb, 0, 0, p_mac_lte_info->oob_rnti[n]);
7056 proto_item_set_generated(ti);
7059 ti = proto_tree_add_uint(sr_tree, hf_mac_lte_context_ueid,
7060 tvb, 0, 0, p_mac_lte_info->oob_ueid[n]);
7061 proto_item_set_generated(ti);
7063 /* Add summary to root. */
7064 proto_item_append_text(sr_ti, " (UE=%u C-RNTI=%u)",
7065 p_mac_lte_info->oob_ueid[n],
7066 p_mac_lte_info->oob_rnti[n]);
7071 if (p_mac_lte_info->sfnSfInfoPresent) {
7072 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7073 "Scheduling Requests (%u) sent (SFN=%-4u, SF=%u): (UE=%u C-RNTI=%u)",
7074 p_mac_lte_info->number_of_srs,
7075 p_mac_lte_info->sysframeNumber,
7076 p_mac_lte_info->subframeNumber,
7077 p_mac_lte_info->oob_ueid[n],
7078 p_mac_lte_info->oob_rnti[n]
7082 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7083 "Scheduling Requests (%u) sent: (UE=%u C-RNTI=%u)",
7084 p_mac_lte_info->number_of_srs,
7085 p_mac_lte_info->oob_ueid[n],
7086 p_mac_lte_info->oob_rnti[n]);
7090 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7091 " (UE=%u C-RNTI=%u)",
7092 p_mac_lte_info->oob_ueid[n],
7093 p_mac_lte_info->oob_rnti[n]);
7096 /* Update SR status for this UE */
7097 if (global_mac_lte_track_sr) {
7098 TrackSRInfo(SR_Request, pinfo, mac_lte_tree, tvb, p_mac_lte_info, n, sr_ti);
7102 case ltemac_sr_failure:
7103 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti,
7104 tvb, 0, 0, p_mac_lte_info->rnti);
7105 proto_item_set_generated(ti);
7107 proto_tree_add_expert_format(mac_lte_tree, pinfo, &ei_mac_lte_oob_sr_failure,
7108 tvb, 0, 0, "Scheduling Request failed for UE %u (RNTI %u)",
7109 p_mac_lte_info->ueid, p_mac_lte_info->rnti);
7110 proto_item_set_generated(ti);
7113 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7114 "Scheduling Request FAILED for UE %u (C-RNTI=%u)",
7115 p_mac_lte_info->ueid,
7116 p_mac_lte_info->rnti);
7118 /* Update SR status */
7119 if (global_mac_lte_track_sr) {
7120 TrackSRInfo(SR_Failure, pinfo, mac_lte_tree, tvb, p_mac_lte_info, 0, ti);
7126 /* Our work here is done */
7130 /* Show remaining meta information */
7131 if (p_mac_lte_info->rntiType != NO_RNTI) {
7132 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti,
7133 tvb, 0, 0, p_mac_lte_info->rnti);
7134 proto_item_set_generated(ti);
7135 proto_item_append_text(context_ti, " (RNTI=%u)", p_mac_lte_info->rnti);
7139 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti_type,
7140 tvb, 0, 0, p_mac_lte_info->rntiType);
7141 proto_item_set_generated(ti);
7143 /* Check that RNTI value is consistent with given RNTI type */
7144 switch (p_mac_lte_info->rntiType) {
7146 if (p_mac_lte_info->rnti != 0xFFFD) {
7147 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7148 "M-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
7149 p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFD);
7154 if (p_mac_lte_info->rnti != 0xFFFE) {
7155 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7156 "P-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
7157 p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFE);
7162 if (p_mac_lte_info->rnti != 0xFFFF) {
7163 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7164 "SI-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
7165 p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFE);
7170 if ((p_mac_lte_info->rnti < 0x0001) || (p_mac_lte_info->rnti > 0x0960)) {
7171 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7172 "RA_RNTI indicated, but given value %u (0x%x) is out of range",
7173 p_mac_lte_info->rnti, p_mac_lte_info->rnti);
7181 if ((p_mac_lte_info->rnti < 0x0001) || (p_mac_lte_info->rnti > 0xFFF3)) {
7182 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_rnti_type,
7183 "%s indicated, but given value %u (0x%x) is out of range",
7184 val_to_str_const(p_mac_lte_info->rntiType, rnti_type_vals, "Unknown"),
7185 p_mac_lte_info->rnti, p_mac_lte_info->rnti);
7194 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_predefined_frame,
7195 tvb, 0, 0, p_mac_lte_info->isPredefinedData);
7196 if (p_mac_lte_info->isPredefinedData) {
7197 proto_item_set_generated(ti);
7200 proto_item_set_hidden(ti);
7203 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_length,
7204 tvb, 0, 0, p_mac_lte_info->length);
7205 proto_item_set_generated(ti);
7206 /* Infer uplink grant size */
7207 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
7208 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_ul_grant_size,
7209 tvb, 0, 0, p_mac_lte_info->length);
7210 proto_item_set_generated(ti);
7213 /* Retx count goes in top-level tree to make it more visible */
7214 if (p_mac_lte_info->reTxCount) {
7215 proto_item *retx_reason_ti;
7216 retx_ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_count,
7217 tvb, 0, 0, p_mac_lte_info->reTxCount);
7218 proto_item_set_generated(retx_ti);
7220 if (p_mac_lte_info->reTxCount >= global_mac_lte_retx_counter_trigger) {
7221 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
7222 expert_add_info_format(pinfo, retx_ti, &ei_mac_lte_ul_mac_frame_retx,
7223 "UE %u: UL MAC frame ReTX no. %u",
7224 p_mac_lte_info->ueid, p_mac_lte_info->reTxCount);
7227 expert_add_info_format(pinfo, retx_ti, &ei_mac_lte_ul_mac_frame_retx,
7228 "UE %u: DL MAC frame ReTX no. %u",
7229 p_mac_lte_info->ueid, p_mac_lte_info->reTxCount);
7233 retx_reason_ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_reason,
7234 tvb, 0, 0, p_mac_lte_info->isPHICHNACK);
7235 proto_item_set_generated(retx_reason_ti);
7238 if (p_mac_lte_info->crcStatusValid) {
7240 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_crc_status,
7241 tvb, 0, 0, p_mac_lte_info->crcStatus);
7242 proto_item_set_generated(ti);
7244 /* Report non-success */
7245 if (p_mac_lte_info->crcStatus != crc_success) {
7246 expert_add_info_format(pinfo, ti, &ei_mac_lte_context_crc_status,
7247 "%s Frame has CRC error problem (%s)",
7248 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL",
7249 val_to_str_const(p_mac_lte_info->crcStatus,
7252 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7253 "%s: <CRC %s> UEId=%u %s=%u ",
7254 (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL",
7255 val_to_str_const(p_mac_lte_info->crcStatus,
7258 p_mac_lte_info->ueid,
7259 val_to_str_const(p_mac_lte_info->rntiType, rnti_type_vals,
7260 "Unknown RNTI type"),
7261 p_mac_lte_info->rnti);
7266 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_carrier_id,
7267 tvb, 0, 0, p_mac_lte_info->carrierId);
7268 proto_item_set_generated(ti);
7270 /* May also have extra Physical layer attributes set for this frame */
7271 show_extra_phy_parameters(pinfo, tvb, mac_lte_tree, p_mac_lte_info);
7273 /* Set context-info parts of tap struct */
7274 tap_info->rnti = p_mac_lte_info->rnti;
7275 tap_info->ueid = p_mac_lte_info->ueid;
7276 tap_info->rntiType = p_mac_lte_info->rntiType;
7277 tap_info->isPredefinedData = p_mac_lte_info->isPredefinedData;
7278 tap_info->isPHYRetx = (p_mac_lte_info->reTxCount >= 1);
7279 tap_info->crcStatusValid = p_mac_lte_info->crcStatusValid;
7280 tap_info->crcStatus = p_mac_lte_info->crcStatus;
7281 tap_info->direction = p_mac_lte_info->direction;
7283 tap_info->mac_lte_time = pinfo->abs_ts;
7285 /* Add hidden item to filter on */
7286 if ((p_mac_lte_info->rntiType == C_RNTI) ||
7287 (p_mac_lte_info->rntiType == SPS_RNTI) ||
7288 (p_mac_lte_info->rntiType == SC_RNTI) ||
7289 (p_mac_lte_info->rntiType == G_RNTI)) {
7290 hidden_root_ti = proto_tree_add_string_format(tree,
7291 (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
7297 proto_item_set_hidden(hidden_root_ti);
7298 } else if (p_mac_lte_info->rntiType == SL_RNTI) {
7299 hidden_root_ti = proto_tree_add_string_format(tree,
7304 proto_item_set_hidden(hidden_root_ti);
7307 /* Also set total number of bytes (won't be used for UL/DL-SCH) */
7308 tap_info->single_number_of_bytes = tvb_reported_length_remaining(tvb, offset);
7310 /* If we know its predefined data, don't try to decode any further */
7311 if (p_mac_lte_info->isPredefinedData) {
7312 proto_tree_add_item(mac_lte_tree, hf_mac_lte_predefined_pdu, tvb, offset, -1, ENC_NA);
7313 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
7314 "Predefined data (%u bytes%s)",
7315 p_mac_lte_info->length,
7316 (p_mac_lte_info->length > tvb_reported_length_remaining(tvb, offset) ?
7320 /* Queue tap info */
7321 if (!pinfo->flags.in_error_pkt) {
7322 tap_queue_packet(mac_lte_tap, pinfo, tap_info);
7328 /* IF CRC status failed, just do decode as raw bytes */
7329 if (!global_mac_lte_dissect_crc_failures &&
7330 (p_mac_lte_info->crcStatusValid &&
7331 (p_mac_lte_info->crcStatus != crc_success))) {
7333 proto_tree_add_item(mac_lte_tree, hf_mac_lte_raw_pdu, tvb, offset, -1, ENC_NA);
7334 write_pdu_label_and_info(pdu_ti, NULL, pinfo, "Raw data (%u bytes)", tvb_reported_length_remaining(tvb, offset));
7336 /* For uplink grants, update SR status. N.B. only newTx grant should stop SR */
7337 if ((p_mac_lte_info->direction == DIRECTION_UPLINK) && (p_mac_lte_info->reTxCount == 0) &&
7338 global_mac_lte_track_sr) {
7340 TrackSRInfo(SR_Grant, pinfo, tree, tvb, p_mac_lte_info, 0, NULL);
7341 if (global_mac_lte_show_drx) {
7342 if (!PINFO_FD_VISITED(pinfo)) {
7343 /* Update UE state to this subframe (but before this event is processed) */
7344 update_drx_info(pinfo, p_mac_lte_info);
7346 /* Store 'before' snapshot of UE state for this frame */
7347 set_drx_info(pinfo, p_mac_lte_info, TRUE, pdu_instance);
7349 /* Show current DRX state in tree as 'before' */
7350 show_drx_info(pinfo, tree, tvb, p_mac_lte_info, TRUE, pdu_instance);
7355 TODO: unfortunately DL retx detection won't get done if we return here... */
7356 if (!pinfo->flags.in_error_pkt) {
7357 tap_queue_packet(mac_lte_tap, pinfo, tap_info);
7363 /* Reset this counter */
7364 s_number_of_rlc_pdus_shown = 0;
7366 /* Dissect the MAC PDU itself. Format depends upon RNTI type. */
7367 switch (p_mac_lte_info->rntiType) {
7371 dissect_pch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, tap_info);
7376 dissect_rar(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, tap_info);
7383 /* Can be UL-SCH or DL-SCH */
7384 dissect_ulsch_or_dlsch(tvb, pinfo, mac_lte_tree, pdu_ti, offset,
7385 p_mac_lte_info, tap_info, retx_ti,
7386 context_tree, pdu_instance);
7390 /* BCH over DL-SCH */
7391 dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7396 dissect_mch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7401 dissect_sl_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset);
7406 dissect_slsch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7410 /* Must be BCH over BCH... */
7411 dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7419 /* Queue tap info */
7420 tap_queue_packet(mac_lte_tap, pinfo, tap_info);
7428 /* Initializes the hash tables each time a new
7429 * file is loaded or re-loaded in wireshark */
7430 static void mac_lte_init_protocol(void)
7433 memset(&UL_tti_info, 0, sizeof(UL_tti_info));
7434 UL_tti_info.subframe = 0xff; /* Invalid value */
7435 memset(&DL_tti_info, 0, sizeof(DL_tti_info));
7436 DL_tti_info.subframe = 0xff; /* Invalid value */
7438 mac_lte_msg3_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7439 mac_lte_cr_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7440 mac_lte_msg3_cr_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7441 mac_lte_dl_harq_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7442 mac_lte_dl_harq_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7443 mac_lte_ul_harq_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7444 mac_lte_ul_harq_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7445 mac_lte_ue_sr_state = g_hash_table_new(g_direct_hash, g_direct_equal);
7446 mac_lte_sr_request_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7447 mac_lte_tti_info_result_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7448 mac_lte_ue_channels_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
7449 mac_lte_ue_parameters = g_hash_table_new(g_direct_hash, g_direct_equal);
7450 mac_lte_drx_frame_result = g_hash_table_new(mac_lte_framenum_instance_hash_func, mac_lte_framenum_instance_hash_equal);
7452 /* Forget this setting */
7453 s_rapid_ranges_configured = FALSE;
7456 static void mac_lte_cleanup_protocol(void)
7458 g_hash_table_destroy(mac_lte_msg3_hash);
7459 g_hash_table_destroy(mac_lte_cr_result_hash);
7460 g_hash_table_destroy(mac_lte_msg3_cr_hash);
7461 g_hash_table_destroy(mac_lte_dl_harq_hash);
7462 g_hash_table_destroy(mac_lte_dl_harq_result_hash);
7463 g_hash_table_destroy(mac_lte_ul_harq_hash);
7464 g_hash_table_destroy(mac_lte_ul_harq_result_hash);
7465 g_hash_table_destroy(mac_lte_ue_sr_state);
7466 g_hash_table_destroy(mac_lte_sr_request_hash);
7467 g_hash_table_destroy(mac_lte_tti_info_result_hash);
7468 g_hash_table_destroy(mac_lte_ue_channels_hash);
7469 g_hash_table_destroy(mac_lte_ue_parameters);
7470 g_hash_table_destroy(mac_lte_drx_frame_result);
7473 /* Callback used as part of configuring a channel mapping using UAT */
7474 static void* lcid_drb_mapping_copy_cb(void* dest, const void* orig, size_t len _U_)
7476 const lcid_drb_mapping_t *o = (const lcid_drb_mapping_t *)orig;
7477 lcid_drb_mapping_t *d = (lcid_drb_mapping_t *)dest;
7479 /* Copy all items over */
7481 d->drbid = o->drbid;
7482 d->channel_type = o->channel_type;
7488 /*************************************************************************/
7489 /* These functions get called from outside of this module, i.e. from RRC */
7491 /* Set LCID -> RLC channel mappings from signalling protocol (i.e. RRC or similar). */
7492 void set_mac_lte_channel_mapping(drb_mapping_t *drb_mapping)
7494 ue_dynamic_drb_mappings_t *ue_mappings;
7497 /* Check lcid range */
7498 if (drb_mapping->lcid_present) {
7499 lcid = drb_mapping->lcid;
7501 /* Ignore if LCID is out of range */
7502 if ((lcid < 3) || (lcid > 10)) {
7507 /* Look for existing UE entry */
7508 ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash,
7509 GUINT_TO_POINTER((guint)drb_mapping->ueid));
7511 /* If not found, create & add to table */
7512 ue_mappings = wmem_new0(wmem_file_scope(), ue_dynamic_drb_mappings_t);
7513 g_hash_table_insert(mac_lte_ue_channels_hash,
7514 GUINT_TO_POINTER((guint)drb_mapping->ueid),
7518 /* If lcid wasn't supplied, need to try to look up from drbid */
7519 if ((lcid == 0) && (drb_mapping->drbid < 32)) {
7520 lcid = ue_mappings->drb_to_lcid_mappings[drb_mapping->drbid];
7523 /* Still no lcid - give up */
7527 /* Set array entry */
7528 ue_mappings->mapping[lcid].valid = TRUE;
7529 ue_mappings->mapping[lcid].drbid = drb_mapping->drbid;
7530 ue_mappings->drb_to_lcid_mappings[drb_mapping->drbid] = lcid;
7531 if (drb_mapping->ul_priority_present) {
7532 ue_mappings->mapping[lcid].ul_priority = drb_mapping->ul_priority;
7535 /* Fill in available RLC info */
7536 if (drb_mapping->rlcMode_present) {
7537 switch (drb_mapping->rlcMode) {
7539 if (drb_mapping->rlc_ul_ext_am_sn == TRUE) {
7540 if (drb_mapping->rlc_dl_ext_am_sn == TRUE) {
7541 if (drb_mapping->rlc_ul_ext_li_field == TRUE) {
7542 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7543 ue_mappings->mapping[lcid].channel_type = rlcAM16extLiField;
7545 ue_mappings->mapping[lcid].channel_type = rlcAM16ulExtLiField;
7548 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7549 ue_mappings->mapping[lcid].channel_type = rlcAM16dlExtLiField;
7551 ue_mappings->mapping[lcid].channel_type = rlcAM16;
7555 if (drb_mapping->rlc_ul_ext_li_field == TRUE) {
7556 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7557 ue_mappings->mapping[lcid].channel_type = rlcAMul16extLiField;
7559 ue_mappings->mapping[lcid].channel_type = rlcAMul16ulExtLiField;
7562 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7563 ue_mappings->mapping[lcid].channel_type = rlcAMul16dlExtLiField;
7565 ue_mappings->mapping[lcid].channel_type = rlcAMul16;
7569 } else if (drb_mapping->rlc_dl_ext_am_sn == TRUE) {
7570 if (drb_mapping->rlc_ul_ext_li_field == TRUE) {
7571 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7572 ue_mappings->mapping[lcid].channel_type = rlcAMdl16extLiField;
7574 ue_mappings->mapping[lcid].channel_type = rlcAMdl16ulExtLiField;
7577 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7578 ue_mappings->mapping[lcid].channel_type = rlcAMdl16dlExtLiField;
7580 ue_mappings->mapping[lcid].channel_type = rlcAMdl16;
7583 } else if (drb_mapping->rlc_ul_ext_li_field == TRUE) {
7584 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7585 ue_mappings->mapping[lcid].channel_type = rlcAMextLiField;
7587 ue_mappings->mapping[lcid].channel_type = rlcAMulExtLiField;
7590 if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7591 ue_mappings->mapping[lcid].channel_type = rlcAMdlExtLiField;
7593 ue_mappings->mapping[lcid].channel_type = rlcAM;
7598 if (drb_mapping->um_sn_length_present) {
7599 if (drb_mapping->um_sn_length == 5) {
7600 ue_mappings->mapping[lcid].channel_type = rlcUM5;
7603 ue_mappings->mapping[lcid].channel_type = rlcUM10;
7614 /* Return the configured UL priority for the channel */
7615 static guint8 get_mac_lte_channel_priority(guint16 ueid, guint8 lcid,
7618 ue_dynamic_drb_mappings_t *ue_mappings;
7620 /* Priority only affects UL */
7621 if (direction == DIRECTION_DOWNLINK) {
7625 /* Look up the mappings for this UE */
7626 ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash, GUINT_TO_POINTER((guint)ueid));
7631 /* Won't report value if channel not configured */
7632 if (!ue_mappings->mapping[lcid].valid) {
7636 return ue_mappings->mapping[lcid].ul_priority;
7640 /* Configure the DRX state for this UE (from RRC) */
7641 void set_mac_lte_drx_config(guint16 ueid, drx_config_t *drx_config, packet_info *pinfo)
7643 if (global_mac_lte_show_drx && !PINFO_FD_VISITED(pinfo)) {
7644 ue_parameters_t *ue_params;
7645 guint32 previousFrameNum = 0;
7647 /* Find or create config struct for this UE */
7648 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((guint)ueid));
7649 if (ue_params == NULL) {
7650 ue_params = (ue_parameters_t *)wmem_new0(wmem_file_scope(), ue_parameters_t);
7651 g_hash_table_insert(mac_lte_ue_parameters, GUINT_TO_POINTER((guint)ueid), ue_params);
7654 previousFrameNum = ue_params->drx_state.config.frameNum;
7657 ue_params->drx_state_valid = TRUE;
7659 /* Clearing state when new config comes in... */
7660 init_drx_ue_state(&ue_params->drx_state, TRUE);
7662 /* Copy in new config */
7663 ue_params->drx_state.config = *drx_config;
7664 /* Remember frame when current settings set */
7665 ue_params->drx_state.config.frameNum = pinfo->num;
7666 /* Also remember any previous config frame number */
7667 ue_params->drx_state.config.previousFrameNum = previousFrameNum;
7671 /* Release DRX config for this UE */
7672 void set_mac_lte_drx_config_release(guint16 ueid, packet_info *pinfo)
7674 if (global_mac_lte_show_drx && !PINFO_FD_VISITED(pinfo)) {
7675 ue_parameters_t *ue_params;
7677 /* Find or create config struct for this UE */
7678 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((guint)ueid));
7679 if (ue_params != NULL) {
7680 ue_params->drx_state_valid = FALSE;
7685 /* Configure RAPID group sizes from RRC (SIB2). Note that we currently assume
7686 that they won't change, i.e. if known we just return the last values we ever
7688 void set_mac_lte_rapid_ranges(guint group_A, guint all_RA)
7690 s_rapid_ranges_groupA = group_A;
7691 s_rapid_ranges_RA = all_RA;
7692 s_rapid_ranges_configured = TRUE;
7695 /* Configure the BSR sizes for this UE (from RRC) */
7696 void set_mac_lte_extended_bsr_sizes(guint16 ueid, gboolean use_ext_bsr_sizes, packet_info *pinfo)
7698 if (!PINFO_FD_VISITED(pinfo)) {
7699 ue_parameters_t *ue_params;
7701 /* Find or create config struct for this UE */
7702 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((guint)ueid));
7703 if (ue_params == NULL) {
7704 ue_params = (ue_parameters_t *)wmem_new0(wmem_file_scope(), ue_parameters_t);
7705 g_hash_table_insert(mac_lte_ue_parameters, GUINT_TO_POINTER((guint)ueid), ue_params);
7708 ue_params->use_ext_bsr_sizes = use_ext_bsr_sizes;
7712 /* Configure the simultaneous PUCCH/PUSCH transmission for this UE (from RRC) */
7713 void set_mac_lte_simult_pucch_pusch(guint16 ueid, simult_pucch_pusch_cell_type cell_type, gboolean simult_pucch_pusch, packet_info *pinfo)
7715 if (!PINFO_FD_VISITED(pinfo)) {
7716 ue_parameters_t *ue_params;
7718 /* Find or create config struct for this UE */
7719 ue_params = (ue_parameters_t *)g_hash_table_lookup(mac_lte_ue_parameters, GUINT_TO_POINTER((guint)ueid));
7720 if (ue_params == NULL) {
7721 ue_params = (ue_parameters_t *)wmem_new0(wmem_file_scope(), ue_parameters_t);
7722 g_hash_table_insert(mac_lte_ue_parameters, GUINT_TO_POINTER((guint)ueid), ue_params);
7725 if (cell_type == SIMULT_PUCCH_PUSCH_PCELL) {
7726 ue_params->use_simult_pucch_pusch_pcell = simult_pucch_pusch;
7728 ue_params->use_simult_pucch_pusch_pscell = simult_pucch_pusch;
7733 /* Function to be called from outside this module (e.g. in a plugin) to get per-packet data */
7734 mac_lte_info *get_mac_lte_proto_data(packet_info *pinfo)
7736 return (mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
7739 /* Function to be called from outside this module (e.g. in a plugin) to set per-packet data */
7740 void set_mac_lte_proto_data(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
7742 p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info);
7745 void proto_register_mac_lte(void)
7747 static hf_register_info hf[] =
7749 /**********************************/
7750 /* Items for decoding context */
7751 { &hf_mac_lte_context,
7753 "mac-lte.context", FT_STRING, BASE_NONE, NULL, 0x0,
7757 { &hf_mac_lte_context_radio_type,
7759 "mac-lte.radio-type", FT_UINT8, BASE_DEC, VALS(radio_type_vals), 0x0,
7763 { &hf_mac_lte_context_direction,
7765 "mac-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
7766 "Direction of message", HFILL
7769 { &hf_mac_lte_context_rnti,
7771 "mac-lte.rnti", FT_UINT16, BASE_DEC, NULL, 0x0,
7772 "RNTI associated with message", HFILL
7775 { &hf_mac_lte_context_rnti_type,
7777 "mac-lte.rnti-type", FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0,
7778 "Type of RNTI associated with message", HFILL
7781 { &hf_mac_lte_context_ueid,
7783 "mac-lte.ueid", FT_UINT16, BASE_DEC, NULL, 0x0,
7784 "User Equipment Identifier associated with message", HFILL
7787 { &hf_mac_lte_context_sysframe_number,
7788 { "System Frame Number",
7789 "mac-lte.sfn", FT_UINT16, BASE_DEC, NULL, 0x0,
7790 "System Frame Number associated with message", HFILL
7793 { &hf_mac_lte_context_subframe_number,
7795 "mac-lte.subframe", FT_UINT16, BASE_DEC, NULL, 0x0,
7796 "Subframe number associated with message", HFILL
7799 { &hf_mac_lte_context_grant_subframe_number,
7801 "mac-lte.grant-subframe", FT_UINT16, BASE_DEC, NULL, 0x0,
7802 "Subframe when grant for this PDU was received", HFILL
7805 { &hf_mac_lte_context_predefined_frame,
7806 { "Predefined frame",
7807 "mac-lte.is-predefined-frame", FT_UINT8, BASE_DEC, VALS(predefined_frame_vals), 0x0,
7808 "Predefined test frame (or real MAC PDU)", HFILL
7811 { &hf_mac_lte_context_length,
7812 { "Length of frame",
7813 "mac-lte.length", FT_UINT8, BASE_DEC, NULL, 0x0,
7814 "Original length of frame (including SDUs and padding)", HFILL
7817 { &hf_mac_lte_context_ul_grant_size,
7818 { "Uplink grant size",
7819 "mac-lte.ul-grant-size", FT_UINT8, BASE_DEC, NULL, 0x0,
7820 "Uplink grant size (in bytes)", HFILL
7823 { &hf_mac_lte_context_bch_transport_channel,
7824 { "Transport channel",
7825 "mac-lte.bch-transport-channel", FT_UINT8, BASE_DEC, VALS(bch_transport_channel_vals), 0x0,
7826 "Transport channel BCH data was carried on", HFILL
7829 { &hf_mac_lte_context_retx_count,
7831 "mac-lte.retx-count", FT_UINT8, BASE_DEC, NULL, 0x0,
7832 "Number of times this PDU has been retransmitted", HFILL
7835 { &hf_mac_lte_context_retx_reason,
7837 "mac-lte.retx-reason", FT_UINT8, BASE_DEC, VALS(ul_retx_grant_vals), 0x0,
7838 "Type of UL ReTx grant", HFILL
7841 { &hf_mac_lte_context_crc_status,
7843 "mac-lte.crc-status", FT_UINT8, BASE_DEC, VALS(crc_status_vals), 0x0,
7844 "CRC Status as reported by PHY", HFILL
7847 { &hf_mac_lte_context_carrier_id,
7849 "mac-lte.carrier-id", FT_UINT8, BASE_DEC, VALS(carrier_id_vals), 0x0,
7853 { &hf_mac_lte_context_rapid,
7855 "mac-lte.preamble-sent.rapid", FT_UINT8, BASE_DEC, NULL, 0x0,
7856 "RAPID sent in RACH preamble", HFILL
7859 { &hf_mac_lte_context_rach_attempt_number,
7860 { "RACH Attempt Number",
7861 "mac-lte.preamble-sent.attempt", FT_UINT8, BASE_DEC, NULL, 0x0,
7866 { &hf_mac_lte_ues_ul_per_tti,
7868 "mac-lte.ul-tti-count", FT_UINT8, BASE_DEC, NULL, 0x0,
7869 "In this TTI, this is the nth UL grant", HFILL
7872 { &hf_mac_lte_ues_dl_per_tti,
7874 "mac-lte.dl-tti-count", FT_UINT8, BASE_DEC, NULL, 0x0,
7875 "In this TTI, this is the nth DL PDU", HFILL
7880 /* Extra PHY context */
7881 { &hf_mac_lte_context_phy_ul,
7882 { "UL PHY attributes",
7883 "mac-lte.ul-phy", FT_STRING, BASE_NONE, NULL, 0x0,
7887 { &hf_mac_lte_context_phy_ul_modulation_type,
7888 { "Modulation type",
7889 "mac-lte.ul-phy.modulation-type", FT_UINT8, BASE_DEC, VALS(modulation_type_vals), 0x0,
7893 { &hf_mac_lte_context_phy_ul_tbs_index,
7895 "mac-lte.ul-phy.tbs-index", FT_UINT8, BASE_DEC, NULL, 0x0,
7899 { &hf_mac_lte_context_phy_ul_resource_block_length,
7900 { "Resource Block Length",
7901 "mac-lte.ul-phy.resource-block-length", FT_UINT8, BASE_DEC, NULL, 0x0,
7905 { &hf_mac_lte_context_phy_ul_resource_block_start,
7906 { "Resource Block Start",
7907 "mac-lte.ul-phy.resource-block-start", FT_UINT8, BASE_DEC, NULL, 0x0,
7911 { &hf_mac_lte_context_phy_ul_harq_id,
7913 "mac-lte.ul-phy.harq-id", FT_UINT8, BASE_DEC, NULL, 0x0,
7917 { &hf_mac_lte_context_phy_ul_ndi,
7919 "mac-lte.ul-phy.ndi", FT_UINT8, BASE_DEC, NULL, 0x0,
7920 "UL New Data Indicator", HFILL
7924 { &hf_mac_lte_context_phy_dl,
7925 { "DL PHY attributes",
7926 "mac-lte.dl-phy", FT_STRING, BASE_NONE, NULL, 0x0,
7930 { &hf_mac_lte_context_phy_dl_dci_format,
7932 "mac-lte.dl-phy.dci-format", FT_UINT8, BASE_DEC, VALS(dci_format_vals), 0x0,
7936 { &hf_mac_lte_context_phy_dl_resource_allocation_type,
7937 { "Resource Allocation Type",
7938 "mac-lte.dl-phy.resource-allocation-type", FT_UINT8, BASE_DEC, NULL, 0x0,
7942 { &hf_mac_lte_context_phy_dl_aggregation_level,
7943 { "Aggregation Level",
7944 "mac-lte.dl-phy.aggregation-level", FT_UINT8, BASE_DEC, VALS(aggregation_level_vals), 0x0,
7948 { &hf_mac_lte_context_phy_dl_mcs_index,
7950 "mac-lte.dl-phy.mcs-index", FT_UINT8, BASE_DEC, NULL, 0x0,
7954 { &hf_mac_lte_context_phy_dl_redundancy_version_index,
7956 "mac-lte.dl-phy.rv-index", FT_UINT8, BASE_DEC, NULL, 0x0,
7960 { &hf_mac_lte_context_phy_dl_retx,
7962 "mac-lte.dl-phy.dl-retx", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
7966 { &hf_mac_lte_context_phy_dl_resource_block_length,
7968 "mac-lte.dl-phy.rb-length", FT_UINT8, BASE_DEC, NULL, 0x0,
7972 { &hf_mac_lte_context_phy_dl_harq_id,
7974 "mac-lte.dl-phy.harq-id", FT_UINT8, BASE_DEC, NULL, 0x0,
7978 { &hf_mac_lte_context_phy_dl_ndi,
7980 "mac-lte.dl-phy.ndi", FT_UINT8, BASE_DEC, NULL, 0x0,
7981 "New Data Indicator", HFILL
7984 { &hf_mac_lte_context_phy_dl_tb,
7986 "mac-lte.dl-phy.tb", FT_UINT8, BASE_DEC, NULL, 0x0,
7987 "Transport Block (antenna #)", HFILL
7991 /* Out-of-band events */
7992 { &hf_mac_lte_oob_send_preamble,
7994 "mac-lte.preamble-sent", FT_STRING, BASE_NONE, NULL, 0x0,
7998 { &hf_mac_lte_number_of_srs,
8000 "mac-lte.sr-req.count", FT_UINT32, BASE_DEC, NULL, 0x0,
8001 "Number of UEs doing SR in this frame", HFILL
8005 /*******************************************/
8006 /* MAC shared channel header fields */
8007 { &hf_mac_lte_ulsch,
8009 "mac-lte.ulsch", FT_STRING, BASE_NONE, NULL, 0x0,
8013 { &hf_mac_lte_ulsch_header,
8015 "mac-lte.ulsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8019 { &hf_mac_lte_dlsch_header,
8021 "mac-lte.dlsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8025 { &hf_mac_lte_dlsch,
8027 "mac-lte.dlsch", FT_STRING, BASE_NONE, NULL, 0x0,
8031 { &hf_mac_lte_sch_subheader,
8033 "mac-lte.sch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8039 "mac-lte.mch", FT_STRING, BASE_NONE, NULL, 0x0,
8043 { &hf_mac_lte_mch_header,
8045 "mac-lte.mch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8049 { &hf_mac_lte_mch_subheader,
8051 "mac-lte.mch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8055 { &hf_mac_lte_slsch,
8057 "mac-lte.slsch", FT_STRING, BASE_NONE, NULL, 0x0,
8061 { &hf_mac_lte_slsch_header,
8063 "mac-lte.slsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8067 { &hf_mac_lte_slsch_subheader,
8068 { "SL-SCH sub-header",
8069 "mac-lte.slsch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8073 { &hf_mac_lte_sch_reserved,
8074 { "SCH reserved bit",
8075 "mac-lte.sch.reserved", FT_UINT8, BASE_HEX, NULL, 0x80,
8079 { &hf_mac_lte_sch_format2,
8081 "mac-lte.sch.format2", FT_BOOLEAN, 8, TFS(&format2_vals), 0x40,
8085 { &hf_mac_lte_sch_extended,
8087 "mac-lte.sch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8088 "Extension - i.e. further headers after this one", HFILL
8091 { &hf_mac_lte_dlsch_lcid,
8093 "mac-lte.dlsch.lcid", FT_UINT8, BASE_HEX, VALS(dlsch_lcid_vals), 0x1f,
8094 "DL-SCH Logical Channel Identifier", HFILL
8097 { &hf_mac_lte_ulsch_lcid,
8099 "mac-lte.ulsch.lcid", FT_UINT8, BASE_HEX, VALS(ulsch_lcid_vals), 0x1f,
8100 "UL-SCH Logical Channel Identifier", HFILL
8103 { &hf_mac_lte_sch_format,
8105 "mac-lte.sch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8109 { &hf_mac_lte_sch_length,
8111 "mac-lte.sch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8112 "Length of MAC SDU or MAC control element", HFILL
8115 { &hf_mac_lte_mch_reserved,
8116 { "MCH reserved bits",
8117 "mac-lte.mch.reserved", FT_UINT8, BASE_HEX, NULL, 0x80,
8121 { &hf_mac_lte_mch_format2,
8123 "mac-lte.mch.format2", FT_BOOLEAN, 8, TFS(&format2_vals), 0x40,
8127 { &hf_mac_lte_mch_extended,
8129 "mac-lte.mch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8130 "Extension - i.e. further headers after this one", HFILL
8133 { &hf_mac_lte_mch_lcid,
8135 "mac-lte.mch.lcid", FT_UINT8, BASE_HEX, VALS(mch_lcid_vals), 0x1f,
8136 "MCH Logical Channel Identifier", HFILL
8139 { &hf_mac_lte_mch_format,
8141 "mac-lte.mch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8145 { &hf_mac_lte_mch_length,
8147 "mac-lte.mch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8148 "Length of MAC SDU or MAC control element", HFILL
8151 { &hf_mac_lte_slsch_version,
8153 "mac-lte.slsch.version", FT_UINT8, BASE_DEC, NULL, 0xf0,
8157 { &hf_mac_lte_slsch_reserved,
8159 "mac-lte.slsch.reserved", FT_UINT8, BASE_HEX, NULL, 0x0f,
8163 { &hf_mac_lte_slsch_src_l2_id,
8164 { "Source Layer-2 ID",
8165 "mac-lte.slsch.src-l2-id", FT_UINT24, BASE_HEX, NULL, 0x0,
8169 { &hf_mac_lte_slsch_dst_l2_id,
8170 { "Destination Layer-2 ID",
8171 "mac-lte.slsch.dst-l2-id", FT_UINT16, BASE_HEX, NULL, 0x0,
8175 { &hf_mac_lte_slsch_dst_l2_id2,
8176 { "Destination Layer-2 ID",
8177 "mac-lte.slsch.dst-l2-id", FT_UINT24, BASE_HEX, NULL, 0x0,
8181 { &hf_mac_lte_slsch_reserved2,
8183 "mac-lte.slsch.reserved", FT_UINT8, BASE_HEX, NULL, 0xc0,
8187 { &hf_mac_lte_slsch_extended,
8189 "mac-lte.slsch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8190 "Extension - i.e. further headers after this one", HFILL
8193 { &hf_mac_lte_slsch_lcid,
8195 "mac-lte.slsch.lcid", FT_UINT8, BASE_HEX, VALS(slsch_lcid_vals), 0x1f,
8196 "SL-SCH Logical Channel Identifier", HFILL
8199 { &hf_mac_lte_slsch_format,
8201 "mac-lte.slsch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8205 { &hf_mac_lte_slsch_length,
8207 "mac-lte.slsch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8208 "Length of MAC SDU or MAC control element", HFILL
8211 { &hf_mac_lte_sch_header_only,
8212 { "MAC PDU Header only",
8213 "mac-lte.sch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
8217 { &hf_mac_lte_mch_header_only,
8218 { "MAC PDU Header only",
8219 "mac-lte.mch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
8223 { &hf_mac_lte_slsch_header_only,
8224 { "MAC PDU Header only",
8225 "mac-lte.slsch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
8230 /********************************/
8232 { &hf_mac_lte_sch_sdu,
8234 "mac-lte.sch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8235 "Shared channel SDU", HFILL
8238 { &hf_mac_lte_mch_sdu,
8240 "mac-lte.mch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8241 "Multicast channel SDU", HFILL
8244 { &hf_mac_lte_bch_pdu,
8246 "mac-lte.bch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8250 { &hf_mac_lte_pch_pdu,
8252 "mac-lte.pch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8256 { &hf_mac_lte_slbch_pdu,
8258 "mac-lte.slbch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8262 { &hf_mac_lte_slsch_sdu,
8264 "mac-lte.slsch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8265 "Sidelink shared channel SDU", HFILL
8268 { &hf_mac_lte_predefined_pdu,
8269 { "Predefined data",
8270 "mac-lte.predefined-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8271 "Predefined test data", HFILL
8274 { &hf_mac_lte_raw_pdu,
8276 "mac-lte.raw-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8277 "Raw bytes of PDU (e.g. if CRC error)", HFILL
8280 { &hf_mac_lte_padding_data,
8282 "mac-lte.padding-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8286 { &hf_mac_lte_padding_length,
8288 "mac-lte.padding-length", FT_INT32, BASE_DEC, NULL, 0x0,
8289 "Length of padding data not included at end of frame", HFILL
8295 /*********************************/
8299 "mac-lte.rar", FT_NONE, BASE_NONE, NULL, 0x0,
8303 { &hf_mac_lte_rar_headers,
8305 "mac-lte.rar.headers", FT_STRING, BASE_NONE, NULL, 0x0,
8309 { &hf_mac_lte_rar_header,
8311 "mac-lte.rar.header", FT_STRING, BASE_NONE, NULL, 0x0,
8315 { &hf_mac_lte_rar_extension,
8317 "mac-lte.rar.e", FT_UINT8, BASE_HEX, NULL, 0x80,
8318 "Extension - i.e. further RAR headers after this one", HFILL
8321 { &hf_mac_lte_rar_t,
8323 "mac-lte.rar.t", FT_UINT8, BASE_HEX, VALS(rar_type_vals), 0x40,
8324 "Type field indicating whether the payload is RAPID or BI", HFILL
8327 { &hf_mac_lte_rar_bi,
8329 "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_vals), 0x0f,
8330 "Backoff Indicator (ms)", HFILL
8333 { &hf_mac_lte_rar_bi_nb,
8335 "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_nb_vals), 0x0f,
8336 "Backoff Indicator (ms)", HFILL
8339 { &hf_mac_lte_rar_rapid,
8341 "mac-lte.rar.rapid", FT_UINT8, BASE_HEX_DEC, NULL, 0x3f,
8342 "Random Access Preamble IDentifier", HFILL
8345 { &hf_mac_lte_rar_no_of_rapids,
8346 { "Number of RAPIDs",
8347 "mac-lte.rar.no-of-rapids", FT_UINT8, BASE_DEC, NULL, 0x0,
8348 "Number of RAPIDs in RAR PDU", HFILL
8351 { &hf_mac_lte_rar_reserved,
8353 "mac-lte.rar.reserved", FT_UINT8, BASE_HEX, NULL, 0x30,
8354 "Reserved bits in RAR header - should be 0", HFILL
8358 { &hf_mac_lte_rar_body,
8360 "mac-lte.rar.body", FT_STRING, BASE_NONE, NULL, 0x0,
8364 { &hf_mac_lte_rar_reserved2,
8366 "mac-lte.rar.reserved2", FT_UINT8, BASE_HEX, NULL, 0x80,
8367 "Reserved bit in RAR body - should be 0", HFILL
8370 { &hf_mac_lte_rar_ta,
8372 "mac-lte.rar.ta", FT_UINT16, BASE_DEC, NULL, 0x7ff0,
8373 "Required adjustment to uplink transmission timing", HFILL
8376 { &hf_mac_lte_rar_ul_grant_ce_mode_b,
8378 "mac-lte.rar.ul-grant", FT_UINT16, BASE_DEC, NULL, 0x0fff,
8379 "Size of UL Grant", HFILL
8382 { &hf_mac_lte_rar_ul_grant,
8384 "mac-lte.rar.ul-grant", FT_UINT24, BASE_DEC, NULL, 0x0fffff,
8385 "Size of UL Grant", HFILL
8388 { &hf_mac_lte_rar_ul_grant_hopping,
8390 "mac-lte.rar.ul-grant.hopping", FT_UINT8, BASE_DEC, NULL, 0x08,
8394 { &hf_mac_lte_rar_ul_grant_fsrba,
8395 { "Fixed sized resource block assignment",
8396 "mac-lte.rar.ul-grant.fsrba", FT_UINT16, BASE_DEC, NULL, 0x07fe,
8400 { &hf_mac_lte_rar_ul_grant_tmcs,
8401 { "Truncated Modulation and coding scheme",
8402 "mac-lte.rar.ul-grant.tmcs", FT_UINT16, BASE_DEC, NULL, 0x01e0,
8406 { &hf_mac_lte_rar_ul_grant_tcsp,
8407 { "TPC command for scheduled PUSCH",
8408 "mac-lte.rar.ul-grant.tcsp", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_tcsp_vals), 0x01c,
8409 "PUSCH power offset in dB" , HFILL
8412 { &hf_mac_lte_rar_ul_grant_ul_delay,
8414 "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, NULL, 0x02,
8418 { &hf_mac_lte_rar_ul_grant_cqi_request,
8420 "mac-lte.rar.ul-grant.cqi-request", FT_UINT8, BASE_DEC, NULL, 0x01,
8424 { &hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_a,
8425 { "Msg3 PUSCH narrowband index",
8426 "mac-lte.rar.ul-grant.msg3-pusch-nb-idx", FT_UINT8, BASE_DEC, NULL, 0x0,
8430 { &hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_a,
8431 { "Msg3 PUSCH Resource allocation",
8432 "mac-lte.rar.ul-grant.msg3-pusch-res-alloc", FT_UINT8, BASE_DEC, NULL, 0x0,
8436 { &hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a,
8437 { "Number of Repetitions for Msg3 PUSCH",
8438 "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,
8442 { &hf_mac_lte_rar_ul_grant_mcs_ce_mode_a,
8444 "mac-lte.rar.ul-grant.mcs", FT_UINT16, BASE_DEC, NULL, 0x0,
8448 { &hf_mac_lte_rar_ul_grant_tpc_ce_mode_a,
8450 "mac-lte.rar.ul-grant.tpc", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_tcsp_vals), 0x0,
8454 { &hf_mac_lte_rar_ul_grant_csi_request_ce_mode_a,
8456 "mac-lte.rar.ul-grant.csi-request", FT_UINT8, BASE_DEC, NULL, 0x0,
8460 { &hf_mac_lte_rar_ul_grant_ul_delay_ce_mode_a,
8462 "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
8466 { &hf_mac_lte_rar_ul_grant_msg3_msg4_mpdcch_nb_idx,
8467 { "Msg3/4 MPDCCH narrowband index",
8468 "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,
8472 { &hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
8474 "mac-lte.rar.ul-grant.padding", FT_UINT8, BASE_HEX, NULL, 0x0,
8478 { &hf_mac_lte_rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b,
8479 { "Msg3 PUSCH narrowband index",
8480 "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,
8484 { &hf_mac_lte_rar_ul_grant_msg3_pusch_res_alloc_ce_mode_b,
8485 { "Msg3 PUSCH resource allocation",
8486 "mac-lte.rar.ul-grant.msg3-pusch-res-alloc", FT_UINT16, BASE_DEC, NULL, 0x0380,
8490 { &hf_mac_lte_rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b,
8491 { "Number of Repetitions for Msg3 PUSCH",
8492 "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,
8496 { &hf_mac_lte_rar_ul_grant_tbs_ce_mode_b,
8498 "mac-lte.rar.ul-grant.tbs", FT_UINT8, BASE_DEC, NULL, 0x0c,
8502 { &hf_mac_lte_rar_ul_grant_ul_subcarrier_spacing,
8503 { "Uplink subcarrier spacing",
8504 "mac-lte.rar.ul-grant.ul-subcarrier-spacing", FT_BOOLEAN, 8, TFS(&ul_subcarrier_spacing_val), 0x08,
8508 { &hf_mac_lte_rar_ul_grant_subcarrier_indication,
8509 { "Subcarrier indication",
8510 "mac-lte.rar.ul-grant.subcarrier-indication", FT_UINT16, BASE_DEC, NULL, 0x07e0,
8514 { &hf_mac_lte_rar_ul_grant_scheduling_delay,
8515 { "Scheduling delay",
8516 "mac-lte.rar.ul-grant.scheduling-delay", FT_UINT8, BASE_DEC, VALS(scheduling_delay_vals), 0x18,
8520 { &hf_mac_lte_rar_ul_grant_msg3_repetition_number,
8521 { "Msg3 repetition number",
8522 "mac-lte.rar.ul-grant.msg3-repetition-number", FT_UINT8, BASE_DEC, VALS(msg3_rep_nb_vals), 0x07,
8526 { &hf_mac_lte_rar_ul_grant_mcs_index,
8528 "mac-lte.rar.ul-grant.mcs-index", FT_UINT8, BASE_DEC, NULL, 0xe0,
8532 { &hf_mac_lte_rar_ul_grant_padding_nb_mode,
8534 "mac-lte.rar.ul-grant.padding", FT_UINT8, BASE_HEX, NULL, 0x1f,
8538 { &hf_mac_lte_rar_temporary_crnti,
8539 { "Temporary C-RNTI",
8540 "mac-lte.rar.temporary-crnti", FT_UINT16, BASE_DEC, NULL, 0x0,
8545 /**********************/
8546 /* Control PDU fields */
8547 { &hf_mac_lte_control_bsr,
8549 "mac-lte.control.bsr", FT_STRING, BASE_NONE, NULL, 0x0,
8550 "Buffer Status Report", HFILL
8553 { &hf_mac_lte_control_bsr_lcg_id,
8554 { "Logical Channel Group ID",
8555 "mac-lte.control.bsr.lcg-id", FT_UINT8, BASE_DEC, NULL, 0xc0,
8559 { &hf_mac_lte_control_short_bsr_buffer_size,
8561 "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
8562 "Buffer Size available in all channels in group", HFILL
8565 { &hf_mac_lte_control_long_bsr_buffer_size_0,
8567 "mac-lte.control.bsr.buffer-size-0", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0xfc,
8568 "Buffer Size available in logical channel group 0", HFILL
8571 { &hf_mac_lte_control_long_bsr_buffer_size_1,
8573 "mac-lte.control.bsr.buffer-size-1", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x03f0,
8574 "Buffer Size available in logical channel group 1", HFILL
8577 { &hf_mac_lte_control_long_bsr_buffer_size_2,
8579 "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x0fc0,
8580 "Buffer Size available in logical channel group 2", HFILL
8583 { &hf_mac_lte_control_long_bsr_buffer_size_3,
8585 "mac-lte.control.bsr.buffer-size-3", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
8586 "Buffer Size available in logical channel group 3", HFILL
8589 { &hf_mac_lte_control_short_ext_bsr_buffer_size,
8591 "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x3f,
8592 "Buffer Size available in all channels in group", HFILL
8595 { &hf_mac_lte_control_long_ext_bsr_buffer_size_0,
8597 "mac-lte.control.bsr.buffer-size-0", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0xfc,
8598 "Buffer Size available in logical channel group 0", HFILL
8601 { &hf_mac_lte_control_long_ext_bsr_buffer_size_1,
8603 "mac-lte.control.bsr.buffer-size-1", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x03f0,
8604 "Buffer Size available in logical channel group 1", HFILL
8607 { &hf_mac_lte_control_long_ext_bsr_buffer_size_2,
8609 "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x0fc0,
8610 "Buffer Size available in logical channel group 2", HFILL
8613 { &hf_mac_lte_control_long_ext_bsr_buffer_size_3,
8615 "mac-lte.control.bsr.buffer-size-3", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x3f,
8616 "Buffer Size available in logical channel group 3", HFILL
8619 { &hf_mac_lte_bsr_size_median,
8620 { "Buffer Size Median",
8621 "mac-lte.control.bsr.buffer-size-median", FT_UINT8, BASE_DEC, NULL, 0x0,
8625 { &hf_mac_lte_control_crnti,
8627 "mac-lte.control.crnti", FT_UINT16, BASE_DEC, NULL, 0x0,
8628 "C-RNTI for the UE", HFILL
8631 { &hf_mac_lte_control_timing_advance,
8633 "mac-lte.control.timing-advance", FT_STRING, BASE_NONE, NULL, 0x0,
8637 { &hf_mac_lte_control_timing_advance_group_id,
8638 { "Timing Advance Group Identity",
8639 "mac-lte.control.timing-advance.group-id", FT_UINT8, BASE_DEC, NULL, 0xc0,
8643 { &hf_mac_lte_control_timing_advance_command,
8644 { "Timing Advance Command",
8645 "mac-lte.control.timing-advance.command", FT_UINT8, BASE_DEC, NULL, 0x3f,
8646 "Timing Advance (0-63 - see 36.213, 4.2.3)", HFILL
8649 { &hf_mac_lte_control_ue_contention_resolution,
8650 { "UE Contention Resolution",
8651 "mac-lte.control.ue-contention-resolution", FT_STRING, BASE_NONE, NULL, 0x0,
8655 { &hf_mac_lte_control_ue_contention_resolution_identity,
8656 { "UE Contention Resolution Identity",
8657 "mac-lte.control.ue-contention-resolution.identity", FT_BYTES, BASE_NONE, NULL, 0x0,
8661 { &hf_mac_lte_control_ue_contention_resolution_msg3,
8663 "mac-lte.control.ue-contention-resolution.msg3", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
8667 { &hf_mac_lte_control_ue_contention_resolution_msg3_matched,
8668 { "UE Contention Resolution Matches Msg3",
8669 "mac-lte.control.ue-contention-resolution.matches-msg3", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
8673 { &hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
8674 { "Time since Msg3",
8675 "mac-lte.control.ue-contention-resolution.time-since-msg3", FT_UINT32, BASE_DEC, NULL, 0x0,
8676 "Time in ms since corresponding Msg3", HFILL
8679 { &hf_mac_lte_control_msg3_to_cr,
8681 "mac-lte.msg3-cr-response", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
8686 { &hf_mac_lte_control_power_headroom,
8687 { "Power Headroom Report",
8688 "mac-lte.control.power-headroom", FT_STRING, BASE_NONE, NULL, 0x0,
8692 { &hf_mac_lte_control_power_headroom_reserved,
8694 "mac-lte.control.power-headroom.reserved", FT_UINT8, BASE_DEC, NULL, 0xc0,
8695 "Reserved bits, should be 0", HFILL
8698 { &hf_mac_lte_control_power_headroom_level,
8699 { "Power Headroom Level",
8700 "mac-lte.control.power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
8701 &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
8705 { &hf_mac_lte_control_dual_conn_power_headroom,
8706 { "Dual Connectivity Power Headroom Report",
8707 "mac-lte.control.dual-conn-power-headroom", FT_STRING, BASE_NONE,
8708 NULL, 0x0, NULL, HFILL
8711 { &hf_mac_lte_control_dual_conn_power_headroom_c7,
8712 { "SCell Index 7 Power Headroom",
8713 "mac-lte.control.dual-conn-power-headroom.c7", FT_BOOLEAN, 8,
8714 TFS(&mac_lte_scell_ph_vals), 0x80, NULL, HFILL
8717 { &hf_mac_lte_control_dual_conn_power_headroom_c6,
8718 { "SCell Index 6 Power Headroom",
8719 "mac-lte.control.dual-conn-power-headroom.c6", FT_BOOLEAN, 8,
8720 TFS(&mac_lte_scell_ph_vals), 0x40, NULL, HFILL
8723 { &hf_mac_lte_control_dual_conn_power_headroom_c5,
8724 { "SCell Index 5 Power Headroom",
8725 "mac-lte.control.dual-conn-power-headroom.c5", FT_BOOLEAN, 8,
8726 TFS(&mac_lte_scell_ph_vals), 0x20, NULL, HFILL
8729 { &hf_mac_lte_control_dual_conn_power_headroom_c4,
8730 { "SCell Index 4 Power Headroom",
8731 "mac-lte.control.dual-conn-power-headroom.c4", FT_BOOLEAN, 8,
8732 TFS(&mac_lte_scell_ph_vals), 0x10, NULL, HFILL
8735 { &hf_mac_lte_control_dual_conn_power_headroom_c3,
8736 { "SCell Index 3 Power Headroom",
8737 "mac-lte.control.dual-conn-power-headroom.c3", FT_BOOLEAN, 8,
8738 TFS(&mac_lte_scell_ph_vals), 0x08, NULL, HFILL
8741 { &hf_mac_lte_control_dual_conn_power_headroom_c2,
8742 { "SCell Index 2 Power Headroom",
8743 "mac-lte.control.dual-conn-power-headroom.c2", FT_BOOLEAN, 8,
8744 TFS(&mac_lte_scell_ph_vals), 0x04, NULL, HFILL
8747 { &hf_mac_lte_control_dual_conn_power_headroom_c1,
8748 { "SCell Index 1 Power Headroom",
8749 "mac-lte.control.dual-conn-power-headroom.c1", FT_BOOLEAN, 8,
8750 TFS(&mac_lte_scell_ph_vals), 0x02, NULL, HFILL
8753 { &hf_mac_lte_control_dual_conn_power_headroom_reserved,
8755 "mac-lte.control.dual-conn-power-headroom.reserved", FT_UINT8, BASE_DEC,
8756 NULL, 0x01, "Reserved bit, should be 0", HFILL
8759 { &hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
8761 "mac-lte.control.dual-conn-power-headroom.power-backoff", FT_BOOLEAN, 8,
8762 TFS(&mac_lte_power_backoff_vals), 0x80, NULL, HFILL
8765 { &hf_mac_lte_control_dual_conn_power_headroom_value,
8766 { "Power Headroom Value",
8767 "mac-lte.control.dual-conn-power-headroom.value", FT_BOOLEAN, 8,
8768 TFS(&mac_lte_ph_value_vals), 0x40, NULL, HFILL
8771 { &hf_mac_lte_control_dual_conn_power_headroom_level,
8772 { "Power Headroom Level",
8773 "mac-lte.control.dual-conn-power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
8774 &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
8777 { &hf_mac_lte_control_dual_conn_power_headroom_reserved2,
8779 "mac-lte.control.dual-conn-power-headroom.reserved2", FT_UINT8, BASE_DEC,
8780 NULL, 0xc0, "Reserved bits, should be 0", HFILL
8783 { &hf_mac_lte_control_dual_conn_power_headroom_pcmaxc,
8784 { "Configured UE Transmit Power",
8785 "mac-lte.control.ext-power-headroom.pcmaxc", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
8786 &pcmaxc_vals_ext, 0x3f, "Pcmax,c in dBm", HFILL
8790 { &hf_mac_lte_control_ext_power_headroom,
8791 { "Extended Power Headroom Report",
8792 "mac-lte.control.ext-power-headroom", FT_STRING, BASE_NONE,
8793 NULL, 0x0, NULL, HFILL
8796 { &hf_mac_lte_control_ext_power_headroom_c7,
8797 { "SCell Index 7 Power Headroom",
8798 "mac-lte.control.ext-power-headroom.c7", FT_BOOLEAN, 8,
8799 TFS(&mac_lte_scell_ph_vals), 0x80, NULL, HFILL
8802 { &hf_mac_lte_control_ext_power_headroom_c6,
8803 { "SCell Index 6 Power Headroom",
8804 "mac-lte.control.ext-power-headroom.c6", FT_BOOLEAN, 8,
8805 TFS(&mac_lte_scell_ph_vals), 0x40, NULL, HFILL
8808 { &hf_mac_lte_control_ext_power_headroom_c5,
8809 { "SCell Index 5 Power Headroom",
8810 "mac-lte.control.ext-power-headroom.c5", FT_BOOLEAN, 8,
8811 TFS(&mac_lte_scell_ph_vals), 0x20, NULL, HFILL
8814 { &hf_mac_lte_control_ext_power_headroom_c4,
8815 { "SCell Index 4 Power Headroom",
8816 "mac-lte.control.ext-power-headroom.c4", FT_BOOLEAN, 8,
8817 TFS(&mac_lte_scell_ph_vals), 0x10, NULL, HFILL
8820 { &hf_mac_lte_control_ext_power_headroom_c3,
8821 { "SCell Index 3 Power Headroom",
8822 "mac-lte.control.ext-power-headroom.c3", FT_BOOLEAN, 8,
8823 TFS(&mac_lte_scell_ph_vals), 0x08, NULL, HFILL
8826 { &hf_mac_lte_control_ext_power_headroom_c2,
8827 { "SCell Index 2 Power Headroom",
8828 "mac-lte.control.ext-power-headroom.c2", FT_BOOLEAN, 8,
8829 TFS(&mac_lte_scell_ph_vals), 0x04, NULL, HFILL
8832 { &hf_mac_lte_control_ext_power_headroom_c1,
8833 { "SCell Index 1 Power Headroom",
8834 "mac-lte.control.ext-power-headroom.c1", FT_BOOLEAN, 8,
8835 TFS(&mac_lte_scell_ph_vals), 0x02, NULL, HFILL
8838 { &hf_mac_lte_control_ext_power_headroom_reserved,
8840 "mac-lte.control.ext-power-headroom.reserved", FT_UINT8, BASE_DEC,
8841 NULL, 0x01, "Reserved bit, should be 0", HFILL
8844 { &hf_mac_lte_control_ext_power_headroom_power_backoff,
8846 "mac-lte.control.ext-power-headroom.power-backoff", FT_BOOLEAN, 8,
8847 TFS(&mac_lte_power_backoff_vals), 0x80, NULL, HFILL
8850 { &hf_mac_lte_control_ext_power_headroom_value,
8851 { "Power Headroom Value",
8852 "mac-lte.control.ext-power-headroom.value", FT_BOOLEAN, 8,
8853 TFS(&mac_lte_ph_value_vals), 0x40, NULL, HFILL
8856 { &hf_mac_lte_control_ext_power_headroom_level,
8857 { "Power Headroom Level",
8858 "mac-lte.control.ext-power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
8859 &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
8862 { &hf_mac_lte_control_ext_power_headroom_reserved2,
8864 "mac-lte.control.ext-power-headroom.reserved2", FT_UINT8, BASE_DEC,
8865 NULL, 0xc0, "Reserved bits, should be 0", HFILL
8868 { &hf_mac_lte_control_ext_power_headroom_pcmaxc,
8869 { "Configured UE Transmit Power",
8870 "mac-lte.control.ext-power-headroom.pcmaxc", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
8871 &pcmaxc_vals_ext, 0x3f, "Pcmax,c in dBm", HFILL
8875 { &hf_mac_lte_control_activation_deactivation,
8876 { "Activation/Deactivation",
8877 "mac-lte.control.activation-deactivation", FT_STRING, BASE_NONE,
8878 NULL, 0x0, NULL, HFILL
8881 { &hf_mac_lte_control_activation_deactivation_c7,
8882 { "SCell Index 7 Status",
8883 "mac-lte.control.activation-deactivation.c7", FT_BOOLEAN, 8,
8884 TFS(&mac_lte_scell_status_vals), 0x80, NULL, HFILL
8887 { &hf_mac_lte_control_activation_deactivation_c6,
8888 { "SCell Index 6 Status",
8889 "mac-lte.control.activation-deactivation.c6", FT_BOOLEAN, 8,
8890 TFS(&mac_lte_scell_status_vals), 0x40, NULL, HFILL
8893 { &hf_mac_lte_control_activation_deactivation_c5,
8894 { "SCell Index 5 Status",
8895 "mac-lte.control.activation-deactivation.c5", FT_BOOLEAN, 8,
8896 TFS(&mac_lte_scell_status_vals), 0x20, NULL, HFILL
8899 { &hf_mac_lte_control_activation_deactivation_c4,
8900 { "SCell Index 4 Status",
8901 "mac-lte.control.activation-deactivation.c4", FT_BOOLEAN, 8,
8902 TFS(&mac_lte_scell_status_vals), 0x10, NULL, HFILL
8905 { &hf_mac_lte_control_activation_deactivation_c3,
8906 { "SCell Index 3 Status",
8907 "mac-lte.control.activation-deactivation.c3", FT_BOOLEAN, 8,
8908 TFS(&mac_lte_scell_status_vals), 0x08, NULL, HFILL
8911 { &hf_mac_lte_control_activation_deactivation_c2,
8912 { "SCell Index 2 Status",
8913 "mac-lte.control.activation-deactivation.c2", FT_BOOLEAN, 8,
8914 TFS(&mac_lte_scell_status_vals), 0x04, NULL, HFILL
8917 { &hf_mac_lte_control_activation_deactivation_c1,
8918 { "SCell Index 1 Status",
8919 "mac-lte.control.activation-deactivation.c1", FT_BOOLEAN, 8,
8920 TFS(&mac_lte_scell_status_vals), 0x02, NULL, HFILL
8923 { &hf_mac_lte_control_activation_deactivation_reserved,
8925 "mac-lte.control.activation-deactivation.reserved", FT_UINT8, BASE_DEC,
8926 NULL, 0x01, "Reserved bit, should be 0", HFILL
8929 { &hf_mac_lte_control_activation_deactivation_c15,
8930 { "SCell Index 15 Status",
8931 "mac-lte.control.activation-deactivation.c15", FT_BOOLEAN, 8,
8932 TFS(&mac_lte_scell_status_vals), 0x80, NULL, HFILL
8935 { &hf_mac_lte_control_activation_deactivation_c14,
8936 { "SCell Index 14 Status",
8937 "mac-lte.control.activation-deactivation.c14", FT_BOOLEAN, 8,
8938 TFS(&mac_lte_scell_status_vals), 0x40, NULL, HFILL
8941 { &hf_mac_lte_control_activation_deactivation_c13,
8942 { "SCell Index 13 Status",
8943 "mac-lte.control.activation-deactivation.c13", FT_BOOLEAN, 8,
8944 TFS(&mac_lte_scell_status_vals), 0x20, NULL, HFILL
8947 { &hf_mac_lte_control_activation_deactivation_c12,
8948 { "SCell Index 12 Status",
8949 "mac-lte.control.activation-deactivation.c12", FT_BOOLEAN, 8,
8950 TFS(&mac_lte_scell_status_vals), 0x10, NULL, HFILL
8953 { &hf_mac_lte_control_activation_deactivation_c11,
8954 { "SCell Index 11 Status",
8955 "mac-lte.control.activation-deactivation.c11", FT_BOOLEAN, 8,
8956 TFS(&mac_lte_scell_status_vals), 0x08, NULL, HFILL
8959 { &hf_mac_lte_control_activation_deactivation_c10,
8960 { "SCell Index 10 Status",
8961 "mac-lte.control.activation-deactivation.c10", FT_BOOLEAN, 8,
8962 TFS(&mac_lte_scell_status_vals), 0x04, NULL, HFILL
8965 { &hf_mac_lte_control_activation_deactivation_c9,
8966 { "SCell Index 9 Status",
8967 "mac-lte.control.activation-deactivation.c9", FT_BOOLEAN, 8,
8968 TFS(&mac_lte_scell_status_vals), 0x02, NULL, HFILL
8971 { &hf_mac_lte_control_activation_deactivation_c8,
8972 { "SCell Index 8 Status",
8973 "mac-lte.control.activation-deactivation.c8", FT_BOOLEAN, 8,
8974 TFS(&mac_lte_scell_status_vals), 0x01, NULL, HFILL
8977 { &hf_mac_lte_control_activation_deactivation_c23,
8978 { "SCell Index 23 Status",
8979 "mac-lte.control.activation-deactivation.c23", FT_BOOLEAN, 8,
8980 TFS(&mac_lte_scell_status_vals), 0x80, NULL, HFILL
8983 { &hf_mac_lte_control_activation_deactivation_c22,
8984 { "SCell Index 22 Status",
8985 "mac-lte.control.activation-deactivation.c22", FT_BOOLEAN, 8,
8986 TFS(&mac_lte_scell_status_vals), 0x40, NULL, HFILL
8989 { &hf_mac_lte_control_activation_deactivation_c21,
8990 { "SCell Index 21 Status",
8991 "mac-lte.control.activation-deactivation.c21", FT_BOOLEAN, 8,
8992 TFS(&mac_lte_scell_status_vals), 0x20, NULL, HFILL
8995 { &hf_mac_lte_control_activation_deactivation_c20,
8996 { "SCell Index 20 Status",
8997 "mac-lte.control.activation-deactivation.c20", FT_BOOLEAN, 8,
8998 TFS(&mac_lte_scell_status_vals), 0x10, NULL, HFILL
9001 { &hf_mac_lte_control_activation_deactivation_c19,
9002 { "SCell Index 19 Status",
9003 "mac-lte.control.activation-deactivation.c19", FT_BOOLEAN, 8,
9004 TFS(&mac_lte_scell_status_vals), 0x08, NULL, HFILL
9007 { &hf_mac_lte_control_activation_deactivation_c18,
9008 { "SCell Index 18 Status",
9009 "mac-lte.control.activation-deactivation.c18", FT_BOOLEAN, 8,
9010 TFS(&mac_lte_scell_status_vals), 0x04, NULL, HFILL
9013 { &hf_mac_lte_control_activation_deactivation_c17,
9014 { "SCell Index 17 Status",
9015 "mac-lte.control.activation-deactivation.c17", FT_BOOLEAN, 8,
9016 TFS(&mac_lte_scell_status_vals), 0x02, NULL, HFILL
9019 { &hf_mac_lte_control_activation_deactivation_c16,
9020 { "SCell Index 16 Status",
9021 "mac-lte.control.activation-deactivation.c16", FT_BOOLEAN, 8,
9022 TFS(&mac_lte_scell_status_vals), 0x01, NULL, HFILL
9025 { &hf_mac_lte_control_activation_deactivation_c31,
9026 { "SCell Index 31 Status",
9027 "mac-lte.control.activation-deactivation.c31", FT_BOOLEAN, 8,
9028 TFS(&mac_lte_scell_status_vals), 0x80, NULL, HFILL
9031 { &hf_mac_lte_control_activation_deactivation_c30,
9032 { "SCell Index 30 Status",
9033 "mac-lte.control.activation-deactivation.c30", FT_BOOLEAN, 8,
9034 TFS(&mac_lte_scell_status_vals), 0x40, NULL, HFILL
9037 { &hf_mac_lte_control_activation_deactivation_c29,
9038 { "SCell Index 29 Status",
9039 "mac-lte.control.activation-deactivation.c29", FT_BOOLEAN, 8,
9040 TFS(&mac_lte_scell_status_vals), 0x20, NULL, HFILL
9043 { &hf_mac_lte_control_activation_deactivation_c28,
9044 { "SCell Index 28 Status",
9045 "mac-lte.control.activation-deactivation.c28", FT_BOOLEAN, 8,
9046 TFS(&mac_lte_scell_status_vals), 0x10, NULL, HFILL
9049 { &hf_mac_lte_control_activation_deactivation_c27,
9050 { "SCell Index 27 Status",
9051 "mac-lte.control.activation-deactivation.c27", FT_BOOLEAN, 8,
9052 TFS(&mac_lte_scell_status_vals), 0x08, NULL, HFILL
9055 { &hf_mac_lte_control_activation_deactivation_c26,
9056 { "SCell Index 26 Status",
9057 "mac-lte.control.activation-deactivation.c26", FT_BOOLEAN, 8,
9058 TFS(&mac_lte_scell_status_vals), 0x04, NULL, HFILL
9061 { &hf_mac_lte_control_activation_deactivation_c25,
9062 { "SCell Index 25 Status",
9063 "mac-lte.control.activation-deactivation.c25", FT_BOOLEAN, 8,
9064 TFS(&mac_lte_scell_status_vals), 0x02, NULL, HFILL
9067 { &hf_mac_lte_control_activation_deactivation_c24,
9068 { "SCell Index 24 Status",
9069 "mac-lte.control.activation-deactivation.c24", FT_BOOLEAN, 8,
9070 TFS(&mac_lte_scell_status_vals), 0x01, NULL, HFILL
9074 { &hf_mac_lte_control_mch_scheduling_info,
9075 { "MCH Scheduling Information",
9076 "mac-lte.control.mch_scheduling_info", FT_STRING, BASE_NONE, NULL, 0x0,
9080 { &hf_mac_lte_control_mch_scheduling_info_lcid,
9082 "mac-lte.control.mch_scheduling_info.lcid", FT_UINT8, BASE_HEX, VALS(mch_lcid_vals), 0xf8,
9083 "Logical Channel ID of the MTCH", HFILL
9086 { &hf_mac_lte_control_mch_scheduling_info_stop_mtch,
9088 "mac-lte.control.mch_scheduling_info.stop_mtch", FT_UINT16, BASE_DEC, NULL, 0x07ff,
9089 "Ordinal number of the subframe where the corresponding MTCH stops", HFILL
9093 { &hf_mac_lte_control_sidelink_bsr,
9095 "mac-lte.control.sidelink-bsr", FT_STRING, BASE_NONE, NULL, 0x0,
9099 { &hf_mac_lte_control_sidelink_bsr_destination_idx_odd,
9100 { "Destination Index",
9101 "mac-lte.control.sidelink-bsr.destination-idx", FT_UINT8, BASE_DEC, NULL, 0xf0,
9105 { &hf_mac_lte_control_sidelink_bsr_lcg_id_odd,
9106 { "Logical Channel Group ID",
9107 "mac-lte.control.sidelink-bsr.lcg-id", FT_UINT8, BASE_DEC, NULL, 0x0c,
9111 { &hf_mac_lte_control_sidelink_bsr_buffer_size_odd,
9113 "mac-lte.control.sidelink-bsr.buffer-size", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x03f0,
9114 "Buffer Size available in all channels in group", HFILL
9117 { &hf_mac_lte_control_sidelink_bsr_destination_idx_even,
9118 { "Destination Index",
9119 "mac-lte.control.sidelink-bsr.destination-idx", FT_UINT8, BASE_DEC, NULL, 0x0f,
9123 { &hf_mac_lte_control_sidelink_bsr_lcg_id_even,
9124 { "Logical Channel Group ID",
9125 "mac-lte.control.sidelink-bsr.lcg-id", FT_UINT8, BASE_DEC, NULL, 0xc0,
9129 { &hf_mac_lte_control_sidelink_bsr_buffer_size_even,
9131 "mac-lte.control.sidelink-bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
9132 "Buffer Size available in all channels in group", HFILL
9135 { &hf_mac_lte_control_sidelink_reserved,
9137 "mac-lte.control.sidelink-bsr.reserved", FT_UINT8, BASE_DEC,
9138 NULL, 0x0f, "Reserved bits, should be 0", HFILL
9142 { &hf_mac_lte_control_data_vol_power_headroom,
9143 { "Data Volume and Power Headroom Report",
9144 "mac-lte.control.data-vol-power-headroom", FT_STRING, BASE_NONE, NULL, 0x0,
9148 { &hf_mac_lte_control_data_vol_power_headroom_reserved,
9150 "mac-lte.control.data-vol-power-headroom.reserved", FT_UINT8, BASE_DEC,
9151 NULL, 0xc0, "Reserved bits, should be 0", HFILL
9154 { &hf_mac_lte_control_data_vol_power_headroom_level,
9155 { "Power Headroom Level",
9156 "mac-lte.control.data-vol-power-headroom.level", FT_UINT8, BASE_DEC,
9157 VALS(data_vol_power_headroom_level_vals), 0x30, NULL, HFILL
9160 { &hf_mac_lte_control_data_vol_power_headroom_data_vol,
9162 "mac-lte.control.data-vol-power-headroom.data-vol", FT_UINT8, BASE_DEC,
9163 VALS(data_vol_power_headroom_data_vol_vals), 0x0f, NULL, HFILL
9167 { &hf_mac_lte_control_recommended_bit_rate,
9168 { "Recommended Bit Rate",
9169 "mac-lte.control.recommended-bit-rate", FT_STRING, BASE_NONE,
9170 NULL, 0x0, NULL, HFILL
9173 { &hf_mac_lte_control_recommended_bit_rate_lcid,
9175 "mac-lte.control.recommended-bit-rate.lcid", FT_UINT8, BASE_DEC,
9176 NULL, 0xf0, NULL, HFILL
9179 { &hf_mac_lte_control_recommended_bit_rate_dir,
9181 "mac-lte.control.recommended-bit-rate.dir", FT_BOOLEAN, 8,
9182 TFS(&tfs_uplink_downlink), 0x08, NULL, HFILL
9185 { &hf_mac_lte_control_recommended_bit_rate_bit_rate,
9187 "mac-lte.control.recommended-bit-rate.bit-rate", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
9188 &bit_rate_vals_ext, 0x07e0, NULL, HFILL
9191 { &hf_mac_lte_control_recommended_bit_rate_reserved,
9193 "mac-lte.control.recommended-bit-rate.reserved", FT_UINT8, BASE_HEX,
9194 NULL, 0x1f, "Reserved bits, should be 0", HFILL
9198 { &hf_mac_lte_control_recommended_bit_rate_query,
9199 { "Recommended Bit Rate Query",
9200 "mac-lte.control.recommended-bit-rate-query", FT_STRING, BASE_NONE,
9201 NULL, 0x0, NULL, HFILL
9204 { &hf_mac_lte_control_recommended_bit_rate_query_lcid,
9206 "mac-lte.control.recommended-bit-rate-query.lcid", FT_UINT8, BASE_DEC,
9207 NULL, 0xf0, NULL, HFILL
9210 { &hf_mac_lte_control_recommended_bit_rate_query_dir,
9212 "mac-lte.control.recommended-bit-rate-query.dir", FT_BOOLEAN, 8,
9213 TFS(&tfs_uplink_downlink), 0x08, NULL, HFILL
9216 { &hf_mac_lte_control_recommended_bit_rate_query_bit_rate,
9218 "mac-lte.control.recommended-bit-rate-query.bit-rate", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
9219 &bit_rate_vals_ext, 0x07e0, NULL, HFILL
9222 { &hf_mac_lte_control_recommended_bit_rate_query_reserved,
9224 "mac-lte.control.recommended-bit-rate-query.reserved", FT_UINT8, BASE_HEX,
9225 NULL, 0x1f, "Reserved bits, should be 0", HFILL
9229 { &hf_mac_lte_control_activation_deactivation_csi_rs,
9230 { "Activation/Deactivation of CSI-RS",
9231 "mac-lte.control.activation-deactivation-csi-rs", FT_STRING, BASE_NONE,
9232 NULL, 0x0, NULL, HFILL
9235 { &hf_mac_lte_control_activation_deactivation_csi_rs_a8,
9236 { "CSI-RS Resource Index 8",
9237 "mac-lte.control.activation-deactivation-csi-rs.a8", FT_BOOLEAN, 8,
9238 TFS(&tfs_activated_deactivated), 0x80, NULL, HFILL
9241 { &hf_mac_lte_control_activation_deactivation_csi_rs_a7,
9242 { "CSI-RS Resource Index 7",
9243 "mac-lte.control.activation-deactivation-csi-rs.a7", FT_BOOLEAN, 8,
9244 TFS(&tfs_activated_deactivated), 0x40, NULL, HFILL
9247 { &hf_mac_lte_control_activation_deactivation_csi_rs_a6,
9248 { "CSI-RS Resource Index 6",
9249 "mac-lte.control.activation-deactivation-csi-rs.a6", FT_BOOLEAN, 8,
9250 TFS(&tfs_activated_deactivated), 0x20, NULL, HFILL
9253 { &hf_mac_lte_control_activation_deactivation_csi_rs_a5,
9254 { "CSI-RS Resource Index 5",
9255 "mac-lte.control.activation-deactivation-csi-rs.a5", FT_BOOLEAN, 8,
9256 TFS(&tfs_activated_deactivated), 0x10, NULL, HFILL
9259 { &hf_mac_lte_control_activation_deactivation_csi_rs_a4,
9260 { "CSI-RS Resource Index 4",
9261 "mac-lte.control.activation-deactivation-csi-rs.a4", FT_BOOLEAN, 8,
9262 TFS(&tfs_activated_deactivated), 0x08, NULL, HFILL
9265 { &hf_mac_lte_control_activation_deactivation_csi_rs_a3,
9266 { "CSI-RS Resource Index 3",
9267 "mac-lte.control.activation-deactivation-csi-rs.a3", FT_BOOLEAN, 8,
9268 TFS(&tfs_activated_deactivated), 0x04, NULL, HFILL
9271 { &hf_mac_lte_control_activation_deactivation_csi_rs_a2,
9272 { "CSI-RS Resource Index 2",
9273 "mac-lte.control.activation-deactivation-csi-rs.a2", FT_BOOLEAN, 8,
9274 TFS(&tfs_activated_deactivated), 0x02, NULL, HFILL
9277 { &hf_mac_lte_control_activation_deactivation_csi_rs_a1,
9278 { "CSI-RS Resource Index 1",
9279 "mac-lte.control.activation-deactivation-csi-rs.a1", FT_BOOLEAN, 8,
9280 TFS(&tfs_activated_deactivated), 0x01, NULL, HFILL
9284 /* Generated fields */
9285 { &hf_mac_lte_dl_harq_resend_original_frame,
9286 { "Frame with previous tx",
9287 "mac-lte.dlsch.retx.original-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV), 0x0,
9291 { &hf_mac_lte_dl_harq_resend_time_since_previous_frame,
9292 { "Time since previous tx (ms)",
9293 "mac-lte.dlsch.retx.time-since-previous", FT_UINT16, BASE_DEC, NULL, 0x0,
9297 { &hf_mac_lte_dl_harq_resend_next_frame,
9298 { "Frame with next tx",
9299 "mac-lte.dlsch.retx.next-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_NEXT), 0x0,
9303 { &hf_mac_lte_dl_harq_resend_time_until_next_frame,
9304 { "Time until next tx (ms)",
9305 "mac-lte.dlsch.retx.time-until-next", FT_UINT16, BASE_DEC, NULL, 0x0,
9310 { &hf_mac_lte_ul_harq_resend_original_frame,
9311 { "Frame with previous tx",
9312 "mac-lte.ulsch.retx.original-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_PREV), 0x0,
9316 { &hf_mac_lte_ul_harq_resend_time_since_previous_frame,
9317 { "Time since previous tx (ms)",
9318 "mac-lte.ulsch.retx.time-since-previous", FT_UINT16, BASE_DEC, NULL, 0x0,
9322 { &hf_mac_lte_ul_harq_resend_next_frame,
9323 { "Frame with next tx",
9324 "mac-lte.ulsch.retx.next-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RETRANS_NEXT), 0x0,
9328 { &hf_mac_lte_ul_harq_resend_time_until_next_frame,
9329 { "Time until next tx (ms)",
9330 "mac-lte.ulsch.retx.time-until-next", FT_UINT16, BASE_DEC, NULL, 0x0,
9335 { &hf_mac_lte_grant_answering_sr,
9336 { "First Grant Following SR from",
9337 "mac-lte.ulsch.grant-answering-sr", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
9341 { &hf_mac_lte_failure_answering_sr,
9342 { "SR which failed",
9343 "mac-lte.ulsch.failure-answering-sr", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
9347 { &hf_mac_lte_sr_leading_to_failure,
9349 "mac-lte.ulsch.failure-answering-sr-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
9353 { &hf_mac_lte_sr_leading_to_grant,
9354 { "This SR results in a grant here",
9355 "mac-lte.ulsch.grant-answering-sr-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
9359 { &hf_mac_lte_sr_time_since_request,
9360 { "Time since SR (ms)",
9361 "mac-lte.ulsch.time-since-sr", FT_UINT32, BASE_DEC, NULL, 0x0,
9365 { &hf_mac_lte_sr_time_until_answer,
9366 { "Time until answer (ms)",
9367 "mac-lte.ulsch.time-until-sr-answer", FT_UINT32, BASE_DEC, NULL, 0x0,
9372 { &hf_mac_lte_drx_config,
9373 { "DRX Configuration",
9374 "mac-lte.drx-config", FT_STRING, BASE_NONE,
9375 NULL, 0x0, NULL, HFILL
9378 { &hf_mac_lte_drx_config_frame_num,
9380 "mac-lte.drx-config.config-frame", FT_FRAMENUM, BASE_NONE,
9381 NULL, 0x0, NULL, HFILL
9384 { &hf_mac_lte_drx_config_previous_frame_num,
9385 { "Previous Config Frame",
9386 "mac-lte.drx-config.previous-config-frame", FT_FRAMENUM, BASE_NONE,
9387 NULL, 0x0, NULL, HFILL
9390 { &hf_mac_lte_drx_config_long_cycle,
9392 "mac-lte.drx-config.long-cycle", FT_UINT16, BASE_DEC,
9393 NULL, 0x0, NULL, HFILL
9396 { &hf_mac_lte_drx_config_cycle_offset,
9398 "mac-lte.drx-config.cycle-offset", FT_UINT16, BASE_DEC,
9399 NULL, 0x0, NULL, HFILL
9402 { &hf_mac_lte_drx_config_onduration_timer,
9403 { "OnDuration Timer",
9404 "mac-lte.drx-config.onduration-timer", FT_UINT16, BASE_DEC,
9405 NULL, 0x0, NULL, HFILL
9408 { &hf_mac_lte_drx_config_inactivity_timer,
9409 { "Inactivity Timer",
9410 "mac-lte.drx-config.inactivity-timer", FT_UINT16, BASE_DEC,
9411 NULL, 0x0, NULL, HFILL
9414 { &hf_mac_lte_drx_config_retransmission_timer,
9415 { "Retransmission Timer",
9416 "mac-lte.drx-config.retransmission-timer", FT_UINT16, BASE_DEC,
9417 NULL, 0x0, NULL, HFILL
9420 { &hf_mac_lte_drx_config_short_cycle,
9422 "mac-lte.drx-config.short-cycle", FT_UINT16, BASE_DEC,
9423 NULL, 0x0, NULL, HFILL
9426 { &hf_mac_lte_drx_config_short_cycle_timer,
9427 { "Short cycle Timer",
9428 "mac-lte.drx-config.short-cycle-timer", FT_UINT16, BASE_DEC,
9429 NULL, 0x0, NULL, HFILL
9433 { &hf_mac_lte_drx_state,
9435 "mac-lte.drx-state", FT_STRING, BASE_NONE,
9436 NULL, 0x0, NULL, HFILL
9439 { &hf_mac_lte_drx_state_long_cycle_offset,
9440 { "Long cycle offset",
9441 "mac-lte.drx-state.long-cycle-offset", FT_UINT16, BASE_DEC,
9442 NULL, 0x0, NULL, HFILL
9445 { &hf_mac_lte_drx_state_short_cycle_offset,
9446 { "Short cycle offset",
9447 "mac-lte.drx-state.short-cycle-offset", FT_UINT16, BASE_DEC,
9448 NULL, 0x0, NULL, HFILL
9451 { &hf_mac_lte_drx_state_inactivity_remaining,
9452 { "Inactivity remaining",
9453 "mac-lte.drx-state.inactivity-remaining", FT_UINT16, BASE_DEC,
9454 NULL, 0x0, NULL, HFILL
9457 { &hf_mac_lte_drx_state_onduration_remaining,
9458 { "Onduration remaining",
9459 "mac-lte.drx-state.onduration-remaining", FT_UINT16, BASE_DEC,
9460 NULL, 0x0, NULL, HFILL
9463 { &hf_mac_lte_drx_state_retransmission_remaining,
9464 { "Retransmission remaining",
9465 "mac-lte.drx-state.retransmission-remaining", FT_UINT16, BASE_DEC,
9466 NULL, 0x0, NULL, HFILL
9469 { &hf_mac_lte_drx_state_rtt_remaining,
9471 "mac-lte.drx-state.rtt-remaining", FT_UINT16, BASE_DEC,
9472 NULL, 0x0, NULL, HFILL
9475 { &hf_mac_lte_drx_state_short_cycle_remaining,
9476 { "Short-cycle timer remaining",
9477 "mac-lte.drx-state.short-cycle-remaining", FT_UINT16, BASE_DEC,
9478 NULL, 0x0, NULL, HFILL
9483 static gint *ett[] =
9486 &ett_mac_lte_context,
9487 &ett_mac_lte_phy_context,
9488 &ett_mac_lte_rar_headers,
9489 &ett_mac_lte_rar_header,
9490 &ett_mac_lte_rar_body,
9491 &ett_mac_lte_rar_ul_grant,
9492 &ett_mac_lte_ulsch_header,
9493 &ett_mac_lte_dlsch_header,
9494 &ett_mac_lte_mch_header,
9495 &ett_mac_lte_sch_subheader,
9496 &ett_mac_lte_mch_subheader,
9497 &ett_mac_lte_slsch_header,
9498 &ett_mac_lte_slsch_subheader,
9502 &ett_mac_lte_activation_deactivation,
9503 &ett_mac_lte_contention_resolution,
9504 &ett_mac_lte_timing_advance,
9505 &ett_mac_lte_power_headroom,
9506 &ett_mac_lte_dual_conn_power_headroom,
9507 &ett_mac_lte_dual_conn_power_headroom_cell,
9508 &ett_mac_lte_extended_power_headroom,
9509 &ett_mac_lte_extended_power_headroom_cell,
9510 &ett_mac_lte_mch_scheduling_info,
9512 &ett_mac_lte_drx_config,
9513 &ett_mac_lte_drx_state,
9514 &ett_mac_lte_sidelink_bsr,
9515 &ett_mac_lte_data_vol_power_headroom,
9516 &ett_mac_lte_recommended_bit_rate,
9517 &ett_mac_lte_recommended_bit_rate_query,
9518 &ett_mac_lte_activation_deactivation_csi_rs
9521 static ei_register_info ei[] = {
9522 { &ei_mac_lte_reserved_not_zero, { "mac-lte.reserved-not-zero", PI_MALFORMED, PI_ERROR, "Reserved bit not zero", EXPFILL }},
9523 { &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 }},
9524 { &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 }},
9525 { &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 }},
9526 { &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 }},
9527 { &ei_mac_lte_bch_pdu, { "mac-lte.bch.pdu.uplink", PI_MALFORMED, PI_ERROR, "BCH data should not be received in Uplink!", EXPFILL }},
9528 { &ei_mac_lte_pch_pdu, { "mac-lte.pch.pdu.uplink", PI_MALFORMED, PI_ERROR, "PCH data should not be received in Uplink!", EXPFILL }},
9529 { &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 }},
9530 { &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 }},
9531 { &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 }},
9532 { &ei_mac_lte_sr_invalid_event, { "mac-lte.ulsch.sr-invalid-event", PI_SEQUENCE, PI_ERROR, "Invalid SR event for UE", EXPFILL }},
9533 { &ei_mac_lte_dlsch_lcid, { "mac-lte.dlsch.lcid.DRX-received", PI_SEQUENCE, PI_NOTE, "DRX command received for UE", EXPFILL }},
9534 { &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 }},
9535 { &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 }},
9536 { &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 }},
9537 { &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 }},
9538 { &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 }},
9539 { &ei_mac_lte_lcid_unexpected, { "mac-lte.lcid-unexpected", PI_MALFORMED, PI_ERROR, "?L-SCH: Unexpected LCID received", EXPFILL }},
9540 { &ei_mac_lte_too_many_subheaders, { "mac-lte.too-many-subheaders", PI_MALFORMED, PI_ERROR, "Reached too many subheaders - frame obviously malformed", EXPFILL }},
9541 { &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 }},
9542 { &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 }},
9543 { &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 }},
9544 { &ei_mac_lte_control_element_size_invalid, { "mac-lte.control-element.size-invalid", PI_MALFORMED, PI_ERROR, "Control Element has an unexpected size", EXPFILL }},
9545 { &ei_mac_lte_bsr_warn_threshold_exceeded, { "mac-lte.bsr-warn-threshold-exceeded", PI_SEQUENCE, PI_WARN, "BSR for LCG X exceeds threshold", EXPFILL }},
9546 { &ei_mac_lte_sch_header_only_truncated, { "mac-lte.sch.header-only-truncated", PI_SEQUENCE, PI_NOTE, "MAC PDU SDUs have been omitted", EXPFILL }},
9547 { &ei_mac_lte_mch_header_only_truncated, { "mac-lte.mch.header-only-truncated", PI_SEQUENCE, PI_NOTE, "MAC PDU SDUs have been omitted", EXPFILL }},
9548 { &ei_mac_lte_slsch_header_only_truncated, { "mac-lte.slsch.header-only-truncated", PI_SEQUENCE, PI_NOTE, "MAC PDU SDUs have been omitted", EXPFILL }},
9549 { &ei_mac_lte_context_length, { "mac-lte.length.invalid", PI_MALFORMED, PI_ERROR, "MAC PDU is longer than reported length", EXPFILL }},
9550 { &ei_mac_lte_rach_preamble_sent_warn, { "mac-lte.rach-preamble-sent", PI_SEQUENCE, PI_WARN, "RACH Preamble sent", EXPFILL }},
9551 { &ei_mac_lte_rach_preamble_sent_note, { "mac-lte.rach-preamble-sent", PI_SEQUENCE, PI_NOTE, "RACH Preamble sent", EXPFILL }},
9552 { &ei_mac_lte_oob_send_sr, { "mac-lte.sr-req", PI_SEQUENCE, PI_NOTE, "Scheduling Request sent", EXPFILL }},
9553 { &ei_mac_lte_oob_sr_failure, { "mac-lte.sr-failure", PI_SEQUENCE, PI_ERROR, "Scheduling Request failed", EXPFILL }},
9554 { &ei_mac_lte_context_sysframe_number, { "mac-lte.sfn.out-of-range", PI_MALFORMED, PI_ERROR, "Sysframe number out of range", EXPFILL }},
9555 { &ei_mac_lte_context_rnti_type, { "mac-lte.rnti-type.invalid", PI_MALFORMED, PI_ERROR, "RNTI indicated, but value is not correct", EXPFILL }},
9556 { &ei_mac_lte_ul_mac_frame_retx, { "mac-lte.ul-mac-frame-retx", PI_SEQUENCE, PI_WARN, "UL MAC frame ReTX", EXPFILL }},
9557 { &ei_mac_lte_context_crc_status, { "mac-lte.crc-status.error", PI_MALFORMED, PI_ERROR, "Frame has CRC error problem", EXPFILL }},
9558 { &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 }},
9559 { &ei_mac_lte_sch_invalid_length, { "mac-lte.sch.invalid-length", PI_MALFORMED, PI_WARN, "Invalid PDU length (should be >= 32768)", EXPFILL }},
9560 { &ei_mac_lte_mch_invalid_length, { "mac-lte.mch.invalid-length", PI_MALFORMED, PI_WARN, "Invalid PDU length (should be >= 32768)", EXPFILL }},
9561 { &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 }},
9562 { &ei_mac_lte_unknown_udp_framing_tag, { "mac-lte.unknown-udp-framing-tag", PI_UNDECODED, PI_WARN, "Unknown UDP framing tag, aborting dissection", EXPFILL }}
9565 static const enum_val_t show_info_col_vals[] = {
9566 {"show-phy", "PHY Info", ShowPHYLayer},
9567 {"show-mac", "MAC Info", ShowMACLayer},
9568 {"show-rlc", "RLC Info", ShowRLCLayer},
9572 static const enum_val_t lcid_drb_source_vals[] = {
9573 {"from-static-stable", "From static table", FromStaticTable},
9574 {"from-configuration-protocol", "From configuration protocol", FromConfigurationProtocol},
9579 module_t *mac_lte_module;
9580 expert_module_t* expert_mac_lte;
9582 static uat_field_t lcid_drb_mapping_flds[] = {
9583 UAT_FLD_VS(lcid_drb_mappings, lcid, "lcid", drb_lcid_vals, "The MAC LCID"),
9584 UAT_FLD_DEC(lcid_drb_mappings, drbid,"drb id (1-32)", "Identifier of logical data channel"),
9585 UAT_FLD_VS(lcid_drb_mappings, channel_type, "RLC Channel Type", rlc_channel_type_vals, "The MAC LCID"),
9589 /* Register protocol. */
9590 proto_mac_lte = proto_register_protocol("MAC-LTE", "MAC-LTE", "mac-lte");
9591 proto_register_field_array(proto_mac_lte, hf, array_length(hf));
9592 proto_register_subtree_array(ett, array_length(ett));
9593 expert_mac_lte = expert_register_protocol(proto_mac_lte);
9594 expert_register_field_array(expert_mac_lte, ei, array_length(ei));
9596 /* Allow other dissectors to find this one by name. */
9597 register_dissector("mac-lte", dissect_mac_lte, proto_mac_lte);
9599 /* Register the tap name */
9600 mac_lte_tap = register_tap("mac-lte");
9603 mac_lte_module = prefs_register_protocol(proto_mac_lte, NULL);
9605 /* Obsolete preferences */
9606 prefs_register_obsolete_preference(mac_lte_module, "single_rar");
9607 prefs_register_obsolete_preference(mac_lte_module, "check_reserved_bits");
9608 prefs_register_obsolete_preference(mac_lte_module, "decode_rar_ul_grant");
9609 prefs_register_obsolete_preference(mac_lte_module, "show_rlc_info_column");
9610 prefs_register_obsolete_preference(mac_lte_module, "attempt_to_detect_dl_harq_resend");
9611 prefs_register_obsolete_preference(mac_lte_module, "attempt_to_track_ul_harq_resend");
9613 prefs_register_uint_preference(mac_lte_module, "retx_count_warn",
9614 "Number of Re-Transmits before expert warning triggered",
9615 "Number of Re-Transmits before expert warning triggered",
9616 10, &global_mac_lte_retx_counter_trigger);
9618 prefs_register_bool_preference(mac_lte_module, "attempt_rrc_decode",
9619 "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
9620 "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
9621 &global_mac_lte_attempt_rrc_decode);
9623 prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_crc_failures",
9624 "Dissect frames that have failed CRC check",
9625 "Attempt to dissect frames that have failed CRC check",
9626 &global_mac_lte_dissect_crc_failures);
9628 prefs_register_obsolete_preference(mac_lte_module, "heuristic_mac_lte_over_udp");
9630 prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_srb_sdus",
9631 "Attempt to dissect LCID 1&2 as srb1&2",
9632 "Will call LTE RLC dissector with standard settings as per RRC spec",
9633 &global_mac_lte_attempt_srb_decode);
9635 prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_mcch",
9636 "Attempt to dissect MCH LCID 0 as MCCH",
9637 "Will call LTE RLC dissector for MCH LCID 0",
9638 &global_mac_lte_attempt_mcch_decode);
9640 prefs_register_bool_preference(mac_lte_module, "call_rlc_for_mtch",
9641 "Call RLC dissector MTCH LCIDs",
9642 "Call RLC dissector MTCH LCIDs",
9643 &global_mac_lte_call_rlc_for_mtch);
9645 prefs_register_enum_preference(mac_lte_module, "lcid_to_drb_mapping_source",
9646 "Source of LCID -> drb channel settings",
9647 "Set whether LCID -> drb Table is taken from static table (below) or from "
9648 "info learned from control protocol (e.g. RRC)",
9649 &global_mac_lte_lcid_drb_source, lcid_drb_source_vals, FALSE);
9651 lcid_drb_mappings_uat = uat_new("Static LCID -> drb Table",
9652 sizeof(lcid_drb_mapping_t),
9656 &num_lcid_drb_mappings,
9657 UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
9658 "", /* TODO: is this ref to help manual? */
9659 lcid_drb_mapping_copy_cb,
9664 lcid_drb_mapping_flds );
9666 prefs_register_uat_preference(mac_lte_module,
9668 "LCID -> DRB Mappings Table",
9669 "A table that maps from configurable lcids -> RLC logical channels",
9670 lcid_drb_mappings_uat);
9672 prefs_register_uint_preference(mac_lte_module, "bsr_warn_threshold",
9673 "BSR size when warning should be issued (0 - 63)",
9674 "If any BSR report is >= this number, an expert warning will be added",
9675 10, &global_mac_lte_bsr_warn_threshold);
9677 prefs_register_bool_preference(mac_lte_module, "track_sr",
9678 "Track status of SRs within UEs",
9679 "Track status of SRs, providing links between requests, failure indications and grants",
9680 &global_mac_lte_track_sr);
9682 prefs_register_enum_preference(mac_lte_module, "layer_to_show",
9683 "Which layer info to show in Info column",
9684 "Can show PHY, MAC or RLC layer info in Info column",
9685 &global_mac_lte_layer_to_show, show_info_col_vals, FALSE);
9687 prefs_register_bool_preference(mac_lte_module, "decode_cr_body",
9688 "Decode CR body as UL CCCH",
9689 "Attempt to decode 6 bytes of Contention Resolution body as an UL CCCH PDU",
9690 &global_mac_lte_decode_cr_body);
9692 prefs_register_bool_preference(mac_lte_module, "show_drx",
9693 "Show DRX Information (Incomplete/experimental!)",
9694 "Apply DRX config and show DRX state within each UE",
9695 &global_mac_lte_show_drx);
9697 prefs_register_bool_preference(mac_lte_module, "show_bsr_median",
9698 "Show BSR Median value",
9699 "Add as a generated field the middle of the range indicated by the BSR index",
9700 &global_mac_lte_show_BSR_median);
9702 register_init_routine(&mac_lte_init_protocol);
9703 register_cleanup_routine(&mac_lte_cleanup_protocol);
9706 void proto_reg_handoff_mac_lte(void)
9708 /* Add as a heuristic UDP dissector */
9709 heur_dissector_add("udp", dissect_mac_lte_heur, "MAC-LTE over UDP", "mac_lte_udp", proto_mac_lte, HEURISTIC_DISABLE);
9711 rlc_lte_handle = find_dissector_add_dependency("rlc-lte", proto_mac_lte);
9712 lte_rrc_bcch_dl_sch_handle = find_dissector_add_dependency("lte_rrc.bcch_dl_sch", proto_mac_lte);
9713 lte_rrc_bcch_dl_sch_br_handle = find_dissector_add_dependency("lte_rrc.bcch_dl_sch_br", proto_mac_lte);
9714 lte_rrc_bcch_dl_sch_nb_handle = find_dissector_add_dependency("lte_rrc.bcch_dl_sch.nb", proto_mac_lte);
9715 lte_rrc_bcch_bch_handle = find_dissector_add_dependency("lte_rrc.bcch_bch", proto_mac_lte);
9716 lte_rrc_bcch_bch_nb_handle = find_dissector_add_dependency("lte_rrc.bcch_bch.nb", proto_mac_lte);
9717 lte_rrc_pcch_handle = find_dissector_add_dependency("lte_rrc.pcch", proto_mac_lte);
9718 lte_rrc_pcch_nb_handle = find_dissector_add_dependency("lte_rrc.pcch.nb", proto_mac_lte);
9719 lte_rrc_ul_ccch_handle = find_dissector_add_dependency("lte_rrc.ul_ccch", proto_mac_lte);
9720 lte_rrc_ul_ccch_nb_handle = find_dissector_add_dependency("lte_rrc.ul_ccch.nb", proto_mac_lte);
9721 lte_rrc_dl_ccch_handle = find_dissector_add_dependency("lte_rrc.dl_ccch", proto_mac_lte);
9722 lte_rrc_dl_ccch_nb_handle = find_dissector_add_dependency("lte_rrc.dl_ccch.nb", proto_mac_lte);
9723 lte_rrc_sbcch_sl_bch_handle = find_dissector_add_dependency("lte_rrc.sbcch_sl_bch", proto_mac_lte);
9724 lte_rrc_sc_mcch_handle = find_dissector_add_dependency("lte_rrc.sc_mcch", proto_mac_lte);
9728 * Editor modelines - https://www.wireshark.org/tools/modelines.html
9733 * indent-tabs-mode: nil
9736 * vi: set shiftwidth=4 tabstop=8 expandtab:
9737 * :indentSize=4:tabSize=8:noTabs=true: