HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / epan / dissectors / packet-mac-lte.c
1 /* Routines for LTE MAC disassembly
2  *
3  * Martin Mathieson
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11
12 #include "config.h"
13
14 #include <epan/packet.h>
15 #include <epan/exceptions.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
18 #include <epan/tap.h>
19 #include <epan/uat.h>
20 #include <epan/proto_data.h>
21 #include "packet-mac-lte.h"
22 #include "packet-rlc-lte.h"
23
24 void proto_register_mac_lte(void);
25 void proto_reg_handoff_mac_lte(void);
26
27 /* Described in:
28  * 3GPP TS 36.321 Evolved Universal Terrestrial Radio Access (E-UTRA)
29  *                Medium Access Control (MAC) protocol specification v14.3.0
30  */
31
32
33 /* Initialize the protocol and registered fields. */
34 int proto_mac_lte = -1;
35
36 static int mac_lte_tap = -1;
37
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;
52
53
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;
72
73 static int hf_mac_lte_context_rapid = -1;
74 static int hf_mac_lte_context_rach_attempt_number = -1;
75
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;
79
80
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;
89
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;
101
102
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;
106
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;
119
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;
143
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;
147
148 /* Data */
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;
159
160
161 /* RAR fields */
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;
203
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;
228
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;
327
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;
332
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;
337
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;
344
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;
355
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;
366
367 /* Subtrees. */
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;
402
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;
444
445
446 /* Constants and value strings */
447
448 static const value_string radio_type_vals[] =
449 {
450     { FDD_RADIO,      "FDD"},
451     { TDD_RADIO,      "TDD"},
452     { 0, NULL }
453 };
454
455
456 static const value_string direction_vals[] =
457 {
458     { DIRECTION_UPLINK,      "Uplink"},
459     { DIRECTION_DOWNLINK,    "Downlink"},
460     { 0, NULL }
461 };
462
463
464 static const value_string rnti_type_vals[] =
465 {
466     { NO_RNTI,     "NO-RNTI"},
467     { P_RNTI,      "P-RNTI"},
468     { RA_RNTI,     "RA-RNTI"},
469     { C_RNTI,      "C-RNTI"},
470     { SI_RNTI,     "SI-RNTI"},
471     { SPS_RNTI,    "SPS-RNTI"},
472     { M_RNTI,      "M-RNTI"},
473     { SL_BCH_RNTI, "SL-BCH-RNTI"},
474     { SL_RNTI,     "SL-RNTI"},
475     { SC_RNTI,     "SC-RNTI"},
476     { G_RNTI,      "G-RNTI"},
477     { 0, NULL }
478 };
479
480 static const value_string bch_transport_channel_vals[] =
481 {
482     { SI_RNTI,      "DL-SCH"},
483     { NO_RNTI,      "BCH"},
484     { 0, NULL }
485 };
486
487 static const value_string crc_status_vals[] =
488 {
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"},
495     { 0, NULL }
496 };
497
498 static const value_string carrier_id_vals[] =
499 {
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"},
508     { 0, NULL }
509 };
510
511 static const value_string dci_format_vals[] =
512 {
513     {  0, "0"},
514     {  1, "1"},
515     {  2, "1A"},
516     {  3, "1B"},
517     {  4, "1C"},
518     {  5, "1D"},
519     {  6, "2"},
520     {  7, "2A"},
521     {  8, "3/3A"},
522     {  9, "2B"},
523     { 10, "2C"},
524     { 11, "2D"},
525     { 12, "4"},
526     { 13, "6-0A"},
527     { 14, "6-1A"},
528     { 15, "6-2"},
529     { 16, "N0"},
530     { 17, "N1"},
531     { 18, "N2"},
532     {  0, NULL }
533 };
534
535 static const value_string aggregation_level_vals[] =
536 {
537     { 0, "1"},
538     { 1, "2"},
539     { 2, "4"},
540     { 3, "8"},
541     { 4, "16"},
542     { 5, "24"},
543     { 0, NULL }
544 };
545
546 static const value_string modulation_type_vals[] =
547 {
548     { 2, "QPSK"},
549     { 4, "QAM16"},
550     { 6, "QAM64"},
551     { 0, NULL }
552 };
553
554 static const true_false_string mac_lte_scell_ph_vals = {
555     "Reported",
556     "Not reported"
557 };
558
559 static const true_false_string mac_lte_power_backoff_vals = {
560     "Applied",
561     "Not applied"
562 };
563
564 static const true_false_string mac_lte_ph_value_vals = {
565     "Based on reference format",
566     "Based on real transmission"
567 };
568
569 static const true_false_string mac_lte_scell_status_vals = {
570     "Activated",
571     "Deactivated"
572 };
573
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
585
586 static const value_string dlsch_lcid_vals[] =
587 {
588     { 0,                                      "CCCH"},
589     { 1,                                      "1"},
590     { 2,                                      "2"},
591     { 3,                                      "3"},
592     { 4,                                      "4"},
593     { 5,                                      "5"},
594     { 6,                                      "6"},
595     { 7,                                      "7"},
596     { 8,                                      "8"},
597     { 9,                                      "9"},
598     { 10,                                     "10"},
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" },
610     { 0, NULL }
611 };
612
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
624
625 static const value_string ulsch_lcid_vals[] =
626 {
627     { 0,                                    "CCCH"},
628     { 1,                                    "1"},
629     { 2,                                    "2"},
630     { 3,                                    "3"},
631     { 4,                                    "4"},
632     { 5,                                    "5"},
633     { 6,                                    "6"},
634     { 7,                                    "7"},
635     { 8,                                    "8"},
636     { 9,                                    "9"},
637     { 10,                                   "10"},
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" },
652     { 0, NULL }
653 };
654
655 #define MCH_SCHEDULING_INFO_LCID 0x1e
656
657 static const value_string mch_lcid_vals[] =
658 {
659     { 0,                            "MCCH"},
660     { 1,                            "1"},
661     { 2,                            "2"},
662     { 3,                            "3"},
663     { 4,                            "4"},
664     { 5,                            "5"},
665     { 6,                            "6"},
666     { 7,                            "7"},
667     { 8,                            "8"},
668     { 9,                            "9"},
669     { 10,                           "10"},
670     { 11,                           "11"},
671     { 12,                           "12"},
672     { 13,                           "13"},
673     { 14,                           "14"},
674     { 15,                           "15"},
675     { 16,                           "16"},
676     { 17,                           "17"},
677     { 18,                           "18"},
678     { 19,                           "19"},
679     { 20,                           "20"},
680     { 21,                           "21"},
681     { 22,                           "22"},
682     { 23,                           "23"},
683     { 24,                           "24"},
684     { 25,                           "25"},
685     { 26,                           "26"},
686     { 27,                           "27"},
687     { 28,                           "28"},
688     { MCH_SCHEDULING_INFO_LCID,     "MCH Scheduling Information"},
689     { PADDING_LCID,                 "Padding" },
690     { 0, NULL }
691 };
692
693 static const value_string slsch_lcid_vals[] =
694 {
695     { 0,            "Reserved"},
696     { 1,            "1"},
697     { 2,            "2"},
698     { 3,            "3"},
699     { 4,            "4"},
700     { 5,            "5"},
701     { 6,            "6"},
702     { 7,            "7"},
703     { 8,            "8"},
704     { 9,            "9"},
705     { 10,           "10"},
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" },
710     { 0, NULL }
711 };
712
713 static const true_false_string format_vals =
714 {
715     "Data length is >= 128 bytes",
716     "Data length is < 128 bytes"
717 };
718
719 static const true_false_string format2_vals =
720 {
721     "Data length is >= 32768 bytes",
722     "Data length is < 32768 bytes"
723 };
724
725 static const value_string rar_type_vals[] =
726 {
727     { 0,      "Backoff Indicator present"},
728     { 1,      "RAPID present"},
729     { 0, NULL }
730 };
731
732
733 static const value_string rar_bi_vals[] =
734 {
735     { 0,      "0"},
736     { 1,      "10"},
737     { 2,      "20"},
738     { 3,      "30"},
739     { 4,      "40"},
740     { 5,      "60"},
741     { 6,      "80"},
742     { 7,      "120"},
743     { 8,      "160"},
744     { 9,      "240"},
745     { 10,     "320"},
746     { 11,     "480"},
747     { 12,     "960"},
748     { 0, NULL }
749 };
750
751
752 static const value_string rar_bi_nb_vals[] =
753 {
754     { 0,      "0"},
755     { 1,      "256"},
756     { 2,      "512"},
757     { 3,      "1024"},
758     { 4,      "2048"},
759     { 5,      "4096"},
760     { 6,      "8192"},
761     { 7,      "16384"},
762     { 8,      "32768"},
763     { 9,      "65536"},
764     { 10,     "131072"},
765     { 11,     "262144"},
766     { 12,     "524288"},
767     { 0, NULL }
768 };
769
770
771 static const value_string rar_ul_grant_tcsp_vals[] =
772 {
773     { 0, "-6 dB"},
774     { 1, "-4 dB" },
775     { 2, "-2 dB" },
776     { 3, "0 dB" },
777     { 4, "2 dB" },
778     { 5, "4 dB" },
779     { 6, "6 dB" },
780     { 7, "8 dB" },
781     { 0, NULL }
782 };
783
784
785 static const value_string rar_ul_grant_msg3_pusch_nb_idx_ce_mode_b_vals[] =
786 {
787     { 0, "NBrar mod Nnb"},
788     { 1, "(NBrar+1) mod Nnb"},
789     { 2, "(NBrar+2) mod Nnb"},
790     { 3, "(NBrar+3) mod Nnb"},
791     { 0, NULL}
792 };
793
794
795 static const value_string rar_ul_grant_msg3_msg4_mpdcch_nb_idx_vals[] =
796 {
797     { 0, "NBrar mod Nnb2"},
798     { 1, "(NBrar+1) mod Nnb2"},
799     { 2, "(NBrar+2) mod Nnb2"},
800     { 3, "(NBrar+3) mod Nnb2"},
801     { 0, NULL}
802 };
803
804
805 static const value_string rar_ul_grant_nb_rep_msg3_pusch_ce_mode_a_vals[] =
806 {
807     { 0, "Ya/8"},
808     { 1, "Ya/4"},
809     { 2, "Ya/2"},
810     { 3, "Ya"},
811     { 0, NULL}
812 };
813
814
815 static const value_string rar_ul_grant_nb_rep_msg3_pusch_ce_mode_b_vals[] =
816 {
817     { 0, "Yb/128"},
818     { 1, "Yb/64"},
819     { 2, "Yb/32"},
820     { 3, "Yb/16"},
821     { 4, "Yb/8"},
822     { 5, "Yb/4"},
823     { 6, "Yb/2"},
824     { 7, "Yb"},
825     { 0, NULL}
826 };
827
828
829 static const true_false_string ul_subcarrier_spacing_val =
830 {
831     "15 kHz",
832     "3.75 kHz"
833 };
834
835
836 static const value_string scheduling_delay_vals[]=
837 {
838     { 0, "k0 = 8"},
839     { 1, "k0 = 16"},
840     { 2, "k0 = 32"},
841     { 3, "k0 = 64"},
842     { 0, NULL}
843 };
844
845
846 static const value_string msg3_rep_nb_vals[] =
847 {
848     { 0, "1"},
849     { 1, "2"},
850     { 2, "4"},
851     { 3, "8"},
852     { 4, "16"},
853     { 5, "32"},
854     { 6, "64"},
855     { 7, "128"},
856     { 0, NULL}
857 };
858
859
860 static const value_string buffer_size_vals[] =
861 {
862     { 0,      "BS = 0"},
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"},
926     { 0, NULL }
927 };
928 static value_string_ext buffer_size_vals_ext = VALUE_STRING_EXT_INIT(buffer_size_vals);
929
930 static guint32 buffer_size_median[64] = {
931     0,  /* BS = 0 */
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 */
995 };
996
997 static const value_string ext_buffer_size_vals[] =
998 {
999     { 0,      "BS = 0"},
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"},
1063     { 0, NULL }
1064 };
1065 static value_string_ext ext_buffer_size_vals_ext = VALUE_STRING_EXT_INIT(ext_buffer_size_vals);
1066
1067 static guint32 ext_buffer_size_median[64] = {
1068     0,  /* BS = 0 */
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 */
1132 };
1133
1134 static const value_string power_headroom_vals[] =
1135 {
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"},
1199     { 63,     "PH >= 40"},
1200     { 0, NULL }
1201 };
1202 static value_string_ext power_headroom_vals_ext = VALUE_STRING_EXT_INIT(power_headroom_vals);
1203
1204 static const value_string pcmaxc_vals[] =
1205 {
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"},
1270     { 0, NULL }
1271 };
1272 static value_string_ext pcmaxc_vals_ext = VALUE_STRING_EXT_INIT(pcmaxc_vals);
1273
1274 static const value_string data_vol_power_headroom_level_vals[] =
1275 {
1276     { 0, "POWER_HEADROOM_0"},
1277     { 1, "POWER_HEADROOM_1"},
1278     { 2, "POWER_HEADROOM_2"},
1279     { 3, "POWER_HEADROOM_3"},
1280     { 0, NULL }
1281 };
1282
1283 static const value_string data_vol_power_headroom_data_vol_vals[] =
1284 {
1285     { 0,  "DV = 0"},
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"},
1300     { 15, "DV > 1500"},
1301     { 0, NULL }
1302 };
1303
1304 static const value_string bit_rate_vals[] =
1305 {
1306     { 0, "no bit rate recommendation"},
1307     { 1, "0 kbit/s"},
1308     { 2, "8 kbit/s"},
1309     { 3, "10 kbit/s"},
1310     { 4, "12 kbit/s"},
1311     { 5, "16 kbit/s"},
1312     { 6, "20 kbit/s"},
1313     { 7, "24 kbit/s"},
1314     { 8, "28 kbit/s"},
1315     { 9, "32 kbit/s"},
1316     { 10, "36 kbit/s"},
1317     { 11, "40 kbit/s"},
1318     { 12, "48 kbit/s"},
1319     { 13, "56 kbit/s"},
1320     { 14, "72 kbit/s"},
1321     { 15, "88 kbit/s"},
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"},
1363     { 0, NULL }
1364 };
1365 static value_string_ext bit_rate_vals_ext = VALUE_STRING_EXT_INIT(bit_rate_vals);
1366
1367 static const value_string header_only_vals[] =
1368 {
1369     { 0,      "MAC PDU Headers and body present"},
1370     { 1,      "MAC PDU Headers only"},
1371     { 0, NULL }
1372 };
1373
1374 static const value_string predefined_frame_vals[] =
1375 {
1376     { 0,      "Real MAC PDU present - will dissect"},
1377     { 1,      "Predefined frame present - will not dissect"},
1378     { 0, NULL }
1379 };
1380
1381 static const value_string ul_retx_grant_vals[] =
1382 {
1383     { 0,      "PDCCH ReTx"},
1384     { 1,      "PHICH NACK"},
1385     { 0, NULL }
1386 };
1387
1388 /**************************************************************************/
1389 /* Preferences state                                                      */
1390 /**************************************************************************/
1391
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;
1395
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;
1398
1399 /* Whether should attempt to dissect frames failing CRC check */
1400 static gboolean global_mac_lte_dissect_crc_failures = FALSE;
1401
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;
1404
1405 /* Whether should attempt to decode MCH LCID 0 as MCCH */
1406 static gboolean global_mac_lte_attempt_mcch_decode = FALSE;
1407
1408 /* Whether should call RLC dissector to decode MTCH LCIDs */
1409 static gboolean global_mac_lte_call_rlc_for_mtch = FALSE;
1410
1411 /* Where to take LCID -> DRB mappings from */
1412 enum lcid_drb_source {
1413     FromStaticTable, FromConfigurationProtocol
1414 };
1415 static gint global_mac_lte_lcid_drb_source = (gint)FromStaticTable;
1416
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 */
1419
1420 /* Whether or not to track SRs and related frames */
1421 static gboolean global_mac_lte_track_sr = TRUE;
1422
1423 /* Which layer info to show in the info column */
1424 enum layer_to_show {
1425     ShowPHYLayer, ShowMACLayer, ShowRLCLayer
1426 };
1427
1428 /* Which layer's details to show in Info column */
1429 static gint     global_mac_lte_layer_to_show = (gint)ShowRLCLayer;
1430
1431 /* Whether to decode Contention Resolution body as UL CCCH */
1432 static gboolean global_mac_lte_decode_cr_body = FALSE;
1433
1434 /* Whether to record config and try to show DRX state for each configured UE */
1435 static gboolean global_mac_lte_show_drx = FALSE;
1436
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;
1439
1440
1441 /* When showing RLC info, count PDUs so can append info column properly */
1442 static guint8   s_number_of_rlc_pdus_shown = 0;
1443
1444 /***********************************************************************/
1445 /* How to dissect lcid 3-10 (presume drb logical channels)             */
1446
1447 static const value_string drb_lcid_vals[] = {
1448     { 3,  "LCID 3"},
1449     { 4,  "LCID 4"},
1450     { 5,  "LCID 5"},
1451     { 6,  "LCID 6"},
1452     { 7,  "LCID 7"},
1453     { 8,  "LCID 8"},
1454     { 9,  "LCID 9"},
1455     { 10, "LCID 10"},
1456     { 0, NULL }
1457 };
1458
1459 typedef enum rlc_channel_type_t {
1460     rlcRaw,
1461     rlcTM,
1462     rlcUM5,
1463     rlcUM10,
1464     rlcAM,
1465     rlcAMulExtLiField,
1466     rlcAMdlExtLiField,
1467     rlcAMextLiField,
1468     rlcAMul16,
1469     rlcAMdl16,
1470     rlcAM16,
1471     rlcAMul16ulExtLiField,
1472     rlcAMdl16ulExtLiField,
1473     rlcAM16ulExtLiField,
1474     rlcAMul16dlExtLiField,
1475     rlcAMdl16dlExtLiField,
1476     rlcAM16dlExtLiField,
1477     rlcAMul16extLiField,
1478     rlcAMdl16extLiField,
1479     rlcAM16extLiField,
1480 } rlc_channel_type_t;
1481
1482 static const value_string rlc_channel_type_vals[] = {
1483     { rlcTM                , "TM"},
1484     { rlcUM5               , "UM, SN Len=5"},
1485     { rlcUM10              , "UM, SN Len=10"},
1486     { rlcAM                , "AM"},
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"},
1502     { 0, NULL }
1503 };
1504
1505
1506 /* Mapping type */
1507 typedef struct lcid_drb_mapping_t {
1508     guint16 lcid;
1509     gint    drbid;
1510     rlc_channel_type_t channel_type;
1511 } lcid_drb_mapping_t;
1512
1513 /* Mapping entity */
1514 static lcid_drb_mapping_t *lcid_drb_mappings = NULL;
1515 static guint num_lcid_drb_mappings = 0;
1516
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")
1520
1521 /* UAT object */
1522 static uat_t* lcid_drb_mappings_uat;
1523
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 {
1527     gboolean valid;
1528     gint     drbid;
1529     rlc_channel_type_t channel_type;
1530     guint8   ul_priority;
1531 } dynamic_lcid_drb_mapping_t;
1532
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;
1537
1538 static GHashTable *mac_lte_ue_channels_hash = NULL;
1539
1540
1541 extern int proto_rlc_lte;
1542
1543 /***************************************************************/
1544
1545
1546
1547 /***************************************************************/
1548 /* Keeping track of Msg3 bodies so they can be compared with   */
1549 /* Contention Resolution bodies.                               */
1550
1551 typedef struct Msg3Data {
1552     guint8   data[6];
1553     nstime_t msg3Time;
1554     guint32  framenum;
1555 } Msg3Data;
1556
1557
1558 /* This table stores (RNTI -> Msg3Data*).  Will be populated when
1559    Msg3 frames are first read.  */
1560 static GHashTable *mac_lte_msg3_hash = NULL;
1561
1562 typedef enum ContentionResolutionStatus {
1563     NoMsg3,
1564     Msg3Match,
1565     Msg3NoMatch
1566 } ContentionResolutionStatus;
1567
1568 typedef struct ContentionResolutionResult {
1569     ContentionResolutionStatus status;
1570     guint                      msg3FrameNum;
1571     guint                      msSinceMsg3;
1572 } ContentionResolutionResult;
1573
1574
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;
1578
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;
1582
1583 /**************************************************************************/
1584
1585
1586
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   */
1591 /* being logged!                                                */
1592
1593 /* Could be bigger, but more than enough to flag suspected resends */
1594 #define MAX_EXPECTED_PDU_LENGTH 2048
1595
1596 typedef struct LastFrameData {
1597     gboolean inUse;
1598     guint32  framenum;
1599     gboolean ndi;
1600     nstime_t received_time;
1601     gint     length;
1602     guint8   data[MAX_EXPECTED_PDU_LENGTH];
1603 } LastFrameData;
1604
1605 typedef struct DLHarqBuffers {
1606     LastFrameData harqid[2][15];  /* 2 blocks (1 for each antenna) needed for DL */
1607 } DLHarqBuffers;
1608
1609
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;
1613
1614 typedef struct DLHARQResult {
1615     gboolean    previousSet, nextSet;
1616     guint       previousFrameNum;
1617     guint       timeSincePreviousFrame;
1618     guint       nextFrameNum;
1619     guint       timeToNextFrame;
1620 } DLHARQResult;
1621
1622
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;
1626
1627 /**************************************************************************/
1628
1629
1630 /*****************************************************************/
1631 /* Keeping track of last UL frames per C-RNTI so can verify when */
1632 /* told that a frame is a retx                                   */
1633
1634 typedef struct ULHarqBuffers {
1635     LastFrameData harqid[8];
1636 } ULHarqBuffers;
1637
1638
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;
1642
1643 typedef struct ULHARQResult {
1644     gboolean    previousSet, nextSet;
1645     guint       previousFrameNum;
1646     guint       timeSincePreviousFrame;
1647     guint       nextFrameNum;
1648     guint       timeToNextFrame;
1649 } ULHARQResult;
1650
1651
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;
1656
1657 /**************************************************************************/
1658
1659
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                                                   */
1666
1667 typedef enum SREvent {
1668     SR_Grant,
1669     SR_Request,
1670     SR_Failure
1671 } SREvent;
1672
1673 static const value_string sr_event_vals[] =
1674 {
1675     { SR_Grant,        "Grant"},
1676     { SR_Request,      "SR Request"},
1677     { SR_Failure,      "SR Failure"},
1678     { 0,               NULL}
1679 };
1680
1681 typedef enum SRStatus {
1682     None,
1683     SR_Outstanding,
1684     SR_Failed
1685 } SRStatus;
1686
1687 static const value_string sr_status_vals[] =
1688 {
1689     { None,                "Receiving grants"},
1690     { SR_Outstanding,      "SR Request outstanding"},
1691     { SR_Failed,           "SR has Failed"},
1692     { 0,                   NULL}
1693 };
1694
1695
1696 typedef struct SRState {
1697     SRStatus status;
1698     guint32  lastSRFramenum;
1699     guint32  lastGrantFramenum;
1700     nstime_t requestTime;
1701 } SRState;
1702
1703
1704 /* This table keeps track of the SR state for each UE.
1705    (RNTI -> SRState) */
1706 static GHashTable *mac_lte_ue_sr_state = NULL;
1707
1708
1709 typedef enum SRResultType {
1710     GrantAnsweringSR,
1711     FailureAnsweringSR,
1712     SRLeadingToGrant,
1713     SRLeadingToFailure,
1714     InvalidSREvent
1715 } SRResultType;
1716
1717
1718 typedef struct SRResult {
1719     SRResultType type;
1720     guint32      frameNum;
1721     guint32      timeDifference;
1722
1723     /* These 2 are only used with InvalidSREvent */
1724     SRStatus     status;
1725     SREvent      event;
1726 } SRResult;
1727
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;
1731
1732 /**************************************************************************/
1733
1734
1735 typedef struct drx_running_state_t
1736 {
1737     gboolean     firstCycleStartSet;
1738
1739     /* Cycle information */
1740     gboolean     inShortCycle;
1741
1742     /* Timers */
1743     nstime_t     currentTime;  /* absolute time of last PDU. Used to detect whole
1744                                   missing SFN cycle */
1745
1746     guint64      currentTicks;
1747     guint16      currentSFN;
1748     guint16      currentSF;
1749
1750     /* These timers are absolute times when these events expire */
1751     guint64      onDurationTimer;
1752     guint64      inactivityTimer;
1753     guint64      RTT[8];
1754     guint64      retransmissionTimer[8];
1755     guint64      shortCycleTimer;
1756
1757 } drx_running_state_t;
1758
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;
1765 } drx_state_t;
1766
1767 typedef struct ue_parameters_t
1768 {
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;
1774 } ue_parameters_t;
1775
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;
1779
1780
1781 /**************************************************************************/
1782 /* DRX State                                                              */
1783 /* Config for current cycle/timer state for a configured UE               */
1784
1785
1786 typedef struct drx_state_key_t {
1787     guint32 frameNumber;
1788     guint   pdu_instance;
1789 } drx_state_key_t;
1790
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;
1794
1795 static gint mac_lte_framenum_instance_hash_equal(gconstpointer v, gconstpointer v2)
1796 {
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;
1799
1800     return ((p1->frameNumber == p2->frameNumber) &&
1801             (p1->pdu_instance == p2->pdu_instance));
1802 }
1803
1804 static guint mac_lte_framenum_instance_hash_func(gconstpointer v)
1805 {
1806     const drx_state_key_t *p1 = (const drx_state_key_t*)v;
1807
1808     return p1->frameNumber + (p1->pdu_instance >> 8);
1809 }
1810
1811
1812
1813
1814 /* Initialise the UE DRX state */
1815 static void init_drx_ue_state(drx_state_t *drx_state, gboolean at_init)
1816 {
1817     int i;
1818     drx_state->state_before.inShortCycle = FALSE;
1819     if (at_init) {
1820         drx_state->state_before.onDurationTimer = G_GUINT64_CONSTANT(0);
1821     }
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);
1826     }
1827     drx_state->state_before.shortCycleTimer = G_GUINT64_CONSTANT(0);
1828 }
1829
1830 typedef enum drx_timer_type_t {
1831     drx_onduration_timer,
1832     drx_inactivity_timer,
1833     drx_rtt_timer,
1834     drx_retx_timer,
1835     drx_short_cycle_timer
1836 } drx_timer_type_t;
1837
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)
1840 {
1841     /* Get current time in ms */
1842     guint64 *pTimer;
1843     guint16 timerLength;
1844
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;
1850             break;
1851         case drx_inactivity_timer:
1852             pTimer = &(p_state->state_before.inactivityTimer);
1853             timerLength = p_state->config.inactivityTimer;
1854             break;
1855         case drx_rtt_timer:
1856             pTimer = &(p_state->state_before.RTT[timer_id]);
1857             timerLength = 8;
1858             break;
1859         case drx_retx_timer:
1860             pTimer = &(p_state->state_before.retransmissionTimer[timer_id]);
1861             timerLength = p_state->config.retransmissionTimer;
1862             break;
1863         case drx_short_cycle_timer:
1864         default:
1865             pTimer = &(p_state->state_before.shortCycleTimer);
1866             timerLength = p_state->config.shortCycle * p_state->config.shortCycleTimer;
1867             break;
1868     }
1869
1870     /* Set timer */
1871     *pTimer = p_state->state_before.currentTicks + timerLength;
1872 }
1873
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)
1876 {
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);
1881             break;
1882         case drx_inactivity_timer:
1883             p_state->state_before.inactivityTimer = G_GUINT64_CONSTANT(0);
1884             break;
1885         case drx_rtt_timer:
1886             p_state->state_before.RTT[timer_id] = G_GUINT64_CONSTANT(0);
1887             break;
1888         case drx_retx_timer:
1889             p_state->state_before.retransmissionTimer[timer_id] = G_GUINT64_CONSTANT(0);
1890             break;
1891         case drx_short_cycle_timer:
1892             p_state->state_before.shortCycleTimer = G_GUINT64_CONSTANT(0);
1893             break;
1894     }
1895 }
1896
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)
1901 {
1902     guint64 *pTimer = NULL;
1903     drx_running_state_t *state_to_use;
1904
1905     if (before_event) {
1906         state_to_use = &p_state->state_before;
1907     }
1908     else {
1909         state_to_use = &p_state->state_after;
1910     }
1911
1912
1913     /* Get pointer to timer value */
1914     switch (timer_type) {
1915         case drx_onduration_timer:
1916             pTimer = &(state_to_use->onDurationTimer);
1917             break;
1918         case drx_inactivity_timer:
1919             pTimer = &(state_to_use->inactivityTimer);
1920             break;
1921         case drx_rtt_timer:
1922             pTimer = &(state_to_use->RTT[timer_id]);
1923             break;
1924         case drx_retx_timer:
1925             pTimer = &(state_to_use->retransmissionTimer[timer_id]);
1926             break;
1927         case drx_short_cycle_timer:
1928             pTimer = &(state_to_use->shortCycleTimer);
1929             break;
1930
1931         default:
1932             return FALSE;
1933     }
1934
1935     /* TODO: verify using SFN/SF ? */
1936     if (state_to_use->currentTicks == *pTimer) {
1937         *time_until_expires = 0;
1938         return TRUE;
1939     }
1940
1941     if (state_to_use->currentTicks > *pTimer) {
1942         *time_until_expires = 0;
1943     }
1944     else {
1945         *time_until_expires = *pTimer - state_to_use->currentTicks;
1946     }
1947
1948     return FALSE;
1949 }
1950
1951
1952 /* Handling of triggers that can prompt changes in state */
1953
1954 static void mac_lte_drx_new_ulsch_data(guint16 ueid)
1955 {
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));
1959
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);
1963     }
1964 }
1965
1966 static void mac_lte_drx_new_dlsch_data(guint16 ueid)
1967 {
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));
1971
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);
1975     }
1976 }
1977
1978 static void mac_lte_drx_dl_crc_error(guint16 ueid)
1979 {
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));
1983
1984     /* Start timer */
1985     if ((ue_params != NULL) && ue_params->drx_state_valid) {
1986         mac_lte_drx_start_timer(&ue_params->drx_state, drx_retx_timer, 0);
1987     }
1988 }
1989
1990 /* A DRX control element has been received */
1991 static void mac_lte_drx_control_element_received(guint16 ueid)
1992 {
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));
1996
1997     /* Start timers */
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);
2001     }
2002 }
2003
2004
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)
2008 {
2009     int harq_id;
2010     guint64 time_until_expires;
2011
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));
2015
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;
2021
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;
2027
2028             ue_state->state_before.currentTicks = SFN*10 + SF;
2029
2030             ue_state->state_before.firstCycleStartSet = TRUE;
2031         }
2032
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. */
2037
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);
2041         }
2042
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;
2045
2046             /* Check for timers that have expired and change state accordingly */
2047
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;
2052                 }
2053             }
2054
2055             /* See if onDuration timer should be started */
2056
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);
2060                 }
2061             }
2062             else {
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);
2065                 }
2066             }
2067
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);
2074                 }
2075             }
2076
2077             /* Reception of DRX command is dealt with separately at the moment... */
2078
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);
2084                 }
2085             }
2086
2087
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;
2093                 }
2094                 else {
2095                     ue_state->state_before.currentSFN++;
2096                 }
2097             }
2098             else {
2099                 ue_state->state_before.currentSF++;
2100             }
2101
2102             ue_state->state_before.currentTicks++;
2103         }
2104
2105         /* Set current time to now */
2106         ue_state->state_before.currentTime = pinfo->abs_ts;
2107     }
2108 }
2109
2110 /* Convenience function to get a pointer for the hash_func to work with */
2111 static gpointer get_drx_result_hash_key(guint32 frameNumber,
2112                                         guint pdu_instance,
2113                                         gboolean do_persist)
2114 {
2115     static drx_state_key_t key;
2116     drx_state_key_t *p_key;
2117
2118     /* Only allocate a struct when will be adding entry */
2119     if (do_persist) {
2120         p_key = wmem_new0(wmem_file_scope(), drx_state_key_t);
2121     }
2122     else {
2123         memset(&key, 0, sizeof(drx_state_key_t));
2124         p_key = &key;
2125     }
2126
2127     /* Fill in details, and return pointer */
2128     p_key->frameNumber = frameNumber;
2129     p_key->pdu_instance = pdu_instance;
2130
2131     return p_key;
2132 }
2133
2134
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)
2138 {
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;
2143
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 */
2147         if (before_event) {
2148             /* Copy UE snapshot for this frame, and add to result table */
2149             frame_result = wmem_new(wmem_file_scope(), drx_state_t);
2150
2151             /* Deep-copy this snapshot for this frame */
2152             *frame_result = ue_params->drx_state;
2153
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);
2156         }
2157         else {
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;
2164             }
2165         }
2166     }
2167 }
2168
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)
2172 {
2173     drx_state_t         *frame_state;
2174     drx_running_state_t *state_to_show;
2175     guint64             time_until_expires;
2176     guint               n;
2177
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));
2181
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;
2186
2187         /* Show config only if 'before */
2188         if (before_event) {
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);
2195
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);
2200
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);
2207             }
2208
2209             /* Config fields */
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);
2225
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);
2230
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);
2234             }
2235
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);
2242             }
2243         }
2244
2245         /*************************************/
2246         /* Create state subtree              */
2247         drx_state_ti = proto_tree_add_string_format(tree, hf_mac_lte_drx_state,
2248                                                     tvb, 0, 0, "",
2249                                                     (before_event) ? "DRX State Before" : "DRX State After");
2250         /* Get appropriate state pointer to use below */
2251         if (before_event) {
2252             state_to_show = &frame_state->state_before;
2253         }
2254         else {
2255             state_to_show = &frame_state->state_after;
2256         }
2257
2258         drx_state_tree = proto_item_add_subtree(drx_state_ti, ett_mac_lte_drx_state);
2259         proto_item_set_generated(drx_state_ti);
2260
2261         /* Show cycle information */
2262
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);
2270         }
2271         else {
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;
2275
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);
2279
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);
2286                 }
2287             }
2288         }
2289
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! */
2294
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);
2301             }
2302         }
2303
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);
2310             }
2311         }
2312
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);
2321                 }
2322             }
2323         }
2324
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);
2333                 }
2334             }
2335         }
2336     }
2337 }
2338
2339
2340 /**************************************************************************/
2341
2342
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;
2347
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)
2351 {
2352     if (!s_rapid_ranges_configured) {
2353         return "";
2354     }
2355     else {
2356         if (rapid < s_rapid_ranges_groupA) {
2357             return "[GroupA]";
2358         }
2359         else if (rapid < s_rapid_ranges_RA) {
2360             return "[GroupB]";
2361         }
2362         else {
2363             return "[Non-RA]";
2364         }
2365     }
2366 }
2367
2368 /**************************************************************************/
2369 /* Tracking of extended BSR sizes configuration                           */
2370
2371 static void
2372 get_mac_lte_ue_ext_bsr_sizes(mac_lte_info *p_mac_lte_info)
2373 {
2374     gpointer p_orig_key, p_ue_params;
2375
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;
2382     }
2383 }
2384
2385 /**************************************************************************/
2386 /* Tracking of simultaneous PUCCH/PUSCH configuration                     */
2387
2388 static void
2389 get_mac_lte_ue_simult_pucch_pusch(mac_lte_info *p_mac_lte_info)
2390 {
2391     gpointer p_orig_key, p_ue_params;
2392
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;
2400     }
2401 }
2402
2403 /* Forward declarations */
2404 int dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*);
2405
2406 static guint8 get_mac_lte_channel_priority(guint16 ueid _U_, guint8 lcid,
2407                                            guint8 direction);
2408
2409
2410 static void
2411 call_with_catch_all(dissector_handle_t handle, tvbuff_t* tvb, packet_info *pinfo, proto_tree *tree)
2412 {
2413     /* Call it (catch exceptions so that stats will be updated) */
2414     if (handle) {
2415         TRY {
2416             call_dissector_only(handle, tvb, pinfo, tree, NULL);
2417         }
2418         CATCH_ALL {
2419         }
2420         ENDTRY
2421     }
2422 }
2423
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)
2428 {
2429     gint    offset = *p_offset;
2430     guint8  tag = 0;
2431
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++);
2435
2436     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2437         p_mac_lte_info->detailed_phy_info.ul_info.present = FALSE;
2438     }
2439     else {
2440         p_mac_lte_info->detailed_phy_info.dl_info.present = FALSE;
2441     }
2442
2443     p_mac_lte_info->rntiType = tvb_get_guint8(tvb, offset++);
2444
2445     p_mac_lte_info->sfnSfInfoPresent = FALSE; /* Set this to true later if the relative tag is read */
2446
2447     /* Initialize RNTI with a default value in case optional field is not present */
2448     switch (p_mac_lte_info->rntiType) {
2449         case SC_RNTI:
2450             p_mac_lte_info->rnti = 0xFFFB;
2451             break;
2452         case M_RNTI:
2453             p_mac_lte_info->rnti = 0xFFFD;
2454             break;
2455         case P_RNTI:
2456             p_mac_lte_info->rnti = 0xFFFE;
2457             break;
2458         case SI_RNTI:
2459             p_mac_lte_info->rnti = 0xFFFF;
2460             break;
2461         case RA_RNTI:
2462         case C_RNTI:
2463         case SPS_RNTI:
2464         case SL_RNTI:
2465         case G_RNTI:
2466             p_mac_lte_info->rnti = 0x0001;
2467             break;
2468         default:
2469             break;
2470     }
2471
2472     /* Read optional fields */
2473     while (tag != MAC_LTE_PAYLOAD_TAG) {
2474         /* Process next tag */
2475         tag = tvb_get_guint8(tvb, offset++);
2476         switch (tag) {
2477             case MAC_LTE_RNTI_TAG:
2478                 p_mac_lte_info->rnti = tvb_get_ntohs(tvb, offset);
2479                 offset += 2;
2480                 break;
2481             case MAC_LTE_UEID_TAG:
2482                 p_mac_lte_info->ueid = tvb_get_ntohs(tvb, offset);
2483                 offset += 2;
2484                 break;
2485             case MAC_LTE_FRAME_SUBFRAME_TAG:
2486                 {
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;
2491                     offset += 2;
2492                 }
2493                 break;
2494             case MAC_LTE_PREDEFINED_DATA_TAG:
2495                 p_mac_lte_info->isPredefinedData = tvb_get_guint8(tvb, offset);
2496                 offset++;
2497                 break;
2498             case MAC_LTE_RETX_TAG:
2499                 p_mac_lte_info->reTxCount = tvb_get_guint8(tvb, offset);
2500                 offset++;
2501                 break;
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);
2506                 offset++;
2507                 break;
2508             case MAC_LTE_EXT_BSR_SIZES_TAG:
2509                 p_mac_lte_info->isExtendedBSRSizes = TRUE;
2510                 break;
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);
2514                 offset++;
2515                 p_mac_lte_info->rach_attempt_number = tvb_get_guint8(tvb, offset);
2516                 offset++;
2517                 break;
2518             case MAC_LTE_CARRIER_ID_TAG:
2519                 p_mac_lte_info->carrierId =
2520                     (mac_lte_carrier_id)tvb_get_guint8(tvb, offset);
2521                 offset++;
2522                 break;
2523             case MAC_LTE_PHY_TAG:
2524                 {
2525                     gint len, offset1;
2526
2527                     len = tvb_get_guint8(tvb, offset++);
2528                     offset1 = offset;
2529                     if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
2530                         if (len < 10)
2531                             goto next;
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);
2535                         offset++;
2536                         p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type =
2537                             tvb_get_guint8(tvb, offset);
2538                         offset++;
2539                         p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level =
2540                             tvb_get_guint8(tvb, offset);
2541                         offset++;
2542                         p_mac_lte_info->detailed_phy_info.dl_info.mcs_index =
2543                             tvb_get_guint8(tvb, offset);
2544                         offset++;
2545                         p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index =
2546                             tvb_get_guint8(tvb, offset);
2547                         offset++;
2548                         p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length =
2549                             tvb_get_guint8(tvb, offset);
2550                         offset++;
2551                         p_mac_lte_info->detailed_phy_info.dl_info.harq_id =
2552                             tvb_get_guint8(tvb, offset);
2553                         offset++;
2554                         p_mac_lte_info->detailed_phy_info.dl_info.ndi =
2555                             tvb_get_guint8(tvb, offset);
2556                         offset++;
2557                         p_mac_lte_info->detailed_phy_info.dl_info.transport_block =
2558                             tvb_get_guint8(tvb, offset);
2559                         offset++;
2560                         p_mac_lte_info->dl_retx =
2561                             (mac_lte_dl_retx)tvb_get_guint8(tvb, offset);
2562                     } else {
2563                         if (len < 6)
2564                             goto next;
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);
2568                         offset++;
2569                         p_mac_lte_info->detailed_phy_info.ul_info.tbs_index =
2570                             tvb_get_guint8(tvb, offset);
2571                         offset++;
2572                         p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length =
2573                             tvb_get_guint8(tvb, offset);
2574                         offset++;
2575                         p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start =
2576                             tvb_get_guint8(tvb, offset);
2577                         offset++;
2578                         p_mac_lte_info->detailed_phy_info.ul_info.harq_id =
2579                             tvb_get_guint8(tvb, offset);
2580                         offset++;
2581                         p_mac_lte_info->detailed_phy_info.ul_info.ndi =
2582                             tvb_get_guint8(tvb, offset);
2583                     }
2584                 next:
2585                     offset = offset1 + len;
2586                 }
2587                 break;
2588             case MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG:
2589                 p_mac_lte_info->isSimultPUCCHPUSCHPCell = TRUE;
2590                 break;
2591             case MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG:
2592                 p_mac_lte_info->isSimultPUCCHPUSCHPSCell = TRUE;
2593                 break;
2594             case MAC_LTE_CE_MODE_TAG:
2595                 p_mac_lte_info->ceMode =
2596                     (mac_lte_ce_mode)tvb_get_guint8(tvb, offset);
2597                 offset++;
2598                 break;
2599             case MAC_LTE_NB_MODE_TAG:
2600                 p_mac_lte_info->nbMode =
2601                     (mac_lte_nb_mode)tvb_get_guint8(tvb, offset);
2602                 offset++;
2603                 break;
2604             case MAC_LTE_N_UL_RB_TAG:
2605                 {
2606                     guint8 nUlRb = tvb_get_guint8(tvb, offset);
2607                     offset++;
2608                     switch (nUlRb) {
2609                         case 6:
2610                         case 15:
2611                         case 25:
2612                         case 50:
2613                         case 75:
2614                         case 100:
2615                             p_mac_lte_info->nUlRb = nUlRb;
2616                             break;
2617                         default:
2618                             break;
2619                     }
2620                 }
2621                 break;
2622                 case MAC_LTE_SR_TAG:
2623                     {
2624                         int n;
2625                         // Read number of entries.
2626                         guint16 no_entries = tvb_get_ntohs(tvb, offset);
2627                         offset += 2;
2628                         if ((no_entries == 0) || (no_entries > MAX_SRs)) {
2629                             return FALSE;
2630                         }
2631                         else {
2632                             p_mac_lte_info->oob_event = ltemac_send_sr;
2633                             p_mac_lte_info->number_of_srs = no_entries;
2634                         }
2635
2636                         // Read each entry.
2637                         for (n=0; n < no_entries; n++) {
2638                             p_mac_lte_info->oob_ueid[n] = tvb_get_ntohs(tvb, offset);
2639                             offset += 2;
2640                             p_mac_lte_info->oob_rnti[n] = tvb_get_ntohs(tvb, offset);
2641                             offset += 2;
2642                         }
2643                     }
2644                     break;
2645
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);
2650                 continue;
2651
2652             default:
2653                 /* It must be a recognised tag */
2654                 {
2655                     proto_item *ti;
2656                     proto_tree *subtree;
2657
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,
2663                                           tvb, offset-1, 1);
2664                 }
2665                 wmem_free(wmem_file_scope(), p_mac_lte_info);
2666                 return FALSE;
2667         }
2668     }
2669
2670     /* Pass out where offset is now */
2671     *p_offset = offset;
2672
2673     return TRUE;
2674 }
2675
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_)
2679 {
2680     gint                 offset = 0;
2681     struct mac_lte_info  *p_mac_lte_info;
2682     tvbuff_t             *mac_tvb;
2683
2684     /* Needs to be at least as long as:
2685        - the signature string
2686        - fixed header bytes
2687        - tag for data
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)) {
2690         return FALSE;
2691     }
2692
2693     /* OK, compare with signature string */
2694     if (tvb_strneql(tvb, offset, MAC_LTE_START_STRING, strlen(MAC_LTE_START_STRING)) != 0) {
2695         return FALSE;
2696     }
2697     offset += (gint)strlen(MAC_LTE_START_STRING);
2698
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)) {
2706             return TRUE;
2707         }
2708         /* Store info in packet */
2709         p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info);
2710     }
2711     else {
2712         offset = tvb_reported_length(tvb) - p_mac_lte_info->length;
2713     }
2714
2715     /**************************************/
2716     /* OK, now dissect as MAC LTE         */
2717
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);
2721
2722     return TRUE;
2723 }
2724
2725
2726 /* Write the given formatted text to:
2727    - the info column (if pinfo != NULL)
2728    - 1 or 2 other labels (optional)
2729 */
2730 static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
2731                                      packet_info *pinfo, const char *format, ...)
2732 {
2733     #define MAX_INFO_BUFFER 256
2734     static char info_buffer[MAX_INFO_BUFFER];
2735     va_list ap;
2736
2737     if ((ti1 == NULL) && (ti2 == NULL) && (pinfo == NULL)) {
2738         return;
2739     }
2740
2741     va_start(ap, format);
2742     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
2743     va_end(ap);
2744
2745     /* Add to indicated places */
2746     if (pinfo != NULL) {
2747         col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2748     }
2749     if (ti1 != NULL) {
2750         proto_item_append_text(ti1, "%s", info_buffer);
2751     }
2752     if (ti2 != NULL) {
2753         proto_item_append_text(ti2, "%s", info_buffer);
2754     }
2755 }
2756
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)
2760 {
2761     if ((ti1 == NULL) && (ti2 == NULL) && (pinfo == NULL)) {
2762         return;
2763     }
2764
2765     /* Add to indicated places */
2766     if (pinfo != NULL) {
2767         col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
2768     }
2769     if (ti1 != NULL) {
2770         proto_item_append_text(ti1, "%s", info_buffer);
2771     }
2772     if (ti2 != NULL) {
2773         proto_item_append_text(ti2, "%s", info_buffer);
2774     }
2775 }
2776
2777
2778
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)
2782 {
2783     proto_item *phy_ti;
2784     proto_tree *phy_tree;
2785     proto_item *ti;
2786
2787     if (global_mac_lte_layer_to_show == ShowPHYLayer) {
2788         /* Clear the info column */
2789         col_clear(pinfo->cinfo, COL_INFO);
2790     }
2791
2792     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2793         if (p_mac_lte_info->detailed_phy_info.ul_info.present) {
2794
2795             /* Create root */
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);
2800
2801             /* Add items */
2802             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_modulation_type,
2803                                      tvb, 0, 0,
2804                                      p_mac_lte_info->detailed_phy_info.ul_info.modulation_type);
2805             proto_item_set_generated(ti);
2806
2807             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_tbs_index,
2808                                      tvb, 0, 0,
2809                                      p_mac_lte_info->detailed_phy_info.ul_info.tbs_index);
2810             proto_item_set_generated(ti);
2811
2812             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_length,
2813                                      tvb, 0, 0,
2814                                      p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length);
2815             proto_item_set_generated(ti);
2816
2817             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_start,
2818                                      tvb, 0, 0,
2819                                      p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start);
2820             proto_item_set_generated(ti);
2821
2822             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_harq_id,
2823                                      tvb, 0, 0,
2824                                      p_mac_lte_info->detailed_phy_info.ul_info.harq_id);
2825             proto_item_set_generated(ti);
2826
2827             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_ndi,
2828                                      tvb, 0, 0,
2829                                      p_mac_lte_info->detailed_phy_info.ul_info.ndi);
2830             proto_item_set_generated(ti);
2831
2832
2833             proto_item_append_text(phy_ti, " (");
2834
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);
2845
2846             proto_item_append_text(phy_ti, ")");
2847
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);
2851             }
2852         }
2853     }
2854     else {
2855         if (p_mac_lte_info->detailed_phy_info.dl_info.present) {
2856
2857             /* Create root */
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);
2862
2863             /* Add items */
2864             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_dci_format,
2865                                      tvb, 0, 0,
2866                                      p_mac_lte_info->detailed_phy_info.dl_info.dci_format);
2867             proto_item_set_generated(ti);
2868
2869             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_allocation_type,
2870                                      tvb, 0, 0,
2871                                      p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type);
2872             proto_item_set_generated(ti);
2873
2874             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_aggregation_level,
2875                                      tvb, 0, 0,
2876                                      p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level);
2877             proto_item_set_generated(ti);
2878
2879             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_mcs_index,
2880                                      tvb, 0, 0,
2881                                      p_mac_lte_info->detailed_phy_info.dl_info.mcs_index);
2882             proto_item_set_generated(ti);
2883
2884             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_redundancy_version_index,
2885                                      tvb, 0, 0,
2886                                      p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index);
2887             proto_item_set_generated(ti);
2888
2889             ti = proto_tree_add_boolean(phy_tree, hf_mac_lte_context_phy_dl_retx,
2890                                         tvb, 0, 0,
2891                                         p_mac_lte_info->dl_retx);
2892             proto_item_set_generated(ti);
2893
2894             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_block_length,
2895                                      tvb, 0, 0,
2896                                      p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length);
2897             proto_item_set_generated(ti);
2898
2899             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_harq_id,
2900                                      tvb, 0, 0,
2901                                      p_mac_lte_info->detailed_phy_info.dl_info.harq_id);
2902             proto_item_set_generated(ti);
2903
2904             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_ndi,
2905                                      tvb, 0, 0,
2906                                      p_mac_lte_info->detailed_phy_info.dl_info.ndi);
2907             proto_item_set_generated(ti);
2908
2909             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_tb,
2910                                      tvb, 0, 0,
2911                                      p_mac_lte_info->detailed_phy_info.dl_info.transport_block);
2912             proto_item_set_generated(ti);
2913
2914
2915             proto_item_append_text(phy_ti, " (");
2916
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, ")");
2934
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);
2938             }
2939         }
2940     }
2941 }
2942
2943
2944 /* Dissect a single Random Access Response body */
2945 static gint dissect_rar_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2946                               proto_item *pdu_ti,
2947                               gint offset, guint8 rapid, mac_lte_info *p_mac_lte_info)
2948 {
2949     guint8       reserved;
2950     guint        start_body_offset = offset;
2951     proto_item  *ti;
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;
2957     guint32      ul_grant;
2958     guint16      temp_crnti;
2959     const gchar *rapid_description;
2960     guint32      bits_offset;
2961
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);
2967
2968     /* Dissect an RAR entry */
2969
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);
2975     }
2976
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);
2984         } else {
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);
2987         }
2988     }
2989     offset++;
2990
2991     /* UL Grant */
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);
2995     } else {
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);
2998     }
2999
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);
3003
3004     if (p_mac_lte_info->nbMode == no_nb_mode) {
3005         switch (p_mac_lte_info->ceMode) {
3006             case no_ce_mode:
3007             default:
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);
3011
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);
3015
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);
3019
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);
3023
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);
3027
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);
3031
3032                 offset += 3;
3033                 break;
3034
3035             case ce_mode_a:
3036                 if (p_mac_lte_info->nUlRb == 0) {
3037                     /* UL bandwidth is unknown; do not dissect UL grant */
3038                     offset += 3;
3039                     break;
3040                 }
3041
3042                 bits_offset = (offset<<3) + 4;
3043
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);
3048                     bits_offset += 1;
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);
3052                     bits_offset += 2;
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);
3056                     bits_offset += 3;
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);
3060                     bits_offset += 4;
3061                 }
3062
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);
3066                 bits_offset += 4;
3067
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);
3071                 bits_offset += 2;
3072
3073                 /* MCS (3 bits) */
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);
3076                 bits_offset += 3;
3077
3078                 /* TPC (3 bits) */
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);
3081                 bits_offset += 3;
3082
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);
3086                 bits_offset += 1;
3087
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);
3091                 bits_offset += 1;
3092
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);
3096                 bits_offset += 2;
3097
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);
3111                 }
3112
3113                 offset += 3;
3114                 break;
3115
3116             case ce_mode_b:
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);
3120
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);
3124
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);
3128
3129                 /* TBS (2 bits) */
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);
3132
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);
3136
3137                 offset += 2;
3138                 break;
3139         }
3140     } else {
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);
3143
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);
3146
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);
3149
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);
3152
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);
3155
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);
3158
3159         offset += 3;
3160     }
3161
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);
3165     offset += 2;
3166
3167     rapid_description = get_mac_lte_rapid_description(rapid);
3168
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);
3173
3174     proto_item_set_len(rar_body_ti, offset-start_body_offset);
3175
3176     return offset;
3177 }
3178
3179
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)
3184 {
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;
3189     guint8      extension;
3190     gint        n;
3191     proto_tree *rar_headers_tree;
3192     proto_item *ti;
3193     proto_item *rar_headers_ti;
3194     proto_item *padding_length_ti;
3195     int         start_headers_offset   = offset;
3196
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);
3200
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);
3204
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);
3210
3211
3212     /***************************/
3213     /* Read the header entries */
3214     do {
3215         int start_header_offset = offset;
3216         proto_tree *rar_header_tree;
3217         proto_item *rar_header_ti;
3218         guint8 type_value;
3219         guint8 first_byte = tvb_get_guint8(tvb, offset);
3220
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);
3226
3227         /* Extension */
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);
3230
3231         /* Type */
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);
3234
3235         if (type_value == 0) {
3236             /* Backoff Indicator (BI) case */
3237
3238             guint8 reserved;
3239             proto_item *tii;
3240             proto_item *bi_ti;
3241
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);
3248             }
3249
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);
3254
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);
3258             }
3259             backoff_indicator_seen = TRUE;
3260
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 "));
3265
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);
3269             }
3270
3271         }
3272         else {
3273             /* RAPID case */
3274             /* TODO: complain if the same RAPID appears twice in same frame? */
3275             const gchar *rapid_description;
3276
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);
3279
3280             rapid_description = get_mac_lte_rapid_description(rapids[number_of_rars]);
3281
3282             proto_item_append_text(rar_header_ti, "(RAPID=%u%s)",
3283                                    rapids[number_of_rars],
3284                                    rapid_description);
3285
3286             number_of_rars++;
3287         }
3288
3289         offset++;
3290
3291         /* Finalise length of header tree selection */
3292         proto_item_set_len(rar_header_ti, offset - start_header_offset);
3293
3294     } while (extension && number_of_rars < MAX_RAR_PDUS);
3295
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 "));
3304     }
3305     else {
3306         proto_item_append_text(rar_headers_ti, ")");
3307     }
3308
3309     /* Set length for headers root */
3310     proto_item_set_len(rar_headers_ti, offset-start_headers_offset);
3311
3312
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);
3317     }
3318
3319     /* Update TAP info */
3320     tap_info->number_of_rars += number_of_rars;
3321
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);
3326     }
3327     padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
3328                                            tvb, offset, 0,
3329                                            p_mac_lte_info->length - offset);
3330     proto_item_set_generated(padding_length_ti);
3331
3332     /* Update padding bytes in stats */
3333     tap_info->padding_bytes += (p_mac_lte_info->length - offset);
3334 }
3335
3336
3337 /* Dissect BCH PDU */
3338 static void dissect_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3339                         proto_item *pdu_ti,
3340                         int offset, mac_lte_info *p_mac_lte_info)
3341 {
3342     proto_item *ti;
3343
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,
3349                                               "Unknown"));
3350
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);
3355
3356     /****************************************/
3357     /* Whole frame is BCH data              */
3358
3359     /* Raw data */
3360     ti = proto_tree_add_item(tree, hf_mac_lte_bch_pdu,
3361                              tvb, offset, -1, ENC_NA);
3362
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);
3366
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;
3373                 }
3374                 else {
3375                     protocol_handle = lte_rrc_bcch_dl_sch_br_handle;
3376                 }
3377             }
3378             else {
3379                 protocol_handle = lte_rrc_bcch_dl_sch_nb_handle;
3380             }
3381         }
3382         else {
3383             if (p_mac_lte_info->nbMode == no_nb_mode) {
3384                 protocol_handle = lte_rrc_bcch_bch_handle;
3385             }
3386             else {
3387                 protocol_handle = lte_rrc_bcch_bch_nb_handle;
3388             }
3389         }
3390
3391         /* Hide raw view of bytes */
3392         proto_item_set_hidden(ti);
3393
3394         call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
3395     }
3396
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);
3400     }
3401 }
3402
3403
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)
3407 {
3408     proto_item *ti;
3409
3410     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3411                              "PCH PDU (%u bytes)  ",
3412                              tvb_reported_length_remaining(tvb, offset));
3413
3414     /****************************************/
3415     /* Whole frame is PCH data              */
3416
3417     /* Always show as raw data */
3418     ti = proto_tree_add_item(tree, hf_mac_lte_pch_pdu,
3419                              tvb, offset, -1, ENC_NA);
3420
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;
3424
3425     if (global_mac_lte_attempt_rrc_decode) {
3426
3427         /* Attempt to decode payload using LTE RRC dissector */
3428         tvbuff_t *rrc_tvb = tvb_new_subset_remaining(tvb, offset);
3429
3430         /* Hide raw view of bytes */
3431         proto_item_set_hidden(ti);
3432
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);
3436         }
3437         else {
3438             call_with_catch_all(lte_rrc_pcch_nb_handle, rrc_tvb, pinfo, tree);
3439         }
3440     }
3441
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);
3445     }
3446 }
3447
3448
3449 /* Does this header entry correspond to a fixed-sized control element? */
3450 static int is_fixed_sized_control_element(guint8 lcid, guint8 direction)
3451 {
3452     if (direction == DIRECTION_UPLINK) {
3453         /* Uplink */
3454         switch (lcid) {
3455             case RECOMMENDED_BIT_RATE_QUERY_LCID:
3456             case SPS_CONFIRMATION_LCID:
3457             case POWER_HEADROOM_REPORT_LCID:
3458             case CRNTI_LCID:
3459             case TRUNCATED_BSR_LCID:
3460             case SHORT_BSR_LCID:
3461             case LONG_BSR_LCID:
3462                 return TRUE;
3463
3464             default:
3465                 return FALSE;
3466         }
3467     }
3468     else {
3469         /* Assume Downlink */
3470         switch (lcid) {
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:
3479                 return TRUE;
3480
3481             default:
3482                 return FALSE;
3483         }
3484     }
3485 }
3486
3487
3488 /* Is this a BSR report header? */
3489 static int is_bsr_lcid(guint8 lcid)
3490 {
3491     return ((lcid == TRUNCATED_BSR_LCID) ||
3492             (lcid == SHORT_BSR_LCID) ||
3493             (lcid == LONG_BSR_LCID));
3494 }
3495
3496
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,
3499                                proto_item *pdu_ti,
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)
3505 {
3506     tvbuff_t            *rb_tvb = tvb_new_subset_length(tvb, offset, data_length);
3507     struct rlc_lte_info *p_rlc_lte_info;
3508
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);
3513     }
3514
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;
3527     } else {
3528         p_rlc_lte_info->nbMode = rlc_no_nb_mode;
3529     }
3530
3531     /* Store info in packet */
3532     p_add_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0, p_rlc_lte_info);
3533
3534     if (global_mac_lte_layer_to_show != ShowRLCLayer) {
3535         /* Don't want these columns replaced */
3536         col_set_writable(pinfo->cinfo, -1, FALSE);
3537     }
3538     else {
3539         /* Clear info column before first RLC PDU */
3540         if (s_number_of_rlc_pdus_shown == 0) {
3541             col_clear(pinfo->cinfo, COL_INFO);
3542         }
3543         else {
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);
3547         }
3548     }
3549     s_number_of_rlc_pdus_shown++;
3550
3551     /* Call it (catch exceptions so that stats will be updated) */
3552     call_with_catch_all(rlc_lte_handle, rb_tvb, pinfo, tree);
3553
3554     /* Let columns be written to again */
3555     col_set_writable(pinfo->cinfo, -1, TRUE);
3556 }
3557
3558
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)
3562 {
3563     DLHARQResult *result = NULL;
3564     DLHARQResult *original_result = NULL;
3565
3566     /* If don't have detailed DL PHY info, just give up */
3567     if (!p_mac_lte_info->detailed_phy_info.dl_info.present) {
3568         return;
3569     }
3570
3571     /* TDD may not work... */
3572
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;
3577
3578         DLHarqBuffers *ueData;
3579
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;
3583
3584         /* Check harq-id bounds, give up if invalid */
3585         if ((harq_id >= 15) || (transport_block > 1)) {
3586             return;
3587         }
3588
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));
3591
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) {
3600
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;
3606
3607                     /* Round difference to nearest millisecond */
3608                     gint total_gap = (seconds_between_packets*1000) +
3609                                      ((nseconds_between_packets+500000) / 1000000);
3610
3611                     /* Expect to be within (say) 8-13 subframes since previous */
3612                     if ((total_gap >= 8) && (total_gap <= 13)) {
3613
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);
3620
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);
3626                         }
3627                         original_result->nextSet = TRUE;
3628                         original_result->nextFrameNum = pinfo->num;
3629                         original_result->timeToNextFrame = total_gap;
3630                     }
3631                 }
3632             }
3633         }
3634         else {
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);
3638         }
3639
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;
3648     }
3649     else {
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));
3652     }
3653
3654
3655     /***************************************************/
3656     /* Show link back to original frame (if available) */
3657     if (result != NULL) {
3658         if (result->previousSet) {
3659             proto_item *gap_ti;
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);
3663
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);
3667         }
3668
3669         if (result->nextSet) {
3670             proto_item *gap_ti;
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);
3674
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);
3678         }
3679
3680     }
3681 }
3682
3683
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)
3686 {
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);
3688
3689     if (p_mac_lte_info == NULL) {
3690         return FALSE;
3691     }
3692
3693     if (direction == DIRECTION_UPLINK) {
3694         /* For UL, retx count is stored in per-packet struct */
3695         return (p_mac_lte_info->reTxCount > 0);
3696     }
3697     else {
3698         /* Use answer if told directly */
3699         if (p_mac_lte_info->dl_retx == dl_retx_yes) {
3700             return TRUE;
3701         }
3702         else {
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);
3706         }
3707     }
3708 }
3709
3710
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)
3717 {
3718     ULHARQResult *result = NULL;
3719
3720     /* If don't have detailed DL PHY info, just give up */
3721     if (!p_mac_lte_info->detailed_phy_info.ul_info.present) {
3722         return;
3723     }
3724
3725     /* Give up if harqid is out of range */
3726     if (p_mac_lte_info->detailed_phy_info.ul_info.harq_id >= 8) {
3727         return;
3728     }
3729
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;
3734
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) {
3747
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;
3753
3754                         /* Round to nearest ms */
3755                         gint total_gap = (seconds_between_packets*1000) +
3756                                          ((nseconds_between_packets+500000) / 1000000);
3757
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;
3763
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);
3770
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);
3776                             }
3777                             original_result->nextSet = TRUE;
3778                             original_result->nextFrameNum = pinfo->num;
3779                             original_result->timeToNextFrame = total_gap;
3780                         }
3781                     }
3782                 }
3783             }
3784         }
3785         else {
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);
3789         }
3790
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;
3799     }
3800     else {
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));
3803     }
3804
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;
3810
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);
3814
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);
3818             }
3819         }
3820         else {
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);
3823         }
3824     }
3825
3826     /* Show link forward to any known next Tx */
3827     if ((result != NULL) && result->nextSet) {
3828         proto_item *next_ti, *gap_ti;
3829
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);
3834
3835         proto_item_set_generated(next_ti);
3836
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);
3840     }
3841 }
3842
3843
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)
3847 {
3848     SRResult *result;
3849     result = (SRResult *)g_hash_table_lookup(mac_lte_sr_request_hash, GUINT_TO_POINTER(frameNum));
3850
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);
3854     }
3855     return result;
3856 }
3857
3858
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)
3863 {
3864     SRResult   *result           = NULL;
3865     SRState    *state;
3866     SRResult   *resultForSRFrame = NULL;
3867
3868     guint16     rnti;
3869     guint16     ueid;
3870     proto_item *ti;
3871
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];
3876     }
3877     else {
3878         rnti = p_mac_lte_info->rnti;
3879         ueid = p_mac_lte_info->ueid;
3880     }
3881
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);
3889     }
3890
3891     /* First time through - update state with new info */
3892     if (!PINFO_FD_VISITED(pinfo)) {
3893         guint32 timeSinceRequest;
3894
3895         /* Store time of request */
3896         if (event == SR_Request) {
3897             state->requestTime = pinfo->abs_ts;
3898         }
3899
3900         switch (state->status) {
3901             case None:
3902                 switch (event) {
3903                     case SR_Grant:
3904                         /* Got another grant - fine */
3905
3906                         /* update state */
3907                         state->lastGrantFramenum = pinfo->num;
3908                         break;
3909
3910                     case SR_Request:
3911                         /* Sent an SR - fine */
3912
3913                         /* Update state */
3914                         state->status = SR_Outstanding;
3915                         state->lastSRFramenum = pinfo->num;
3916                         break;
3917
3918                     case SR_Failure:
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;
3924                         break;
3925                 }
3926                 break;
3927
3928             case SR_Outstanding:
3929                 timeSinceRequest = (guint32)(((pinfo->abs_ts.secs - state->requestTime.secs) * 1000) +
3930                                              ((pinfo->abs_ts.nsecs - state->requestTime.nsecs) / 1000000));
3931
3932                 switch (event) {
3933                     case SR_Grant:
3934                         /* Got grant we were waiting for, so state goes to None */
3935
3936                         /* Update state */
3937                         state->status = None;
3938
3939                         /* Set result info */
3940                         result = GetSRResult(pinfo->num, TRUE);
3941                         result->type = GrantAnsweringSR;
3942                         result->frameNum = state->lastSRFramenum;
3943                         result->timeDifference = timeSinceRequest;
3944
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;
3950                         break;
3951
3952                     case SR_Request:
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;
3958                         break;
3959
3960                     case SR_Failure:
3961                         /* We sent an SR but it failed */
3962
3963                         /* Update state */
3964                         state->status = SR_Failed;
3965
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;
3971
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;
3977                         break;
3978                 }
3979                 break;
3980
3981             case SR_Failed:
3982                 switch (event) {
3983                     case SR_Grant:
3984                         /* Got a grant, presumably after a subsequent RACH - fine */
3985
3986                         /* Update state */
3987                         state->status = None;
3988                         break;
3989
3990                     case SR_Request:
3991                         /* Tried another SR after previous one failed.
3992                            Presumably a subsequent RACH was tried in-between... */
3993
3994                         state->status = SR_Outstanding;
3995
3996                         result = GetSRResult(pinfo->num, TRUE);
3997                         result->status = SR_Outstanding;
3998                         result->event = SR_Request;
3999                         break;
4000
4001                     case SR_Failure:
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;
4007                         break;
4008                 }
4009                 break;
4010         }
4011     }
4012
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",
4021                                    ueid);
4022         }
4023         return;
4024     }
4025
4026
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);
4036             break;
4037
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);
4045             break;
4046
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);
4054
4055             break;
4056
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);
4064             break;
4065
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",
4069                                             ueid,
4070                                             val_to_str_const(result->status, sr_status_vals, "Unknown"),
4071                                             val_to_str_const(result->event,  sr_event_vals,  "Unknown"));
4072             break;
4073     }
4074 }
4075
4076
4077 /********************************************************/
4078 /* Count number of UEs/TTI (in both directions)         */
4079 /********************************************************/
4080
4081 /* For keeping track during first pass */
4082 typedef struct tti_info_t {
4083     guint16 subframe;
4084     nstime_t ttiStartTime;
4085     guint ues_in_tti;
4086 } tti_info_t;
4087
4088 static tti_info_t UL_tti_info;
4089 static tti_info_t DL_tti_info;
4090
4091 /* For associating with frame and displaying */
4092 typedef struct TTIInfoResult_t {
4093     guint ues_in_tti;
4094 } TTIInfoResult_t;
4095
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;
4099
4100
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)
4103 {
4104     gboolean same_tti = FALSE;
4105     tti_info_t *tti_info;
4106
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;
4111     }
4112
4113     /* Set tti_info based upon direction */
4114     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4115         tti_info = &UL_tti_info;
4116     }
4117     else {
4118         tti_info = &DL_tti_info;
4119     }
4120
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;
4127
4128         /* Round difference to nearest microsecond */
4129         gint total_us_gap = (seconds_between_packets*1000000) +
4130                            ((nseconds_between_packets+500) / 1000);
4131
4132         if (total_us_gap < 1000) {
4133             same_tti = TRUE;
4134         }
4135     }
4136
4137     /* Update global state */
4138     if (!same_tti) {
4139         tti_info->subframe = p_mac_lte_info->subframeNumber;
4140         tti_info->ttiStartTime = pinfo->abs_ts;
4141         tti_info->ues_in_tti = 1;
4142     }
4143     else {
4144         tti_info->ues_in_tti++;
4145     }
4146
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);
4152
4153     return tti_info->ues_in_tti;
4154 }
4155
4156
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)
4159 {
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);
4169     }
4170 }
4171
4172 static void set_rlc_seqnum_length_ext_li_field(rlc_channel_type_t rlc_channel_type,
4173                                                guint8 direction,
4174                                                guint8 *seqnum_length,
4175                                                gboolean *rlc_ext_li_field)
4176 {
4177     switch (rlc_channel_type) {
4178         case rlcUM5:
4179             *seqnum_length = 5;
4180             break;
4181         case rlcUM10:
4182             *seqnum_length = 10;
4183             break;
4184         case rlcAMulExtLiField:
4185             *seqnum_length = 10;
4186             if (direction == DIRECTION_UPLINK) {
4187                 *rlc_ext_li_field = TRUE;
4188             }
4189             break;
4190         case rlcAMdlExtLiField:
4191             *seqnum_length = 10;
4192             if (direction == DIRECTION_DOWNLINK) {
4193                 *rlc_ext_li_field = TRUE;
4194             }
4195             break;
4196         case rlcAMextLiField:
4197             *seqnum_length = 10;
4198             *rlc_ext_li_field = TRUE;
4199             break;
4200         case rlcAMul16:
4201             if (direction == DIRECTION_UPLINK) {
4202                 *seqnum_length = 16;
4203             } else {
4204                 *seqnum_length = 10;
4205             }
4206             break;
4207         case rlcAMdl16:
4208             if (direction == DIRECTION_UPLINK) {
4209                 *seqnum_length = 10;
4210             } else {
4211                 *seqnum_length = 16;
4212             }
4213             break;
4214         case rlcAM16:
4215             *seqnum_length = 16;
4216             break;
4217         case rlcAMul16ulExtLiField:
4218             if (direction == DIRECTION_UPLINK) {
4219                 *seqnum_length = 16;
4220                 *rlc_ext_li_field = TRUE;
4221             } else {
4222                 *seqnum_length = 10;
4223             }
4224             break;
4225         case rlcAMdl16ulExtLiField:
4226             if (direction == DIRECTION_UPLINK) {
4227                 *seqnum_length = 10;
4228                 *rlc_ext_li_field = TRUE;
4229             } else {
4230                 *seqnum_length = 16;
4231             }
4232             break;
4233         case rlcAM16ulExtLiField:
4234             *seqnum_length = 16;
4235             if (direction == DIRECTION_UPLINK) {
4236                 *rlc_ext_li_field = TRUE;
4237             }
4238             break;
4239         case rlcAMul16dlExtLiField:
4240             if (direction == DIRECTION_UPLINK) {
4241                 *seqnum_length = 16;
4242             } else {
4243                 *seqnum_length = 10;
4244                 *rlc_ext_li_field = TRUE;
4245             }
4246             break;
4247         case rlcAMdl16dlExtLiField:
4248             if (direction == DIRECTION_UPLINK) {
4249                 *seqnum_length = 10;
4250             } else {
4251                 *seqnum_length = 16;
4252                 *rlc_ext_li_field = TRUE;
4253             }
4254             break;
4255         case rlcAM16dlExtLiField:
4256             *seqnum_length = 16;
4257             if (direction == DIRECTION_DOWNLINK) {
4258                 *rlc_ext_li_field = TRUE;
4259             }
4260             break;
4261         case rlcAMul16extLiField:
4262             if (direction == DIRECTION_UPLINK) {
4263                 *seqnum_length = 16;
4264             } else {
4265                 *seqnum_length = 10;
4266             }
4267             *rlc_ext_li_field = TRUE;
4268             break;
4269         case rlcAMdl16extLiField:
4270             if (direction == DIRECTION_UPLINK) {
4271                 *seqnum_length = 10;
4272             } else {
4273                 *seqnum_length = 16;
4274             }
4275             *rlc_ext_li_field = TRUE;
4276             break;
4277         case rlcAM16extLiField:
4278             *seqnum_length = 16;
4279             *rlc_ext_li_field = TRUE;
4280             break;
4281         default:
4282             break;
4283     }
4284 }
4285
4286 /* Lookup channel details for lcid */
4287 static void lookup_rlc_channel_from_lcid(guint16 ueid,
4288                                          guint8 lcid,
4289                                          guint8 direction,
4290                                          rlc_channel_type_t *rlc_channel_type,
4291                                          guint8 *seqnum_length,
4292                                          gint *drb_id,
4293                                          gboolean *rlc_ext_li_field)
4294 {
4295     /* Zero params (in case no match is found) */
4296     *rlc_channel_type = rlcRaw;
4297     *seqnum_length    = 0;
4298     *drb_id           = 0;
4299     *rlc_ext_li_field = FALSE;
4300
4301     if (global_mac_lte_lcid_drb_source == (int)FromStaticTable) {
4302
4303         /* Look up in static (UAT) table */
4304         guint m;
4305         for (m=0; m < num_lcid_drb_mappings; m++) {
4306             if (lcid == lcid_drb_mappings[m].lcid) {
4307
4308                 *rlc_channel_type = lcid_drb_mappings[m].channel_type;
4309
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);
4313
4314                 /* Set drb_id */
4315                 *drb_id = lcid_drb_mappings[m].drbid;
4316                 break;
4317             }
4318         }
4319     }
4320     else {
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));
4323         if (!ue_mappings) {
4324             return;
4325         }
4326
4327         /* Look up setting gleaned from configuration protocol */
4328         if (!ue_mappings->mapping[lcid].valid) {
4329             return;
4330         }
4331
4332         *rlc_channel_type = ue_mappings->mapping[lcid].channel_type;
4333
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);
4337
4338         /* Set drb_id */
4339         *drb_id = ue_mappings->mapping[lcid].drbid;
4340     }
4341 }
4342
4343
4344
4345 #define MAX_HEADERS_IN_PDU 1024
4346
4347 /* UL-SCH and DL-SCH formats have much in common, so handle them in a common
4348    function */
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,
4353                                    guint pdu_instance)
4354 {
4355     guint8            extension;
4356     guint16           n;
4357     proto_item       *truncated_ti;
4358     proto_item       *padding_length_ti;
4359
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];
4364
4365     proto_item *pdu_header_ti;
4366     proto_tree *pdu_header_tree;
4367
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;
4375
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);
4379
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);
4386
4387     tap_info->raw_length = p_mac_lte_info->length;
4388
4389     /******************************************************/
4390     /* DRX information                                    */
4391
4392     /* Update DRX state of UE */
4393     if (global_mac_lte_show_drx) {
4394         if (!PINFO_FD_VISITED(pinfo)) {
4395
4396             /* Update UE state to this subframe (but before this event is processed) */
4397             update_drx_info(pinfo, p_mac_lte_info);
4398
4399             /* Store 'before' snapshot of UE state for this frame */
4400             set_drx_info(pinfo, p_mac_lte_info, TRUE, pdu_instance);
4401         }
4402
4403         /* Show current DRX state in tree as 'before' */
4404         show_drx_info(pinfo, tree, tvb, p_mac_lte_info, TRUE, pdu_instance);
4405
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);
4411                 }
4412             }
4413             else {
4414                 /* Downlink */
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);
4417                 }
4418                 else if (p_mac_lte_info->dl_retx == dl_retx_no) {
4419                     mac_lte_drx_new_dlsch_data(p_mac_lte_info->ueid);
4420                 }
4421             }
4422         }
4423     }
4424
4425
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);
4429     }
4430
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) {
4434
4435         TrackSRInfo(SR_Grant, pinfo, tree, tvb, p_mac_lte_info, 0, NULL);
4436     }
4437
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,
4443                                                  tvb, offset, 0,
4444                                                  "",
4445                                                  "MAC PDU 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);
4450
4451
4452     /************************************************************************/
4453     /* Dissect each sub-header.                                             */
4454     do {
4455         guint8 reserved, format2, initial_lcid;
4456         guint64 length = 0;
4457         proto_item *pdu_subheader_ti;
4458         proto_tree *pdu_subheader_tree;
4459         proto_item *lcid_ti;
4460         proto_item *ti;
4461         gint       offset_start_subheader = offset;
4462         guint8 first_byte = tvb_get_guint8(tvb, offset);
4463
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,
4468                                                         tvb, offset, 1,
4469                                                         "",
4470                                                         "Sub-header");
4471         pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
4472                                                     ett_mac_lte_sch_subheader);
4473
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');
4482         }
4483
4484         /* Format2 bit */
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);
4488
4489         /* Extended bit */
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);
4493
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) {
4498
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,
4502                                      "(%s",
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;
4509             }
4510         }
4511         else {
4512             /* Downlink */
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,
4516                                      "(%s",
4517                                      val_to_str_const(lcids[number_of_headers],
4518                                                       dlsch_lcid_vals, "(Unknown LCID)"));
4519
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);
4526             }
4527         }
4528         offset++;
4529
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;
4534         }
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;
4537         }
4538
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');
4545             return;
4546         }
4547
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);
4552                 return;
4553             }
4554             have_seen_bsr = TRUE;
4555         }
4556
4557         /* Should not see padding after non-padding control... */
4558         if ((lcids[number_of_headers] == PADDING_LCID) &&
4559             extension)
4560         {
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);
4564             }
4565
4566             if (have_seen_non_padding_control) {
4567                 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_before_control_subheader);
4568             }
4569         }
4570
4571         /* Also flag if we have final padding but also padding subheaders
4572            at the start! */
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);
4576         }
4577
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;
4583         }
4584
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);
4588             return;
4589         }
4590
4591
4592         /********************************************************************/
4593         /* Length field follows if not the last header or for a fixed-sized
4594            control element */
4595         if (!extension) {
4596             /* Last one... */
4597             if (is_fixed_sized_control_element(lcids[number_of_headers], p_mac_lte_info->direction)) {
4598                 pdu_lengths[number_of_headers] = 0;
4599             }
4600             else {
4601                 pdu_lengths[number_of_headers] = -1;
4602             }
4603         }
4604         else {
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)) {
4608
4609                 if (format2) {
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);
4615                     }
4616
4617                     offset += 2;
4618                 } else {
4619                     guint8  format;
4620
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);
4625
4626                     /* Now read length field itself */
4627                     if (format) {
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);
4631
4632                         offset += 2;
4633                     }
4634                     else {
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);
4638                         offset++;
4639                     }
4640                 }
4641                 pdu_lengths[number_of_headers] = (gint32)length;
4642             }
4643             else {
4644                 pdu_lengths[number_of_headers] = 0;
4645             }
4646         }
4647
4648
4649         /* Close off description in info column */
4650         switch (pdu_lengths[number_of_headers]) {
4651             case 0:
4652                 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
4653                 break;
4654             case -1:
4655                 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
4656                 break;
4657             default:
4658                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
4659                                          pdu_lengths[number_of_headers]);
4660                 break;
4661         }
4662
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) ?
4667                                                     ulsch_lcid_vals :
4668                                                         dlsch_lcid_vals,
4669                                                 "Unknown"));
4670
4671         switch (pdu_lengths[number_of_headers]) {
4672             case -1:
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,
4678                                                         "Unknown"));
4679                 break;
4680             case 0:
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,
4686                                                         "Unknown"));
4687                 break;
4688             default:
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,
4695                                                         "Unknown"),
4696                                        pdu_lengths[number_of_headers]);
4697                 break;
4698         }
4699
4700
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]);
4708         }
4709
4710         /* Set length of this subheader */
4711         proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
4712
4713         number_of_headers++;
4714     } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
4715
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);
4721         return;
4722     }
4723
4724
4725     /* Append summary to overall PDU header root */
4726     proto_item_append_text(pdu_header_ti, "  [%u subheaders]",
4727                            number_of_headers);
4728
4729     /* And set its length to offset */
4730     proto_item_set_len(pdu_header_ti, offset);
4731
4732
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);
4737
4738         tap_info->isPHYRetx = (p_mac_lte_info->dl_retx == dl_retx_yes);
4739     }
4740
4741
4742     /************************************************************************/
4743     /* Dissect SDUs / control elements / padding.                           */
4744     /************************************************************************/
4745
4746     /* Dissect control element bodies first */
4747
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))) {
4752             break;
4753         }
4754
4755         /* Process what should be a valid control PDU type */
4756         if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
4757
4758             /****************************/
4759             /* DL-SCH Control PDUs      */
4760             switch (lcids[n]) {
4761                 case ACTIVATION_DEACTIVATION_CSI_RS_LCID:
4762                     {
4763                         proto_item *ad_csi_rs_ti;
4764                         proto_tree *ad_csi_rs_tree;
4765                         gint32 i;
4766
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);
4770                         }
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],
4775                                                                     "",
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);
4778
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);
4796                             offset += 1;
4797                         }
4798                     }
4799                     break;
4800                 case RECOMMENDED_BIT_RATE_LCID:
4801                     {
4802                         proto_item *br_ti;
4803                         proto_tree *br_tree;
4804                         proto_item *ti;
4805                         guint32 reserved;
4806
4807                         /* Create BR root */
4808                         br_ti = proto_tree_add_string_format(tree,
4809                                                              hf_mac_lte_control_recommended_bit_rate,
4810                                                              tvb, offset, 2,
4811                                                              "",
4812                                                              "Recommended Bit Rate");
4813                         br_tree = proto_item_add_subtree(br_ti, ett_mac_lte_recommended_bit_rate);
4814
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);
4821                         offset += 1;
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");
4827                         }
4828                         offset += 1;
4829                     }
4830                     break;
4831                 case ACTIVATION_DEACTIVATION_LCID:
4832                 case ACTIVATION_DEACTIVATION_4_BYTES_LCID:
4833                     {
4834                         proto_item *ad_ti;
4835                         proto_tree *ad_tree;
4836                         proto_item *ti;
4837                         guint8 reserved;
4838
4839                         /* Create AD root */
4840                         ad_ti = proto_tree_add_string_format(tree,
4841                                                              hf_mac_lte_control_activation_deactivation,
4842                                                              tvb, offset,
4843                                                              (lcids[n] == ACTIVATION_DEACTIVATION_4_BYTES_LCID) ? 4 : 1,
4844                                                              "",
4845                                                              "Activation/Deactivation");
4846                         ad_tree = proto_item_add_subtree(ad_ti, ett_mac_lte_activation_deactivation);
4847
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");
4868                         }
4869                         offset++;
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);
4887                             offset++;
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);
4904                             offset++;
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);
4921                             offset++;
4922                         }
4923                     }
4924                     break;
4925                 case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
4926                     {
4927                         proto_item *cr_ti;
4928                         proto_tree *cr_tree;
4929                         proto_item *ti;
4930                         ContentionResolutionResult *crResult;
4931
4932                         /* Create CR root */
4933                         cr_ti = proto_tree_add_string_format(tree,
4934                                                              hf_mac_lte_control_ue_contention_resolution,
4935                                                              tvb, offset, 6,
4936                                                              "",
4937                                                              "Contention Resolution");
4938                         cr_tree = proto_item_add_subtree(cr_ti, ett_mac_lte_contention_resolution);
4939
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);
4947                             }
4948                         }
4949
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) {
4953
4954                             /* Need to set result by looking for and comparing with Msg3 */
4955                             Msg3Data *msg3Data;
4956                             guint msg3Key = p_mac_lte_info->rnti;
4957
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);
4961
4962                             /* Look for Msg3 */
4963                             msg3Data = (Msg3Data *)g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(msg3Key));
4964
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;
4970
4971                                 /* Compare the 6 bytes */
4972                                 if (tvb_memeql(tvb, offset, msg3Data->data, 6) == 0) {
4973                                     crResult->status = Msg3Match;
4974                                 }
4975                                 else {
4976                                     crResult->status = Msg3NoMatch;
4977                                 }
4978                             }
4979                             else {
4980                                 crResult->status = NoMsg3;
4981                             }
4982                         }
4983
4984                         /* Now show CR result in tree */
4985                         switch (crResult->status) {
4986                             case NoMsg3:
4987                                 proto_item_append_text(cr_ti, " (no corresponding Msg3 found!)");
4988                                 break;
4989
4990                             case Msg3Match:
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);
4998
4999                                 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
5000                                                             tvb, 0, 0, TRUE);
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);
5004
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));
5009                                 }
5010                                 break;
5011
5012                             case Msg3NoMatch:
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);
5019
5020                                 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
5021                                                              tvb, 0, 0, FALSE);
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);
5028                                 break;
5029                         };
5030
5031                         offset += 6;
5032                     }
5033                     break;
5034                 case TIMING_ADVANCE_LCID:
5035                     {
5036                         proto_item *ta_ti;
5037                         proto_item *ta_value_ti;
5038                         proto_tree *ta_tree;
5039                         guint8      ta_value;
5040
5041                         /* Create TA root */
5042                         ta_ti = proto_tree_add_string_format(tree,
5043                                                              hf_mac_lte_control_timing_advance,
5044                                                              tvb, offset, 1,
5045                                                              "",
5046                                                              "Timing Advance");
5047                         ta_tree = proto_item_add_subtree(ta_ti, ett_mac_lte_timing_advance);
5048
5049                         /* TAG Id */
5050                         proto_tree_add_item(ta_tree, hf_mac_lte_control_timing_advance_group_id,
5051                                             tvb, offset, 1, ENC_BIG_ENDIAN);
5052
5053                         /* TA value */
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);
5057
5058                         if (ta_value == 31) {
5059                             expert_add_info(pinfo, ta_value_ti, &ei_mac_lte_control_timing_advance_command_no_correction);
5060                         }
5061                         else {
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",
5064                                                    ta_value,
5065                                                    (ta_value < 31) ? "-ve" : "+ve");
5066                         }
5067                         offset++;
5068                     }
5069                     break;
5070                 case DRX_COMMAND_LCID:
5071                 case LONG_DRX_COMMAND_LCID:
5072                     /* No payload */
5073                     mac_lte_drx_control_element_received(p_mac_lte_info->ueid);
5074                     break;
5075                 case PADDING_LCID:
5076                     /* No payload (in this position) */
5077                     tap_info->padding_bytes++;
5078                     break;
5079
5080                 default:
5081                     break;
5082             }
5083         }
5084         else {
5085
5086             /**********************************/
5087             /* UL-SCH Control PDUs            */
5088             switch (lcids[n]) {
5089                 case RECOMMENDED_BIT_RATE_QUERY_LCID:
5090                     {
5091                         proto_item *br_ti;
5092                         proto_tree *br_tree;
5093                         proto_item *ti;
5094                         guint32 reserved;
5095
5096                         /* Create BR root */
5097                         br_ti = proto_tree_add_string_format(tree,
5098                                                              hf_mac_lte_control_recommended_bit_rate_query,
5099                                                              tvb, offset, 2,
5100                                                              "",
5101                                                              "Recommended Bit Rate Query");
5102                         br_tree = proto_item_add_subtree(br_ti, ett_mac_lte_recommended_bit_rate_query);
5103
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);
5110                         offset += 1;
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");
5116                         }
5117                         offset += 1;
5118                     }
5119                     break;
5120                 case TRUNCATED_SIDELINK_BSR_LCID:
5121                 case SIDELINK_BSR_LCID:
5122                     {
5123                         proto_item *slbsr_ti;
5124                         proto_tree *slbsr_tree;
5125                         guint32 curr_offset = offset;
5126
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);
5130                         }
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],
5136                                                                     "",
5137                                                                     "Sidelink BSR");
5138                         } else {
5139                             slbsr_ti = proto_tree_add_string_format(tree,
5140                                                                     hf_mac_lte_control_sidelink_bsr,
5141                                                                     tvb, curr_offset, pdu_lengths[n],
5142                                                                     "",
5143                                                                     "Truncated Sidelink BSR");
5144                         }
5145                         slbsr_tree = proto_item_add_subtree(slbsr_ti, ett_mac_lte_sidelink_bsr);
5146
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);
5154                             curr_offset++;
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);
5158                                 curr_offset++;
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);
5163                                 curr_offset++;
5164                             } else {
5165                                 /* Check Reserved bit */
5166                                 guint32 reserved;
5167                                 proto_item *it;
5168
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);
5171                                 if (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");
5175                                     } else {
5176                                         expert_add_info_format(pinfo, it, &ei_mac_lte_reserved_not_zero,
5177                                                                "Truncated Sidelink BSR Reserved bits not zero");
5178                                     }
5179                                 }
5180                                 break;
5181                             }
5182                         }
5183                         offset += pdu_lengths[n];
5184                     }
5185                     break;
5186                 case DUAL_CONN_POWER_HEADROOM_REPORT_LCID:
5187                     {
5188                         proto_item *dcphr_ti;
5189                         proto_tree *dcphr_tree;
5190                         proto_item *ti;
5191                         proto_tree *dcphr_cell_tree;
5192                         proto_item *dcphr_cell_ti;
5193                         guint8 scell_bitmap;
5194                         guint8 byte;
5195                         guint i;
5196                         guint32 curr_offset = offset;
5197
5198                         if (!PINFO_FD_VISITED(pinfo)) {
5199                             get_mac_lte_ue_simult_pucch_pusch(p_mac_lte_info);
5200                         }
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);
5204                         }
5205
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],
5210                                                                 "",
5211                                                                 "Dual Connectivity Power Headroom Report");
5212                         dcphr_tree = proto_item_add_subtree(dcphr_ti, ett_mac_lte_dual_conn_power_headroom);
5213
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");
5236                         }
5237                         curr_offset++;
5238
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"));
5252                             curr_offset++;
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);
5259                                 if (byte & 0xc0) {
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);
5263                                 }
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"));
5268                                 curr_offset++;
5269                             }
5270                         }
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"));
5284                             curr_offset++;
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);
5291                                 if (byte & 0xc0) {
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);
5295                                 }
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"));
5300                                 curr_offset++;
5301                             }
5302                         }
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"));
5314                         curr_offset++;
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);
5321                             if (byte & 0xc0) {
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);
5325                             }
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"));
5330                             curr_offset++;
5331                         }
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"));
5345                                 curr_offset++;
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);
5352                                     if (byte & 0xc0) {
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);
5356                                     }
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"));
5361                                     curr_offset++;
5362                                 }
5363                             }
5364                         }
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]);
5369                         }
5370                         offset += pdu_lengths[n];
5371                     }
5372                     break;
5373                 case EXTENDED_POWER_HEADROOM_REPORT_LCID:
5374                     {
5375                         proto_item *ephr_ti;
5376                         proto_tree *ephr_tree;
5377                         proto_item *ti;
5378                         proto_tree *ephr_cell_tree;
5379                         proto_item *ephr_cell_ti;
5380                         guint8 scell_bitmap;
5381                         guint8 scell_count;
5382                         guint8 byte;
5383                         guint i;
5384                         guint32 curr_offset = offset;
5385                         guint32 computed_header_offset;
5386
5387                         if (!PINFO_FD_VISITED(pinfo)) {
5388                             get_mac_lte_ue_simult_pucch_pusch(p_mac_lte_info);
5389                         }
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);
5393                         }
5394
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],
5399                                                                "",
5400                                                                "Extended Power Headroom Report");
5401                         ephr_tree = proto_item_add_subtree(ephr_ti, ett_mac_lte_extended_power_headroom);
5402
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");
5425                         }
5426                         curr_offset++;
5427
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)) {
5432                                 scell_count++;
5433                             }
5434                         }
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++;
5440                             }
5441                             computed_header_offset++;
5442                         }
5443
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++;
5449                             }
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];
5456                                 break;
5457                             }
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"));
5469                             curr_offset++;
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);
5476                                 if (byte & 0xc0) {
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);
5480                                 }
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"));
5485                                 curr_offset++;
5486                             }
5487                         }
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"));
5499                         curr_offset++;
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);
5506                             if (byte & 0xc0) {
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);
5510                             }
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"));
5515                             curr_offset++;
5516                         }
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"));
5530                                 curr_offset++;
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);
5537                                     if (byte & 0xc0) {
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);
5541                                     }
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"));
5546                                     curr_offset++;
5547                                 }
5548                             }
5549                         }
5550                         offset += pdu_lengths[n];
5551                     }
5552                     break;
5553                 case POWER_HEADROOM_REPORT_LCID:
5554                     {
5555                         proto_item *phr_ti;
5556                         proto_tree *phr_tree;
5557                         proto_item *ti;
5558                         guint8 reserved;
5559                         guint8 level;
5560
5561                         /* Create PHR root */
5562                         phr_ti = proto_tree_add_string_format(tree,
5563                                                               hf_mac_lte_control_power_headroom,
5564                                                               tvb, offset, 1,
5565                                                               "",
5566                                                               "Power Headroom Report");
5567                         phr_tree = proto_item_add_subtree(phr_ti, ett_mac_lte_power_headroom);
5568
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);
5576                         }
5577
5578                         /* Level */
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);
5582
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"));
5586                         offset++;
5587                     }
5588                     break;
5589                 case CRNTI_LCID:
5590                     proto_tree_add_item(tree, hf_mac_lte_control_crnti,
5591                                         tvb, offset, 2, ENC_BIG_ENDIAN);
5592                     offset += 2;
5593                     break;
5594                 /* TODO: treat separately */
5595                 case TRUNCATED_BSR_LCID:
5596                 case SHORT_BSR_LCID:
5597                     {
5598                         proto_tree *bsr_tree;
5599                         proto_item *bsr_ti;
5600                         proto_item *buffer_size_ti;
5601                         guint8 lcgid;
5602                         guint8 buffer_size;
5603                         int hfindex;
5604                         value_string_ext *p_vs_ext;
5605                         guint32 *p_buffer_size_median;
5606
5607                         if (!PINFO_FD_VISITED(pinfo)) {
5608                             get_mac_lte_ue_ext_bsr_sizes(p_mac_lte_info);
5609                         }
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;
5614                         } else {
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;
5618                         }
5619
5620                         if (lcids[n] == SHORT_BSR_LCID) {
5621                             bsr_ti = proto_tree_add_string_format(tree,
5622                                                                   hf_mac_lte_control_bsr,
5623                                                                   tvb, offset, 1,
5624                                                                   "",
5625                                                                   "Short BSR");
5626                         } else {
5627                             bsr_ti = proto_tree_add_string_format(tree,
5628                                                                   hf_mac_lte_control_bsr,
5629                                                                   tvb, offset, 1,
5630                                                                   "",
5631                                                                   "Truncated BSR");
5632                         }
5633                         bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
5634
5635                         /* LCG ID */
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);
5639                         /* Buffer Size */
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);
5647                         }
5648                         offset++;
5649
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,
5654                                                    lcgid,
5655                                                    buffer_size,
5656                                                    val_to_str_ext_const(buffer_size, p_vs_ext, "Unknown"));
5657                         }
5658
5659
5660                         proto_item_append_text(bsr_ti, " (lcgid=%u  %s)",
5661                                                lcgid,
5662                                                val_to_str_ext_const(buffer_size, p_vs_ext, "Unknown"));
5663                     }
5664                     break;
5665                 case LONG_BSR_LCID:
5666                     {
5667                         proto_tree *bsr_tree;
5668                         proto_item *bsr_ti, *bsr_median_ti;
5669                         proto_item *buffer_size_ti;
5670                         guint8     buffer_size[4];
5671                         int hfindex[4];
5672                         value_string_ext *p_vs_ext;
5673                         guint32 *p_buffer_size_median;
5674
5675                         if (!PINFO_FD_VISITED(pinfo)) {
5676                             get_mac_lte_ue_ext_bsr_sizes(p_mac_lte_info);
5677                         }
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;
5685                         } else {
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;
5692                         }
5693
5694                         bsr_ti = proto_tree_add_string_format(tree,
5695                                                               hf_mac_lte_control_bsr,
5696                                                               tvb, offset, 3,
5697                                                               "",
5698                                                               "Long BSR");
5699                         bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
5700
5701                         /* LCID Group 0 */
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;
5705
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);
5710                         }
5711
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,
5716                                                    buffer_size[0],
5717                                                    val_to_str_ext_const(buffer_size[0], p_vs_ext, "Unknown"));
5718                         }
5719
5720                         /* LCID Group 1 */
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);
5724
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);
5729                         }
5730
5731                         offset++;
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,
5736                                                    buffer_size[1],
5737                                                    val_to_str_ext_const(buffer_size[1], p_vs_ext, "Unknown"));
5738                         }
5739
5740                         /* LCID Group 2 */
5741                         buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[2],
5742                                                              tvb, offset, 2, ENC_BIG_ENDIAN);
5743
5744                         buffer_size[2] = ((tvb_get_guint8(tvb, offset) & 0x0f) << 2) | ((tvb_get_guint8(tvb, offset+1) & 0xc0) >> 6);
5745
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);
5750                         }
5751
5752                         offset++;
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,
5757                                                    buffer_size[2],
5758                                                    val_to_str_ext_const(buffer_size[2], p_vs_ext, "Unknown"));
5759                         }
5760
5761                         /* LCID Group 3 */
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;
5765
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);
5770                         }
5771
5772                         offset++;
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,
5777                                                    buffer_size[3],
5778                                                    val_to_str_ext_const(buffer_size[3], p_vs_ext, "Unknown"));
5779                         }
5780
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"));
5787                     }
5788                     break;
5789                 case PADDING_LCID:
5790                     /* No payload, in this position */
5791                     tap_info->padding_bytes++;
5792                     break;
5793
5794                 default:
5795                     break;
5796             }
5797         }
5798     }
5799
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,
5803                                        is_truncated);
5804     if (is_truncated) {
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) {
5812                 break;
5813             }
5814             data_length = (pdu_lengths[n] == -1) ?
5815                             tvb_reported_length_remaining(tvb, offset) :
5816                             pdu_lengths[n];
5817             tap_info->sdus_for_lcid[lcids[n]]++;
5818             tap_info->bytes_for_lcid[lcids[n]] += data_length;
5819             offset += data_length;
5820         }
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);
5824         }
5825         return;
5826     }
5827     else {
5828         proto_item_set_hidden(truncated_ti);
5829     }
5830
5831
5832     /* Now process remaining bodies, which should all be data */
5833     for (; n < number_of_headers; n++) {
5834
5835         /* Data SDUs treated identically for Uplink or downlink channels */
5836         proto_item *sdu_ti;
5837         guint16 data_length;
5838         gboolean rlc_called_for_sdu = FALSE;
5839
5840         /* Break out if meet padding */
5841         if (lcids[n] == PADDING_LCID) {
5842             break;
5843         }
5844
5845         /* Work out length */
5846         data_length = (pdu_lengths[n] == -1) ?
5847                             tvb_reported_length_remaining(tvb, offset) :
5848                             pdu_lengths[n];
5849
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 */
5853             proto_item *dpr_ti;
5854             proto_tree *dpr_tree;
5855             guint32 reserved;
5856
5857             dpr_ti = proto_tree_add_string_format(tree,
5858                                       hf_mac_lte_control_data_vol_power_headroom,
5859                                       tvb, offset, 1,
5860                                       "",
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);
5865             if (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");
5868             }
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);
5871             offset++;
5872             if (pdu_lengths[n] == -1) {
5873                 data_length--;
5874             }
5875         }
5876
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) ?
5882                                                                   ulsch_lcid_vals :
5883                                                                   dlsch_lcid_vals,
5884                                                              "Unknown"),
5885                                              data_length);
5886
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));
5894
5895                 /* Look for previous entry for this UE */
5896                 if (data == NULL) {
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);
5900                 }
5901
5902                 /* Fill in data details */
5903                 data->framenum = pinfo->num;
5904                 tvb_memcpy(tvb, data->data, offset, 6);
5905                 data->msg3Time = pinfo->abs_ts;
5906             }
5907         }
5908
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);
5912
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;
5918                 }
5919                 else {
5920                     protocol_handle = lte_rrc_ul_ccch_nb_handle;
5921                 }
5922             }
5923             else {
5924                 if (p_mac_lte_info->nbMode == no_nb_mode) {
5925                     protocol_handle = lte_rrc_dl_ccch_handle;
5926                 }
5927                 else {
5928                     protocol_handle = lte_rrc_dl_ccch_nb_handle;
5929                 }
5930             }
5931
5932             /* Hide raw view of bytes */
5933             proto_item_set_hidden(sdu_ti);
5934             rlc_called_for_sdu = TRUE;
5935
5936             call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
5937         }
5938
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);
5951
5952                 /* Hide raw view of bytes */
5953                 proto_item_set_hidden(sdu_ti);
5954                 rlc_called_for_sdu = TRUE;
5955             }
5956         }
5957
5958         else if ((lcids[n] >= 3) && (lcids[n] <= 10)) {
5959
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;
5964             gint drb_id;
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);
5968
5969             lookup_rlc_channel_from_lcid(p_mac_lte_info->ueid,
5970                                          lcids[n],
5971                                          p_mac_lte_info->direction,
5972                                          &rlc_channel_type,
5973                                          &seqnum_length,
5974                                          &drb_id,
5975                                          &rlc_ext_li_field);
5976
5977             /* Dissect according to channel type */
5978             switch (rlc_channel_type) {
5979                 case rlcUM5:
5980                 case rlcUM10:
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);
5985                     break;
5986                 case rlcAM:
5987                 case rlcAMulExtLiField:
5988                 case rlcAMdlExtLiField:
5989                 case rlcAMextLiField:
5990                 case rlcAMul16:
5991                 case rlcAMdl16:
5992                 case rlcAM16:
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);
6006                     break;
6007                 case rlcTM:
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);
6012                     break;
6013                 case rlcRaw:
6014                     /* Nothing to do! */
6015                     break;
6016             }
6017
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;
6022             }
6023
6024         }
6025
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);
6029
6030             /* Hide raw view of bytes */
6031             proto_item_set_hidden(sdu_ti);
6032             rlc_called_for_sdu = TRUE;
6033
6034             call_with_catch_all(lte_rrc_sc_mcch_handle, rrc_tvb, pinfo, tree);
6035         }
6036
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)
6040             {
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, "...");
6043             }
6044             else
6045             {
6046                 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, data_length));
6047             }
6048         }
6049
6050         offset += data_length;
6051
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;
6055     }
6056
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) &&
6061             (lcids[0] == 0)) {
6062
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);
6069             }
6070         }
6071     }
6072
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);
6078         }
6079         padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
6080                                                tvb, offset, 0,
6081                                                p_mac_lte_info->length - offset);
6082         proto_item_set_generated(padding_length_ti);
6083
6084         /* Update padding bytes in stats */
6085         tap_info->padding_bytes += (p_mac_lte_info->length - offset);
6086
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);
6093         }
6094     }
6095     else {
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);
6103         }
6104
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);
6111         }
6112     }
6113
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);
6119         }
6120
6121         /* Show current DRX state in tree as 'after' */
6122         show_drx_info(pinfo, tree, tvb, p_mac_lte_info, FALSE, pdu_instance);
6123     }
6124 }
6125
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)
6128 {
6129     guint8            extension;
6130     guint16           n;
6131     proto_item       *truncated_ti;
6132     proto_item       *padding_length_ti;
6133     proto_item       *hidden_root_ti;
6134
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];
6139
6140     proto_item *pdu_header_ti, *sched_info_ti = NULL;
6141     proto_tree *pdu_header_tree;
6142
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;
6148
6149     write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, "MCH: ");
6150
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);
6155
6156     /* Add PDU block header subtree */
6157     pdu_header_ti = proto_tree_add_string_format(tree, hf_mac_lte_mch_header,
6158                                                  tvb, offset, 0,
6159                                                  "",
6160                                                  "MAC PDU Header");
6161     pdu_header_tree = proto_item_add_subtree(pdu_header_ti, ett_mac_lte_mch_header);
6162
6163
6164     /************************************************************************/
6165     /* Dissect each sub-header.                                             */
6166     do {
6167         guint8 reserved, format2;
6168         guint64 length = 0;
6169         proto_item *pdu_subheader_ti;
6170         proto_tree *pdu_subheader_tree;
6171         proto_item *lcid_ti;
6172         proto_item *ti;
6173         gint       offset_start_subheader = offset;
6174         guint8 first_byte = tvb_get_guint8(tvb, offset);
6175
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,
6180                                                         tvb, offset, 1,
6181                                                         "",
6182                                                         "Sub-header");
6183         pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
6184                                                     ett_mac_lte_mch_subheader);
6185
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");
6193         }
6194
6195         /* Format2 bit */
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);
6199
6200         /* Extended bit */
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);
6204
6205         /* LCID */
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;
6211         }
6212         write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6213                                  "(%s",
6214                                  val_to_str_const(lcids[number_of_headers],
6215                                                   mch_lcid_vals, "(Unknown LCID)"));
6216         offset++;
6217
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;
6222         }
6223
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");
6230             return;
6231         }
6232
6233         /* Should not see padding after non-padding control... */
6234         if ((lcids[number_of_headers] > 28) &&
6235             (lcids[number_of_headers] == PADDING_LCID) &&
6236             extension)
6237         {
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);
6241             }
6242
6243             if (have_seen_non_padding_control) {
6244                 expert_add_info(pinfo, lcid_ti, &ei_mac_lte_padding_data_before_control_subheader);
6245             }
6246         }
6247
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;
6252         }
6253
6254
6255
6256         /********************************************************************/
6257         /* Length field follows if not the last header or for a fixed-sized
6258            control element */
6259         if (!extension) {
6260             /* Last one... */
6261             pdu_lengths[number_of_headers] = -1;
6262         }
6263         else {
6264             /* Not the last one */
6265             if (lcids[number_of_headers] != PADDING_LCID) {
6266
6267                 if (format2) {
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);
6273                     }
6274
6275                     offset += 2;
6276                 } else {
6277                     guint8  format;
6278
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);
6283
6284                     /* Now read length field itself */
6285                     if (format) {
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);
6289
6290                         offset += 2;
6291                     }
6292                     else {
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);
6296                         offset++;
6297                     }
6298                 }
6299                 pdu_lengths[number_of_headers] = (gint32)length;
6300             }
6301             else {
6302                 pdu_lengths[number_of_headers] = 0;
6303             }
6304         }
6305
6306
6307         /* Close off description in info column */
6308         switch (pdu_lengths[number_of_headers]) {
6309             case 0:
6310                 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
6311                 break;
6312             case -1:
6313                 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
6314                 break;
6315             default:
6316                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
6317                                          pdu_lengths[number_of_headers]);
6318                 break;
6319         }
6320
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"));
6325
6326         switch (pdu_lengths[number_of_headers]) {
6327             case -1:
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],
6331                                                         mch_lcid_vals,
6332                                                         "Unknown"));
6333                 break;
6334             case 0:
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],
6338                                                         mch_lcid_vals,
6339                                                         "Unknown"));
6340                 break;
6341             default:
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],
6346                                                         mch_lcid_vals,
6347                                                         "Unknown"),
6348                                        pdu_lengths[number_of_headers]);
6349                 break;
6350         }
6351
6352
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]);
6358         }
6359
6360         /* Set length of this subheader */
6361         proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
6362
6363         number_of_headers++;
6364     } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
6365
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);
6371         return;
6372     }
6373
6374
6375     /* Append summary to overall PDU header root */
6376     proto_item_append_text(pdu_header_ti, " (%u subheaders)",
6377                            number_of_headers);
6378
6379     /* And set its length to offset */
6380     proto_item_set_len(pdu_header_ti, offset);
6381
6382
6383     /************************************************************************/
6384     /* Dissect SDUs / control elements / padding.                           */
6385     /************************************************************************/
6386
6387     /* Dissect control element bodies first */
6388
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) {
6392             break;
6393         }
6394
6395         /* Process what should be a valid control PDU type */
6396         switch (lcids[n]) {
6397             case MCH_SCHEDULING_INFO_LCID:
6398                 {
6399                     guint32 curr_offset = offset;
6400                     gint16 i;
6401                     guint16 stop_mtch_val;
6402                     proto_item *mch_sched_info_ti, *ti;
6403                     proto_tree *mch_sched_info_tree;
6404
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);
6408                     }
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");
6412                     }
6413
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],
6417                                                                      "",
6418                                                                      "MCH Scheduling Information");
6419                     mch_sched_info_tree = proto_item_add_subtree(mch_sched_info_ti, ett_mac_lte_mch_scheduling_info);
6420
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)");
6429                         }
6430                         else if (stop_mtch_val == 2047) {
6431                             proto_item_append_text(ti, " (MTCH is not scheduled)");
6432                         }
6433                         curr_offset += 2;
6434                     }
6435
6436                     offset += pdu_lengths[n];
6437                 }
6438                 break;
6439             case PADDING_LCID:
6440                 /* No payload (in this position) */
6441                 break;
6442
6443             default:
6444                 break;
6445         }
6446     }
6447
6448
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,
6452                                        is_truncated);
6453     if (is_truncated) {
6454         proto_item_set_generated(truncated_ti);
6455         expert_add_info(pinfo, truncated_ti, &ei_mac_lte_mch_header_only_truncated);
6456         return;
6457     }
6458     else {
6459         proto_item_set_hidden(truncated_ti);
6460     }
6461
6462
6463     /* Now process remaining bodies, which should all be data */
6464     for (; n < number_of_headers; n++) {
6465
6466         proto_item *sdu_ti;
6467         guint16 data_length;
6468
6469         /* Break out if meet padding */
6470         if (lcids[n] == PADDING_LCID) {
6471             break;
6472         }
6473
6474         /* Work out length */
6475         data_length = (pdu_lengths[n] == -1) ?
6476                             tvb_reported_length_remaining(tvb, offset) :
6477                             pdu_lengths[n];
6478
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);
6489         } else {
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"),
6494                                                  data_length);
6495             if (pdu_lengths[n] >= 30)
6496             {
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, "...");
6499             }
6500             else
6501             {
6502                 proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, data_length));
6503             }
6504         }
6505
6506         offset += data_length;
6507     }
6508
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);
6514         }
6515         padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
6516                                                tvb, offset, 0,
6517                                                p_mac_lte_info->length - offset);
6518         proto_item_set_generated(padding_length_ti);
6519
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);
6525         }
6526     }
6527     else {
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);
6534         }
6535
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);
6541         }
6542     }
6543 }
6544
6545
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)
6549 {
6550     proto_item *ti;
6551
6552     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6553                              "SL-BCH PDU (%u bytes)",
6554                              tvb_reported_length_remaining(tvb, offset));
6555
6556     /****************************************/
6557     /* Whole frame is SL-BCH data           */
6558
6559     /* Raw data */
6560     ti = proto_tree_add_item(tree, hf_mac_lte_slbch_pdu,
6561                              tvb, offset, -1, ENC_NA);
6562
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);
6566
6567         /* Hide raw view of bytes */
6568         proto_item_set_hidden(ti);
6569
6570         call_with_catch_all(lte_rrc_sbcch_sl_bch_handle, rrc_tvb, pinfo, tree);
6571     }
6572 }
6573
6574
6575 /* Dissect SL-SCH PDU */
6576 static void dissect_slsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6577                            proto_item *pdu_ti,
6578                            int offset, mac_lte_info *p_mac_lte_info)
6579 {
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];
6584
6585     proto_item *pdu_header_ti, *pdu_subheader_ti, *ti, *truncated_ti, *padding_length_ti;
6586     proto_tree *pdu_header_tree, *pdu_subheader_tree;
6587
6588     guint8   number_of_padding_subheaders = 0;
6589     gboolean expecting_body_data = FALSE;
6590     gboolean is_truncated;
6591     guint32  reserved, version;
6592
6593     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
6594                              "%s: (SFN=%-4u, SF=%u) UEId=%-3u ",
6595                              "SL-SCH",
6596                              p_mac_lte_info->sysframeNumber,
6597                              p_mac_lte_info->subframeNumber,
6598                              p_mac_lte_info->ueid);
6599
6600     /* Add PDU block header subtree */
6601     pdu_header_ti = proto_tree_add_string_format(tree, hf_mac_lte_slsch_header,
6602                                                  tvb, offset, 0,
6603                                                  "", "MAC PDU Header");
6604     pdu_header_tree = proto_item_add_subtree(pdu_header_ti, ett_mac_lte_slsch_header);
6605
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,
6610                                                     tvb, offset, 6,
6611                                                     "",
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);
6619     offset++;
6620     if (reserved) {
6621         expert_add_info_format(pinfo, ti, &ei_mac_lte_reserved_not_zero,
6622                                "SL-SCH header Reserved bits not zero");
6623     }
6624     proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_src_l2_id,
6625                         tvb, offset, 3, ENC_BIG_ENDIAN);
6626     offset += 3;
6627     if (version == 3) {
6628         proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_dst_l2_id2,
6629                             tvb, offset, 3, ENC_BIG_ENDIAN);
6630         offset += 3;
6631     } else {
6632         proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_slsch_dst_l2_id,
6633                             tvb, offset, 2, ENC_BIG_ENDIAN);
6634         offset += 2;
6635     }
6636
6637     /* Dissect each sub-header */
6638     do {
6639         guint32     first_byte;
6640         guint64     length = 0;
6641         proto_item *lcid_ti;
6642         gint        offset_start_subheader = offset;
6643
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,
6648                                                         tvb, offset, 1,
6649                                                         "",
6650                                                         "Sub-header");
6651         pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
6652                                                     ett_mac_lte_slsch_subheader);
6653
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");
6661         }
6662
6663         /* Extended bit */
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);
6667
6668         /* LCID */
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,
6673                                  "(%s",
6674                                  val_to_str_const(lcids[number_of_headers],
6675                                                   slsch_lcid_vals, "(Unknown LCID)"));
6676         offset++;
6677
6678         /* Remember if we've seen a data subheader */
6679         if (lcids[number_of_headers] <= 10) {
6680             expecting_body_data = TRUE;
6681         }
6682
6683         /* Should not see padding after non-padding control... */
6684         if ((lcids[number_of_headers] == PADDING_LCID) &&
6685             extension)
6686         {
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);
6690             }
6691         }
6692
6693         /* Also flag if we have final padding but also padding subheaders
6694            at the start! */
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);
6698         }
6699
6700         /* Length field follows if not the last header or for a fixed-sized
6701            control element */
6702         if (!extension) {
6703             /* Last one... */
6704             pdu_lengths[number_of_headers] = -1;
6705         } else {
6706             /* Not the last one */
6707             if (lcids[number_of_headers] != PADDING_LCID) {
6708                 guint32 format;
6709
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);
6713
6714                 /* Now read length field itself */
6715                 if (format) {
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);
6719                     offset += 2;
6720                 } else {
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);
6724                     offset++;
6725                 }
6726                 pdu_lengths[number_of_headers] = (gint16)length;
6727             } else {
6728                 pdu_lengths[number_of_headers] = 0;
6729             }
6730         }
6731
6732         /* Close off description in info column */
6733         switch (pdu_lengths[number_of_headers]) {
6734             case 0:
6735                 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ") ");
6736                 break;
6737             case -1:
6738                 write_pdu_label_and_info_literal(pdu_ti, NULL, pinfo, ":remainder) ");
6739                 break;
6740             default:
6741                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
6742                                          pdu_lengths[number_of_headers]);
6743                 break;
6744         }
6745
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"));
6750
6751         switch (pdu_lengths[number_of_headers]) {
6752             case -1:
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"));
6757                 break;
6758             case 0:
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"));
6763                 break;
6764             default:
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]);
6771                 break;
6772         }
6773
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]);
6779         }
6780
6781         /* Set length of this subheader */
6782         proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
6783
6784         number_of_headers++;
6785     } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
6786
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);
6792         return;
6793     }
6794
6795     /* Append summary to overall PDU header root */
6796     proto_item_append_text(pdu_header_ti, "  [%u subheaders]",
6797                            number_of_headers);
6798
6799     /* And set its length to offset */
6800     proto_item_set_len(pdu_header_ti, offset);
6801
6802     /* Dissect control element bodies first */
6803
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) {
6807             break;
6808         }
6809
6810         switch (lcids[n]) {
6811             case PADDING_LCID:
6812                 /* No payload (in this position) */
6813                 break;
6814             default:
6815                 break;
6816         }
6817     }
6818
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,
6822                                        is_truncated);
6823     if (is_truncated) {
6824         proto_item_set_generated(truncated_ti);
6825         expert_add_info(pinfo, truncated_ti, &ei_mac_lte_slsch_header_only_truncated);
6826         return;
6827     } else {
6828         proto_item_set_hidden(truncated_ti);
6829     }
6830
6831
6832     /* Now process remaining bodies, which should all be data */
6833     for (; n < number_of_headers; n++) {
6834         proto_item *sdu_ti;
6835         guint16 data_length;
6836
6837         /* Break out if meet padding */
6838         if (lcids[n] == PADDING_LCID) {
6839             break;
6840         }
6841
6842         /* Work out length */
6843         data_length = (pdu_lengths[n] == -1) ?
6844                             tvb_reported_length_remaining(tvb, offset) :
6845                             pdu_lengths[n];
6846
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"),
6852                                              data_length);
6853
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, "...");
6858         } else {
6859             proto_item_append_text(sdu_ti, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, data_length));
6860         }
6861
6862         offset += data_length;
6863     }
6864
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);
6870         }
6871         padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
6872                                                tvb, offset, 0,
6873                                                p_mac_lte_info->length - offset);
6874         proto_item_set_generated(padding_length_ti);
6875
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);
6881         }
6882     } else {
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);
6889         }
6890
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);
6896         }
6897     }
6898 }
6899
6900
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)
6906 */
6907 int dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
6908 {
6909     proto_tree          *mac_lte_tree;
6910     proto_item          *pdu_ti;
6911     proto_tree          *context_tree;
6912     proto_item          *context_ti;
6913     proto_item          *retx_ti        = NULL;
6914     proto_item          *ti;
6915     proto_item          *hidden_root_ti;
6916     gint                 offset         = 0;
6917     struct mac_lte_info *p_mac_lte_info;
6918     gint                 n;
6919     guint               pdu_instance = GPOINTER_TO_UINT(data);
6920
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));
6923
6924     /* Set protocol name */
6925     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
6926
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);
6931
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);
6934
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);
6938         return 0;
6939     }
6940
6941     /* Clear info column */
6942     col_clear(pinfo->cinfo, COL_INFO);
6943
6944
6945     /*****************************************/
6946     /* Show context information              */
6947
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);
6953
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);
6957
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);
6961
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);
6966     }
6967
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);
6976         }
6977
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);
6987         }
6988
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);
6993         }
6994     }
6995
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;
7002
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);
7009
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);
7013
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);
7017
7018                 rapid_description = get_mac_lte_rapid_description(p_mac_lte_info->rapid);
7019
7020                 /* Info column */
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,
7024                                          rapid_description,
7025                                          p_mac_lte_info->rach_attempt_number);
7026
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,
7032                                        rapid_description,
7033                                        p_mac_lte_info->rach_attempt_number);
7034                 break;
7035             case ltemac_send_sr:
7036                     /* Count of SRs */
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);
7040
7041
7042                 for (n=0; n < p_mac_lte_info->number_of_srs; n++) {
7043                     proto_item *sr_ti;
7044                     proto_tree *sr_tree;
7045
7046                     /* SR event is subtree */
7047                     sr_ti = proto_tree_add_expert_format(mac_lte_tree, pinfo, &ei_mac_lte_oob_send_sr,
7048                                                 tvb, 0, 0,
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);
7052
7053                     /* RNTI */
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);
7057
7058                     /* UEID */
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);
7062
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]);
7067
7068                     /* Info column */
7069
7070                     if(n == 0) {
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]
7079                                                     );
7080                         }
7081                         else {
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]);
7087                         }
7088                     }
7089                     else {
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]);
7094                     }
7095
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);
7099                     }
7100                 }
7101                 break;
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);
7106
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);
7111
7112                 /* Info column */
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);
7117
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);
7121                 }
7122
7123                 break;
7124         }
7125
7126         /* Our work here is done */
7127         return -1;
7128     }
7129
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);
7136     }
7137
7138
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);
7142
7143     /* Check that RNTI value is consistent with given RNTI type */
7144     switch (p_mac_lte_info->rntiType) {
7145         case M_RNTI:
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);
7150                 return 0;
7151             }
7152             break;
7153         case P_RNTI:
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);
7158                 return 0;
7159             }
7160             break;
7161         case SI_RNTI:
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);
7166                 return 0;
7167             }
7168             break;
7169         case RA_RNTI:
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);
7174                 return 0;
7175             }
7176             break;
7177         case C_RNTI:
7178         case SPS_RNTI:
7179         case SL_RNTI:
7180         case G_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);
7186                 return 0;
7187             }
7188             break;
7189
7190         default:
7191             break;
7192     }
7193
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);
7198     }
7199     else {
7200         proto_item_set_hidden(ti);
7201     }
7202
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);
7211     }
7212
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);
7219
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);
7225             }
7226             else {
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);
7230             }
7231         }
7232
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);
7236     }
7237
7238     if (p_mac_lte_info->crcStatusValid) {
7239         /* Set status */
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);
7243
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,
7250                                                     crc_status_vals,
7251                                                     "Unknown"));
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,
7256                                                     crc_status_vals,
7257                                                     "Unknown"),
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);
7262         }
7263     }
7264
7265     /* Carrier Id */
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);
7269
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);
7272
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;
7282
7283     tap_info->mac_lte_time = pinfo->abs_ts;
7284
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) ?
7292                                                           hf_mac_lte_ulsch :
7293                                                           hf_mac_lte_dlsch,
7294                                                       tvb, offset, 0,
7295                                                       "",
7296                                                       "Hidden header");
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,
7300                                                       hf_mac_lte_slsch,
7301                                                       tvb, offset, 0,
7302                                                       "",
7303                                                       "Hidden header");
7304         proto_item_set_hidden(hidden_root_ti);
7305     }
7306
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);
7309
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) ?
7317                                      " - truncated" :
7318                                      ""));
7319
7320         /* Queue tap info */
7321         if (!pinfo->flags.in_error_pkt) {
7322             tap_queue_packet(mac_lte_tap, pinfo, tap_info);
7323         }
7324
7325         return -1;
7326     }
7327
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))) {
7332
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));
7335
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) {
7339
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);
7345
7346                     /* Store 'before' snapshot of UE state for this frame */
7347                     set_drx_info(pinfo, p_mac_lte_info, TRUE, pdu_instance);
7348                 }
7349                 /* Show current DRX state in tree as 'before' */
7350                 show_drx_info(pinfo, tree, tvb, p_mac_lte_info, TRUE, pdu_instance);
7351             }
7352         }
7353
7354         /* Queue tap info.
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);
7358         }
7359
7360         return -1;
7361     }
7362
7363     /* Reset this counter */
7364     s_number_of_rlc_pdus_shown = 0;
7365
7366     /* Dissect the MAC PDU itself. Format depends upon RNTI type. */
7367     switch (p_mac_lte_info->rntiType) {
7368
7369         case P_RNTI:
7370             /* PCH PDU */
7371             dissect_pch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, tap_info);
7372             break;
7373
7374         case RA_RNTI:
7375             /* RAR PDU */
7376             dissect_rar(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, tap_info);
7377             break;
7378
7379         case C_RNTI:
7380         case SPS_RNTI:
7381         case SC_RNTI:
7382         case G_RNTI:
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);
7387             break;
7388
7389         case SI_RNTI:
7390             /* BCH over DL-SCH */
7391             dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7392             break;
7393
7394         case M_RNTI:
7395             /* MCH PDU */
7396             dissect_mch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7397             break;
7398
7399         case SL_BCH_RNTI:
7400             /* SL BCH PDU */
7401             dissect_sl_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset);
7402             break;
7403
7404         case SL_RNTI:
7405             /* SL-SCH PDU */
7406             dissect_slsch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7407             break;
7408
7409         case NO_RNTI:
7410             /* Must be BCH over BCH... */
7411             dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
7412             break;
7413
7414
7415         default:
7416             break;
7417     }
7418
7419     /* Queue tap info */
7420     tap_queue_packet(mac_lte_tap, pinfo, tap_info);
7421
7422     return -1;
7423 }
7424
7425
7426
7427
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)
7431 {
7432     /* Reset structs */
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 */
7437
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);
7451
7452     /* Forget this setting */
7453     s_rapid_ranges_configured = FALSE;
7454 }
7455
7456 static void mac_lte_cleanup_protocol(void)
7457 {
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);
7471 }
7472
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_)
7475 {
7476     const lcid_drb_mapping_t *o = (const lcid_drb_mapping_t *)orig;
7477     lcid_drb_mapping_t       *d = (lcid_drb_mapping_t *)dest;
7478
7479     /* Copy all items over */
7480     d->lcid  = o->lcid;
7481     d->drbid = o->drbid;
7482     d->channel_type = o->channel_type;
7483
7484     return d;
7485 }
7486
7487
7488 /*************************************************************************/
7489 /* These functions get called from outside of this module, i.e. from RRC */
7490
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)
7493 {
7494     ue_dynamic_drb_mappings_t *ue_mappings;
7495     guint8 lcid = 0;
7496
7497     /* Check lcid range */
7498     if (drb_mapping->lcid_present) {
7499         lcid = drb_mapping->lcid;
7500
7501         /* Ignore if LCID is out of range */
7502         if ((lcid < 3) || (lcid > 10)) {
7503             return;
7504         }
7505     }
7506
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));
7510     if (!ue_mappings) {
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),
7515                             ue_mappings);
7516     }
7517
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];
7521     }
7522     if (lcid == 0) {
7523         /* Still no lcid - give up */
7524         return;
7525     }
7526
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;
7533     }
7534
7535     /* Fill in available RLC info */
7536     if (drb_mapping->rlcMode_present) {
7537         switch (drb_mapping->rlcMode) {
7538             case RLC_AM_MODE:
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;
7544                             } else {
7545                                 ue_mappings->mapping[lcid].channel_type = rlcAM16ulExtLiField;
7546                             }
7547                         } else {
7548                             if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7549                                 ue_mappings->mapping[lcid].channel_type = rlcAM16dlExtLiField;
7550                             } else {
7551                                 ue_mappings->mapping[lcid].channel_type = rlcAM16;
7552                             }
7553                         }
7554                     } else {
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;
7558                             } else {
7559                                 ue_mappings->mapping[lcid].channel_type = rlcAMul16ulExtLiField;
7560                             }
7561                         } else {
7562                             if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7563                                 ue_mappings->mapping[lcid].channel_type = rlcAMul16dlExtLiField;
7564                             } else {
7565                                 ue_mappings->mapping[lcid].channel_type = rlcAMul16;
7566                             }
7567                         }
7568                     }
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;
7573                         } else {
7574                             ue_mappings->mapping[lcid].channel_type = rlcAMdl16ulExtLiField;
7575                         }
7576                     } else {
7577                         if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7578                             ue_mappings->mapping[lcid].channel_type = rlcAMdl16dlExtLiField;
7579                         } else {
7580                             ue_mappings->mapping[lcid].channel_type = rlcAMdl16;
7581                         }
7582                     }
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;
7586                     } else {
7587                         ue_mappings->mapping[lcid].channel_type = rlcAMulExtLiField;
7588                     }
7589                 } else {
7590                     if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
7591                         ue_mappings->mapping[lcid].channel_type = rlcAMdlExtLiField;
7592                     } else {
7593                         ue_mappings->mapping[lcid].channel_type = rlcAM;
7594                     }
7595                 }
7596                 break;
7597             case RLC_UM_MODE:
7598                 if (drb_mapping->um_sn_length_present) {
7599                     if (drb_mapping->um_sn_length == 5) {
7600                         ue_mappings->mapping[lcid].channel_type = rlcUM5;
7601                     }
7602                     else {
7603                         ue_mappings->mapping[lcid].channel_type = rlcUM10;
7604                     }
7605                     break;
7606                 }
7607
7608             default:
7609                 break;
7610         }
7611     }
7612 }
7613
7614 /* Return the configured UL priority for the channel */
7615 static guint8 get_mac_lte_channel_priority(guint16 ueid, guint8 lcid,
7616                                            guint8 direction)
7617 {
7618     ue_dynamic_drb_mappings_t *ue_mappings;
7619
7620     /* Priority only affects UL */
7621     if (direction == DIRECTION_DOWNLINK) {
7622         return 0;
7623     }
7624
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));
7627     if (!ue_mappings) {
7628         return 0;
7629     }
7630
7631     /* Won't report value if channel not configured */
7632     if (!ue_mappings->mapping[lcid].valid) {
7633         return 0;
7634     }
7635     else {
7636         return ue_mappings->mapping[lcid].ul_priority;
7637     }
7638 }
7639
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)
7642 {
7643     if (global_mac_lte_show_drx && !PINFO_FD_VISITED(pinfo)) {
7644         ue_parameters_t *ue_params;
7645         guint32 previousFrameNum = 0;
7646
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);
7652         }
7653         else {
7654             previousFrameNum = ue_params->drx_state.config.frameNum;
7655         }
7656
7657         ue_params->drx_state_valid = TRUE;
7658
7659         /* Clearing state when new config comes in... */
7660         init_drx_ue_state(&ue_params->drx_state, TRUE);
7661
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;
7668     }
7669 }
7670
7671 /* Release DRX config for this UE */
7672 void set_mac_lte_drx_config_release(guint16 ueid, packet_info *pinfo)
7673 {
7674     if (global_mac_lte_show_drx && !PINFO_FD_VISITED(pinfo)) {
7675         ue_parameters_t *ue_params;
7676
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;
7681         }
7682     }
7683 }
7684
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
7687    saw. */
7688 void set_mac_lte_rapid_ranges(guint group_A, guint all_RA)
7689 {
7690     s_rapid_ranges_groupA = group_A;
7691     s_rapid_ranges_RA = all_RA;
7692     s_rapid_ranges_configured = TRUE;
7693 }
7694
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)
7697 {
7698     if (!PINFO_FD_VISITED(pinfo)) {
7699         ue_parameters_t *ue_params;
7700
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);
7706         }
7707
7708         ue_params->use_ext_bsr_sizes = use_ext_bsr_sizes;
7709     }
7710 }
7711
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)
7714 {
7715     if (!PINFO_FD_VISITED(pinfo)) {
7716         ue_parameters_t *ue_params;
7717
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);
7723         }
7724
7725         if (cell_type == SIMULT_PUCCH_PUSCH_PCELL) {
7726             ue_params->use_simult_pucch_pusch_pcell = simult_pucch_pusch;
7727         } else {
7728             ue_params->use_simult_pucch_pusch_pscell = simult_pucch_pusch;
7729         }
7730     }
7731 }
7732
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)
7735 {
7736     return (mac_lte_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
7737 }
7738
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)
7741 {
7742     p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info);
7743 }
7744
7745 void proto_register_mac_lte(void)
7746 {
7747     static hf_register_info hf[] =
7748     {
7749         /**********************************/
7750         /* Items for decoding context     */
7751         { &hf_mac_lte_context,
7752             { "Context",
7753               "mac-lte.context", FT_STRING, BASE_NONE, NULL, 0x0,
7754               NULL, HFILL
7755             }
7756         },
7757         { &hf_mac_lte_context_radio_type,
7758             { "Radio Type",
7759               "mac-lte.radio-type", FT_UINT8, BASE_DEC, VALS(radio_type_vals), 0x0,
7760               NULL, HFILL
7761             }
7762         },
7763         { &hf_mac_lte_context_direction,
7764             { "Direction",
7765               "mac-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
7766               "Direction of message", HFILL
7767             }
7768         },
7769         { &hf_mac_lte_context_rnti,
7770             { "RNTI",
7771               "mac-lte.rnti", FT_UINT16, BASE_DEC, NULL, 0x0,
7772               "RNTI associated with message", HFILL
7773             }
7774         },
7775         { &hf_mac_lte_context_rnti_type,
7776             { "RNTI Type",
7777               "mac-lte.rnti-type", FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0,
7778               "Type of RNTI associated with message", HFILL
7779             }
7780         },
7781         { &hf_mac_lte_context_ueid,
7782             { "UEId",
7783               "mac-lte.ueid", FT_UINT16, BASE_DEC, NULL, 0x0,
7784               "User Equipment Identifier associated with message", HFILL
7785             }
7786         },
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
7791             }
7792         },
7793         { &hf_mac_lte_context_subframe_number,
7794             { "Subframe",
7795               "mac-lte.subframe", FT_UINT16, BASE_DEC, NULL, 0x0,
7796               "Subframe number associated with message", HFILL
7797             }
7798         },
7799         { &hf_mac_lte_context_grant_subframe_number,
7800             { "Grant Subframe",
7801               "mac-lte.grant-subframe", FT_UINT16, BASE_DEC, NULL, 0x0,
7802               "Subframe when grant for this PDU was received", HFILL
7803             }
7804         },
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
7809             }
7810         },
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
7815             }
7816         },
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
7821             }
7822         },
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
7827             }
7828         },
7829         { &hf_mac_lte_context_retx_count,
7830             { "ReTX count",
7831               "mac-lte.retx-count", FT_UINT8, BASE_DEC, NULL, 0x0,
7832               "Number of times this PDU has been retransmitted", HFILL
7833             }
7834         },
7835         { &hf_mac_lte_context_retx_reason,
7836             { "ReTX reason",
7837               "mac-lte.retx-reason", FT_UINT8, BASE_DEC, VALS(ul_retx_grant_vals), 0x0,
7838               "Type of UL ReTx grant", HFILL
7839             }
7840         },
7841         { &hf_mac_lte_context_crc_status,
7842             { "CRC Status",
7843               "mac-lte.crc-status", FT_UINT8, BASE_DEC, VALS(crc_status_vals), 0x0,
7844               "CRC Status as reported by PHY", HFILL
7845             }
7846         },
7847         { &hf_mac_lte_context_carrier_id,
7848             { "Carrier Id",
7849               "mac-lte.carrier-id", FT_UINT8, BASE_DEC, VALS(carrier_id_vals), 0x0,
7850               NULL, HFILL
7851             }
7852         },
7853         { &hf_mac_lte_context_rapid,
7854             { "RAPID",
7855               "mac-lte.preamble-sent.rapid", FT_UINT8, BASE_DEC, NULL, 0x0,
7856               "RAPID sent in RACH preamble", HFILL
7857             }
7858         },
7859         { &hf_mac_lte_context_rach_attempt_number,
7860             { "RACH Attempt Number",
7861               "mac-lte.preamble-sent.attempt", FT_UINT8, BASE_DEC, NULL, 0x0,
7862               NULL, HFILL
7863             }
7864         },
7865
7866         { &hf_mac_lte_ues_ul_per_tti,
7867             { "UL UE in TTI",
7868               "mac-lte.ul-tti-count", FT_UINT8, BASE_DEC, NULL, 0x0,
7869               "In this TTI, this is the nth UL grant", HFILL
7870             }
7871         },
7872         { &hf_mac_lte_ues_dl_per_tti,
7873             { "DL UE in TTI",
7874               "mac-lte.dl-tti-count", FT_UINT8, BASE_DEC, NULL, 0x0,
7875               "In this TTI, this is the nth DL PDU", HFILL
7876             }
7877         },
7878
7879
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,
7884               NULL, HFILL
7885             }
7886         },
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,
7890               NULL, HFILL
7891             }
7892         },
7893         { &hf_mac_lte_context_phy_ul_tbs_index,
7894             { "TBs Index",
7895               "mac-lte.ul-phy.tbs-index", FT_UINT8, BASE_DEC, NULL, 0x0,
7896               NULL, HFILL
7897             }
7898         },
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,
7902               NULL, HFILL
7903             }
7904         },
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,
7908               NULL, HFILL
7909             }
7910         },
7911         { &hf_mac_lte_context_phy_ul_harq_id,
7912             { "HARQ Id",
7913               "mac-lte.ul-phy.harq-id", FT_UINT8, BASE_DEC, NULL, 0x0,
7914               NULL, HFILL
7915             }
7916         },
7917         { &hf_mac_lte_context_phy_ul_ndi,
7918             { "NDI",
7919               "mac-lte.ul-phy.ndi", FT_UINT8, BASE_DEC, NULL, 0x0,
7920               "UL New Data Indicator", HFILL
7921             }
7922         },
7923
7924         { &hf_mac_lte_context_phy_dl,
7925             { "DL PHY attributes",
7926               "mac-lte.dl-phy", FT_STRING, BASE_NONE, NULL, 0x0,
7927               NULL, HFILL
7928             }
7929         },
7930         { &hf_mac_lte_context_phy_dl_dci_format,
7931             { "DCI format",
7932               "mac-lte.dl-phy.dci-format", FT_UINT8, BASE_DEC, VALS(dci_format_vals), 0x0,
7933               NULL, HFILL
7934             }
7935         },
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,
7939               NULL, HFILL
7940             }
7941         },
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,
7945               NULL, HFILL
7946             }
7947         },
7948         { &hf_mac_lte_context_phy_dl_mcs_index,
7949             { "MCS Index",
7950               "mac-lte.dl-phy.mcs-index", FT_UINT8, BASE_DEC, NULL, 0x0,
7951               NULL, HFILL
7952             }
7953         },
7954         { &hf_mac_lte_context_phy_dl_redundancy_version_index,
7955             { "RV Index",
7956               "mac-lte.dl-phy.rv-index", FT_UINT8, BASE_DEC, NULL, 0x0,
7957               NULL, HFILL
7958             }
7959         },
7960         { &hf_mac_lte_context_phy_dl_retx,
7961             { "DL Retx",
7962               "mac-lte.dl-phy.dl-retx", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
7963               NULL, HFILL
7964             }
7965         },
7966         { &hf_mac_lte_context_phy_dl_resource_block_length,
7967             { "RB Length",
7968               "mac-lte.dl-phy.rb-length", FT_UINT8, BASE_DEC, NULL, 0x0,
7969               NULL, HFILL
7970             }
7971         },
7972         { &hf_mac_lte_context_phy_dl_harq_id,
7973             { "HARQ Id",
7974               "mac-lte.dl-phy.harq-id", FT_UINT8, BASE_DEC, NULL, 0x0,
7975               NULL, HFILL
7976             }
7977         },
7978         { &hf_mac_lte_context_phy_dl_ndi,
7979             { "NDI",
7980               "mac-lte.dl-phy.ndi", FT_UINT8, BASE_DEC, NULL, 0x0,
7981               "New Data Indicator", HFILL
7982             }
7983         },
7984         { &hf_mac_lte_context_phy_dl_tb,
7985             { "TB",
7986               "mac-lte.dl-phy.tb", FT_UINT8, BASE_DEC, NULL, 0x0,
7987               "Transport Block (antenna #)", HFILL
7988             }
7989         },
7990
7991         /* Out-of-band events */
7992         { &hf_mac_lte_oob_send_preamble,
7993             { "PRACH",
7994               "mac-lte.preamble-sent", FT_STRING, BASE_NONE, NULL, 0x0,
7995               NULL, HFILL
7996             }
7997         },
7998         { &hf_mac_lte_number_of_srs,
7999             { "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
8002             }
8003         },
8004
8005         /*******************************************/
8006         /* MAC shared channel header fields        */
8007         { &hf_mac_lte_ulsch,
8008             { "UL-SCH",
8009               "mac-lte.ulsch", FT_STRING, BASE_NONE, NULL, 0x0,
8010               NULL, HFILL
8011             }
8012         },
8013         { &hf_mac_lte_ulsch_header,
8014             { "UL-SCH Header",
8015               "mac-lte.ulsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8016               NULL, HFILL
8017             }
8018         },
8019         { &hf_mac_lte_dlsch_header,
8020             { "DL-SCH Header",
8021               "mac-lte.dlsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8022               NULL, HFILL
8023             }
8024         },
8025         { &hf_mac_lte_dlsch,
8026             { "DL-SCH",
8027               "mac-lte.dlsch", FT_STRING, BASE_NONE, NULL, 0x0,
8028               NULL, HFILL
8029             }
8030         },
8031         { &hf_mac_lte_sch_subheader,
8032             { "SCH sub-header",
8033               "mac-lte.sch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8034               NULL, HFILL
8035             }
8036         },
8037         { &hf_mac_lte_mch,
8038             { "MCH",
8039               "mac-lte.mch", FT_STRING, BASE_NONE, NULL, 0x0,
8040               NULL, HFILL
8041             }
8042         },
8043         { &hf_mac_lte_mch_header,
8044             { "MCH Header",
8045               "mac-lte.mch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8046               NULL, HFILL
8047             }
8048         },
8049         { &hf_mac_lte_mch_subheader,
8050             { "MCH sub-header",
8051               "mac-lte.mch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8052               NULL, HFILL
8053             }
8054         },
8055         { &hf_mac_lte_slsch,
8056             { "SL-SCH",
8057               "mac-lte.slsch", FT_STRING, BASE_NONE, NULL, 0x0,
8058               NULL, HFILL
8059             }
8060         },
8061         { &hf_mac_lte_slsch_header,
8062             { "SL-SCH Header",
8063               "mac-lte.slsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
8064               NULL, HFILL
8065             }
8066         },
8067         { &hf_mac_lte_slsch_subheader,
8068             { "SL-SCH sub-header",
8069               "mac-lte.slsch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
8070               NULL, HFILL
8071             }
8072         },
8073         { &hf_mac_lte_sch_reserved,
8074             { "SCH reserved bit",
8075               "mac-lte.sch.reserved", FT_UINT8, BASE_HEX, NULL, 0x80,
8076               NULL, HFILL
8077             }
8078         },
8079         { &hf_mac_lte_sch_format2,
8080             { "Format2",
8081               "mac-lte.sch.format2", FT_BOOLEAN, 8, TFS(&format2_vals), 0x40,
8082               NULL, HFILL
8083             }
8084         },
8085         { &hf_mac_lte_sch_extended,
8086             { "Extension",
8087               "mac-lte.sch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8088               "Extension - i.e. further headers after this one", HFILL
8089             }
8090         },
8091         { &hf_mac_lte_dlsch_lcid,
8092             { "LCID",
8093               "mac-lte.dlsch.lcid", FT_UINT8, BASE_HEX, VALS(dlsch_lcid_vals), 0x1f,
8094               "DL-SCH Logical Channel Identifier", HFILL
8095             }
8096         },
8097         { &hf_mac_lte_ulsch_lcid,
8098             { "LCID",
8099               "mac-lte.ulsch.lcid", FT_UINT8, BASE_HEX, VALS(ulsch_lcid_vals), 0x1f,
8100               "UL-SCH Logical Channel Identifier", HFILL
8101             }
8102         },
8103         { &hf_mac_lte_sch_format,
8104             { "Format",
8105               "mac-lte.sch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8106               NULL, HFILL
8107             }
8108         },
8109         { &hf_mac_lte_sch_length,
8110             { "Length",
8111               "mac-lte.sch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8112               "Length of MAC SDU or MAC control element", HFILL
8113             }
8114         },
8115         { &hf_mac_lte_mch_reserved,
8116             { "MCH reserved bits",
8117               "mac-lte.mch.reserved", FT_UINT8, BASE_HEX, NULL, 0x80,
8118               NULL, HFILL
8119             }
8120         },
8121         { &hf_mac_lte_mch_format2,
8122             { "Format2",
8123               "mac-lte.mch.format2", FT_BOOLEAN, 8, TFS(&format2_vals), 0x40,
8124               NULL, HFILL
8125             }
8126         },
8127         { &hf_mac_lte_mch_extended,
8128             { "Extension",
8129               "mac-lte.mch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8130               "Extension - i.e. further headers after this one", HFILL
8131             }
8132         },
8133         { &hf_mac_lte_mch_lcid,
8134             { "LCID",
8135               "mac-lte.mch.lcid", FT_UINT8, BASE_HEX, VALS(mch_lcid_vals), 0x1f,
8136               "MCH Logical Channel Identifier", HFILL
8137             }
8138         },
8139         { &hf_mac_lte_mch_format,
8140             { "Format",
8141               "mac-lte.mch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8142               NULL, HFILL
8143             }
8144         },
8145         { &hf_mac_lte_mch_length,
8146             { "Length",
8147               "mac-lte.mch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8148               "Length of MAC SDU or MAC control element", HFILL
8149             }
8150         },
8151         { &hf_mac_lte_slsch_version,
8152             { "Version",
8153               "mac-lte.slsch.version", FT_UINT8, BASE_DEC, NULL, 0xf0,
8154               NULL, HFILL
8155             }
8156         },
8157         { &hf_mac_lte_slsch_reserved,
8158             { "Reserved bits",
8159               "mac-lte.slsch.reserved", FT_UINT8, BASE_HEX, NULL, 0x0f,
8160               NULL, HFILL
8161             }
8162         },
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,
8166               NULL, HFILL
8167             }
8168         },
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,
8172               NULL, HFILL
8173             }
8174         },
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,
8178               NULL, HFILL
8179             }
8180         },
8181         { &hf_mac_lte_slsch_reserved2,
8182             { "Reserved bits",
8183               "mac-lte.slsch.reserved", FT_UINT8, BASE_HEX, NULL, 0xc0,
8184               NULL, HFILL
8185             }
8186         },
8187         { &hf_mac_lte_slsch_extended,
8188             { "Extension",
8189               "mac-lte.slsch.extended", FT_UINT8, BASE_HEX, NULL, 0x20,
8190               "Extension - i.e. further headers after this one", HFILL
8191             }
8192         },
8193         { &hf_mac_lte_slsch_lcid,
8194             { "LCID",
8195               "mac-lte.slsch.lcid", FT_UINT8, BASE_HEX, VALS(slsch_lcid_vals), 0x1f,
8196               "SL-SCH Logical Channel Identifier", HFILL
8197             }
8198         },
8199         { &hf_mac_lte_slsch_format,
8200             { "Format",
8201               "mac-lte.slsch.format", FT_BOOLEAN, 8, TFS(&format_vals), 0x80,
8202               NULL, HFILL
8203             }
8204         },
8205         { &hf_mac_lte_slsch_length,
8206             { "Length",
8207               "mac-lte.slsch.length", FT_UINT16, BASE_DEC, NULL, 0x0,
8208               "Length of MAC SDU or MAC control element", HFILL
8209             }
8210         },
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,
8214               NULL, HFILL
8215             }
8216         },
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,
8220               NULL, HFILL
8221             }
8222         },
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,
8226               NULL, HFILL
8227             }
8228         },
8229
8230         /********************************/
8231         /* Data                         */
8232         { &hf_mac_lte_sch_sdu,
8233             { "SDU",
8234               "mac-lte.sch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8235               "Shared channel SDU", HFILL
8236             }
8237         },
8238         { &hf_mac_lte_mch_sdu,
8239             { "SDU",
8240               "mac-lte.mch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8241               "Multicast channel SDU", HFILL
8242             }
8243         },
8244         { &hf_mac_lte_bch_pdu,
8245             { "BCH PDU",
8246               "mac-lte.bch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8247               NULL, HFILL
8248             }
8249         },
8250         { &hf_mac_lte_pch_pdu,
8251             { "PCH PDU",
8252               "mac-lte.pch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8253               NULL, HFILL
8254             }
8255         },
8256         { &hf_mac_lte_slbch_pdu,
8257             { "SL-BCH PDU",
8258               "mac-lte.slbch.pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8259               NULL, HFILL
8260             }
8261         },
8262         { &hf_mac_lte_slsch_sdu,
8263             { "SDU",
8264               "mac-lte.slsch.sdu", FT_BYTES, BASE_NONE, NULL, 0x0,
8265               "Sidelink shared channel SDU", HFILL
8266             }
8267         },
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
8272             }
8273         },
8274         { &hf_mac_lte_raw_pdu,
8275             { "Raw data",
8276               "mac-lte.raw-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8277               "Raw bytes of PDU (e.g. if CRC error)", HFILL
8278             }
8279         },
8280         { &hf_mac_lte_padding_data,
8281             { "Padding data",
8282               "mac-lte.padding-data", FT_BYTES, BASE_NONE, NULL, 0x0,
8283               NULL, HFILL
8284             }
8285         },
8286         { &hf_mac_lte_padding_length,
8287             { "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
8290             }
8291         },
8292
8293
8294
8295         /*********************************/
8296         /* RAR fields                    */
8297         { &hf_mac_lte_rar,
8298             { "RAR",
8299               "mac-lte.rar", FT_NONE, BASE_NONE, NULL, 0x0,
8300               NULL, HFILL
8301             }
8302         },
8303         { &hf_mac_lte_rar_headers,
8304             { "RAR Headers",
8305               "mac-lte.rar.headers", FT_STRING, BASE_NONE, NULL, 0x0,
8306               NULL, HFILL
8307             }
8308         },
8309         { &hf_mac_lte_rar_header,
8310             { "RAR Header",
8311               "mac-lte.rar.header", FT_STRING, BASE_NONE, NULL, 0x0,
8312               NULL, HFILL
8313             }
8314         },
8315         { &hf_mac_lte_rar_extension,
8316             { "Extension",
8317               "mac-lte.rar.e", FT_UINT8, BASE_HEX, NULL, 0x80,
8318               "Extension - i.e. further RAR headers after this one", HFILL
8319             }
8320         },
8321         { &hf_mac_lte_rar_t,
8322             { "Type",
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
8325             }
8326         },
8327         { &hf_mac_lte_rar_bi,
8328             { "BI",
8329               "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_vals), 0x0f,
8330               "Backoff Indicator (ms)", HFILL
8331             }
8332         },
8333         { &hf_mac_lte_rar_bi_nb,
8334             { "BI",
8335               "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_nb_vals), 0x0f,
8336               "Backoff Indicator (ms)", HFILL
8337             }
8338         },
8339         { &hf_mac_lte_rar_rapid,
8340             { "RAPID",
8341               "mac-lte.rar.rapid", FT_UINT8, BASE_HEX_DEC, NULL, 0x3f,
8342               "Random Access Preamble IDentifier", HFILL
8343             }
8344         },
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
8349             }
8350         },
8351         { &hf_mac_lte_rar_reserved,
8352             { "Reserved",
8353               "mac-lte.rar.reserved", FT_UINT8, BASE_HEX, NULL, 0x30,
8354               "Reserved bits in RAR header - should be 0", HFILL
8355             }
8356         },
8357
8358         { &hf_mac_lte_rar_body,
8359             { "RAR Body",
8360               "mac-lte.rar.body", FT_STRING, BASE_NONE, NULL, 0x0,
8361               NULL, HFILL
8362             }
8363         },
8364         { &hf_mac_lte_rar_reserved2,
8365             { "Reserved",
8366               "mac-lte.rar.reserved2", FT_UINT8, BASE_HEX, NULL, 0x80,
8367               "Reserved bit in RAR body - should be 0", HFILL
8368             }
8369         },
8370         { &hf_mac_lte_rar_ta,
8371             { "Timing Advance",
8372               "mac-lte.rar.ta", FT_UINT16, BASE_DEC, NULL, 0x7ff0,
8373               "Required adjustment to uplink transmission timing", HFILL
8374             }
8375         },
8376         { &hf_mac_lte_rar_ul_grant_ce_mode_b,
8377             { "UL Grant",
8378               "mac-lte.rar.ul-grant", FT_UINT16, BASE_DEC, NULL, 0x0fff,
8379               "Size of UL Grant", HFILL
8380             }
8381         },
8382         { &hf_mac_lte_rar_ul_grant,
8383             { "UL Grant",
8384               "mac-lte.rar.ul-grant", FT_UINT24, BASE_DEC, NULL, 0x0fffff,
8385               "Size of UL Grant", HFILL
8386             }
8387         },
8388         { &hf_mac_lte_rar_ul_grant_hopping,
8389             { "Hopping Flag",
8390               "mac-lte.rar.ul-grant.hopping", FT_UINT8, BASE_DEC, NULL, 0x08,
8391               NULL, HFILL
8392             }
8393         },
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,
8397               NULL, HFILL
8398             }
8399         },
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,
8403               NULL, HFILL
8404             }
8405         },
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
8410             }
8411         },
8412         { &hf_mac_lte_rar_ul_grant_ul_delay,
8413             { "UL Delay",
8414               "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, NULL, 0x02,
8415               NULL, HFILL
8416             }
8417         },
8418         { &hf_mac_lte_rar_ul_grant_cqi_request,
8419             { "CQI Request",
8420               "mac-lte.rar.ul-grant.cqi-request", FT_UINT8, BASE_DEC, NULL, 0x01,
8421               NULL, HFILL
8422             }
8423         },
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,
8427               NULL, HFILL
8428             }
8429         },
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,
8433               NULL, HFILL
8434             }
8435         },
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,
8439               NULL, HFILL
8440             }
8441         },
8442         { &hf_mac_lte_rar_ul_grant_mcs_ce_mode_a,
8443             { "MCS",
8444               "mac-lte.rar.ul-grant.mcs", FT_UINT16, BASE_DEC, NULL, 0x0,
8445               NULL, HFILL
8446             }
8447         },
8448         { &hf_mac_lte_rar_ul_grant_tpc_ce_mode_a,
8449             { "TPC",
8450               "mac-lte.rar.ul-grant.tpc", FT_UINT8, BASE_DEC, VALS(rar_ul_grant_tcsp_vals), 0x0,
8451               NULL, HFILL
8452             }
8453         },
8454         { &hf_mac_lte_rar_ul_grant_csi_request_ce_mode_a,
8455             { "CSI request",
8456               "mac-lte.rar.ul-grant.csi-request", FT_UINT8, BASE_DEC, NULL, 0x0,
8457               NULL, HFILL
8458             }
8459         },
8460         { &hf_mac_lte_rar_ul_grant_ul_delay_ce_mode_a,
8461             { "UL delay",
8462               "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
8463               NULL, HFILL
8464             }
8465         },
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,
8469               NULL, HFILL
8470             }
8471         },
8472         { &hf_mac_lte_rar_ul_grant_padding_ce_mode_a,
8473             { "Padding",
8474               "mac-lte.rar.ul-grant.padding", FT_UINT8, BASE_HEX, NULL, 0x0,
8475               NULL, HFILL
8476             }
8477         },
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,
8481               NULL, HFILL
8482             }
8483         },
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,
8487               NULL, HFILL
8488             }
8489         },
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,
8493               NULL, HFILL
8494             }
8495         },
8496         { &hf_mac_lte_rar_ul_grant_tbs_ce_mode_b,
8497             { "TBS",
8498               "mac-lte.rar.ul-grant.tbs", FT_UINT8, BASE_DEC, NULL, 0x0c,
8499               NULL, HFILL
8500             }
8501         },
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,
8505               NULL, HFILL
8506             }
8507         },
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,
8511               NULL, HFILL
8512             }
8513         },
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,
8517               NULL, HFILL
8518             }
8519         },
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,
8523               NULL, HFILL
8524             }
8525         },
8526         { &hf_mac_lte_rar_ul_grant_mcs_index,
8527             { "MCS index",
8528               "mac-lte.rar.ul-grant.mcs-index", FT_UINT8, BASE_DEC, NULL, 0xe0,
8529               NULL, HFILL
8530             }
8531         },
8532         { &hf_mac_lte_rar_ul_grant_padding_nb_mode,
8533             { "Padding",
8534               "mac-lte.rar.ul-grant.padding", FT_UINT8, BASE_HEX, NULL, 0x1f,
8535               NULL, HFILL
8536             }
8537         },
8538         { &hf_mac_lte_rar_temporary_crnti,
8539             { "Temporary C-RNTI",
8540               "mac-lte.rar.temporary-crnti", FT_UINT16, BASE_DEC, NULL, 0x0,
8541               NULL, HFILL
8542             }
8543         },
8544
8545         /**********************/
8546         /* Control PDU fields */
8547         { &hf_mac_lte_control_bsr,
8548             { "BSR",
8549               "mac-lte.control.bsr", FT_STRING, BASE_NONE, NULL, 0x0,
8550               "Buffer Status Report", HFILL
8551             }
8552         },
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,
8556               NULL, HFILL
8557             }
8558         },
8559         { &hf_mac_lte_control_short_bsr_buffer_size,
8560             { "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
8563             }
8564         },
8565         { &hf_mac_lte_control_long_bsr_buffer_size_0,
8566             { "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
8569             }
8570         },
8571         { &hf_mac_lte_control_long_bsr_buffer_size_1,
8572             { "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
8575             }
8576         },
8577         { &hf_mac_lte_control_long_bsr_buffer_size_2,
8578             { "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
8581             }
8582         },
8583         { &hf_mac_lte_control_long_bsr_buffer_size_3,
8584             { "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
8587             }
8588         },
8589         { &hf_mac_lte_control_short_ext_bsr_buffer_size,
8590             { "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
8593             }
8594         },
8595         { &hf_mac_lte_control_long_ext_bsr_buffer_size_0,
8596             { "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
8599             }
8600         },
8601         { &hf_mac_lte_control_long_ext_bsr_buffer_size_1,
8602             { "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
8605             }
8606         },
8607         { &hf_mac_lte_control_long_ext_bsr_buffer_size_2,
8608             { "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
8611             }
8612         },
8613         { &hf_mac_lte_control_long_ext_bsr_buffer_size_3,
8614             { "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
8617             }
8618         },
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,
8622               NULL, HFILL
8623             }
8624         },
8625         { &hf_mac_lte_control_crnti,
8626             { "C-RNTI",
8627               "mac-lte.control.crnti", FT_UINT16, BASE_DEC, NULL, 0x0,
8628               "C-RNTI for the UE", HFILL
8629             }
8630         },
8631         { &hf_mac_lte_control_timing_advance,
8632             { "Timing Advance",
8633               "mac-lte.control.timing-advance", FT_STRING, BASE_NONE, NULL, 0x0,
8634               NULL, HFILL
8635             }
8636         },
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,
8640               NULL, HFILL
8641             }
8642         },
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
8647             }
8648         },
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,
8652               NULL, HFILL
8653             }
8654         },
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,
8658               NULL, HFILL
8659             }
8660         },
8661         { &hf_mac_lte_control_ue_contention_resolution_msg3,
8662             { "Msg3",
8663               "mac-lte.control.ue-contention-resolution.msg3", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
8664               NULL, HFILL
8665             }
8666         },
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,
8670               NULL, HFILL
8671             }
8672         },
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
8677             }
8678         },
8679         { &hf_mac_lte_control_msg3_to_cr,
8680             { "CR response",
8681               "mac-lte.msg3-cr-response", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
8682               NULL, HFILL
8683             }
8684         },
8685
8686         { &hf_mac_lte_control_power_headroom,
8687             { "Power Headroom Report",
8688               "mac-lte.control.power-headroom", FT_STRING, BASE_NONE, NULL, 0x0,
8689               NULL, HFILL
8690             }
8691         },
8692         { &hf_mac_lte_control_power_headroom_reserved,
8693             { "Reserved",
8694               "mac-lte.control.power-headroom.reserved", FT_UINT8, BASE_DEC, NULL, 0xc0,
8695               "Reserved bits, should be 0", HFILL
8696             }
8697         },
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
8702             }
8703         },
8704
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
8709             }
8710         },
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
8715             }
8716         },
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
8721             }
8722         },
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
8727             }
8728         },
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
8733             }
8734         },
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
8739             }
8740         },
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
8745             }
8746         },
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
8751             }
8752         },
8753         { &hf_mac_lte_control_dual_conn_power_headroom_reserved,
8754             { "Reserved",
8755               "mac-lte.control.dual-conn-power-headroom.reserved", FT_UINT8, BASE_DEC,
8756               NULL, 0x01, "Reserved bit, should be 0", HFILL
8757             }
8758         },
8759         { &hf_mac_lte_control_dual_conn_power_headroom_power_backoff,
8760             { "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
8763             }
8764         },
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
8769             }
8770         },
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
8775             }
8776         },
8777         { &hf_mac_lte_control_dual_conn_power_headroom_reserved2,
8778             { "Reserved",
8779               "mac-lte.control.dual-conn-power-headroom.reserved2", FT_UINT8, BASE_DEC,
8780               NULL, 0xc0, "Reserved bits, should be 0", HFILL
8781             }
8782         },
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
8787             }
8788         },
8789
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
8794             }
8795         },
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
8800             }
8801         },
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
8806             }
8807         },
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
8812             }
8813         },
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
8818             }
8819         },
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
8824             }
8825         },
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
8830             }
8831         },
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
8836             }
8837         },
8838         { &hf_mac_lte_control_ext_power_headroom_reserved,
8839             { "Reserved",
8840               "mac-lte.control.ext-power-headroom.reserved", FT_UINT8, BASE_DEC,
8841               NULL, 0x01, "Reserved bit, should be 0", HFILL
8842             }
8843         },
8844         { &hf_mac_lte_control_ext_power_headroom_power_backoff,
8845             { "Power Backoff",
8846               "mac-lte.control.ext-power-headroom.power-backoff", FT_BOOLEAN, 8,
8847                TFS(&mac_lte_power_backoff_vals), 0x80, NULL, HFILL
8848             }
8849         },
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
8854             }
8855         },
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
8860             }
8861         },
8862         { &hf_mac_lte_control_ext_power_headroom_reserved2,
8863             { "Reserved",
8864               "mac-lte.control.ext-power-headroom.reserved2", FT_UINT8, BASE_DEC,
8865               NULL, 0xc0, "Reserved bits, should be 0", HFILL
8866             }
8867         },
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
8872             }
8873         },
8874
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
8879             }
8880         },
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
8885             }
8886         },
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
8891             }
8892         },
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
8897             }
8898         },
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
8903             }
8904         },
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
8909             }
8910         },
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
8915             }
8916         },
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
8921             }
8922         },
8923         { &hf_mac_lte_control_activation_deactivation_reserved,
8924             { "Reserved",
8925               "mac-lte.control.activation-deactivation.reserved", FT_UINT8, BASE_DEC,
8926               NULL, 0x01, "Reserved bit, should be 0", HFILL
8927             }
8928         },
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
8933             }
8934         },
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
8939             }
8940         },
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
8945             }
8946         },
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
8951             }
8952         },
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
8957             }
8958         },
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
8963             }
8964         },
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
8969             }
8970         },
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
8975             }
8976         },
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
8981             }
8982         },
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
8987             }
8988         },
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
8993             }
8994         },
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
8999             }
9000         },
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
9005             }
9006         },
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
9011             }
9012         },
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
9017             }
9018         },
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
9023             }
9024         },
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
9029             }
9030         },
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
9035             }
9036         },
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
9041             }
9042         },
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
9047             }
9048         },
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
9053             }
9054         },
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
9059             }
9060         },
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
9065             }
9066         },
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
9071             }
9072         },
9073
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,
9077               NULL, HFILL
9078             }
9079         },
9080         { &hf_mac_lte_control_mch_scheduling_info_lcid,
9081             { "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
9084             }
9085         },
9086         { &hf_mac_lte_control_mch_scheduling_info_stop_mtch,
9087             { "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
9090             }
9091         },
9092
9093         { &hf_mac_lte_control_sidelink_bsr,
9094             { "Sidelink BSR",
9095               "mac-lte.control.sidelink-bsr", FT_STRING, BASE_NONE, NULL, 0x0,
9096               NULL, HFILL
9097             }
9098         },
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,
9102               NULL, HFILL
9103             }
9104         },
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,
9108               NULL, HFILL
9109             }
9110         },
9111         { &hf_mac_lte_control_sidelink_bsr_buffer_size_odd,
9112             { "Buffer Size",
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
9115             }
9116         },
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,
9120               NULL, HFILL
9121             }
9122         },
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,
9126               NULL, HFILL
9127             }
9128         },
9129         { &hf_mac_lte_control_sidelink_bsr_buffer_size_even,
9130             { "Buffer Size",
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
9133             }
9134         },
9135         { &hf_mac_lte_control_sidelink_reserved,
9136             { "Reserved",
9137               "mac-lte.control.sidelink-bsr.reserved", FT_UINT8, BASE_DEC,
9138               NULL, 0x0f, "Reserved bits, should be 0", HFILL
9139             }
9140         },
9141
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,
9145               NULL, HFILL
9146             }
9147         },
9148         { &hf_mac_lte_control_data_vol_power_headroom_reserved,
9149             { "Reserved",
9150               "mac-lte.control.data-vol-power-headroom.reserved", FT_UINT8, BASE_DEC,
9151               NULL, 0xc0, "Reserved bits, should be 0", HFILL
9152             }
9153         },
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
9158             }
9159         },
9160         { &hf_mac_lte_control_data_vol_power_headroom_data_vol,
9161             { "Data Volume",
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
9164             }
9165         },
9166
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
9171             }
9172         },
9173         { &hf_mac_lte_control_recommended_bit_rate_lcid,
9174             { "LCID",
9175               "mac-lte.control.recommended-bit-rate.lcid", FT_UINT8, BASE_DEC,
9176               NULL, 0xf0, NULL, HFILL
9177             }
9178         },
9179         { &hf_mac_lte_control_recommended_bit_rate_dir,
9180             { "Direction",
9181               "mac-lte.control.recommended-bit-rate.dir", FT_BOOLEAN, 8,
9182               TFS(&tfs_uplink_downlink), 0x08, NULL, HFILL
9183             }
9184         },
9185         { &hf_mac_lte_control_recommended_bit_rate_bit_rate,
9186             { "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
9189             }
9190         },
9191         { &hf_mac_lte_control_recommended_bit_rate_reserved,
9192             { "Reserved",
9193               "mac-lte.control.recommended-bit-rate.reserved", FT_UINT8, BASE_HEX,
9194               NULL, 0x1f, "Reserved bits, should be 0", HFILL
9195             }
9196         },
9197
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
9202             }
9203         },
9204         { &hf_mac_lte_control_recommended_bit_rate_query_lcid,
9205             { "LCID",
9206               "mac-lte.control.recommended-bit-rate-query.lcid", FT_UINT8, BASE_DEC,
9207               NULL, 0xf0, NULL, HFILL
9208             }
9209         },
9210         { &hf_mac_lte_control_recommended_bit_rate_query_dir,
9211             { "Direction",
9212               "mac-lte.control.recommended-bit-rate-query.dir", FT_BOOLEAN, 8,
9213               TFS(&tfs_uplink_downlink), 0x08, NULL, HFILL
9214             }
9215         },
9216         { &hf_mac_lte_control_recommended_bit_rate_query_bit_rate,
9217             { "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
9220             }
9221         },
9222         { &hf_mac_lte_control_recommended_bit_rate_query_reserved,
9223             { "Reserved",
9224               "mac-lte.control.recommended-bit-rate-query.reserved", FT_UINT8, BASE_HEX,
9225               NULL, 0x1f, "Reserved bits, should be 0", HFILL
9226             }
9227         },
9228
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
9233             }
9234         },
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
9239             }
9240         },
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
9245             }
9246         },
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
9251             }
9252         },
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
9257             }
9258         },
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
9263             }
9264         },
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
9269             }
9270         },
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
9275             }
9276         },
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
9281             }
9282         },
9283
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,
9288               NULL, HFILL
9289             }
9290         },
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,
9294               NULL, HFILL
9295             }
9296         },
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,
9300               NULL, HFILL
9301             }
9302         },
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,
9306               NULL, HFILL
9307             }
9308         },
9309
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,
9313               NULL, HFILL
9314             }
9315         },
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,
9319               NULL, HFILL
9320             }
9321         },
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,
9325               NULL, HFILL
9326             }
9327         },
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,
9331               NULL, HFILL
9332             }
9333         },
9334
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,
9338               NULL, HFILL
9339             }
9340         },
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,
9344               NULL, HFILL
9345             }
9346         },
9347         { &hf_mac_lte_sr_leading_to_failure,
9348             { "This SR fails",
9349               "mac-lte.ulsch.failure-answering-sr-frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
9350               NULL, HFILL
9351             }
9352         },
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,
9356               NULL, HFILL
9357             }
9358         },
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,
9362               NULL, HFILL
9363             }
9364         },
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,
9368               NULL, HFILL
9369             }
9370         },
9371
9372         { &hf_mac_lte_drx_config,
9373             { "DRX Configuration",
9374               "mac-lte.drx-config", FT_STRING, BASE_NONE,
9375               NULL, 0x0, NULL, HFILL
9376             }
9377         },
9378         { &hf_mac_lte_drx_config_frame_num,
9379             { "Config Frame",
9380               "mac-lte.drx-config.config-frame", FT_FRAMENUM, BASE_NONE,
9381               NULL, 0x0, NULL, HFILL
9382             }
9383         },
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
9388             }
9389         },
9390         { &hf_mac_lte_drx_config_long_cycle,
9391             { "Long cycle",
9392               "mac-lte.drx-config.long-cycle", FT_UINT16, BASE_DEC,
9393               NULL, 0x0, NULL, HFILL
9394             }
9395         },
9396         { &hf_mac_lte_drx_config_cycle_offset,
9397             { "Cycle offset",
9398               "mac-lte.drx-config.cycle-offset", FT_UINT16, BASE_DEC,
9399               NULL, 0x0, NULL, HFILL
9400             }
9401         },
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
9406             }
9407         },
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
9412             }
9413         },
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
9418             }
9419         },
9420         { &hf_mac_lte_drx_config_short_cycle,
9421             { "Short cycle",
9422               "mac-lte.drx-config.short-cycle", FT_UINT16, BASE_DEC,
9423               NULL, 0x0, NULL, HFILL
9424             }
9425         },
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
9430             }
9431         },
9432
9433         { &hf_mac_lte_drx_state,
9434             { "DRX State",
9435               "mac-lte.drx-state", FT_STRING, BASE_NONE,
9436               NULL, 0x0, NULL, HFILL
9437             }
9438         },
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
9443             }
9444         },
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
9449             }
9450         },
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
9455             }
9456         },
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
9461             }
9462         },
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
9467             }
9468         },
9469         { &hf_mac_lte_drx_state_rtt_remaining,
9470             { "RTT remaining",
9471               "mac-lte.drx-state.rtt-remaining", FT_UINT16, BASE_DEC,
9472               NULL, 0x0, NULL, HFILL
9473             }
9474         },
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
9479             }
9480         },
9481     };
9482
9483     static gint *ett[] =
9484     {
9485         &ett_mac_lte,
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,
9499         &ett_mac_lte_bch,
9500         &ett_mac_lte_bsr,
9501         &ett_mac_lte_pch,
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,
9511         &ett_mac_lte_oob,
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
9519     };
9520
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 }}
9563     };
9564
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},
9569         {NULL, NULL, -1}
9570     };
9571
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},
9575         {NULL, NULL, -1}
9576     };
9577
9578
9579     module_t *mac_lte_module;
9580     expert_module_t* expert_mac_lte;
9581
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"),
9586         UAT_END_FIELDS
9587     };
9588
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));
9595
9596     /* Allow other dissectors to find this one by name. */
9597     register_dissector("mac-lte", dissect_mac_lte, proto_mac_lte);
9598
9599     /* Register the tap name */
9600     mac_lte_tap = register_tap("mac-lte");
9601
9602     /* Preferences */
9603     mac_lte_module = prefs_register_protocol(proto_mac_lte, NULL);
9604
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");
9612
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);
9617
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);
9622
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);
9627
9628     prefs_register_obsolete_preference(mac_lte_module, "heuristic_mac_lte_over_udp");
9629
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);
9634
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);
9639
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);
9644
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);
9650
9651     lcid_drb_mappings_uat = uat_new("Static LCID -> drb Table",
9652                                     sizeof(lcid_drb_mapping_t),
9653                                     "drb_logchans",
9654                                     TRUE,
9655                                     &lcid_drb_mappings,
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,
9660                                     NULL,
9661                                     NULL,
9662                                     NULL,
9663                                     NULL,
9664                                     lcid_drb_mapping_flds );
9665
9666     prefs_register_uat_preference(mac_lte_module,
9667                                   "drb_table",
9668                                   "LCID -> DRB Mappings Table",
9669                                   "A table that maps from configurable lcids -> RLC logical channels",
9670                                   lcid_drb_mappings_uat);
9671
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);
9676
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);
9681
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);
9686
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);
9691
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);
9696
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);
9701
9702     register_init_routine(&mac_lte_init_protocol);
9703     register_cleanup_routine(&mac_lte_cleanup_protocol);
9704 }
9705
9706 void proto_reg_handoff_mac_lte(void)
9707 {
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);
9710
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);
9725 }
9726
9727 /*
9728  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
9729  *
9730  * Local variables:
9731  * c-basic-offset: 4
9732  * tab-width: 8
9733  * indent-tabs-mode: nil
9734  * End:
9735  *
9736  * vi: set shiftwidth=4 tabstop=8 expandtab:
9737  * :indentSize=4:tabSize=8:noTabs=true:
9738  */