Update Free Software Foundation address.
[metze/wireshark/wip.git] / epan / dissectors / packet-mac-lte.c
1 /* Routines for LTE MAC disassembly
2  *
3  * Martin Mathieson
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include <epan/packet.h>
29 #include <epan/expert.h>
30 #include <epan/prefs.h>
31 #include <epan/tap.h>
32 #include <epan/uat.h>
33
34 #include "packet-mac-lte.h"
35 #include "packet-rlc-lte.h"
36
37
38 /* Described in:
39  * 3GPP TS 36.321 Evolved Universal Terrestrial Radio Access (E-UTRA)
40  *                Medium Access Control (MAC) protocol specification (Release 10)
41  */
42
43
44 /* Initialize the protocol and registered fields. */
45 int proto_mac_lte = -1;
46
47 static int mac_lte_tap = -1;
48
49 /* Decoding context */
50 static int hf_mac_lte_context = -1;
51 static int hf_mac_lte_context_radio_type = -1;
52 static int hf_mac_lte_context_direction = -1;
53 static int hf_mac_lte_context_rnti = -1;
54 static int hf_mac_lte_context_rnti_type = -1;
55 static int hf_mac_lte_context_ueid = -1;
56 static int hf_mac_lte_context_sysframe_number = -1;
57 static int hf_mac_lte_context_subframe_number = -1;
58 static int hf_mac_lte_context_grant_subframe_number = -1;
59 static int hf_mac_lte_context_predefined_frame = -1;
60 static int hf_mac_lte_context_length = -1;
61 static int hf_mac_lte_context_ul_grant_size = -1;
62 static int hf_mac_lte_context_bch_transport_channel = -1;
63 static int hf_mac_lte_context_retx_count = -1;
64 static int hf_mac_lte_context_retx_reason = -1;
65 static int hf_mac_lte_context_crc_status = -1;
66 static int hf_mac_lte_context_rapid = -1;
67 static int hf_mac_lte_context_rach_attempt_number = -1;
68
69 /* Inferred context */
70 static int hf_mac_lte_ues_ul_per_tti = -1;
71 static int hf_mac_lte_ues_dl_per_tti = -1;
72
73
74 /* Extra PHY context */
75 static int hf_mac_lte_context_phy_ul = -1;
76 static int hf_mac_lte_context_phy_ul_modulation_type = -1;
77 static int hf_mac_lte_context_phy_ul_tbs_index = -1;
78 static int hf_mac_lte_context_phy_ul_resource_block_length = -1;
79 static int hf_mac_lte_context_phy_ul_resource_block_start = -1;
80 static int hf_mac_lte_context_phy_ul_harq_id = -1;
81 static int hf_mac_lte_context_phy_ul_ndi = -1;
82
83 static int hf_mac_lte_context_phy_dl = -1;
84 static int hf_mac_lte_context_phy_dl_dci_format = -1;
85 static int hf_mac_lte_context_phy_dl_resource_allocation_type = -1;
86 static int hf_mac_lte_context_phy_dl_aggregation_level = -1;
87 static int hf_mac_lte_context_phy_dl_mcs_index = -1;
88 static int hf_mac_lte_context_phy_dl_redundancy_version_index = -1;
89 static int hf_mac_lte_context_phy_dl_retx = -1;
90 static int hf_mac_lte_context_phy_dl_resource_block_length = -1;
91 static int hf_mac_lte_context_phy_dl_crc_status = -1;
92 static int hf_mac_lte_context_phy_dl_harq_id = -1;
93 static int hf_mac_lte_context_phy_dl_ndi = -1;
94 static int hf_mac_lte_context_phy_dl_tb = -1;
95
96
97 /* Out-of-band events */
98 static int hf_mac_lte_oob_send_preamble = -1;
99 static int hf_mac_lte_oob_send_sr = -1;
100 static int hf_mac_lte_number_of_srs = -1;
101 static int hf_mac_lte_oob_sr_failure = -1;
102
103 /* MAC SCH/MCH header fields */
104 static int hf_mac_lte_ulsch = -1;
105 static int hf_mac_lte_ulsch_header = -1;
106 static int hf_mac_lte_dlsch = -1;
107 static int hf_mac_lte_dlsch_header = -1;
108 static int hf_mac_lte_sch_subheader = -1;
109 static int hf_mac_lte_mch = -1;
110 static int hf_mac_lte_mch_header = -1;
111 static int hf_mac_lte_mch_subheader = -1;
112
113 static int hf_mac_lte_sch_reserved = -1;
114 static int hf_mac_lte_dlsch_lcid = -1;
115 static int hf_mac_lte_ulsch_lcid = -1;
116 static int hf_mac_lte_sch_extended = -1;
117 static int hf_mac_lte_sch_format = -1;
118 static int hf_mac_lte_sch_length = -1;
119 static int hf_mac_lte_mch_reserved = -1;
120 static int hf_mac_lte_mch_lcid = -1;
121 static int hf_mac_lte_mch_extended = -1;
122 static int hf_mac_lte_mch_format = -1;
123 static int hf_mac_lte_mch_length = -1;
124
125 static int hf_mac_lte_sch_header_only = -1;
126 static int hf_mac_lte_mch_header_only = -1;
127
128 /* Data */
129 static int hf_mac_lte_sch_sdu = -1;
130 static int hf_mac_lte_mch_sdu = -1;
131 static int hf_mac_lte_bch_pdu = -1;
132 static int hf_mac_lte_pch_pdu = -1;
133 static int hf_mac_lte_predefined_pdu = -1;
134 static int hf_mac_lte_raw_pdu = -1;
135 static int hf_mac_lte_padding_data = -1;
136 static int hf_mac_lte_padding_length = -1;
137
138
139 /* RAR fields */
140 static int hf_mac_lte_rar = -1;
141 static int hf_mac_lte_rar_headers = -1;
142 static int hf_mac_lte_rar_header = -1;
143 static int hf_mac_lte_rar_extension = -1;
144 static int hf_mac_lte_rar_t = -1;
145 static int hf_mac_lte_rar_bi = -1;
146 static int hf_mac_lte_rar_rapid = -1;
147 static int hf_mac_lte_rar_reserved = -1;
148 static int hf_mac_lte_rar_body = -1;
149 static int hf_mac_lte_rar_reserved2 = -1;
150 static int hf_mac_lte_rar_ta = -1;
151 static int hf_mac_lte_rar_ul_grant = -1;
152 static int hf_mac_lte_rar_ul_grant_hopping = -1;
153 static int hf_mac_lte_rar_ul_grant_fsrba = -1;
154 static int hf_mac_lte_rar_ul_grant_tmcs = -1;
155 static int hf_mac_lte_rar_ul_grant_tcsp = -1;
156 static int hf_mac_lte_rar_ul_grant_ul_delay = -1;
157 static int hf_mac_lte_rar_ul_grant_cqi_request = -1;
158 static int hf_mac_lte_rar_temporary_crnti = -1;
159
160 /* Common channel control values */
161 static int hf_mac_lte_control_bsr = -1;
162 static int hf_mac_lte_control_bsr_lcg_id = -1;
163 static int hf_mac_lte_control_short_bsr_buffer_size = -1;
164 static int hf_mac_lte_control_long_bsr_buffer_size_0 = -1;
165 static int hf_mac_lte_control_long_bsr_buffer_size_1 = -1;
166 static int hf_mac_lte_control_long_bsr_buffer_size_2 = -1;
167 static int hf_mac_lte_control_long_bsr_buffer_size_3 = -1;
168 static int hf_mac_lte_control_short_ext_bsr_buffer_size = -1;
169 static int hf_mac_lte_control_long_ext_bsr_buffer_size_0 = -1;
170 static int hf_mac_lte_control_long_ext_bsr_buffer_size_1 = -1;
171 static int hf_mac_lte_control_long_ext_bsr_buffer_size_2 = -1;
172 static int hf_mac_lte_control_long_ext_bsr_buffer_size_3 = -1;
173 static int hf_mac_lte_control_crnti = -1;
174 static int hf_mac_lte_control_timing_advance = -1;
175 static int hf_mac_lte_control_timing_advance_reserved = -1;
176 static int hf_mac_lte_control_ue_contention_resolution = -1;
177 static int hf_mac_lte_control_ue_contention_resolution_identity = -1;
178 static int hf_mac_lte_control_ue_contention_resolution_msg3 = -1;
179 static int hf_mac_lte_control_ue_contention_resolution_msg3_matched = -1;
180 static int hf_mac_lte_control_ue_contention_resolution_time_since_msg3 = -1;
181 static int hf_mac_lte_control_power_headroom = -1;
182 static int hf_mac_lte_control_power_headroom_reserved = -1;
183 static int hf_mac_lte_control_power_headroom_level = -1;
184 static int hf_mac_lte_control_ext_power_headroom = -1;
185 static int hf_mac_lte_control_ext_power_headroom_c7 = -1;
186 static int hf_mac_lte_control_ext_power_headroom_c6 = -1;
187 static int hf_mac_lte_control_ext_power_headroom_c5 = -1;
188 static int hf_mac_lte_control_ext_power_headroom_c4 = -1;
189 static int hf_mac_lte_control_ext_power_headroom_c3 = -1;
190 static int hf_mac_lte_control_ext_power_headroom_c2 = -1;
191 static int hf_mac_lte_control_ext_power_headroom_c1 = -1;
192 static int hf_mac_lte_control_ext_power_headroom_reserved = -1;
193 static int hf_mac_lte_control_ext_power_headroom_power_backoff = -1;
194 static int hf_mac_lte_control_ext_power_headroom_value = -1;
195 static int hf_mac_lte_control_ext_power_headroom_level = -1;
196 static int hf_mac_lte_control_ext_power_headroom_reserved2 = -1;
197 static int hf_mac_lte_control_ext_power_headroom_pcmaxc = -1;
198 static int hf_mac_lte_control_activation_deactivation = -1;
199 static int hf_mac_lte_control_activation_deactivation_c7 = -1;
200 static int hf_mac_lte_control_activation_deactivation_c6 = -1;
201 static int hf_mac_lte_control_activation_deactivation_c5 = -1;
202 static int hf_mac_lte_control_activation_deactivation_c4 = -1;
203 static int hf_mac_lte_control_activation_deactivation_c3 = -1;
204 static int hf_mac_lte_control_activation_deactivation_c2 = -1;
205 static int hf_mac_lte_control_activation_deactivation_c1 = -1;
206 static int hf_mac_lte_control_activation_deactivation_reserved = -1;
207 static int hf_mac_lte_control_mch_scheduling_info = -1;
208 static int hf_mac_lte_control_mch_scheduling_info_lcid = -1;
209 static int hf_mac_lte_control_mch_scheduling_info_stop_mtch = -1;
210
211 static int hf_mac_lte_dl_harq_resend_original_frame = -1;
212 static int hf_mac_lte_dl_harq_resend_time_since_previous_frame = -1;
213 static int hf_mac_lte_dl_harq_resend_next_frame = -1;
214 static int hf_mac_lte_dl_harq_resend_time_until_next_frame = -1;
215
216 static int hf_mac_lte_ul_harq_resend_original_frame = -1;
217 static int hf_mac_lte_ul_harq_resend_time_since_previous_frame = -1;
218 static int hf_mac_lte_ul_harq_resend_next_frame = -1;
219 static int hf_mac_lte_ul_harq_resend_time_until_next_frame = -1;
220
221
222 static int hf_mac_lte_grant_answering_sr = -1;
223 static int hf_mac_lte_failure_answering_sr = -1;
224 static int hf_mac_lte_sr_leading_to_failure = -1;
225 static int hf_mac_lte_sr_leading_to_grant = -1;
226 static int hf_mac_lte_sr_invalid_event = -1;
227 static int hf_mac_lte_sr_time_since_request = -1;
228 static int hf_mac_lte_sr_time_until_answer = -1;
229
230
231 /* Subtrees. */
232 static int ett_mac_lte = -1;
233 static int ett_mac_lte_context = -1;
234 static int ett_mac_lte_phy_context = -1;
235 static int ett_mac_lte_ulsch_header = -1;
236 static int ett_mac_lte_dlsch_header = -1;
237 static int ett_mac_lte_mch_header = -1;
238 static int ett_mac_lte_sch_subheader = -1;
239 static int ett_mac_lte_mch_subheader = -1;
240 static int ett_mac_lte_rar_headers = -1;
241 static int ett_mac_lte_rar_header = -1;
242 static int ett_mac_lte_rar_body = -1;
243 static int ett_mac_lte_rar_ul_grant = -1;
244 static int ett_mac_lte_bsr = -1;
245 static int ett_mac_lte_bch = -1;
246 static int ett_mac_lte_pch = -1;
247 static int ett_mac_lte_activation_deactivation = -1;
248 static int ett_mac_lte_contention_resolution = -1;
249 static int ett_mac_lte_power_headroom = -1;
250 static int ett_mac_lte_extended_power_headroom = -1;
251 static int ett_mac_lte_extended_power_headroom_cell = -1;
252 static int ett_mac_lte_mch_scheduling_info = -1;
253 static int ett_mac_lte_oob = -1;
254
255
256
257 /* Constants and value strings */
258
259 static const value_string radio_type_vals[] =
260 {
261     { FDD_RADIO,      "FDD"},
262     { TDD_RADIO,      "TDD"},
263     { 0, NULL }
264 };
265
266
267 static const value_string direction_vals[] =
268 {
269     { DIRECTION_UPLINK,      "Uplink"},
270     { DIRECTION_DOWNLINK,    "Downlink"},
271     { 0, NULL }
272 };
273
274
275 static const value_string rnti_type_vals[] =
276 {
277     { NO_RNTI,     "NO-RNTI"},
278     { P_RNTI,      "P-RNTI"},
279     { RA_RNTI,     "RA-RNTI"},
280     { C_RNTI,      "C-RNTI"},
281     { SI_RNTI,     "SI-RNTI"},
282     { SPS_RNTI,    "SPS-RNTI"},
283     { M_RNTI,      "M-RNTI"},
284     { 0, NULL }
285 };
286
287 static const value_string bch_transport_channel_vals[] =
288 {
289     { SI_RNTI,      "DL-SCH"},
290     { NO_RNTI,      "BCH"},
291     { 0, NULL }
292 };
293
294 static const value_string crc_status_vals[] =
295 {
296     { crc_success,                "OK"},
297     { crc_fail,                   "Failed"},
298     { crc_high_code_rate,         "High Code Rate"},
299     { crc_pdsch_lost,             "PDSCH Lost"},
300     { crc_duplicate_nonzero_rv,   "Duplicate_nonzero_rv"},
301     { 0, NULL }
302 };
303
304
305 static const value_string dci_format_vals[] =
306 {
307     { 0, "0"},
308     { 1, "1"},
309     { 2, "1A"},
310     { 3, "1B"},
311     { 4, "1C"},
312     { 5, "1D"},
313     { 6, "2"},
314     { 7, "2A"},
315     { 8, "3/3A"},
316     { 0, NULL }
317 };
318
319 static const value_string aggregation_level_vals[] =
320 {
321     { 0, "1"},
322     { 1, "2"},
323     { 2, "4"},
324     { 3, "8"},
325     { 0, NULL }
326 };
327
328 static const value_string modulation_type_vals[] =
329 {
330     { 2, "QPSK"},
331     { 4, "QAM16"},
332     { 6, "QAM64"},
333     { 0, NULL }
334 };
335
336 static const true_false_string mac_lte_scell_ph_vals = {
337     "Reported",
338     "Not reported"
339 };
340
341 static const true_false_string mac_lte_power_backoff_vals = {
342     "Applied",
343     "Not applied"
344 };
345
346 static const true_false_string mac_lte_ph_value_vals = {
347     "Based on reference format",
348     "Based on real transmission"
349 };
350
351 static const true_false_string mac_lte_scell_status_vals = {
352     "Activated",
353     "Deactivated"
354 };
355
356 #define ACTIVATION_DEACTIVATION_LCID           0x1b
357 #define UE_CONTENTION_RESOLUTION_IDENTITY_LCID 0x1c
358 #define TIMING_ADVANCE_LCID                    0x1d
359 #define DRX_COMMAND_LCID                       0x1e
360 #define PADDING_LCID                           0x1f
361
362 static const value_string dlsch_lcid_vals[] =
363 {
364     { 0,                                        "CCCH"},
365     { 1,                                        "1"},
366     { 2,                                        "2"},
367     { 3,                                        "3"},
368     { 4,                                        "4"},
369     { 5,                                        "5"},
370     { 6,                                        "6"},
371     { 7,                                        "7"},
372     { 8,                                        "8"},
373     { 9,                                        "9"},
374     { 10,                                       "10"},
375     { ACTIVATION_DEACTIVATION_LCID          ,   "Activation/Deactivation"},
376     { UE_CONTENTION_RESOLUTION_IDENTITY_LCID,   "UE Contention Resolution Identity"},
377     { TIMING_ADVANCE_LCID                   ,   "Timing Advance"},
378     { DRX_COMMAND_LCID                      ,   "DRX Command"},
379     { PADDING_LCID                          ,   "Padding" },
380     { 0, NULL }
381 };
382
383 #define EXTENDED_POWER_HEADROOM_REPORT_LCID 0x19
384 #define POWER_HEADROOM_REPORT_LCID          0x1a
385 #define CRNTI_LCID                          0x1b
386 #define TRUNCATED_BSR_LCID                  0x1c
387 #define SHORT_BSR_LCID                      0x1d
388 #define LONG_BSR_LCID                       0x1e
389
390 static const value_string ulsch_lcid_vals[] =
391 {
392     { 0,                                   "CCCH"},
393     { 1,                                   "1"},
394     { 2,                                   "2"},
395     { 3,                                   "3"},
396     { 4,                                   "4"},
397     { 5,                                   "5"},
398     { 6,                                   "6"},
399     { 7,                                   "7"},
400     { 8,                                   "8"},
401     { 9,                                   "9"},
402     { 10,                                  "10"},
403     { EXTENDED_POWER_HEADROOM_REPORT_LCID, "Extended Power Headroom Report"},
404     { POWER_HEADROOM_REPORT_LCID,          "Power Headroom Report"},
405     { CRNTI_LCID,                          "C-RNTI"},
406     { TRUNCATED_BSR_LCID,                  "Truncated BSR"},
407     { SHORT_BSR_LCID,                      "Short BSR"},
408     { LONG_BSR_LCID,                       "Long BSR"},
409     { PADDING_LCID,                        "Padding" },
410     { 0, NULL }
411 };
412
413 #define MCH_SCHEDULING_INFO_LCID 0x1e
414
415 static const value_string mch_lcid_vals[] =
416 {
417     { 0,                            "MCCH"},
418     { 1,                            "1"},
419     { 2,                            "2"},
420     { 3,                            "3"},
421     { 4,                            "4"},
422     { 5,                            "5"},
423     { 6,                            "6"},
424     { 7,                            "7"},
425     { 8,                            "8"},
426     { 9,                            "9"},
427     { 10,                           "10"},
428     { 11,                           "11"},
429     { 12,                           "12"},
430     { 13,                           "13"},
431     { 14,                           "14"},
432     { 15,                           "15"},
433     { 16,                           "16"},
434     { 17,                           "17"},
435     { 18,                           "18"},
436     { 19,                           "19"},
437     { 20,                           "20"},
438     { 21,                           "21"},
439     { 22,                           "22"},
440     { 23,                           "23"},
441     { 24,                           "24"},
442     { 25,                           "25"},
443     { 26,                           "26"},
444     { 27,                           "27"},
445     { 28,                           "28"},
446     { MCH_SCHEDULING_INFO_LCID,     "MCH Scheduling Information"},
447     { PADDING_LCID,                 "Padding" },
448     { 0, NULL }
449 };
450
451 static const value_string format_vals[] =
452 {
453     { 0,      "Data length is < 128 bytes"},
454     { 1,      "Data length is >= 128 bytes"},
455     { 0, NULL }
456 };
457
458
459 static const value_string rar_type_vals[] =
460 {
461     { 0,      "Backoff Indicator present"},
462     { 1,      "RAPID present"},
463     { 0, NULL }
464 };
465
466
467 static const value_string rar_bi_vals[] =
468 {
469     { 0,      "0"},
470     { 1,      "10"},
471     { 2,      "20"},
472     { 3,      "30"},
473     { 4,      "40"},
474     { 5,      "60"},
475     { 6,      "80"},
476     { 7,      "120"},
477     { 8,      "160"},
478     { 9,      "240"},
479     { 10,     "320"},
480     { 11,     "480"},
481     { 12,     "960"},
482     { 0, NULL }
483 };
484
485
486 static const value_string buffer_size_vals[] =
487 {
488     { 0,      "BS = 0"},
489     { 1,      "0 < BS <= 10"},
490     { 2,      "10 < BS <= 12"},
491     { 3,      "12 < BS <= 14"},
492     { 4,      "14 < BS <= 17"},
493     { 5,      "17 < BS <= 19"},
494     { 6,      "19 < BS <= 22"},
495     { 7,      "22 < BS <= 26"},
496     { 8,      "26 < BS <= 31"},
497     { 9,      "31 < BS <= 36"},
498     { 10,     "36 < BS <= 42"},
499     { 11,     "42 < BS <= 49"},
500     { 12,     "49 < BS <= 57"},
501     { 13,     "47 < BS <= 67"},
502     { 14,     "67 < BS <= 78"},
503     { 15,     "78 < BS <= 91"},
504     { 16,     "91 < BS <= 107"},
505     { 17,     "107 < BS <= 125"},
506     { 18,     "125 < BS <= 146"},
507     { 19,     "146 < BS <= 171"},
508     { 20,     "171 < BS <= 200"},
509     { 21,     "200 < BS <= 234"},
510     { 22,     "234 < BS <= 274"},
511     { 23,     "274 < BS <= 321"},
512     { 24,     "321 < BS <= 376"},
513     { 25,     "376 < BS <= 440"},
514     { 26,     "440 < BS <= 515"},
515     { 27,     "515 < BS <= 603"},
516     { 28,     "603 < BS <= 706"},
517     { 29,     "706 < BS <= 826"},
518     { 30,     "826 < BS <= 967"},
519     { 31,     "967 < BS <= 1132"},
520     { 32,     "1132 < BS <= 1326"},
521     { 33,     "1326 < BS <= 1552"},
522     { 34,     "1552 < BS <= 1817"},
523     { 35,     "1817 < BS <= 2127"},
524     { 36,     "2127 < BS <= 2490"},
525     { 37,     "2490 < BS <= 2915"},
526     { 38,     "2915 < BS <= 3413"},
527     { 39,     "3413 < BS <= 3995"},
528     { 40,     "3995 < BS <= 4677"},
529     { 41,     "4677 < BS <= 5476"},
530     { 42,     "5476 < BS <= 6411"},
531     { 43,     "6411 < BS <= 7505"},
532     { 44,     "7505 < BS <= 8787"},
533     { 45,     "8787 < BS <= 10276"},
534     { 46,     "10287 < BS <= 12043"},
535     { 47,     "12043 < BS <= 14099"},
536     { 48,     "14099 < BS <= 16507"},
537     { 49,     "16507 < BS <= 19325"},
538     { 50,     "19325 < BS <= 22624"},
539     { 51,     "22624 < BS <= 26487"},
540     { 52,     "26487 < BS <= 31009"},
541     { 53,     "31009 < BS <= 36304"},
542     { 54,     "36304 < BS <= 42502"},
543     { 55,     "42502 < BS <= 49759"},
544     { 56,     "49759 < BS <= 58255"},
545     { 57,     "58255 < BS <= 68201"},
546     { 58,     "68201 < BS <= 79846"},
547     { 59,     "79846 < BS <= 93479"},
548     { 60,     "93479 < BS <= 109439"},
549     { 61,     "109439 < BS <= 128125"},
550     { 62,     "128125 < BS <= 150000"},
551     { 63,     "BS > 150000"},
552     { 0, NULL }
553 };
554 static value_string_ext buffer_size_vals_ext = VALUE_STRING_EXT_INIT(buffer_size_vals);
555
556 static const value_string ext_buffer_size_vals[] =
557 {
558     { 0,      "BS = 0"},
559     { 1,      "0 < BS <= 10"},
560     { 2,      "10 < BS <= 13"},
561     { 3,      "13 < BS <= 16"},
562     { 4,      "16 < BS <= 19"},
563     { 5,      "19 < BS <= 23"},
564     { 6,      "23 < BS <= 29"},
565     { 7,      "29 < BS <= 35"},
566     { 8,      "35 < BS <= 43"},
567     { 9,      "43 < BS <= 53"},
568     { 10,     "53 < BS <= 65"},
569     { 11,     "65 < BS <= 80"},
570     { 12,     "80 < BS <= 98"},
571     { 13,     "98 < BS <= 120"},
572     { 14,     "120 < BS <= 147"},
573     { 15,     "147 < BS <= 181"},
574     { 16,     "181 < BS <= 223"},
575     { 17,     "223 < BS <= 274"},
576     { 18,     "274 < BS <= 337"},
577     { 19,     "337 < BS <= 414"},
578     { 20,     "414 < BS <= 509"},
579     { 21,     "509 < BS <= 625"},
580     { 22,     "625 < BS <= 769"},
581     { 23,     "769 < BS <= 945"},
582     { 24,     "945 < BS <= 1162"},
583     { 25,     "1162 < BS <= 1429"},
584     { 26,     "1429 < BS <= 1757"},
585     { 27,     "1757 < BS <= 2161"},
586     { 28,     "2161 < BS <= 2657"},
587     { 29,     "2657 < BS <= 3267"},
588     { 30,     "3267 < BS <= 4017"},
589     { 31,     "4017 < BS <= 4940"},
590     { 32,     "4940 < BS <= 6074"},
591     { 33,     "6074 < BS <= 7469"},
592     { 34,     "7469 < BS <= 9185"},
593     { 35,     "9185 < BS <= 11294"},
594     { 36,     "11294 < BS <= 13888"},
595     { 37,     "13888 < BS <= 17077"},
596     { 38,     "17077 < BS <= 20999"},
597     { 39,     "20999 < BS <= 25822"},
598     { 40,     "25822 < BS <= 31752"},
599     { 41,     "31752 < BS <= 39045"},
600     { 42,     "39045 < BS <= 48012"},
601     { 43,     "48012 < BS <= 59039"},
602     { 44,     "59039 < BS <= 72598"},
603     { 45,     "72598 < BS <= 89272"},
604     { 46,     "89272 < BS <= 109774"},
605     { 47,     "109774 < BS <= 134986"},
606     { 48,     "134986 < BS <= 165989"},
607     { 49,     "165989 < BS <= 204111"},
608     { 50,     "204111 < BS <= 250990"},
609     { 51,     "250990 < BS <= 308634"},
610     { 52,     "308634 < BS <= 379519"},
611     { 53,     "379519 < BS <= 466683"},
612     { 54,     "466683 < BS <= 573866"},
613     { 55,     "573866 < BS <= 705666"},
614     { 56,     "705666 < BS <= 867737"},
615     { 57,     "867737 < BS <= 1067031"},
616     { 58,     "1067031 < BS <= 1312097"},
617     { 59,     "1312097 < BS <= 1613447"},
618     { 60,     "1613447 < BS <= 1984009"},
619     { 61,     "1984009 < BS <= 2439678"},
620     { 62,     "2439678 < BS <= 3000000"},
621     { 63,     "BS > 3000000"},
622     { 0, NULL }
623 };
624 static value_string_ext ext_buffer_size_vals_ext = VALUE_STRING_EXT_INIT(ext_buffer_size_vals);
625
626 static const value_string power_headroom_vals[] =
627 {
628     { 0,      "-23 <= PH < -22"},
629     { 1,      "-22 <= PH < -21"},
630     { 2,      "-21 <= PH < -20"},
631     { 3,      "-20 <= PH < -19"},
632     { 4,      "-19 <= PH < -18"},
633     { 5,      "-18 <= PH < -17"},
634     { 6,      "-17 <= PH < -16"},
635     { 7,      "-16 <= PH < -15"},
636     { 8,      "-15 <= PH < -14"},
637     { 9,      "-14 <= PH < -13"},
638     { 10,     "-13 <= PH < -12"},
639     { 11,     "-12 <= PH < -11"},
640     { 12,     "-11 <= PH < -10"},
641     { 13,     "-10 <= PH < -9"},
642     { 14,     "-9 <= PH < -8"},
643     { 15,     "-8 <= PH < -7"},
644     { 16,     "-7 <= PH < -6"},
645     { 17,     "-6 <= PH < -5"},
646     { 18,     "-5 <= PH < -4"},
647     { 19,     "-4 <= PH < -3"},
648     { 20,     "-3 <= PH < -2"},
649     { 21,     "-2 <= PH < -1"},
650     { 22,     "-1 <= PH < 0"},
651     { 23,     "0 <= PH < 1"},
652     { 24,     "1 <= PH < 2"},
653     { 25,     "2 <= PH < 3"},
654     { 26,     "3 <= PH < 4"},
655     { 27,     "4 <= PH < 5"},
656     { 28,     "5 <= PH < 6"},
657     { 29,     "6 <= PH < 7"},
658     { 30,     "7 <= PH < 8"},
659     { 31,     "8 <= PH < 9"},
660     { 32,     "9 <= PH < 10"},
661     { 33,     "10 <= PH < 11"},
662     { 34,     "11 <= PH < 12"},
663     { 35,     "12 <= PH < 13"},
664     { 36,     "13 <= PH < 14"},
665     { 37,     "14 <= PH < 15"},
666     { 38,     "15 <= PH < 16"},
667     { 39,     "16 <= PH < 17"},
668     { 40,     "17 <= PH < 18"},
669     { 41,     "18 <= PH < 19"},
670     { 42,     "19 <= PH < 20"},
671     { 43,     "20 <= PH < 21"},
672     { 44,     "21 <= PH < 22"},
673     { 45,     "22 <= PH < 23"},
674     { 46,     "23 <= PH < 24"},
675     { 47,     "24 <= PH < 25"},
676     { 48,     "25 <= PH < 26"},
677     { 49,     "26 <= PH < 27"},
678     { 50,     "27 <= PH < 28"},
679     { 51,     "28 <= PH < 29"},
680     { 52,     "29 <= PH < 30"},
681     { 53,     "30 <= PH < 31"},
682     { 54,     "31 <= PH < 32"},
683     { 55,     "32 <= PH < 33"},
684     { 56,     "33 <= PH < 34"},
685     { 57,     "34 <= PH < 35"},
686     { 58,     "34 <= PH < 36"},
687     { 59,     "36 <= PH < 37"},
688     { 60,     "37 <= PH < 38"},
689     { 61,     "38 <= PH < 39"},
690     { 62,     "39 <= PH < 40"},
691     { 63,     "PH >= 40"},
692     { 0, NULL }
693 };
694 static value_string_ext power_headroom_vals_ext = VALUE_STRING_EXT_INIT(power_headroom_vals);
695
696 static const value_string pcmaxc_vals[] =
697 {
698     { 0,      "Pcmax,c < -29"},
699     { 1,      "-29 <= Pcmax,c < -28"},
700     { 2,      "-28 <= Pcmax,c < -27"},
701     { 3,      "-27 <= Pcmax,c < -26"},
702     { 4,      "-26 <= Pcmax,c < -25"},
703     { 5,      "-25 <= Pcmax,c < -24"},
704     { 6,      "-24 <= Pcmax,c < -23"},
705     { 7,      "-23 <= Pcmax,c < -22"},
706     { 8,      "-22 <= Pcmax,c < -21"},
707     { 9,      "-21 <= Pcmax,c < -20"},
708     { 10,     "-20 <= Pcmax,c < -19"},
709     { 11,     "-19 <= Pcmax,c < -18"},
710     { 12,     "-18 <= Pcmax,c < -17"},
711     { 13,     "-17 <= Pcmax,c < -16"},
712     { 14,     "-16 <= Pcmax,c < -15"},
713     { 15,     "-15 <= Pcmax,c < -14"},
714     { 16,     "-14 <= Pcmax,c < -13"},
715     { 17,     "-13 <= Pcmax,c < -12"},
716     { 18,     "-12 <= Pcmax,c < -11"},
717     { 19,     "-11 <= Pcmax,c < -10"},
718     { 20,     "-10 <= Pcmax,c < -9"},
719     { 21,     "-9 <= Pcmax,c < -8"},
720     { 22,     "-8 <= Pcmax,c < -7"},
721     { 23,     "-7 <= Pcmax,c < -6"},
722     { 24,     "-6 <= Pcmax,c < -5"},
723     { 25,     "-5 <= Pcmax,c < -4"},
724     { 26,     "-4 <= Pcmax,c < -3"},
725     { 27,     "-3 <= Pcmax,c < -2"},
726     { 28,     "-2 <= Pcmax,c < -1"},
727     { 29,     "-1 <= Pcmax,c < 0"},
728     { 30,     "0 <= Pcmax,c < 1"},
729     { 31,     "1 <= Pcmax,c < 2"},
730     { 32,     "2 <= Pcmax,c < 3"},
731     { 33,     "3 <= Pcmax,c < 4"},
732     { 34,     "4 <= Pcmax,c < 5"},
733     { 35,     "5 <= Pcmax,c < 6"},
734     { 36,     "6 <= Pcmax,c < 7"},
735     { 37,     "7 <= Pcmax,c < 8"},
736     { 38,     "8 <= Pcmax,c < 9"},
737     { 39,     "9 <= Pcmax,c < 10"},
738     { 40,     "10 <= Pcmax,c < 11"},
739     { 41,     "11 <= Pcmax,c < 12"},
740     { 42,     "12 <= Pcmax,c < 13"},
741     { 43,     "13 <= Pcmax,c < 14"},
742     { 44,     "14 <= Pcmax,c < 15"},
743     { 45,     "15 <= Pcmax,c < 16"},
744     { 46,     "16 <= Pcmax,c < 17"},
745     { 47,     "17 <= Pcmax,c < 18"},
746     { 48,     "18 <= Pcmax,c < 19"},
747     { 49,     "19 <= Pcmax,c < 20"},
748     { 50,     "20 <= Pcmax,c < 21"},
749     { 51,     "21 <= Pcmax,c < 22"},
750     { 52,     "22 <= Pcmax,c < 23"},
751     { 53,     "23 <= Pcmax,c < 24"},
752     { 54,     "24 <= Pcmax,c < 25"},
753     { 55,     "25 <= Pcmax,c < 26"},
754     { 56,     "26 <= Pcmax,c < 27"},
755     { 57,     "27 <= Pcmax,c < 28"},
756     { 58,     "28 <= Pcmax,c < 29"},
757     { 59,     "29 <= Pcmax,c < 30"},
758     { 60,     "30 <= Pcmax,c < 31"},
759     { 61,     "31 <= Pcmax,c < 32"},
760     { 62,     "32 <= Pcmax,c < 33"},
761     { 63,     "33 <= Pcmax,c"},
762     { 0, NULL }
763 };
764 static value_string_ext pcmaxc_vals_ext = VALUE_STRING_EXT_INIT(pcmaxc_vals);
765
766 static const value_string header_only_vals[] =
767 {
768     { 0,      "MAC PDU Headers and body present"},
769     { 1,      "MAC PDU Headers only"},
770     { 0, NULL }
771 };
772
773 static const value_string predefined_frame_vals[] =
774 {
775     { 0,      "Real MAC PDU present - will dissect"},
776     { 1,      "Predefined frame present - will not dissect"},
777     { 0, NULL }
778 };
779
780 static const value_string ul_retx_grant_vals[] =
781 {
782     { 0,      "PDCCH ReTx"},
783     { 1,      "PHICH NACK"},
784     { 0, NULL }
785 };
786
787 /**************************************************************************/
788 /* Preferences state                                                      */
789 /**************************************************************************/
790
791 /* If this PDU has been NACK'd (by HARQ) more than a certain number of times,
792    we trigger an expert warning. */
793 static gint global_mac_lte_retx_counter_trigger = 3;
794
795 /* By default try to decode transparent data (BCH, PCH and CCCH) data using LTE RRC dissector */
796 static gboolean global_mac_lte_attempt_rrc_decode = TRUE;
797
798 /* Whether should attempt to dissect frames failing CRC check */
799 static gboolean global_mac_lte_dissect_crc_failures = FALSE;
800
801 /* Whether should attempt to decode lcid 1&2 SDUs as srb1/2 (i.e. AM RLC) */
802 static gboolean global_mac_lte_attempt_srb_decode = TRUE;
803
804 /* Where to take LCID -> DRB mappings from */
805 enum lcid_drb_source {
806     FromStaticTable, FromConfigurationProtocol
807 };
808 static gint global_mac_lte_lcid_drb_source = (gint)FromStaticTable;
809
810 /* Threshold for warning in expert info about high BSR values */
811 static gint global_mac_lte_bsr_warn_threshold = 50; /* default is 19325 -> 22624 */
812
813 /* Whether or not to track SRs and related frames */
814 static gboolean global_mac_lte_track_sr = TRUE;
815
816 /* Which layer info to show in the info column */
817 enum layer_to_show {
818     ShowPHYLayer, ShowMACLayer, ShowRLCLayer
819 };
820
821 /* Which layer's details to show in Info column */
822 static gint     global_mac_lte_layer_to_show = (gint)ShowRLCLayer;
823
824 /* When showing RLC info, count PDUs so can append info column properly */
825 static guint8   s_number_of_rlc_pdus_shown = 0;
826
827 /***********************************************************************/
828 /* How to dissect lcid 3-10 (presume drb logical channels)             */
829
830 static const value_string drb_lcid_vals[] = {
831     { 3,  "LCID 3"},
832     { 4,  "LCID 4"},
833     { 5,  "LCID 5"},
834     { 6,  "LCID 6"},
835     { 7,  "LCID 7"},
836     { 8,  "LCID 8"},
837     { 9,  "LCID 9"},
838     { 10, "LCID 10"},
839     { 0, NULL }
840 };
841
842 typedef enum rlc_channel_type_t {
843     rlcRaw,
844     rlcTM,
845     rlcUM5,
846     rlcUM10,
847     rlcAM
848 } rlc_channel_type_t;
849
850 static const value_string rlc_channel_type_vals[] = {
851     { rlcTM,    "TM"},
852     { rlcUM5 ,  "UM, SN Len=5"},
853     { rlcUM10,  "UM, SN Len=10"},
854     { rlcAM  ,  "AM"},
855     { 0, NULL }
856 };
857
858
859 /* Mapping type */
860 typedef struct lcid_drb_mapping_t {
861     guint16 lcid;
862     gint    drbid;
863     rlc_channel_type_t channel_type;
864 } lcid_drb_mapping_t;
865
866 /* Mapping entity */
867 static lcid_drb_mapping_t *lcid_drb_mappings = NULL;
868 static guint num_lcid_drb_mappings = 0;
869
870 UAT_VS_DEF(lcid_drb_mappings, lcid, lcid_drb_mapping_t, 3, "LCID 3")
871 UAT_DEC_CB_DEF(lcid_drb_mappings, drbid, lcid_drb_mapping_t)
872 UAT_VS_DEF(lcid_drb_mappings, channel_type, lcid_drb_mapping_t, 2, "AM")
873
874 /* UAT object */
875 static uat_t* lcid_drb_mappings_uat;
876
877 /* Dynamic mappings (set by configuration protocol)
878    LCID is the index into the array of these */
879 typedef struct dynamic_lcid_drb_mapping_t {
880     gboolean valid;
881     gint     drbid;
882     rlc_channel_type_t channel_type;
883     guint8   ul_priority;
884 } dynamic_lcid_drb_mapping_t;
885
886 static dynamic_lcid_drb_mapping_t dynamic_lcid_drb_mapping[11];
887
888
889 extern int proto_rlc_lte;
890
891 /***************************************************************/
892
893
894
895 /***************************************************************/
896 /* Keeping track of Msg3 bodies so they can be compared with   */
897 /* Contention Resolution bodies.                               */
898
899 typedef struct Msg3Data {
900     guint8   data[6];
901     nstime_t msg3Time;
902     guint32  framenum;
903 } Msg3Data;
904
905
906 /* This table stores (RNTI -> Msg3Data*).  Will be populated when
907    Msg3 frames are first read.  */
908 static GHashTable *mac_lte_msg3_hash = NULL;
909
910 /* Hash table functions for mac_lte_msg3_hash.  Hash is just the (RNTI) key */
911 static gint mac_lte_rnti_hash_equal(gconstpointer v, gconstpointer v2)
912 {
913     return (v == v2);
914 }
915
916 static guint mac_lte_rnti_hash_func(gconstpointer v)
917 {
918     return GPOINTER_TO_UINT(v);
919 }
920
921
922 typedef enum ContentionResolutionStatus {
923     NoMsg3,
924     Msg3Match,
925     Msg3NoMatch
926 } ContentionResolutionStatus;
927
928 typedef struct ContentionResolutionResult {
929     ContentionResolutionStatus status;
930     guint                      msg3FrameNum;
931     guint                      msSinceMsg3;
932 } ContentionResolutionResult;
933
934
935 /* This table stores (CRFrameNum -> CRResult).  It is assigned during the first
936    pass and used thereafter */
937 static GHashTable *mac_lte_cr_result_hash = NULL;
938
939 /* Hash table functions for mac_lte_cr_result_hash.  Hash is just the (framenum) key */
940 static gint mac_lte_framenum_hash_equal(gconstpointer v, gconstpointer v2)
941 {
942     return (v == v2);
943 }
944
945 static guint mac_lte_framenum_hash_func(gconstpointer v)
946 {
947     return GPOINTER_TO_UINT(v);
948 }
949
950 /**************************************************************************/
951
952
953
954 /****************************************************************/
955 /* Keeping track of last DL frames per C-RNTI so can guess when */
956 /* there has been a HARQ retransmission                         */
957 /* TODO: this should be simplified now that harq-id & ndi are   */
958 /* being logged!                                                */
959
960 /* Could be bigger, but more than enough to flag suspected resends */
961 #define MAX_EXPECTED_PDU_LENGTH 2048
962
963 typedef struct LastFrameData {
964     gboolean inUse;
965     guint32  framenum;
966     gboolean ndi;
967     nstime_t received_time;
968     gint     length;
969     guint8   data[MAX_EXPECTED_PDU_LENGTH];
970 } LastFrameData;
971
972 typedef struct DLHarqBuffers {
973     LastFrameData harqid[2][15];  /* 2 blocks (1 for each antenna) needed for DL */
974 } DLHarqBuffers;
975
976
977 /* This table stores (RNTI -> DLHARQBuffers*).  Will be populated when
978    DL frames are first read.  */
979 static GHashTable *mac_lte_dl_harq_hash = NULL;
980
981 typedef struct DLHARQResult {
982     gboolean    previousSet, nextSet;
983     guint       previousFrameNum;
984     guint       timeSincePreviousFrame;
985     guint       nextFrameNum;
986     guint       timeToNextFrame;
987 } DLHARQResult;
988
989
990 /* This table stores (FrameNumber -> *DLHARQResult).  It is assigned during the first
991    pass and used thereafter */
992 static GHashTable *mac_lte_dl_harq_result_hash = NULL;
993
994 /**************************************************************************/
995
996
997 /*****************************************************************/
998 /* Keeping track of last UL frames per C-RNTI so can verify when */
999 /* told that a frame is a retx                                   */
1000
1001 typedef struct ULHarqBuffers {
1002     LastFrameData harqid[8];
1003 } ULHarqBuffers;
1004
1005
1006 /* This table stores (RNTI -> ULHarqBuffers*).  Will be populated when
1007    UL frames are first read.  */
1008 static GHashTable *mac_lte_ul_harq_hash = NULL;
1009
1010 typedef struct ULHARQResult {
1011     gboolean    previousSet, nextSet;
1012     guint       previousFrameNum;
1013     guint       timeSincePreviousFrame;
1014     guint       nextFrameNum;
1015     guint       timeToNextFrame;
1016 } ULHARQResult;
1017
1018
1019 /* This table stores (FrameNum -> ULHARQResult).  It is assigned during the first
1020    pass and used thereafter */
1021 static GHashTable *mac_lte_ul_harq_result_hash = NULL;
1022
1023 /**************************************************************************/
1024
1025
1026 /**************************************************************************/
1027 /* Tracking of Scheduling Requests (SRs).                                 */
1028 /* Keep track of:                                                         */
1029 /* - last grant before SR                                                 */
1030 /* - SR failures following request                                        */
1031 /* - grant following SR                                                   */
1032
1033 typedef enum SREvent {
1034     SR_Grant,
1035     SR_Request,
1036     SR_Failure
1037 } SREvent;
1038
1039 static const value_string sr_event_vals[] =
1040 {
1041     { SR_Grant,        "Grant"},
1042     { SR_Request,      "SR Request"},
1043     { SR_Failure,      "SR Failure"},
1044     { 0,               NULL}
1045 };
1046
1047 typedef enum SRStatus {
1048     None,
1049     SR_Outstanding,
1050     SR_Failed
1051 } SRStatus;
1052
1053 static const value_string sr_status_vals[] =
1054 {
1055     { None,                "Receiving grants"},
1056     { SR_Outstanding,      "SR Request outstanding"},
1057     { SR_Failed,           "SR has Failed"},
1058     { 0,                   NULL}
1059 };
1060
1061
1062 typedef struct SRState {
1063     SRStatus status;
1064     guint32  lastSRFramenum;
1065     guint32  lastGrantFramenum;
1066     nstime_t requestTime;
1067 } SRState;
1068
1069
1070 /* This table keeps track of the SR state for each UE.
1071    (RNTI -> SRState) */
1072 static GHashTable *mac_lte_ue_sr_state = NULL;
1073
1074
1075 typedef enum SRResultType {
1076     GrantAnsweringSR,
1077     FailureAnsweringSR,
1078     SRLeadingToGrant,
1079     SRLeadingToFailure,
1080     InvalidSREvent
1081 } SRResultType;
1082
1083
1084 typedef struct SRResult {
1085     SRResultType type;
1086     guint32      frameNum;
1087     guint32      timeDifference;
1088
1089     /* These 2 are only used with InvalidSREvent */
1090     SRStatus     status;
1091     SREvent      event;
1092 } SRResult;
1093
1094 /* Entries in this table are created during the first pass
1095    It maps (SRFrameNum -> SRResult) */
1096 static GHashTable *mac_lte_sr_request_hash = NULL;
1097
1098
1099 /**************************************************************************/
1100
1101
1102
1103 /* Forward declarations */
1104 void proto_reg_handoff_mac_lte(void);
1105 void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1106
1107 static guint8 get_mac_lte_channel_priority(guint16 ueid _U_, guint8 lcid,
1108                                            guint8 direction);
1109
1110
1111 /* Heuristic dissection */
1112 static gboolean global_mac_lte_heur = FALSE;
1113
1114 static void call_with_catch_all(dissector_handle_t handle, tvbuff_t* tvb, packet_info *pinfo, proto_tree *tree)
1115 {
1116     /* Call it (catch exceptions so that stats will be updated) */
1117     TRY {
1118         call_dissector_only(handle, tvb, pinfo, tree);
1119     }
1120     CATCH_ALL {
1121     }
1122     ENDTRY
1123 }
1124
1125 /* Dissect context fields in the format described in packet-mac-lte.h.
1126    Return TRUE if the necessary information was successfully found */
1127 gboolean dissect_mac_lte_context_fields(struct mac_lte_info  *p_mac_lte_info, tvbuff_t *tvb,
1128                                         gint *p_offset)
1129 {
1130     gint    offset = *p_offset;
1131     guint8  tag = 0;
1132
1133     /* Read fixed fields */
1134     p_mac_lte_info->radioType = tvb_get_guint8(tvb, offset++);
1135     p_mac_lte_info->direction = tvb_get_guint8(tvb, offset++);
1136
1137     /* TODO: currently no support for detailed PHY info... */
1138     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
1139         p_mac_lte_info->detailed_phy_info.ul_info.present = FALSE;
1140     }
1141     else {
1142         p_mac_lte_info->detailed_phy_info.dl_info.present = FALSE;
1143     }
1144
1145     p_mac_lte_info->rntiType = tvb_get_guint8(tvb, offset++);
1146
1147     /* Initialize RNTI with a default value in case optional field is not present */
1148     switch (p_mac_lte_info->rntiType) {
1149         case M_RNTI:
1150             p_mac_lte_info->rnti = 0xFFFD;
1151             break;
1152         case P_RNTI:
1153             p_mac_lte_info->rnti = 0xFFFE;
1154             break;
1155         case SI_RNTI:
1156             p_mac_lte_info->rnti = 0xFFFF;
1157             break;
1158         case RA_RNTI:
1159         case C_RNTI:
1160         case SPS_RNTI:
1161             p_mac_lte_info->rnti = 0x0001;
1162             break;
1163         default:
1164             break;
1165     }
1166
1167     /* Read optional fields */
1168     while (tag != MAC_LTE_PAYLOAD_TAG) {
1169         /* Process next tag */
1170         tag = tvb_get_guint8(tvb, offset++);
1171         switch (tag) {
1172             case MAC_LTE_RNTI_TAG:
1173                 p_mac_lte_info->rnti = tvb_get_ntohs(tvb, offset);
1174                 offset += 2;
1175                 break;
1176             case MAC_LTE_UEID_TAG:
1177                 p_mac_lte_info->ueid = tvb_get_ntohs(tvb, offset);
1178                 offset += 2;
1179                 break;
1180             case MAC_LTE_SUBFRAME_TAG:
1181                 p_mac_lte_info->subframeNumber = tvb_get_ntohs(tvb, offset);
1182                 offset += 2;
1183                 break;
1184             case MAC_LTE_PREDEFINED_DATA_TAG:
1185                 p_mac_lte_info->isPredefinedData = tvb_get_guint8(tvb, offset);
1186                 offset++;
1187                 break;
1188             case MAC_LTE_RETX_TAG:
1189                 p_mac_lte_info->reTxCount = tvb_get_guint8(tvb, offset);
1190                 offset++;
1191                 break;
1192             case MAC_LTE_CRC_STATUS_TAG:
1193                 p_mac_lte_info->crcStatusValid = TRUE;
1194                 p_mac_lte_info->detailed_phy_info.dl_info.crc_status = tvb_get_guint8(tvb, offset);
1195                 offset++;
1196                 break;
1197             case MAC_LTE_EXT_BSR_SIZES_TAG:
1198                 p_mac_lte_info->isExtendedBSRSizes = TRUE;
1199                 break;
1200
1201             case MAC_LTE_PAYLOAD_TAG:
1202                 /* Have reached data, so set payload length and get out of loop */
1203                 p_mac_lte_info->length= tvb_length_remaining(tvb, offset);
1204                 continue;
1205
1206             default:
1207                 /* It must be a recognised tag */
1208                 return FALSE;
1209         }
1210     }
1211
1212     /* Pass out where offset is now */
1213     *p_offset = offset;
1214
1215     return TRUE;
1216 }
1217
1218 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
1219 static gboolean dissect_mac_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
1220                                      proto_tree *tree)
1221 {
1222     gint                 offset = 0;
1223     struct mac_lte_info  *p_mac_lte_info;
1224     tvbuff_t             *mac_tvb;
1225     gboolean             infoAlreadySet = FALSE;
1226
1227     /* This is a heuristic dissector, which means we get all the UDP
1228      * traffic not sent to a known dissector and not claimed by
1229      * a heuristic dissector called before us!
1230      */
1231
1232     if (!global_mac_lte_heur) {
1233         return FALSE;
1234     }
1235
1236     /* Do this again on re-dissection to re-discover offset of actual PDU */
1237
1238     /* Needs to be at least as long as:
1239        - the signature string
1240        - fixed header bytes
1241        - tag for data
1242        - at least one byte of MAC PDU payload */
1243     if ((size_t)tvb_length_remaining(tvb, offset) < (strlen(MAC_LTE_START_STRING)+3+2)) {
1244         return FALSE;
1245     }
1246
1247     /* OK, compare with signature string */
1248     if (tvb_strneql(tvb, offset, MAC_LTE_START_STRING, strlen(MAC_LTE_START_STRING)) != 0) {
1249         return FALSE;
1250     }
1251     offset += (gint)strlen(MAC_LTE_START_STRING);
1252
1253     /* If redissecting, use previous info struct (if available) */
1254     p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte);
1255     if (p_mac_lte_info == NULL) {
1256         /* Allocate new info struct for this frame */
1257         p_mac_lte_info = se_alloc0(sizeof(struct mac_lte_info));
1258         infoAlreadySet = FALSE;
1259     }
1260     else {
1261         infoAlreadySet = TRUE;
1262     }
1263
1264     /* Dissect the fields to populate p_mac_lte */
1265     if (!dissect_mac_lte_context_fields(p_mac_lte_info, tvb, &offset)) {
1266         return FALSE;
1267     }
1268
1269
1270     if (!infoAlreadySet) {
1271         /* Store info in packet */
1272         p_add_proto_data(pinfo->fd, proto_mac_lte, p_mac_lte_info);
1273     }
1274
1275     /**************************************/
1276     /* OK, now dissect as MAC LTE         */
1277
1278     /* Create tvb that starts at actual MAC PDU */
1279     mac_tvb = tvb_new_subset(tvb, offset, -1, tvb_reported_length(tvb)-offset);
1280     dissect_mac_lte(mac_tvb, pinfo, tree);
1281
1282     return TRUE;
1283 }
1284
1285
1286 /* Write the given formatted text to:
1287    - the info column (if pinfo != NULL)
1288    - 1 or 2 other labels (optional)
1289 */
1290 static void write_pdu_label_and_info(proto_item *ti1, proto_item *ti2,
1291                                      packet_info *pinfo, const char *format, ...)
1292 {
1293     #define MAX_INFO_BUFFER 256
1294     static char info_buffer[MAX_INFO_BUFFER];
1295
1296     va_list ap;
1297
1298     va_start(ap, format);
1299     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
1300     va_end(ap);
1301
1302     /* Add to indicated places */
1303     if (pinfo != NULL) {
1304         col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
1305     }
1306     if (ti1 != NULL) {
1307         proto_item_append_text(ti1, "%s", info_buffer);
1308     }
1309     if (ti2 != NULL) {
1310         proto_item_append_text(ti2, "%s", info_buffer);
1311     }
1312 }
1313
1314 /* Show extra PHY parameters (if present) */
1315 static void show_extra_phy_parameters(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree,
1316                                       struct mac_lte_info *p_mac_lte_info)
1317 {
1318     proto_item *phy_ti;
1319     proto_tree *phy_tree;
1320     proto_item *ti;
1321
1322     if (global_mac_lte_layer_to_show == ShowPHYLayer) {
1323         /* Clear the info column */
1324         col_clear(pinfo->cinfo, COL_INFO);
1325     }
1326
1327     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
1328         if (p_mac_lte_info->detailed_phy_info.ul_info.present) {
1329
1330             /* Create root */
1331             phy_ti = proto_tree_add_string_format(tree, hf_mac_lte_context_phy_ul,
1332                                                   tvb, 0, 0, "", "UL PHY Context");
1333             phy_tree = proto_item_add_subtree(phy_ti, ett_mac_lte_phy_context);
1334             PROTO_ITEM_SET_GENERATED(phy_ti);
1335
1336             /* Add items */
1337             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_modulation_type,
1338                                      tvb, 0, 0,
1339                                      p_mac_lte_info->detailed_phy_info.ul_info.modulation_type);
1340             PROTO_ITEM_SET_GENERATED(ti);
1341
1342             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_tbs_index,
1343                                      tvb, 0, 0,
1344                                      p_mac_lte_info->detailed_phy_info.ul_info.tbs_index);
1345             PROTO_ITEM_SET_GENERATED(ti);
1346
1347             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_length,
1348                                      tvb, 0, 0,
1349                                      p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length);
1350             PROTO_ITEM_SET_GENERATED(ti);
1351
1352             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_resource_block_start,
1353                                      tvb, 0, 0,
1354                                      p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start);
1355             PROTO_ITEM_SET_GENERATED(ti);
1356
1357             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_harq_id,
1358                                      tvb, 0, 0,
1359                                      p_mac_lte_info->detailed_phy_info.ul_info.harq_id);
1360             PROTO_ITEM_SET_GENERATED(ti);
1361
1362             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_ul_ndi,
1363                                      tvb, 0, 0,
1364                                      p_mac_lte_info->detailed_phy_info.ul_info.ndi);
1365             PROTO_ITEM_SET_GENERATED(ti);
1366
1367
1368             proto_item_append_text(phy_ti, " (");
1369
1370             write_pdu_label_and_info(phy_ti, NULL,
1371                                      (global_mac_lte_layer_to_show == ShowPHYLayer) ? pinfo : NULL,
1372                                      "UL: UEId=%u RNTI=%u %s Tbs_Index=%u RB_len=%u RB_start=%u",
1373                                      p_mac_lte_info->ueid,
1374                                      p_mac_lte_info->rnti,
1375                                      val_to_str_const(p_mac_lte_info->detailed_phy_info.ul_info.modulation_type,
1376                                                       modulation_type_vals, "Unknown"),
1377                                      p_mac_lte_info->detailed_phy_info.ul_info.tbs_index,
1378                                      p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length,
1379                                      p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start);
1380
1381             proto_item_append_text(phy_ti, ")");
1382
1383             /* Don't want columns to be replaced now */
1384             if (global_mac_lte_layer_to_show == ShowPHYLayer) {
1385                 col_set_writable(pinfo->cinfo, FALSE);
1386             }
1387         }
1388     }
1389     else {
1390         if (p_mac_lte_info->detailed_phy_info.dl_info.present) {
1391
1392             /* Create root */
1393             phy_ti = proto_tree_add_string_format(tree, hf_mac_lte_context_phy_dl,
1394                                                   tvb, 0, 0, "", "DL PHY Context");
1395             phy_tree = proto_item_add_subtree(phy_ti, ett_mac_lte_phy_context);
1396             PROTO_ITEM_SET_GENERATED(phy_ti);
1397
1398             /* Add items */
1399             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_dci_format,
1400                                      tvb, 0, 0,
1401                                      p_mac_lte_info->detailed_phy_info.dl_info.dci_format);
1402             PROTO_ITEM_SET_GENERATED(ti);
1403
1404             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_allocation_type,
1405                                      tvb, 0, 0,
1406                                      p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type);
1407             PROTO_ITEM_SET_GENERATED(ti);
1408
1409             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_aggregation_level,
1410                                      tvb, 0, 0,
1411                                      p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level);
1412             PROTO_ITEM_SET_GENERATED(ti);
1413
1414             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_mcs_index,
1415                                      tvb, 0, 0,
1416                                      p_mac_lte_info->detailed_phy_info.dl_info.mcs_index);
1417             PROTO_ITEM_SET_GENERATED(ti);
1418
1419             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_redundancy_version_index,
1420                                      tvb, 0, 0,
1421                                      p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index);
1422             PROTO_ITEM_SET_GENERATED(ti);
1423
1424             ti = proto_tree_add_boolean(phy_tree, hf_mac_lte_context_phy_dl_retx,
1425                                         tvb, 0, 0,
1426                                         p_mac_lte_info->dl_retx);
1427             PROTO_ITEM_SET_GENERATED(ti);
1428
1429             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_resource_block_length,
1430                                      tvb, 0, 0,
1431                                      p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length);
1432             PROTO_ITEM_SET_GENERATED(ti);
1433
1434             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_crc_status,
1435                                      tvb, 0, 0,
1436                                      p_mac_lte_info->detailed_phy_info.dl_info.crc_status);
1437             PROTO_ITEM_SET_GENERATED(ti);
1438
1439             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_harq_id,
1440                                      tvb, 0, 0,
1441                                      p_mac_lte_info->detailed_phy_info.dl_info.harq_id);
1442             PROTO_ITEM_SET_GENERATED(ti);
1443
1444             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_ndi,
1445                                      tvb, 0, 0,
1446                                      p_mac_lte_info->detailed_phy_info.dl_info.ndi);
1447             PROTO_ITEM_SET_GENERATED(ti);
1448
1449             ti = proto_tree_add_uint(phy_tree, hf_mac_lte_context_phy_dl_tb,
1450                                      tvb, 0, 0,
1451                                      p_mac_lte_info->detailed_phy_info.dl_info.transport_block);
1452             PROTO_ITEM_SET_GENERATED(ti);
1453
1454
1455             proto_item_append_text(phy_ti, " (");
1456
1457             write_pdu_label_and_info(phy_ti, NULL,
1458                                      (global_mac_lte_layer_to_show == ShowPHYLayer) ? pinfo : NULL,
1459                                      "DL: UEId=%u RNTI=%u DCI_Format=%s Res_Alloc=%u Aggr_Level=%s MCS=%u RV=%u "
1460                                      "Res_Block_len=%u CRC_status=%s HARQ_id=%u NDI=%u",
1461                                      p_mac_lte_info->ueid,
1462                                      p_mac_lte_info->rnti,
1463                                      val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.dci_format,
1464                                                       dci_format_vals, "Unknown"),
1465                                      p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type,
1466                                      val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level,
1467                                                       aggregation_level_vals, "Unknown"),
1468                                      p_mac_lte_info->detailed_phy_info.dl_info.mcs_index,
1469                                      p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index,
1470                                      p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length,
1471                                      val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.crc_status,
1472                                                       crc_status_vals, "Unknown"),
1473                                      p_mac_lte_info->detailed_phy_info.dl_info.harq_id,
1474                                      p_mac_lte_info->detailed_phy_info.dl_info.ndi);
1475             proto_item_append_text(phy_ti, ")");
1476
1477             /* Don't want columns to be replaced now */
1478             if (global_mac_lte_layer_to_show == ShowPHYLayer) {
1479                 col_set_writable(pinfo->cinfo, FALSE);
1480             }
1481         }
1482     }
1483 }
1484
1485
1486 /* Dissect a single Random Access Reponse body */
1487 static gint dissect_rar_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1488                               proto_item *pdu_ti,
1489                               gint offset, guint8 rapid)
1490 {
1491     guint8      reserved;
1492     guint       start_body_offset = offset;
1493     proto_item *ti;
1494     proto_item *rar_body_ti;
1495     proto_tree *rar_body_tree;
1496     proto_tree *ul_grant_tree;
1497     proto_item *ul_grant_ti;
1498     guint16     timing_advance;
1499     guint32     ul_grant;
1500     guint16     temp_crnti;
1501
1502     /* Create tree for this Body */
1503     rar_body_ti = proto_tree_add_item(tree,
1504                                       hf_mac_lte_rar_body,
1505                                       tvb, offset, 0, ENC_ASCII|ENC_NA);
1506     rar_body_tree = proto_item_add_subtree(rar_body_ti, ett_mac_lte_rar_body);
1507
1508     /* Dissect an RAR entry */
1509
1510     /* Check reserved bit */
1511     reserved = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
1512     ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_reserved2, tvb, offset, 1, ENC_BIG_ENDIAN);
1513     if (reserved != 0) {
1514             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1515                       "RAR body Reserved bit not zero (found 0x%x)", reserved);
1516     }
1517
1518     /* Timing Advance */
1519     timing_advance = (tvb_get_ntohs(tvb, offset) & 0x7ff0) >> 4;
1520     ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ta, tvb, offset, 2, ENC_BIG_ENDIAN);
1521     if (timing_advance != 0) {
1522         expert_add_info_format(pinfo, ti, PI_SEQUENCE, (timing_advance <= 31) ? PI_NOTE : PI_WARN,
1523                                "RAR Timing advance not zero (%u)", timing_advance);
1524     }
1525     offset++;
1526
1527     /* UL Grant */
1528     ul_grant = (tvb_get_ntohl(tvb, offset) & 0x0fffff00) >> 8;
1529     ul_grant_ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ul_grant, tvb, offset, 3, ENC_BIG_ENDIAN);
1530
1531     /* Break these 20 bits down as described in 36.213, section 6.2 */
1532     /* Create subtree for UL grant break-down */
1533     ul_grant_tree = proto_item_add_subtree(ul_grant_ti, ett_mac_lte_rar_ul_grant);
1534
1535     /* Hopping flag (1 bit) */
1536     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_hopping,
1537                         tvb, offset, 1, ENC_BIG_ENDIAN);
1538
1539     /* Fixed sized resource block assignment (10 bits) */
1540     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_fsrba,
1541                         tvb, offset, 2, ENC_BIG_ENDIAN);
1542
1543     /* Truncated Modulation and coding scheme (4 bits) */
1544     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tmcs,
1545                         tvb, offset+1, 2, ENC_BIG_ENDIAN);
1546
1547     /* TPC command for scheduled PUSCH (3 bits) */
1548     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tcsp,
1549                         tvb, offset+2, 1, ENC_BIG_ENDIAN);
1550
1551     /* UL delay (1 bit) */
1552     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_delay,
1553                         tvb, offset+2, 1, ENC_BIG_ENDIAN);
1554
1555     /* CQI request (1 bit) */
1556     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_cqi_request,
1557                         tvb, offset+2, 1, ENC_BIG_ENDIAN);
1558
1559     offset += 3;
1560
1561     /* Temporary C-RNTI */
1562     temp_crnti = tvb_get_ntohs(tvb, offset);
1563     proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_temporary_crnti, tvb, offset, 2, ENC_BIG_ENDIAN);
1564     offset += 2;
1565
1566     write_pdu_label_and_info(pdu_ti, rar_body_ti, pinfo,
1567                              "(RAPID=%u: TA=%u, UL-Grant=%u, Temp C-RNTI=%u) ",
1568                              rapid, timing_advance, ul_grant, temp_crnti);
1569
1570     proto_item_set_len(rar_body_ti, offset-start_body_offset);
1571
1572     return offset;
1573 }
1574
1575
1576 #define MAX_RAR_PDUS 64
1577 /* Dissect Random Access Reponse (RAR) PDU */
1578 static void dissect_rar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *pdu_ti,
1579                         gint offset, mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info)
1580 {
1581     gint        number_of_rars         = 0; /* No of RAR bodies expected following headers */
1582     guint8     *rapids                 = ep_alloc(MAX_RAR_PDUS * sizeof(guint8));
1583     gboolean    backoff_indicator_seen = FALSE;
1584     guint8      backoff_indicator      = 0;
1585     guint8      extension;
1586     gint        n;
1587     proto_tree *rar_headers_tree;
1588     proto_item *ti;
1589     proto_item *rar_headers_ti;
1590     proto_item *padding_length_ti;
1591     int         start_headers_offset   = offset;
1592
1593     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
1594                              "RAR (RA-RNTI=%u, SF=%u) ",
1595                              p_mac_lte_info->rnti, p_mac_lte_info->subframeNumber);
1596
1597     /* Create hidden 'virtual root' so can filter on mac-lte.rar */
1598     ti = proto_tree_add_item(tree, hf_mac_lte_rar, tvb, offset, -1, ENC_NA);
1599     PROTO_ITEM_SET_HIDDEN(ti);
1600
1601     /* Create headers tree */
1602     rar_headers_ti = proto_tree_add_item(tree,
1603                                          hf_mac_lte_rar_headers,
1604                                          tvb, offset, 0, ENC_ASCII|ENC_NA);
1605     rar_headers_tree = proto_item_add_subtree(rar_headers_ti, ett_mac_lte_rar_headers);
1606
1607
1608     /***************************/
1609     /* Read the header entries */
1610     do {
1611         int start_header_offset = offset;
1612         proto_tree *rar_header_tree;
1613         proto_item *rar_header_ti;
1614         guint8 type_value;
1615         guint8 first_byte = tvb_get_guint8(tvb, offset);
1616
1617         /* Create tree for this header */
1618         rar_header_ti = proto_tree_add_item(rar_headers_tree,
1619                                             hf_mac_lte_rar_header,
1620                                             tvb, offset, 0, ENC_ASCII|ENC_NA);
1621         rar_header_tree = proto_item_add_subtree(rar_header_ti, ett_mac_lte_rar_header);
1622
1623         /* Extension */
1624         extension = (first_byte & 0x80) >> 7;
1625         proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
1626
1627         /* Type */
1628         type_value = (first_byte & 0x40) >> 6;
1629         proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_t, tvb, offset, 1, ENC_BIG_ENDIAN);
1630
1631         if (type_value == 0) {
1632             /* Backoff Indicator (BI) case */
1633
1634             guint8 reserved;
1635             proto_item *tii;
1636             proto_item *bi_ti;
1637
1638             /* 2 Reserved bits */
1639             reserved = (tvb_get_guint8(tvb, offset) & 0x30) >> 4;
1640             tii = proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1641             if (reserved != 0) {
1642                 expert_add_info_format(pinfo, tii, PI_MALFORMED, PI_ERROR,
1643                                        "RAR header Reserved bits not zero (found 0x%x)", reserved);
1644             }
1645
1646             /* Backoff Indicator */
1647             backoff_indicator = tvb_get_guint8(tvb, offset) & 0x0f;
1648             bi_ti = proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_bi, tvb, offset, 1, ENC_BIG_ENDIAN);
1649
1650             /* As of March 2009 spec, it must be first, and may only appear once */
1651             if (backoff_indicator_seen) {
1652                 expert_add_info_format(pinfo, bi_ti, PI_MALFORMED, PI_ERROR,
1653                                        "MAC RAR PDU has > 1 Backoff Indicator subheader present");
1654             }
1655             backoff_indicator_seen = TRUE;
1656
1657             write_pdu_label_and_info(pdu_ti, rar_header_ti, pinfo,
1658                                      "(Backoff Indicator=%sms)",
1659                                      val_to_str_const(backoff_indicator, rar_bi_vals, "Illegal-value "));
1660
1661             /* If present, it must be the first subheader */
1662             if (number_of_rars > 0) {
1663                 expert_add_info_format(pinfo, bi_ti, PI_MALFORMED, PI_WARN,
1664                                        "Backoff Indicator must appear as first subheader");
1665             }
1666
1667         }
1668         else {
1669             /* RAPID case */
1670             /* TODO: complain if the same RAPID appears twice in same frame? */
1671             rapids[number_of_rars] = tvb_get_guint8(tvb, offset) & 0x3f;
1672             proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_rapid, tvb, offset, 1, ENC_BIG_ENDIAN);
1673
1674             proto_item_append_text(rar_header_ti, "(RAPID=%u)", rapids[number_of_rars]);
1675
1676             number_of_rars++;
1677         }
1678
1679         offset++;
1680
1681         /* Finalise length of header tree selection */
1682         proto_item_set_len(rar_header_ti, offset - start_header_offset);
1683
1684     } while (extension && number_of_rars < MAX_RAR_PDUS);
1685
1686     /* Append summary to headers root */
1687     proto_item_append_text(rar_headers_ti, " (%u RARs", number_of_rars);
1688     if (backoff_indicator_seen) {
1689         proto_item_append_text(rar_headers_ti, ", BI=%sms)",
1690                                val_to_str_const(backoff_indicator, rar_bi_vals, "Illegal-value "));
1691     }
1692     else {
1693         proto_item_append_text(rar_headers_ti, ")");
1694     }
1695
1696     /* Set length for headers root */
1697     proto_item_set_len(rar_headers_ti, offset-start_headers_offset);
1698
1699
1700     /***************************/
1701     /* Read any indicated RARs */
1702     for (n=0; n < number_of_rars; n++) {
1703         offset = dissect_rar_entry(tvb, pinfo, tree, pdu_ti, offset, rapids[n]);
1704     }
1705
1706     /* Update TAP info */
1707     tap_info->number_of_rars += number_of_rars;
1708
1709     /* Padding may follow */
1710     if (tvb_length_remaining(tvb, offset) > 0) {
1711         proto_tree_add_item(tree, hf_mac_lte_padding_data,
1712                             tvb, offset, -1, ENC_NA);
1713     }
1714     padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
1715                                            tvb, offset, 0,
1716                                            p_mac_lte_info->length - offset);
1717     PROTO_ITEM_SET_GENERATED(padding_length_ti);
1718
1719     /* Update padding bytes in stats */
1720     tap_info->padding_bytes += (p_mac_lte_info->length - offset);
1721 }
1722
1723
1724 /* Dissect BCH PDU */
1725 static void dissect_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1726                         proto_item *pdu_ti,
1727                         int offset, mac_lte_info *p_mac_lte_info)
1728 {
1729     proto_item *ti;
1730
1731     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
1732                              "BCH PDU (%u bytes, on %s transport)  ",
1733                              tvb_length_remaining(tvb, offset),
1734                              val_to_str_const(p_mac_lte_info->rntiType,
1735                                               bch_transport_channel_vals,
1736                                               "Unknown"));
1737
1738     /* Show which transport layer it came in on (inferred from RNTI type) */
1739     ti = proto_tree_add_uint(tree, hf_mac_lte_context_bch_transport_channel,
1740                              tvb, offset, 0, p_mac_lte_info->rntiType);
1741     PROTO_ITEM_SET_GENERATED(ti);
1742
1743     /****************************************/
1744     /* Whole frame is BCH data              */
1745
1746     /* Raw data */
1747     ti = proto_tree_add_item(tree, hf_mac_lte_bch_pdu,
1748                              tvb, offset, -1, ENC_NA);
1749
1750     if (global_mac_lte_attempt_rrc_decode) {
1751         /* Attempt to decode payload using LTE RRC dissector */
1752         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
1753
1754         /* Get appropriate dissector handle */
1755         dissector_handle_t protocol_handle = 0;
1756         if (p_mac_lte_info->rntiType == SI_RNTI) {
1757             protocol_handle = find_dissector("lte_rrc.bcch_dl_sch");
1758         }
1759         else {
1760             protocol_handle = find_dissector("lte_rrc.bcch_bch");
1761         }
1762
1763         /* Hide raw view of bytes */
1764         PROTO_ITEM_SET_HIDDEN(ti);
1765
1766         call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
1767     }
1768
1769     /* Check that this *is* downlink! */
1770     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
1771         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1772                                "BCH data should not be received in Uplink!");
1773     }
1774 }
1775
1776
1777 /* Dissect PCH PDU */
1778 static void dissect_pch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1779                         proto_item *pdu_ti, int offset, guint8 direction)
1780 {
1781     proto_item *ti;
1782
1783     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
1784                              "PCH PDU (%u bytes)  ",
1785                              tvb_length_remaining(tvb, offset));
1786
1787     /****************************************/
1788     /* Whole frame is PCH data              */
1789
1790     /* Always show as raw data */
1791     ti = proto_tree_add_item(tree, hf_mac_lte_pch_pdu,
1792                              tvb, offset, -1, ENC_NA);
1793
1794     if (global_mac_lte_attempt_rrc_decode) {
1795
1796         /* Attempt to decode payload using LTE RRC dissector */
1797         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
1798
1799         /* Get appropriate dissector handle */
1800         dissector_handle_t protocol_handle = find_dissector("lte-rrc.pcch");
1801
1802         /* Hide raw view of bytes */
1803         PROTO_ITEM_SET_HIDDEN(ti);
1804
1805         /* Call it (catch exceptions so that stats will be updated) */
1806         TRY {
1807             call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
1808         }
1809         CATCH_ALL {
1810         }
1811         ENDTRY
1812     }
1813
1814     /* Check that this *is* downlink! */
1815     if (direction == DIRECTION_UPLINK) {
1816         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1817                                "PCH data should not be received in Uplink!");
1818     }
1819 }
1820
1821
1822 /* Does this header entry correspond to a fixed-sized control element? */
1823 static int is_fixed_sized_control_element(guint8 lcid, guint8 direction)
1824 {
1825     if (direction == DIRECTION_UPLINK) {
1826         /* Uplink */
1827         switch (lcid) {
1828             case POWER_HEADROOM_REPORT_LCID:
1829             case CRNTI_LCID:
1830             case TRUNCATED_BSR_LCID:
1831             case SHORT_BSR_LCID:
1832             case LONG_BSR_LCID:
1833                 return TRUE;
1834
1835             default:
1836                 return FALSE;
1837         }
1838     }
1839     else {
1840         /* Assume Downlink */
1841         switch (lcid) {
1842             case ACTIVATION_DEACTIVATION_LCID:
1843             case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
1844             case TIMING_ADVANCE_LCID:
1845             case DRX_COMMAND_LCID:
1846                 return TRUE;
1847
1848             default:
1849                 return FALSE;
1850         }
1851     }
1852 }
1853
1854
1855 /* Is this a BSR report header? */
1856 static int is_bsr_lcid(guint8 lcid)
1857 {
1858     return ((lcid == TRUNCATED_BSR_LCID) ||
1859             (lcid == SHORT_BSR_LCID) ||
1860             (lcid == LONG_BSR_LCID));
1861 }
1862
1863
1864 /* Helper function to call RLC dissector for SDUs (where channel params are known) */
1865 static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1866                                proto_item *pdu_ti,
1867                                int offset, guint16 data_length,
1868                                guint8 mode, guint8 direction, guint16 ueid,
1869                                guint16 channelType, guint16 channelId,
1870                                guint8 UMSequenceNumberLength,
1871                                guint8 priority)
1872 {
1873     tvbuff_t            *srb_tvb = tvb_new_subset(tvb, offset, data_length, data_length);
1874     struct rlc_lte_info *p_rlc_lte_info;
1875
1876     /* Get RLC dissector handle */
1877     volatile dissector_handle_t protocol_handle = find_dissector("rlc-lte");
1878
1879     /* Resuse or create RLC info */
1880     p_rlc_lte_info = p_get_proto_data(pinfo->fd, proto_rlc_lte);
1881     if (p_rlc_lte_info == NULL) {
1882         p_rlc_lte_info = se_alloc0(sizeof(struct rlc_lte_info));
1883     }
1884
1885     /* Fill in struct details for srb channels */
1886     p_rlc_lte_info->rlcMode = mode;
1887     p_rlc_lte_info->direction = direction;
1888     p_rlc_lte_info->priority = priority;
1889     p_rlc_lte_info->ueid = ueid;
1890     p_rlc_lte_info->channelType = channelType;
1891     p_rlc_lte_info->channelId = channelId;
1892     p_rlc_lte_info->pduLength = data_length;
1893     p_rlc_lte_info->UMSequenceNumberLength = UMSequenceNumberLength;
1894
1895     /* Store info in packet */
1896     p_add_proto_data(pinfo->fd, proto_rlc_lte, p_rlc_lte_info);
1897
1898     if (global_mac_lte_layer_to_show != ShowRLCLayer) {
1899         /* Don't want these columns replaced */
1900         col_set_writable(pinfo->cinfo, FALSE);
1901     }
1902     else {
1903         /* Clear info column before first RLC PDU */
1904         if (s_number_of_rlc_pdus_shown == 0) {
1905             col_clear(pinfo->cinfo, COL_INFO);
1906         }
1907         else {
1908             /* Add a separator and protect column contents here */
1909             write_pdu_label_and_info(pdu_ti, NULL, pinfo, "   ||   ");
1910             col_set_fence(pinfo->cinfo, COL_INFO);
1911         }
1912     }
1913     s_number_of_rlc_pdus_shown++;
1914
1915     /* Call it (catch exceptions so that stats will be updated) */
1916     TRY {
1917         call_dissector_only(protocol_handle, srb_tvb, pinfo, tree);
1918     }
1919     CATCH_ALL {
1920     }
1921     ENDTRY
1922
1923     /* Let columns be written to again */
1924     col_set_writable(pinfo->cinfo, TRUE);
1925 }
1926
1927
1928 /* For DL frames, look for previous Tx. Add link back if found */
1929 static void TrackReportedDLHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatile int length,
1930                                       proto_tree *tree, mac_lte_info *p_mac_lte_info)
1931 {
1932     DLHARQResult *result = NULL;
1933     DLHARQResult *original_result = NULL;
1934
1935     /* If don't have detailed DL PHy info, just give up */
1936     if (!p_mac_lte_info->detailed_phy_info.dl_info.present) {
1937         return;
1938     }
1939
1940     /* TDD may not work... */
1941
1942     if (!pinfo->fd->flags.visited) {
1943         /* First time, so set result and update DL harq table */
1944         LastFrameData *lastData = NULL;
1945         LastFrameData *thisData = NULL;
1946
1947         DLHarqBuffers *ueData;
1948
1949         /* Read these for convenience */
1950         guint8 harq_id = p_mac_lte_info->detailed_phy_info.dl_info.harq_id;
1951         guint8 transport_block = p_mac_lte_info->detailed_phy_info.dl_info.transport_block;
1952
1953         /* Check harq-id bounds, give up if invalid */
1954         if ((harq_id >= 15) || (transport_block+1 > 2)) {
1955             return;
1956         }
1957
1958         /* Look up entry for this UE/RNTI */
1959         ueData = g_hash_table_lookup(mac_lte_dl_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti));
1960
1961         if (ueData != NULL) {
1962             /* Get previous info for this harq-id */
1963             lastData = &(ueData->harqid[transport_block][harq_id]);
1964             if (lastData->inUse) {
1965                 /* Compare time difference, ndi, data to see if this looks like a retx */
1966                 if ((length == lastData->length) &&
1967                     (p_mac_lte_info->detailed_phy_info.dl_info.ndi == lastData->ndi) &&
1968                     tvb_memeql(tvb, 0, lastData->data, MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0) {
1969
1970                     /* Work out gap between frames */
1971                     gint seconds_between_packets = (gint)
1972                           (pinfo->fd->abs_ts.secs - lastData->received_time.secs);
1973                     gint nseconds_between_packets =
1974                           pinfo->fd->abs_ts.nsecs - lastData->received_time.nsecs;
1975
1976                     /* Round difference to nearest millisecond */
1977                     gint total_gap = (seconds_between_packets*1000) +
1978                                      ((nseconds_between_packets+500000) / 1000000);
1979
1980                     /* Expect to be within (say) 8-13 subframes since previous */
1981                     if ((total_gap >= 8) && (total_gap <= 13)) {
1982
1983                         /* Resend detected! Store result pointing back. */
1984                         result = se_alloc0(sizeof(DLHARQResult));
1985                         result->previousSet = TRUE;
1986                         result->previousFrameNum = lastData->framenum;
1987                         result->timeSincePreviousFrame = total_gap;
1988                         g_hash_table_insert(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num), result);
1989
1990                         /* Now make previous frame point forward to here */
1991                         original_result = g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(lastData->framenum));
1992                         if (original_result == NULL) {
1993                             original_result = se_alloc0(sizeof(ULHARQResult));
1994                             g_hash_table_insert(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(lastData->framenum), original_result);
1995                         }
1996                         original_result->nextSet = TRUE;
1997                         original_result->nextFrameNum = pinfo->fd->num;
1998                         original_result->timeToNextFrame = total_gap;
1999                     }
2000                 }
2001             }
2002         }
2003         else {
2004             /* Allocate entry in table for this UE/RNTI */
2005             ueData = se_alloc0(sizeof(DLHarqBuffers));
2006             g_hash_table_insert(mac_lte_dl_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti), ueData);
2007         }
2008
2009         /* Store this frame's details in table */
2010         thisData = &(ueData->harqid[transport_block][harq_id]);
2011         thisData->inUse = TRUE;
2012         thisData->length = length;
2013         tvb_memcpy(tvb, thisData->data, 0, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH));
2014         thisData->ndi = p_mac_lte_info->detailed_phy_info.dl_info.ndi;
2015         thisData->framenum = pinfo->fd->num;
2016         thisData->received_time = pinfo->fd->abs_ts;
2017     }
2018     else {
2019         /* Not first time, so just set whats already stored in result */
2020         result = g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
2021     }
2022
2023
2024     /***************************************************/
2025     /* Show link back to original frame (if available) */
2026     if (result != NULL) {
2027         if (result->previousSet) {
2028             proto_item *gap_ti;
2029             proto_item *original_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_original_frame,
2030                                                           tvb, 0, 0, result->previousFrameNum);
2031             PROTO_ITEM_SET_GENERATED(original_ti);
2032
2033             gap_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_time_since_previous_frame,
2034                                          tvb, 0, 0, result->timeSincePreviousFrame);
2035             PROTO_ITEM_SET_GENERATED(gap_ti);
2036         }
2037
2038         if (result->nextSet) {
2039             proto_item *gap_ti;
2040             proto_item *next_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_next_frame,
2041                                                       tvb, 0, 0, result->nextFrameNum);
2042             PROTO_ITEM_SET_GENERATED(next_ti);
2043
2044             gap_ti = proto_tree_add_uint(tree, hf_mac_lte_dl_harq_resend_time_until_next_frame,
2045                                          tvb, 0, 0, result->timeToNextFrame);
2046             PROTO_ITEM_SET_GENERATED(gap_ti);
2047         }
2048
2049     }
2050 }
2051
2052
2053 /* Return TRUE if the given packet is thought to be a retx */
2054 int is_mac_lte_frame_retx(packet_info *pinfo, guint8 direction)
2055 {
2056     struct mac_lte_info *p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte);
2057
2058     if (direction == DIRECTION_UPLINK) {
2059         /* For UL, retx count is stored in per-packet struct */
2060         return ((p_mac_lte_info != NULL) && (p_mac_lte_info->reTxCount > 0));
2061     }
2062     else {
2063         /* Use answer if told directly */
2064         if (p_mac_lte_info->dl_retx == dl_retx_yes) {
2065             return TRUE;
2066         }
2067         else {
2068             /* Otherwise look up in table */
2069             DLHARQResult *result = g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
2070             return ((result != NULL) && result->previousSet);
2071         }
2072     }
2073 }
2074
2075
2076 /* Track UL frames, so that when a retx is indicated, we can search for
2077    the original tx.  We will either find it, and provide a link back to it,
2078    or flag that we couldn't find as an expert error */
2079 static void TrackReportedULHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatile int offset,
2080                                       proto_tree *tree, mac_lte_info *p_mac_lte_info,
2081                                       proto_item *retx_ti)
2082 {
2083     ULHARQResult *result = NULL;
2084
2085     /* If don't have detailed DL PHY info, just give up */
2086     if (!p_mac_lte_info->detailed_phy_info.ul_info.present) {
2087         return;
2088     }
2089
2090     /* Give up if harqid is out of range */
2091     if (p_mac_lte_info->detailed_phy_info.ul_info.harq_id >= 8) {
2092         return;
2093     }
2094
2095     if (!pinfo->fd->flags.visited) {
2096         /* First time, so set result and update UL harq table */
2097         LastFrameData *lastData = NULL;
2098         LastFrameData *thisData = NULL;
2099
2100         /* Look up entry for this UE/RNTI */
2101         ULHarqBuffers *ueData =
2102             g_hash_table_lookup(mac_lte_ul_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti));
2103         if (ueData != NULL) {
2104             if (p_mac_lte_info->reTxCount >= 1) {
2105                 /* Looking for frame previously on this harq-id */
2106                 lastData = &(ueData->harqid[p_mac_lte_info->detailed_phy_info.ul_info.harq_id]);
2107                 if (lastData->inUse) {
2108                     /* Compare time, sf, data to see if this looks like a retx */
2109                     if ((tvb_length_remaining(tvb, offset) == lastData->length) &&
2110                         (p_mac_lte_info->detailed_phy_info.ul_info.ndi == lastData->ndi) &&
2111                         tvb_memeql(tvb, offset, lastData->data, MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0) {
2112
2113                         /* Work out gap between frames */
2114                         gint seconds_between_packets = (gint)
2115                               (pinfo->fd->abs_ts.secs - lastData->received_time.secs);
2116                         gint nseconds_between_packets =
2117                               pinfo->fd->abs_ts.nsecs - lastData->received_time.nsecs;
2118
2119                         /* Round to nearest ms */
2120                         gint total_gap = (seconds_between_packets*1000) +
2121                                          ((nseconds_between_packets+500000) / 1000000);
2122
2123                         /* Could be as many as max-tx (which we don't know) * 8ms ago.
2124                            32 is the most I've seen... */
2125                         if (total_gap <= 33) {
2126                             ULHARQResult *original_result = NULL;
2127
2128                             /* Original detected!!! Store result pointing back */
2129                             result = se_alloc0(sizeof(ULHARQResult));
2130                             result->previousSet = TRUE;
2131                             result->previousFrameNum = lastData->framenum;
2132                             result->timeSincePreviousFrame = total_gap;
2133                             g_hash_table_insert(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num), result);
2134
2135                             /* Now make previous frame point forward to here */
2136                             original_result = g_hash_table_lookup(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(lastData->framenum));
2137                             if (original_result == NULL) {
2138                                 original_result = se_alloc0(sizeof(ULHARQResult));
2139                                 g_hash_table_insert(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(lastData->framenum), original_result);
2140                             }
2141                             original_result->nextSet = TRUE;
2142                             original_result->nextFrameNum = pinfo->fd->num;
2143                             original_result->timeToNextFrame = total_gap;
2144                         }
2145                     }
2146                 }
2147             }
2148         }
2149         else {
2150             /* Allocate entry in table for this UE/RNTI */
2151             ueData = se_alloc0(sizeof(ULHarqBuffers));
2152             g_hash_table_insert(mac_lte_ul_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti), ueData);
2153         }
2154
2155         /* Store this frame's details in table */
2156         thisData = &(ueData->harqid[p_mac_lte_info->detailed_phy_info.ul_info.harq_id]);
2157         thisData->inUse = TRUE;
2158         thisData->length = tvb_length_remaining(tvb, offset);
2159         tvb_memcpy(tvb, thisData->data, offset, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH));
2160         thisData->ndi = p_mac_lte_info->detailed_phy_info.ul_info.ndi;
2161         thisData->framenum = pinfo->fd->num;
2162         thisData->received_time = pinfo->fd->abs_ts;
2163     }
2164     else {
2165         /* Not first time, so just get whats already stored in result */
2166         result = g_hash_table_lookup(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
2167     }
2168
2169     /* Show any link back to previous Tx */
2170     if (retx_ti != NULL) {
2171         if (result != NULL) {
2172             if (result->previousSet) {
2173                 proto_item *original_ti, *gap_ti;
2174
2175                 original_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_original_frame,
2176                                                   tvb, 0, 0, result->previousFrameNum);
2177                 PROTO_ITEM_SET_GENERATED(original_ti);
2178
2179                 gap_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_time_since_previous_frame,
2180                                              tvb, 0, 0, result->timeSincePreviousFrame);
2181                 PROTO_ITEM_SET_GENERATED(gap_ti);
2182             }
2183         }
2184         else {
2185             expert_add_info_format(pinfo, retx_ti, PI_SEQUENCE, PI_ERROR,
2186                                    "Original Tx of UL frame not found (UE %u) !!", p_mac_lte_info->ueid);
2187         }
2188     }
2189
2190     /* Show link forward to any known next Tx */
2191     if ((result != NULL) && result->nextSet) {
2192         proto_item *next_ti, *gap_ti;
2193
2194         next_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_next_frame,
2195                                           tvb, 0, 0, result->nextFrameNum);
2196         expert_add_info_format(pinfo, next_ti, PI_SEQUENCE, PI_WARN,
2197                                "UL MAC PDU (UE %u) needed to be retransmitted", p_mac_lte_info->ueid);
2198
2199         PROTO_ITEM_SET_GENERATED(next_ti);
2200
2201         gap_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_time_until_next_frame,
2202                                      tvb, 0, 0, result->timeToNextFrame);
2203         PROTO_ITEM_SET_GENERATED(gap_ti);
2204     }
2205 }
2206
2207
2208 /* Look up SRResult associated with a given frame. Will create one if necessary
2209    if can_create is set */
2210 static SRResult *GetSRResult(guint32 frameNum, gboolean can_create)
2211 {
2212     SRResult *result;
2213     result = g_hash_table_lookup(mac_lte_sr_request_hash, GUINT_TO_POINTER(frameNum));
2214
2215     if ((result == NULL) && can_create) {
2216         result = se_alloc0(sizeof(SRResult));
2217         g_hash_table_insert(mac_lte_sr_request_hash, GUINT_TO_POINTER((guint)frameNum), result);
2218     }
2219     return result;
2220 }
2221
2222
2223 /* Keep track of SR requests, failures and related grants, in order to show them
2224    as generated fields in these frames */
2225 static void TrackSRInfo(SREvent event, packet_info *pinfo, proto_tree *tree,
2226                         tvbuff_t *tvb, mac_lte_info *p_mac_lte_info, gint idx, proto_item *event_ti)
2227 {
2228     SRResult   *result           = NULL;
2229     SRState    *state;
2230     SRResult   *resultForSRFrame = NULL;
2231
2232     guint16     rnti;
2233     guint16     ueid;
2234     proto_item *ti;
2235
2236     /* Get appropriate identifiers */
2237     if (event == SR_Request) {
2238         rnti = p_mac_lte_info->oob_rnti[idx];
2239         ueid = p_mac_lte_info->oob_ueid[idx];
2240     }
2241     else {
2242         rnti = p_mac_lte_info->rnti;
2243         ueid = p_mac_lte_info->ueid;
2244     }
2245
2246     /* Create state for this RNTI if necessary */
2247     state = g_hash_table_lookup(mac_lte_ue_sr_state, GUINT_TO_POINTER((guint)rnti));
2248     if (state == NULL) {
2249         /* Allocate status for this RNTI */
2250         state = se_alloc(sizeof(SRState));
2251         state->status = None;
2252         g_hash_table_insert(mac_lte_ue_sr_state, GUINT_TO_POINTER((guint)rnti), state);
2253     }
2254
2255     /* First time through - update state with new info */
2256     if (!pinfo->fd->flags.visited) {
2257         guint32 timeSinceRequest;
2258
2259         /* Store time of request */
2260         if (event == SR_Request) {
2261             state->requestTime = pinfo->fd->abs_ts;
2262         }
2263
2264         switch (state->status) {
2265             case None:
2266                 switch (event) {
2267                     case SR_Grant:
2268                         /* Got another grant - fine */
2269
2270                         /* update state */
2271                         state->lastGrantFramenum = pinfo->fd->num;
2272                         break;
2273
2274                     case SR_Request:
2275                         /* Sent an SR - fine */
2276
2277                         /* Update state */
2278                         state->status = SR_Outstanding;
2279                         state->lastSRFramenum = pinfo->fd->num;
2280                         break;
2281
2282                     case SR_Failure:
2283                         /* This is an error, since we hadn't send an SR... */
2284                         result = GetSRResult(pinfo->fd->num, TRUE);
2285                         result->type = InvalidSREvent;
2286                         result->status = None;
2287                         result->event = SR_Failure;
2288                         break;
2289                 }
2290                 break;
2291
2292             case SR_Outstanding:
2293                 timeSinceRequest = (guint32)(((pinfo->fd->abs_ts.secs - state->requestTime.secs) * 1000) +
2294                                              ((pinfo->fd->abs_ts.nsecs - state->requestTime.nsecs) / 1000000));
2295
2296                 switch (event) {
2297                     case SR_Grant:
2298                         /* Got grant we were waiting for, so state goes to None */
2299
2300                         /* Update state */
2301                         state->status = None;
2302
2303                         /* Set result info */
2304                         result = GetSRResult(pinfo->fd->num, TRUE);
2305                         result->type = GrantAnsweringSR;
2306                         result->frameNum = state->lastSRFramenum;
2307                         result->timeDifference = timeSinceRequest;
2308
2309                         /* Also set forward link for SR */
2310                         resultForSRFrame = GetSRResult(state->lastSRFramenum, TRUE);
2311                         resultForSRFrame->type = SRLeadingToGrant;
2312                         resultForSRFrame->frameNum = pinfo->fd->num;
2313                         resultForSRFrame->timeDifference = timeSinceRequest;
2314                         break;
2315
2316                     case SR_Request:
2317                         /* Another request when already have one pending */
2318                         result = GetSRResult(pinfo->fd->num, TRUE);
2319                         result->type = InvalidSREvent;
2320                         result->status = SR_Outstanding;
2321                         result->event = SR_Request;
2322                         break;
2323
2324                     case SR_Failure:
2325                         /* We sent an SR but it failed */
2326
2327                         /* Update state */
2328                         state->status = SR_Failed;
2329
2330                         /* Set result info for failure frame */
2331                         result = GetSRResult(pinfo->fd->num, TRUE);
2332                         result->type = FailureAnsweringSR;
2333                         result->frameNum = state->lastSRFramenum;
2334                         result->timeDifference = timeSinceRequest;
2335
2336                         /* Also set forward link for SR */
2337                         resultForSRFrame = GetSRResult(state->lastSRFramenum, TRUE);
2338                         resultForSRFrame->type = SRLeadingToFailure;
2339                         resultForSRFrame->frameNum = pinfo->fd->num;
2340                         resultForSRFrame->timeDifference = timeSinceRequest;
2341                         break;
2342                 }
2343                 break;
2344
2345             case SR_Failed:
2346                 switch (event) {
2347                     case SR_Grant:
2348                         /* Got a grant, presumably after a subsequent RACH - fine */
2349
2350                         /* Update state */
2351                         state->status = None;
2352                         break;
2353
2354                     case SR_Request:
2355                         /* Tried another SR after previous one failed.
2356                            Presumably a subsequent RACH was tried in-between... */
2357
2358                         state->status = SR_Outstanding;
2359
2360                         result = GetSRResult(pinfo->fd->num, TRUE);
2361                         result->status = SR_Outstanding;
2362                         result->event = SR_Request;
2363                         break;
2364
2365                     case SR_Failure:
2366                         /* 2 failures in a row.... */
2367                         result = GetSRResult(pinfo->fd->num, TRUE);
2368                         result->type = InvalidSREvent;
2369                         result->status = SR_Failed;
2370                         result->event = SR_Failure;
2371                         break;
2372                 }
2373                 break;
2374         }
2375     }
2376
2377     /* Get stored result for this frame */
2378     result = GetSRResult(pinfo->fd->num, FALSE);
2379     if (result == NULL) {
2380         /* For an SR frame, there should always be either a PDCCH grant or indication
2381            that the SR has failed */
2382         if (event == SR_Request) {
2383             expert_add_info_format(pinfo, event_ti, PI_SEQUENCE, PI_ERROR,
2384                                    "UE %u: SR results in neither a grant nor a failure indication",
2385                                    ueid);
2386         }
2387         return;
2388     }
2389
2390
2391     /* Show result info */
2392     switch (result->type) {
2393         case GrantAnsweringSR:
2394             ti = proto_tree_add_uint(tree, hf_mac_lte_grant_answering_sr,
2395                                      tvb, 0, 0, result->frameNum);
2396             PROTO_ITEM_SET_GENERATED(ti);
2397             ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_since_request,
2398                                      tvb, 0, 0, result->timeDifference);
2399             PROTO_ITEM_SET_GENERATED(ti);
2400             break;
2401
2402         case FailureAnsweringSR:
2403             ti = proto_tree_add_uint(tree, hf_mac_lte_failure_answering_sr,
2404                                      tvb, 0, 0, result->frameNum);
2405             PROTO_ITEM_SET_GENERATED(ti);
2406             ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_since_request,
2407                                      tvb, 0, 0, result->timeDifference);
2408             PROTO_ITEM_SET_GENERATED(ti);
2409             break;
2410
2411         case SRLeadingToGrant:
2412             ti = proto_tree_add_uint(tree, hf_mac_lte_sr_leading_to_grant,
2413                                      tvb, 0, 0, result->frameNum);
2414             PROTO_ITEM_SET_GENERATED(ti);
2415             ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_until_answer,
2416                                      tvb, 0, 0, result->timeDifference);
2417             PROTO_ITEM_SET_GENERATED(ti);
2418
2419             break;
2420
2421         case SRLeadingToFailure:
2422             ti = proto_tree_add_uint(tree, hf_mac_lte_sr_leading_to_failure,
2423                                      tvb, 0, 0, result->frameNum);
2424             PROTO_ITEM_SET_GENERATED(ti);
2425             ti = proto_tree_add_uint(tree, hf_mac_lte_sr_time_until_answer,
2426                                      tvb, 0, 0, result->timeDifference);
2427             PROTO_ITEM_SET_GENERATED(ti);
2428             break;
2429
2430         case InvalidSREvent:
2431             ti = proto_tree_add_none_format(tree, hf_mac_lte_sr_invalid_event,
2432                                             tvb, 0, 0, "UE %u: Invalid SR event - state=%s, event=%s",
2433                                             ueid,
2434                                             val_to_str_const(result->status, sr_status_vals, "Unknown"),
2435                                             val_to_str_const(result->event,  sr_event_vals,  "Unknown"));
2436             PROTO_ITEM_SET_GENERATED(ti);
2437             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_ERROR,
2438                                    "Invalid SR event for UE %u (C-RNTI %u) - state=%s, event=%s",
2439                                    ueid, rnti,
2440                                    val_to_str_const(result->status, sr_status_vals, "Unknown"),
2441                                    val_to_str_const(result->event,  sr_event_vals,  "Unknown"));
2442             break;
2443     }
2444 }
2445
2446
2447 /********************************************************/
2448 /* Count number of UEs/TTI (in both directions)         */
2449 /********************************************************/
2450
2451 /* For keeping track during first pass */
2452 typedef struct tti_info_t {
2453     guint16 subframe;
2454     nstime_t ttiStartTime;
2455     guint ues_in_tti;
2456 } tti_info_t;
2457
2458 static tti_info_t UL_tti_info;
2459 static tti_info_t DL_tti_info;
2460
2461 /* For associating with frame and displaying */
2462 typedef struct TTIInfoResult_t {
2463     guint ues_in_tti;
2464 } TTIInfoResult_t;
2465
2466 /* This table stores (FrameNumber -> *TTIInfoResult_t).  It is assigned during the first
2467    pass and used thereafter */
2468 static GHashTable *mac_lte_tti_info_result_hash = NULL;
2469
2470
2471 /* Work out which UE this is within TTI (within direction). Return answer */
2472 static guint16 count_ues_tti(mac_lte_info *p_mac_lte_info, packet_info *pinfo)
2473 {
2474     gboolean same_tti = FALSE;
2475     tti_info_t *tti_info;
2476
2477     /* Just return any previous result */
2478     TTIInfoResult_t *result = g_hash_table_lookup(mac_lte_tti_info_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
2479     if (result != NULL) {
2480         return result->ues_in_tti;
2481     }
2482
2483     /* Set tti_info based upon direction */
2484     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2485         tti_info = &UL_tti_info;
2486     }
2487     else {
2488         tti_info = &DL_tti_info;
2489     }
2490
2491     /* Work out if we are still in the same tti as before */
2492     if (tti_info->subframe == p_mac_lte_info->subframeNumber) {
2493         gint seconds_between_packets = (gint)
2494               (pinfo->fd->abs_ts.secs - tti_info->ttiStartTime.secs);
2495         gint nseconds_between_packets =
2496               pinfo->fd->abs_ts.nsecs -  tti_info->ttiStartTime.nsecs;
2497
2498         /* Round difference to nearest microsecond */
2499         gint total_us_gap = (seconds_between_packets*1000000) +
2500                            ((nseconds_between_packets+500) / 1000);
2501
2502         if (total_us_gap < 1000) {
2503             same_tti = TRUE;
2504         }
2505     }
2506
2507     /* Update global state */
2508     if (!same_tti) {
2509         tti_info->subframe = p_mac_lte_info->subframeNumber;
2510         tti_info->ttiStartTime = pinfo->fd->abs_ts;
2511         tti_info->ues_in_tti = 1;
2512     }
2513     else {
2514         tti_info->ues_in_tti++;
2515     }
2516
2517     /* Set result state for this frame */
2518     result = se_alloc(sizeof(TTIInfoResult_t));
2519     result->ues_in_tti = tti_info->ues_in_tti;
2520     g_hash_table_insert(mac_lte_tti_info_result_hash,
2521                         GUINT_TO_POINTER(pinfo->fd->num), result);
2522
2523     return tti_info->ues_in_tti;
2524 }
2525
2526
2527 /* Show which UE this is (within direction) for this TTI */
2528 static void show_ues_tti(packet_info *pinfo, mac_lte_info *p_mac_lte_info, tvbuff_t *tvb, proto_tree *context_tree)
2529 {
2530     /* Look up result */
2531     TTIInfoResult_t *result = g_hash_table_lookup(mac_lte_tti_info_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
2532     if (result != NULL) {
2533         proto_item *ti =  proto_tree_add_uint(context_tree,
2534                                               (p_mac_lte_info->direction == DIRECTION_UPLINK) ?
2535                                                   hf_mac_lte_ues_ul_per_tti :
2536                                                   hf_mac_lte_ues_dl_per_tti,
2537                                               tvb, 0, 0, result->ues_in_tti);
2538         PROTO_ITEM_SET_GENERATED(ti);
2539     }
2540 }
2541
2542
2543
2544 /* Lookup channel details for lcid */
2545 static void lookup_rlc_channel_from_lcid(guint8 lcid,
2546                                          rlc_channel_type_t *rlc_channel_type,
2547                                          guint8 *UM_seqnum_length,
2548                                          gint *drb_id)
2549 {
2550     /* Zero params (in case no match is found) */
2551     *rlc_channel_type = rlcRaw;
2552     *UM_seqnum_length = 0;
2553     *drb_id           = 0;
2554
2555     if (global_mac_lte_lcid_drb_source == (int)FromStaticTable) {
2556
2557         /* Look up in static (UAT) table */
2558         guint m;
2559         for (m=0; m < num_lcid_drb_mappings; m++) {
2560             if (lcid == lcid_drb_mappings[m].lcid) {
2561
2562                 *rlc_channel_type = lcid_drb_mappings[m].channel_type;
2563
2564                 /* Set UM_seqnum_length */
2565                 switch (*rlc_channel_type) {
2566                     case rlcUM5:
2567                         *UM_seqnum_length = 5;
2568                         break;
2569                     case rlcUM10:
2570                         *UM_seqnum_length = 10;
2571                         break;
2572                     default:
2573                         break;
2574                 }
2575
2576                 /* Set drb_id */
2577                 *drb_id = lcid_drb_mappings[m].drbid;
2578                 break;
2579             }
2580         }
2581     }
2582     else {
2583         /* Look up setting gleaned from configuration protocol */
2584         if (!dynamic_lcid_drb_mapping[lcid].valid) {
2585             return;
2586         }
2587
2588         *rlc_channel_type = dynamic_lcid_drb_mapping[lcid].channel_type;
2589
2590         /* Set UM_seqnum_length */
2591         switch (*rlc_channel_type) {
2592             case rlcUM5:
2593                 *UM_seqnum_length = 5;
2594                 break;
2595             case rlcUM10:
2596                 *UM_seqnum_length = 10;
2597                 break;
2598             default:
2599                 break;
2600         }
2601
2602         /* Set drb_id */
2603         *drb_id = dynamic_lcid_drb_mapping[lcid].drbid;
2604     }
2605 }
2606
2607
2608
2609 #define MAX_HEADERS_IN_PDU 1024
2610
2611 /* UL-SCH and DL-SCH formats have much in common, so handle them in a common
2612    function */
2613 static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2614                                    proto_item *pdu_ti,
2615                                    volatile guint32 offset, guint8 direction,
2616                                    mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info,
2617                                    proto_item *retx_ti,
2618                                    proto_tree *context_tree)
2619 {
2620     guint8            extension;
2621     volatile guint16  n;
2622     proto_item       *truncated_ti;
2623     proto_item       *padding_length_ti;
2624     proto_item       *hidden_root_ti;
2625
2626     /* Keep track of LCIDs and lengths as we dissect the header */
2627     volatile guint16 number_of_headers = 0;
2628     guint8           lcids[MAX_HEADERS_IN_PDU];
2629     gint16           pdu_lengths[MAX_HEADERS_IN_PDU];
2630
2631     proto_item *pdu_header_ti;
2632     proto_tree *pdu_header_tree;
2633
2634     gboolean   have_seen_data_header = FALSE;
2635     guint8     number_of_padding_subheaders = 0;
2636     gboolean   have_seen_non_padding_control = FALSE;
2637     gboolean   have_seen_bsr = FALSE;
2638     gboolean   expecting_body_data = FALSE;
2639     volatile   guint32    is_truncated = FALSE;
2640
2641     /* Maintain/show UEs/TTI count */
2642     tap_info->ueInTTI = count_ues_tti(p_mac_lte_info, pinfo);
2643     show_ues_tti(pinfo, p_mac_lte_info, tvb, context_tree);
2644
2645     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
2646                              "%s: (SF=%u) UEId=%-3u ",
2647                              (direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
2648                              p_mac_lte_info->subframeNumber,
2649                              p_mac_lte_info->ueid);
2650
2651     tap_info->raw_length = p_mac_lte_info->length;
2652
2653     /* For uplink frames, if this is logged as a resend, look for original tx */
2654     if (direction == DIRECTION_UPLINK) {
2655         TrackReportedULHARQResend(pinfo, tvb, offset, tree, p_mac_lte_info, retx_ti);
2656     }
2657
2658     /* For uplink grants, update SR status.  N.B. only newTx grant should stop SR */
2659     if ((direction == DIRECTION_UPLINK) && (p_mac_lte_info->reTxCount == 0) &&
2660         global_mac_lte_track_sr) {
2661
2662         TrackSRInfo(SR_Grant, pinfo, tree, tvb, p_mac_lte_info, 0, NULL);
2663     }
2664
2665     /* Add hidden item to filter on */
2666     hidden_root_ti = proto_tree_add_string_format(tree,
2667                                                  (direction == DIRECTION_UPLINK) ?
2668                                                     hf_mac_lte_ulsch :
2669                                                     hf_mac_lte_dlsch,
2670                                                  tvb, offset, 0,
2671                                                  "",
2672                                                  "Hidden header");
2673     PROTO_ITEM_SET_HIDDEN(hidden_root_ti);
2674
2675     /* Add PDU block header subtree */
2676     pdu_header_ti = proto_tree_add_string_format(tree,
2677                                                  (direction == DIRECTION_UPLINK) ?
2678                                                     hf_mac_lte_ulsch_header :
2679                                                     hf_mac_lte_dlsch_header,
2680                                                  tvb, offset, 0,
2681                                                  "",
2682                                                  "MAC PDU Header");
2683     pdu_header_tree = proto_item_add_subtree(pdu_header_ti,
2684                                              (direction == DIRECTION_UPLINK) ?
2685                                                     ett_mac_lte_ulsch_header :
2686                                                     ett_mac_lte_dlsch_header);
2687
2688
2689     /************************************************************************/
2690     /* Dissect each sub-header.                                             */
2691     do {
2692         guint8 reserved;
2693         guint64 length = 0;
2694         proto_item *pdu_subheader_ti;
2695         proto_tree *pdu_subheader_tree;
2696         proto_item *lcid_ti;
2697         proto_item *ti;
2698         gint       offset_start_subheader = offset;
2699         guint8 first_byte = tvb_get_guint8(tvb, offset);
2700
2701         /* Add PDU block header subtree.
2702            Default with length of 1 byte. */
2703         pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
2704                                                         hf_mac_lte_sch_subheader,
2705                                                         tvb, offset, 1,
2706                                                         "",
2707                                                         "Sub-header");
2708         pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
2709                                                     ett_mac_lte_sch_subheader);
2710
2711         /* Check 1st 2 reserved bits */
2712         reserved = (first_byte & 0xc0) >> 6;
2713         ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_reserved,
2714                                  tvb, offset, 1, ENC_BIG_ENDIAN);
2715         if (reserved != 0) {
2716             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
2717                                    "%cL-SCH header Reserved bits not zero",
2718                                    (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D');
2719         }
2720
2721         /* Extended bit */
2722         extension = (first_byte & 0x20) >> 5;
2723         proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_extended,
2724                             tvb, offset, 1, ENC_BIG_ENDIAN);
2725
2726         /* LCID.  Has different meaning depending upon direction. */
2727         lcids[number_of_headers] = first_byte & 0x1f;
2728         if (direction == DIRECTION_UPLINK) {
2729
2730             lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_ulsch_lcid,
2731                                           tvb, offset, 1, ENC_BIG_ENDIAN);
2732             write_pdu_label_and_info(pdu_ti, NULL, pinfo,
2733                                      "(%s",
2734                                      val_to_str_const(lcids[number_of_headers],
2735                                                       ulsch_lcid_vals, "(Unknown LCID)"));
2736         }
2737         else {
2738             /* Downlink */
2739             lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_dlsch_lcid,
2740                                           tvb, offset, 1, ENC_BIG_ENDIAN);
2741             write_pdu_label_and_info(pdu_ti, NULL, pinfo,
2742                                      "(%s",
2743                                      val_to_str_const(lcids[number_of_headers],
2744                                                       dlsch_lcid_vals, "(Unknown LCID)"));
2745
2746             if (lcids[number_of_headers] == DRX_COMMAND_LCID) {
2747                 expert_add_info_format(pinfo, lcid_ti, PI_SEQUENCE, PI_NOTE,
2748                                        "DRX command received for UE %u (RNTI %u)",
2749                                        p_mac_lte_info->ueid, p_mac_lte_info->rnti);
2750             }
2751         }
2752         offset++;
2753
2754         /* Remember if we've seen a data subheader */
2755         if (lcids[number_of_headers] <= 10) {
2756             have_seen_data_header = TRUE;
2757             expecting_body_data = TRUE;
2758         }
2759
2760         /* Show an expert item if a contol subheader (except Padding) appears
2761            *after* a data PDU */
2762         if (have_seen_data_header &&
2763             (lcids[number_of_headers] > 10) && (lcids[number_of_headers] != PADDING_LCID)) {
2764             expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
2765                                    "%cL-SCH Control subheaders should not appear after data subheaders",
2766                                    (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D');
2767             return;
2768         }
2769
2770         /* Show an expert item if we're seeing more then one BSR in a frame */
2771         if ((direction == DIRECTION_UPLINK) && is_bsr_lcid(lcids[number_of_headers])) {
2772             if (have_seen_bsr) {
2773                 expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
2774                                        "There shouldn't be > 1 BSR in a frame");
2775                 return;
2776             }
2777             have_seen_bsr = TRUE;
2778         }
2779
2780         /* Should not see padding after non-padding control... */
2781         if ((lcids[number_of_headers] > 10) &&
2782             (lcids[number_of_headers] == PADDING_LCID) &&
2783             extension)
2784         {
2785             number_of_padding_subheaders++;
2786             if (number_of_padding_subheaders > 2) {
2787                 expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_WARN,
2788                                        "Should not see more than 2 padding subheaders in one frame");
2789             }
2790
2791             if (have_seen_non_padding_control) {
2792                 expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
2793                                        "Padding should come before other control subheaders!");
2794             }
2795         }
2796
2797         /* Remember that we've seen non-padding control */
2798         if ((lcids[number_of_headers] > 10) &&
2799             (lcids[number_of_headers] != PADDING_LCID)) {
2800             have_seen_non_padding_control = TRUE;
2801         }
2802
2803
2804
2805         /********************************************************************/
2806         /* Length field follows if not the last header or for a fixed-sized
2807            control element */
2808         if (!extension) {
2809             /* Last one... */
2810             if (is_fixed_sized_control_element(lcids[number_of_headers], direction)) {
2811                 pdu_lengths[number_of_headers] = 0;
2812             }
2813             else {
2814                 pdu_lengths[number_of_headers] = -1;
2815             }
2816         }
2817         else {
2818             /* Not the last one */
2819             if (!is_fixed_sized_control_element(lcids[number_of_headers], direction) &&
2820                 (lcids[number_of_headers] != PADDING_LCID)) {
2821
2822                 guint8  format;
2823
2824                 /* F(ormat) bit tells us how long the length field is */
2825                 format = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
2826                 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_format,
2827                                     tvb, offset, 1, ENC_BIG_ENDIAN);
2828
2829                 /* Now read length field itself */
2830                 if (format) {
2831                     /* >= 128 - use 15 bits */
2832                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
2833                                                 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
2834
2835                     offset += 2;
2836                 }
2837                 else {
2838                     /* Less than 128 - only 7 bits */
2839                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
2840                                                 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
2841                     offset++;
2842                 }
2843                 pdu_lengths[number_of_headers] = (gint16)length;
2844             }
2845             else {
2846                 pdu_lengths[number_of_headers] = 0;
2847             }
2848         }
2849
2850
2851         /* Close off description in info column */
2852         switch (pdu_lengths[number_of_headers]) {
2853             case 0:
2854                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ") ");
2855                 break;
2856             case -1:
2857                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":remainder) ");
2858                 break;
2859             default:
2860                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
2861                                          pdu_lengths[number_of_headers]);
2862                 break;
2863         }
2864
2865         /* Append summary to subheader root */
2866         proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
2867                                val_to_str_const(lcids[number_of_headers],
2868                                                 (direction == DIRECTION_UPLINK) ?
2869                                                     ulsch_lcid_vals :
2870                                                         dlsch_lcid_vals,
2871                                                 "Unknown"));
2872
2873         switch (pdu_lengths[number_of_headers]) {
2874             case -1:
2875                 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
2876                 proto_item_append_text(pdu_header_ti, " (%s:remainder)",
2877                                        val_to_str_const(lcids[number_of_headers],
2878                                                         (direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals,
2879                                                         "Unknown"));
2880                 break;
2881             case 0:
2882                 proto_item_append_text(pdu_subheader_ti, ")");
2883                 proto_item_append_text(pdu_header_ti, " (%s)",
2884                                        val_to_str_const(lcids[number_of_headers],
2885                                                         (direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals,
2886                                                         "Unknown"));
2887                 break;
2888             default:
2889                 proto_item_append_text(pdu_subheader_ti, ", length=%u)",
2890                                        pdu_lengths[number_of_headers]);
2891                 proto_item_append_text(pdu_header_ti, " (%s:%u)",
2892                                        val_to_str_const(lcids[number_of_headers],
2893                                                         (direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals,
2894                                                         "Unknown"),
2895                                        pdu_lengths[number_of_headers]);
2896                 break;
2897         }
2898
2899
2900         /* Flag unknown lcid values in expert info */
2901         if (match_strval(lcids[number_of_headers],
2902                          (direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals) == NULL) {
2903             expert_add_info_format(pinfo, pdu_subheader_ti, PI_MALFORMED, PI_ERROR,
2904                                    "%cL-SCH: Unexpected LCID received (%u)",
2905                                    (p_mac_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D',
2906                                    lcids[number_of_headers]);
2907         }
2908
2909         /* Set length of this subheader */
2910         proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
2911
2912         number_of_headers++;
2913     } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
2914
2915     /* Check that we didn't reach the end of the subheader array... */
2916     if (number_of_headers >= MAX_HEADERS_IN_PDU) {
2917         proto_item *ti = proto_tree_add_text(tree, tvb, offset, 1,
2918                                              "Reached %u subheaders - frame obviously malformed",
2919                                              MAX_HEADERS_IN_PDU);
2920         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
2921                                "Reached %u subheaders - frame obviously malformed",
2922                                MAX_HEADERS_IN_PDU);
2923         return;
2924     }
2925
2926
2927     /* Append summary to overall PDU header root */
2928     proto_item_append_text(pdu_header_ti, "  [%u subheaders]",
2929                            number_of_headers);
2930
2931     /* And set its length to offset */
2932     proto_item_set_len(pdu_header_ti, offset);
2933
2934
2935     /* For DL, see if this is a retx.  Use whole PDU present (i.e. ignore padding if not logged) */
2936     if (direction == DIRECTION_DOWNLINK) {
2937         /* Result will be added to context tree */
2938         TrackReportedDLHARQResend(pinfo, tvb, tvb_length_remaining(tvb, 0), context_tree, p_mac_lte_info);
2939
2940         tap_info->isPHYRetx = (p_mac_lte_info->dl_retx == dl_retx_yes);
2941     }
2942
2943
2944     /************************************************************************/
2945     /* Dissect SDUs / control elements / padding.                           */
2946     /************************************************************************/
2947
2948     /* Dissect control element bodies first */
2949
2950     for (n=0; n < number_of_headers; n++) {
2951         /* Get out of loop once see any data SDU subheaders */
2952         if (lcids[n] <= 10) {
2953             break;
2954         }
2955
2956         /* Process what should be a valid control PDU type */
2957         if (direction == DIRECTION_DOWNLINK) {
2958
2959             /****************************/
2960             /* DL-SCH Control PDUs      */
2961             switch (lcids[n]) {
2962                 case ACTIVATION_DEACTIVATION_LCID:
2963                     {
2964                         proto_item *ad_ti;
2965                         proto_tree *ad_tree;
2966                         proto_item *ti;
2967                         guint8 reserved;
2968
2969                         /* Create AD root */
2970                         ad_ti = proto_tree_add_string_format(tree,
2971                                                              hf_mac_lte_control_activation_deactivation,
2972                                                              tvb, offset, 1,
2973                                                              "",
2974                                                              "Activation/Deactivation");
2975                         ad_tree = proto_item_add_subtree(ad_ti, ett_mac_lte_activation_deactivation);
2976
2977                         proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c7,
2978                                             tvb, offset, 1, ENC_BIG_ENDIAN);
2979                         proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c6,
2980                                             tvb, offset, 1, ENC_BIG_ENDIAN);
2981                         proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c5,
2982                                             tvb, offset, 1, ENC_BIG_ENDIAN);
2983                         proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c4,
2984                                             tvb, offset, 1, ENC_BIG_ENDIAN);
2985                         proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c3,
2986                                             tvb, offset, 1, ENC_BIG_ENDIAN);
2987                         proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c2,
2988                                             tvb, offset, 1, ENC_BIG_ENDIAN);
2989                         proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_c1,
2990                                             tvb, offset, 1, ENC_BIG_ENDIAN);
2991                         ti = proto_tree_add_item(ad_tree, hf_mac_lte_control_activation_deactivation_reserved,
2992                                                  tvb, offset, 1, ENC_BIG_ENDIAN);
2993                         reserved = tvb_get_guint8(tvb, offset) & 0x01;
2994                         if (reserved != 0) {
2995                             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
2996                                                    "Activation/Deactivation Reserved bit not zero");
2997                         }
2998                         offset++;
2999                     }
3000                     break;
3001                 case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
3002                     {
3003                         proto_item *cr_ti;
3004                         proto_tree *cr_tree;
3005                         proto_item *ti;
3006                         ContentionResolutionResult *crResult;
3007
3008                         /* Create CR root */
3009                         cr_ti = proto_tree_add_string_format(tree,
3010                                                              hf_mac_lte_control_ue_contention_resolution,
3011                                                              tvb, offset, 6,
3012                                                              "",
3013                                                              "Contention Resolution");
3014                         cr_tree = proto_item_add_subtree(cr_ti, ett_mac_lte_contention_resolution);
3015
3016
3017                         proto_tree_add_item(cr_tree, hf_mac_lte_control_ue_contention_resolution_identity,
3018                                             tvb, offset, 6, ENC_NA);
3019
3020                         /* Get pointer to result struct for this frame */
3021                         crResult =  g_hash_table_lookup(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
3022                         if (crResult == NULL) {
3023
3024                             /* Need to set result by looking for and comparing with Msg3 */
3025                             Msg3Data *msg3Data;
3026                             guint msg3Key = p_mac_lte_info->rnti;
3027
3028                             /* Allocate result and add it to the table */
3029                             crResult = se_alloc(sizeof(ContentionResolutionResult));
3030                             g_hash_table_insert(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->fd->num), crResult);
3031
3032                             /* Look for Msg3 */
3033                             msg3Data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(msg3Key));
3034
3035                             /* Compare CCCH bytes */
3036                             if (msg3Data != NULL) {
3037                                 crResult->msSinceMsg3 = (guint32)(((pinfo->fd->abs_ts.secs - msg3Data->msg3Time.secs) * 1000) +
3038                                                                   ((pinfo->fd->abs_ts.nsecs - msg3Data->msg3Time.nsecs) / 1000000));
3039                                 crResult->msg3FrameNum = msg3Data->framenum;
3040
3041                                 /* Compare the 6 bytes */
3042                                 if (tvb_memeql(tvb, offset, msg3Data->data, 6) == 0) {
3043                                     crResult->status = Msg3Match;
3044                                 }
3045                                 else {
3046                                     crResult->status = Msg3NoMatch;
3047                                 }
3048                             }
3049                             else {
3050                                 crResult->status = NoMsg3;
3051                             }
3052                         }
3053
3054                         /* Now show CR result in tree */
3055                         switch (crResult->status) {
3056                             case NoMsg3:
3057                                 proto_item_append_text(cr_ti, " (no corresponding Msg3 found!)");
3058                                 break;
3059
3060                             case Msg3Match:
3061                                 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
3062                                                          tvb, 0, 0, crResult->msg3FrameNum);
3063                                 PROTO_ITEM_SET_GENERATED(ti);
3064                                 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
3065                                                          tvb, 0, 0, crResult->msSinceMsg3);
3066                                 PROTO_ITEM_SET_GENERATED(ti);
3067
3068                                 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
3069                                                             tvb, 0, 0, TRUE);
3070                                 PROTO_ITEM_SET_GENERATED(ti);
3071                                 proto_item_append_text(cr_ti, " (matches Msg3 from frame %u, %ums ago)",
3072                                                        crResult->msg3FrameNum, crResult->msSinceMsg3);
3073                                 break;
3074
3075                             case Msg3NoMatch:
3076                                 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
3077                                                          tvb, 0, 0, crResult->msg3FrameNum);
3078                                 PROTO_ITEM_SET_GENERATED(ti);
3079                                 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
3080                                                          tvb, 0, 0, crResult->msSinceMsg3);
3081                                 PROTO_ITEM_SET_GENERATED(ti);
3082
3083                                 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
3084                                                              tvb, 0, 0, FALSE);
3085                                 expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
3086                                                        "CR body in Msg4 doesn't match Msg3 CCCH in frame %u",
3087                                                        crResult->msg3FrameNum);
3088                                 PROTO_ITEM_SET_GENERATED(ti);
3089                                 proto_item_append_text(cr_ti, " (doesn't match Msg3 from frame %u, %u ago)",
3090                                                        crResult->msg3FrameNum, crResult->msSinceMsg3);
3091                                 break;
3092                         };
3093
3094                         offset += 6;
3095                     }
3096                     break;
3097                 case TIMING_ADVANCE_LCID:
3098                     {
3099                         proto_item *ta_ti;
3100                         proto_item *reserved_ti;
3101                         guint8      reserved;
3102                         guint8      ta_value;
3103
3104                         /* Check 2 reserved bits */
3105                         reserved = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
3106                         reserved_ti = proto_tree_add_item(tree, hf_mac_lte_control_timing_advance_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
3107                         if (reserved != 0) {
3108                             expert_add_info_format(pinfo, reserved_ti, PI_MALFORMED, PI_ERROR,
3109                                                    "Timing Advance Reserved bits not zero (found 0x%x)", reserved);
3110                         }
3111
3112                         /* TA value */
3113                         ta_value = tvb_get_guint8(tvb, offset) & 0x3f;
3114                         ta_ti = proto_tree_add_item(tree, hf_mac_lte_control_timing_advance,
3115                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
3116
3117                         if (ta_value == 31) {
3118                             expert_add_info_format(pinfo, ta_ti, PI_SEQUENCE,
3119                                                    PI_NOTE,
3120                                                    "Timing Advance control element received (no correction needed)");
3121                         }
3122                         else {
3123                             expert_add_info_format(pinfo, ta_ti, PI_SEQUENCE,
3124                                                    PI_WARN,
3125                                                    "Timing Advance control element received (%u) %s correction needed",
3126                                                    ta_value,
3127                                                    (ta_value < 31) ? "-ve" : "+ve");
3128                         }
3129                         offset++;
3130                     }
3131                     break;
3132                 case DRX_COMMAND_LCID:
3133                     /* No payload */
3134                     break;
3135                 case PADDING_LCID:
3136                     /* No payload (in this position) */
3137                     tap_info->padding_bytes++;
3138                     break;
3139
3140                 default:
3141                     break;
3142             }
3143         }
3144         else {
3145
3146             /**********************************/
3147             /* UL-SCH Control PDUs            */
3148             switch (lcids[n]) {
3149                 case EXTENDED_POWER_HEADROOM_REPORT_LCID:
3150                     {
3151                         proto_item *ephr_ti;
3152                         proto_tree *ephr_tree;
3153                         proto_item *ti;
3154                         proto_tree *ephr_cell_tree;
3155                         proto_item *ephr_cell_ti;
3156                         guint8 scell_bitmap;
3157                         guint8 scell_count;
3158                         guint8 byte;
3159                         guint i;
3160                         guint32 curr_offset = offset;
3161                         guint32 computed_header_offset;
3162
3163                         if (pdu_lengths[n] == -1) {
3164                             /* Control Element size is the remaining PDU */
3165                             pdu_lengths[n] = (gint16)tvb_length_remaining(tvb, curr_offset);
3166                         }
3167
3168                         /* Create EPHR root */
3169                         ephr_ti = proto_tree_add_string_format(tree,
3170                                                                hf_mac_lte_control_ext_power_headroom,
3171                                                                tvb, curr_offset, pdu_lengths[n],
3172                                                                "",
3173                                                                "Extended Power Headroom");
3174                         ephr_tree = proto_item_add_subtree(ephr_ti, ett_mac_lte_extended_power_headroom);
3175
3176                         scell_bitmap = tvb_get_guint8(tvb, curr_offset);
3177                         proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c7,
3178                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3179                         proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c6,
3180                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3181                         proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c5,
3182                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3183                         proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c4,
3184                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3185                         proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c3,
3186                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3187                         proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c2,
3188                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3189                         proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_c1,
3190                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3191                         /* Check Reserved bit */
3192                         ti = proto_tree_add_item(ephr_tree, hf_mac_lte_control_ext_power_headroom_reserved,
3193                                                  tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3194                         if (scell_bitmap & 0x01) {
3195                             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
3196                                                    "Extended Power Headroom Reserved bit not zero");
3197                         }
3198                         curr_offset++;
3199
3200                         /* Compute expected header size to deduce if PH Type 2 report is present or not */
3201                         /* First count the number of SCells */
3202                         for (i = 0, scell_count = 0; i < 7; i++) {
3203                             if (scell_bitmap & (0x80>>i)) {
3204                                 scell_count++;
3205                             }
3206                         }
3207                         /* Now quickly parse the header */
3208                         computed_header_offset = curr_offset;
3209                         for (i = 0; i < scell_count; i++) {
3210                             if (tvb_get_guint8(tvb, computed_header_offset) & 0x80) {
3211                                 computed_header_offset++;
3212                             }
3213                             computed_header_offset++;
3214                         }
3215
3216                         if ((gint16)(computed_header_offset + 1 - curr_offset) != pdu_lengths[n]) {
3217                             /* PH Type 2 is present */
3218                             if (tvb_get_guint8(tvb, computed_header_offset) & 0x80) {
3219                                 computed_header_offset++;
3220                             }
3221                             computed_header_offset++;
3222                             if ((gint16)(computed_header_offset + 1 - curr_offset) != pdu_lengths[n]) {
3223                                 expert_add_info_format(pinfo, ephr_ti, PI_MALFORMED, PI_ERROR,
3224                                     "Control Element has an unexpected size (computed=%d, actual=%d)",
3225                                     computed_header_offset + 1 - curr_offset, pdu_lengths[n]);
3226                                 offset += pdu_lengths[n];
3227                                 break;
3228                             }
3229                             byte = tvb_get_guint8(tvb, curr_offset);
3230                             ephr_cell_ti = proto_tree_add_text(ephr_tree, tvb, curr_offset, ((byte&0x80)?2:1), "PCell");
3231                             ephr_cell_tree = proto_item_add_subtree(ephr_cell_ti, ett_mac_lte_extended_power_headroom_cell);
3232                             proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
3233                                                 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3234                             proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
3235                                                 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3236                             proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
3237                                                 tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3238                             proto_item_append_text(ephr_cell_ti, " (%s)",
3239                                                    val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
3240                             curr_offset++;
3241                             if (byte & 0x80) {
3242                                 /* Pcmax,c field is present */
3243                                 byte = tvb_get_guint8(tvb, curr_offset);
3244                                 /* Check 2 Reserved bits */
3245                                 ti = proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
3246                                                          tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3247                                 if (byte & 0xc0) {
3248                                     expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
3249                                                            "Extended Power Headroom Reserved bits not zero (found 0x%x)",
3250                                                            (byte & 0xc0) >> 6);
3251                                 }
3252                                 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
3253                                                     tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3254                                 proto_item_append_text(ephr_cell_ti, " (%s)",
3255                                                        val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
3256                                 curr_offset++;
3257                             }
3258                         } else {
3259                             if ((gint16)(computed_header_offset + 1 - curr_offset) != pdu_lengths[n]) {
3260                                 expert_add_info_format(pinfo, ephr_ti, PI_MALFORMED, PI_ERROR,
3261                                     "Control Element has an unexpected size (computed=%d, actual=%d)",
3262                                     computed_header_offset + 1 - curr_offset, pdu_lengths[n]);
3263                                 offset += pdu_lengths[n];
3264                                 break;
3265                             }
3266                         }
3267                         for (i = 1, scell_bitmap>>=1; i <= 7; i++, scell_bitmap>>=1) {
3268                             if (scell_bitmap & 0x01) {
3269                                 byte = tvb_get_guint8(tvb, curr_offset);
3270                                 ephr_cell_ti = proto_tree_add_text(ephr_tree, tvb, curr_offset, ((byte&0x80)?2:1), "SCell Index %u", i);
3271                                 ephr_cell_tree = proto_item_add_subtree(ephr_cell_ti, ett_mac_lte_extended_power_headroom_cell);
3272                                 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_power_backoff,
3273                                                     tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3274                                 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_value,
3275                                                     tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3276                                 proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_level,
3277                                                     tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3278                                 proto_item_append_text(ephr_cell_ti, " (%s)",
3279                                                        val_to_str_ext_const((byte&0x3f), &power_headroom_vals_ext, "Unknown"));
3280                                 curr_offset++;
3281                                 if (byte & 0x80) {
3282                                     /* Pcmax,c field is present */
3283                                     byte = tvb_get_guint8(tvb, curr_offset);
3284                                     /* Check 2 Reserved bits */
3285                                     ti = proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_reserved2,
3286                                                              tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3287                                     if (byte & 0xc0) {
3288                                         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
3289                                                                "Extended Power Headroom Reserved bits not zero (found 0x%x)",
3290                                                                (byte & 0xc0) >> 6);
3291                                     }
3292                                     proto_tree_add_item(ephr_cell_tree, hf_mac_lte_control_ext_power_headroom_pcmaxc,
3293                                                         tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3294                                     proto_item_append_text(ephr_cell_ti, " (%s)",
3295                                                            val_to_str_ext_const((byte&0x3f), &pcmaxc_vals_ext, "Unknown"));
3296                                     curr_offset++;
3297                                 }
3298                             }
3299                         }
3300                         offset += pdu_lengths[n];
3301                     }
3302                     break;
3303                 case POWER_HEADROOM_REPORT_LCID:
3304                     {
3305                         proto_item *phr_ti;
3306                         proto_tree *phr_tree;
3307                         proto_item *ti;
3308                         guint8 reserved;
3309                         guint8 level;
3310
3311                         /* Create PHR root */
3312                         phr_ti = proto_tree_add_string_format(tree,
3313                                                               hf_mac_lte_control_power_headroom,
3314                                                               tvb, offset, 1,
3315                                                               "",
3316                                                               "Power Headroom");
3317                         phr_tree = proto_item_add_subtree(phr_ti, ett_mac_lte_power_headroom);
3318
3319                         /* Check 2 Reserved bits */
3320                         reserved = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
3321                         ti = proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_reserved,
3322                                                  tvb, offset, 1, ENC_BIG_ENDIAN);
3323                         if (reserved != 0) {
3324                             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
3325                                                    "Power Headroom Reserved bits not zero (found 0x%x)", reserved);
3326                         }
3327
3328                         /* Level */
3329                         level = tvb_get_guint8(tvb, offset) & 0x3f;
3330                         proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_level,
3331                                             tvb, offset, 1, ENC_BIG_ENDIAN);
3332
3333                         /* Show value in root label */
3334                         proto_item_append_text(phr_ti, " (%s)",
3335                                                val_to_str_ext_const(level, &power_headroom_vals_ext, "Unknown"));
3336                         offset++;
3337                     }
3338
3339
3340                     break;
3341                 case CRNTI_LCID:
3342                     proto_tree_add_item(tree, hf_mac_lte_control_crnti,
3343                                         tvb, offset, 2, ENC_BIG_ENDIAN);
3344                     offset += 2;
3345                     break;
3346                 case TRUNCATED_BSR_LCID:
3347                 case SHORT_BSR_LCID:
3348                     {
3349                         proto_tree *bsr_tree;
3350                         proto_item *bsr_ti;
3351                         proto_item *buffer_size_ti;
3352                         guint8 lcgid;
3353                         guint8 buffer_size;
3354                         int hfindex;
3355                         value_string_ext *p_vs_ext;
3356
3357                         if (p_mac_lte_info->isExtendedBSRSizes) {
3358                             hfindex = hf_mac_lte_control_short_ext_bsr_buffer_size;
3359                             p_vs_ext = &ext_buffer_size_vals_ext;
3360                         } else {
3361                             hfindex = hf_mac_lte_control_short_bsr_buffer_size;
3362                             p_vs_ext = &buffer_size_vals_ext;
3363                         }
3364
3365                         bsr_ti = proto_tree_add_string_format(tree,
3366                                                               hf_mac_lte_control_bsr,
3367                                                               tvb, offset, 1,
3368                                                               "",
3369                                                               "Short BSR");
3370                         bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
3371
3372                         /* LCG ID */
3373                         lcgid = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
3374                         proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_lcg_id,
3375                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
3376                         /* Buffer Size */
3377                         buffer_size = tvb_get_guint8(tvb, offset) & 0x3f;
3378                         buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex,
3379                                                              tvb, offset, 1, ENC_BIG_ENDIAN);
3380                         offset++;
3381                         if (buffer_size >= global_mac_lte_bsr_warn_threshold) {
3382                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
3383                                                    "UE %u - BSR for LCG %u exceeds threshold: %u (%s)",
3384                                                    p_mac_lte_info->ueid,
3385                                                    lcgid,
3386                                                    buffer_size,
3387                                                    val_to_str_ext_const(buffer_size, p_vs_ext, "Unknown"));
3388                         }
3389
3390
3391                         proto_item_append_text(bsr_ti, " (lcgid=%u  %s)",
3392                                                lcgid,
3393                                                val_to_str_ext_const(buffer_size, &buffer_size_vals_ext, "Unknown"));
3394                     }
3395                     break;
3396                 case LONG_BSR_LCID:
3397                     {
3398                         proto_tree *bsr_tree;
3399                         proto_item *bsr_ti;
3400                         proto_item *buffer_size_ti;
3401                         guint8     buffer_size[4];
3402                         int hfindex[4];
3403                         value_string_ext *p_vs_ext;
3404
3405                         if (p_mac_lte_info->isExtendedBSRSizes) {
3406                             hfindex[0] = hf_mac_lte_control_long_ext_bsr_buffer_size_0;
3407                             hfindex[1] = hf_mac_lte_control_long_ext_bsr_buffer_size_1;
3408                             hfindex[2] = hf_mac_lte_control_long_ext_bsr_buffer_size_2;
3409                             hfindex[3] = hf_mac_lte_control_long_ext_bsr_buffer_size_3;
3410                             p_vs_ext = &ext_buffer_size_vals_ext;
3411                         } else {
3412                             hfindex[0] = hf_mac_lte_control_long_bsr_buffer_size_0;
3413                             hfindex[1] = hf_mac_lte_control_long_bsr_buffer_size_1;
3414                             hfindex[2] = hf_mac_lte_control_long_bsr_buffer_size_2;
3415                             hfindex[3] = hf_mac_lte_control_long_bsr_buffer_size_3;
3416                             p_vs_ext = &buffer_size_vals_ext;
3417                         }
3418
3419                         bsr_ti = proto_tree_add_string_format(tree,
3420                                                               hf_mac_lte_control_bsr,
3421                                                               tvb, offset, 3,
3422                                                               "",
3423                                                               "Long BSR");
3424                         bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
3425
3426                         /* LCID Group 0 */
3427                         buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[0],
3428                                                              tvb, offset, 1, ENC_BIG_ENDIAN);
3429                         buffer_size[0] = (tvb_get_guint8(tvb, offset) & 0xfc) >> 2;
3430                         if (buffer_size[0] >= global_mac_lte_bsr_warn_threshold) {
3431                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
3432                                                    "UE %u - BSR for LCG 0 exceeds threshold: %u (%s)",
3433                                                    p_mac_lte_info->ueid,
3434                                                    buffer_size[0],
3435                                                    val_to_str_ext_const(buffer_size[0], p_vs_ext, "Unknown"));
3436                         }
3437
3438                         /* LCID Group 1 */
3439                         buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[1],
3440                                                              tvb, offset, 2, ENC_BIG_ENDIAN);
3441                         buffer_size[1] = ((tvb_get_guint8(tvb, offset) & 0x03) << 4) | ((tvb_get_guint8(tvb, offset+1) & 0xf0) >> 4);
3442                         offset++;
3443                         if (buffer_size[1] >= global_mac_lte_bsr_warn_threshold) {
3444                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
3445                                                    "UE %u - BSR for LCG 1 exceeds threshold: %u (%s)",
3446                                                    p_mac_lte_info->ueid,
3447                                                    buffer_size[1],
3448                                                    val_to_str_ext_const(buffer_size[1], p_vs_ext, "Unknown"));
3449                         }
3450
3451                         /* LCID Group 2 */
3452                         buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[2],
3453                                                              tvb, offset, 2, ENC_BIG_ENDIAN);
3454
3455                         buffer_size[2] = ((tvb_get_guint8(tvb, offset) & 0x0f) << 2) | ((tvb_get_guint8(tvb, offset+1) & 0xc0) >> 6);
3456                         offset++;
3457                         if (buffer_size[2] >= global_mac_lte_bsr_warn_threshold) {
3458                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
3459                                                    "UE %u - BSR for LCG 2 exceeds threshold: %u (%s)",
3460                                                    p_mac_lte_info->ueid,
3461                                                    buffer_size[2],
3462                                                    val_to_str_ext_const(buffer_size[2], p_vs_ext, "Unknown"));
3463                         }
3464
3465                         /* LCID Group 3 */
3466                         buffer_size_ti = proto_tree_add_item(bsr_tree, hfindex[3],
3467                                                              tvb, offset, 1, ENC_BIG_ENDIAN);
3468                         buffer_size[3] = tvb_get_guint8(tvb, offset) & 0x3f;
3469                         offset++;
3470                         if (buffer_size[3] >= global_mac_lte_bsr_warn_threshold) {
3471                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
3472                                                    "UE %u - BSR for LCG 3 exceeds threshold: %u (%s)",
3473                                                    p_mac_lte_info->ueid,
3474                                                    buffer_size[3],
3475                                                    val_to_str_ext_const(buffer_size[3], p_vs_ext, "Unknown"));
3476                         }
3477
3478                         /* Append summary to parent */
3479                         proto_item_append_text(bsr_ti, "   0:(%s)  1:(%s)  2:(%s)  3:(%s)",
3480                                                val_to_str_ext_const(buffer_size[0], p_vs_ext, "Unknown"),
3481                                                val_to_str_ext_const(buffer_size[1], p_vs_ext, "Unknown"),
3482                                                val_to_str_ext_const(buffer_size[2], p_vs_ext, "Unknown"),
3483                                                val_to_str_ext_const(buffer_size[3], p_vs_ext, "Unknown"));
3484                     }
3485                     break;
3486                 case PADDING_LCID:
3487                     /* No payload, in this position */
3488                     tap_info->padding_bytes++;
3489                     break;
3490
3491                 default:
3492                     break;
3493             }
3494         }
3495     }
3496
3497     /* There might not be any data, if only headers (plus control data) were logged */
3498     is_truncated = ((tvb_length_remaining(tvb, offset) == 0) && expecting_body_data);
3499     truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_sch_header_only, tvb, 0, 0,
3500                                        is_truncated);
3501     if (is_truncated) {
3502         PROTO_ITEM_SET_GENERATED(truncated_ti);
3503         expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
3504                                "MAC PDU SDUs have been omitted");
3505         return;
3506     }
3507     else {
3508         PROTO_ITEM_SET_HIDDEN(truncated_ti);
3509     }
3510
3511
3512     /* Now process remaining bodies, which should all be data */
3513     for (; n < number_of_headers; n++) {
3514
3515         /* Data SDUs treated identically for Uplink or downlink channels */
3516         proto_item *sdu_ti;
3517         const guint8 *pdu_data;
3518         volatile guint16 data_length;
3519         int i;
3520         char buff[64];
3521
3522         /* Break out if meet padding */
3523         if (lcids[n] == PADDING_LCID) {
3524             break;
3525         }
3526
3527         /* Work out length */
3528         data_length = (pdu_lengths[n] == -1) ?
3529                             tvb_length_remaining(tvb, offset) :
3530                             pdu_lengths[n];
3531
3532         /* Dissect SDU as raw bytes */
3533         sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_sch_sdu, tvb, offset, pdu_lengths[n],
3534                                              NULL, "SDU (%s, length=%u bytes): ",
3535                                              val_to_str_const(lcids[n],
3536                                                               (direction == DIRECTION_UPLINK) ?
3537                                                                   ulsch_lcid_vals :
3538                                                                   dlsch_lcid_vals,
3539                                                              "Unknown"),
3540                                              data_length);
3541         /* Show bytes too.  There must be a nicer way of doing this! */
3542         pdu_data = tvb_get_ptr(tvb, offset, pdu_lengths[n]);
3543         for (i=0; i < data_length; i++) {
3544             g_snprintf(buff+(i*2), 3, "%02x",  pdu_data[i]);
3545             if (i >= 30) {
3546                 g_snprintf(buff+(i*2), 4, "...");
3547                 break;
3548             }
3549         }
3550         proto_item_append_text(sdu_ti, "%s", buff);
3551
3552
3553         /* Look for Msg3 data so that it may be compared with later
3554            Contention Resolution body */
3555         if ((lcids[n] == 0) && (direction == DIRECTION_UPLINK) && (data_length == 6)) {
3556             if (!pinfo->fd->flags.visited) {
3557                 guint key = p_mac_lte_info->rnti;
3558                 Msg3Data *data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(key));
3559
3560                 /* Look for previous entry for this UE */
3561                 if (data == NULL) {
3562                     /* Allocate space for data and add to table */
3563                     data = se_alloc(sizeof(Msg3Data));
3564                     g_hash_table_insert(mac_lte_msg3_hash, GUINT_TO_POINTER(key), data);
3565                 }
3566
3567                 /* Fill in data details */
3568                 data->framenum = pinfo->fd->num;
3569                 tvb_memcpy(tvb, data->data, offset, data_length);
3570                 data->msg3Time = pinfo->fd->abs_ts;
3571             }
3572         }
3573
3574         /* CCCH frames can be dissected directly by LTE RRC... */
3575         if ((lcids[n] == 0) && global_mac_lte_attempt_rrc_decode) {
3576             tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, data_length, data_length);
3577
3578             /* Get appropriate dissector handle */
3579             volatile dissector_handle_t protocol_handle = 0;
3580             if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
3581                 protocol_handle = find_dissector("lte_rrc.ul_ccch");
3582             }
3583             else {
3584                 protocol_handle = find_dissector("lte_rrc.dl_ccch");
3585             }
3586
3587             /* Hide raw view of bytes */
3588             PROTO_ITEM_SET_HIDDEN(sdu_ti);
3589
3590             call_with_catch_all(protocol_handle, rrc_tvb, pinfo, tree);
3591         }
3592
3593         /* LCID 1 and 2 can be assumed to be srb1&2, so can dissect as RLC AM */
3594         else if ((lcids[n] == 1) || (lcids[n] == 2)) {
3595             if (global_mac_lte_attempt_srb_decode) {
3596                 /* Call RLC dissector */
3597                 call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
3598                                    RLC_AM_MODE, direction, p_mac_lte_info->ueid,
3599                                    CHANNEL_TYPE_SRB, lcids[n], 0,
3600                                    get_mac_lte_channel_priority(p_mac_lte_info->ueid,
3601                                                                 lcids[n], direction));
3602
3603                 /* Hide raw view of bytes */
3604                 PROTO_ITEM_SET_HIDDEN(sdu_ti);
3605             }
3606         }
3607
3608         else if ((lcids[n] >= 2) && (lcids[n] <= 10)) {
3609
3610             /* Look for mapping for this LCID to drb channel set by UAT table */
3611             rlc_channel_type_t rlc_channel_type;
3612             guint8 UM_seqnum_length;
3613             gint drb_id;
3614             guint8 priority = get_mac_lte_channel_priority(p_mac_lte_info->ueid,
3615                                                            lcids[n], direction);
3616
3617             lookup_rlc_channel_from_lcid(lcids[n],
3618                                          &rlc_channel_type,
3619                                          &UM_seqnum_length,
3620                                          &drb_id);
3621
3622             /* Dissect according to channel type */
3623             switch (rlc_channel_type) {
3624                 case rlcUM5:
3625                     call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
3626                                        RLC_UM_MODE, direction, p_mac_lte_info->ueid,
3627                                        CHANNEL_TYPE_DRB, (guint16)drb_id, UM_seqnum_length,
3628                                        priority);
3629                     break;
3630                 case rlcUM10:
3631                     call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
3632                                        RLC_UM_MODE, direction, p_mac_lte_info->ueid,
3633                                        CHANNEL_TYPE_DRB, (guint16)drb_id, UM_seqnum_length,
3634                                        priority);
3635                     break;
3636                 case rlcAM:
3637                     call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
3638                                        RLC_AM_MODE, direction, p_mac_lte_info->ueid,
3639                                        CHANNEL_TYPE_DRB, (guint16)drb_id, 0,
3640                                        priority);
3641                     break;
3642                 case rlcTM:
3643                     call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
3644                                        RLC_TM_MODE, direction, p_mac_lte_info->ueid,
3645                                        CHANNEL_TYPE_DRB, (guint16)drb_id, 0,
3646                                        priority);
3647                     break;
3648                 case rlcRaw:
3649                     /* Nothing to do! */
3650                     break;
3651             }
3652
3653             if (rlc_channel_type != rlcRaw) {
3654                 /* Hide raw view of bytes */
3655                 PROTO_ITEM_SET_HIDDEN(sdu_ti);
3656             }
3657
3658         }
3659
3660         offset += data_length;
3661
3662         /* Update tap byte count for this channel */
3663         tap_info->bytes_for_lcid[lcids[n]] += data_length;
3664         tap_info->sdus_for_lcid[lcids[n]]++;
3665     }
3666
3667
3668     /* Now padding, if present, extends to the end of the PDU */
3669     if (lcids[number_of_headers-1] == PADDING_LCID) {
3670         if (tvb_length_remaining(tvb, offset) > 0) {
3671             proto_tree_add_item(tree, hf_mac_lte_padding_data,
3672                                 tvb, offset, -1, ENC_NA);
3673         }
3674         padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
3675                                                tvb, offset, 0,
3676                                                p_mac_lte_info->length - offset);
3677         PROTO_ITEM_SET_GENERATED(padding_length_ti);
3678
3679         /* Update padding bytes in stats */
3680         tap_info->padding_bytes += (p_mac_lte_info->length - offset);
3681
3682         /* Make sure the PDU isn't bigger than reported! */
3683         if (offset > p_mac_lte_info->length) {
3684             expert_add_info_format(pinfo, padding_length_ti, PI_MALFORMED, PI_ERROR,
3685                                    "%s MAC PDU is longer than reported length (reported=%u, actual=%u)",
3686                                    (direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
3687                                    p_mac_lte_info->length, offset);
3688         }
3689     }
3690     else {
3691         /* There is no padding at the end of the frame */
3692         if (!is_truncated && (offset < p_mac_lte_info->length)) {
3693             /* There is a problem if we haven't used all of the PDU */
3694             expert_add_info_format(pinfo, pdu_ti, PI_MALFORMED, PI_ERROR,
3695                                    "%s PDU for UE %u is shorter than reported length (reported=%u, actual=%u)",
3696                                    (direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
3697                                    p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
3698         }
3699
3700         if (!is_truncated && (offset > p_mac_lte_info->length)) {
3701             /* There is a problem if the PDU is longer than rpeported */
3702             expert_add_info_format(pinfo, pdu_ti, PI_MALFORMED, PI_ERROR,
3703                                    "%s PDU for UE %u is longer than reported length (reported=%u, actual=%u)",
3704                                    (direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
3705                                    p_mac_lte_info->ueid, p_mac_lte_info->length, offset);
3706         }
3707     }
3708 }
3709
3710 static void dissect_mch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *pdu_ti,
3711                         volatile guint32 offset, mac_lte_info *p_mac_lte_info)
3712 {
3713     guint8            extension;
3714     volatile guint16  n;
3715     proto_item       *truncated_ti;
3716     proto_item       *padding_length_ti;
3717     proto_item       *hidden_root_ti;
3718
3719     /* Keep track of LCIDs and lengths as we dissect the header */
3720     volatile guint16 number_of_headers = 0;
3721     guint8  lcids[MAX_HEADERS_IN_PDU];
3722     gint16  pdu_lengths[MAX_HEADERS_IN_PDU];
3723
3724     proto_item *pdu_header_ti;
3725     proto_tree *pdu_header_tree;
3726
3727     gboolean   have_seen_data_header = FALSE;
3728     guint8     number_of_padding_subheaders = 0;
3729     gboolean   have_seen_non_padding_control = FALSE;
3730     gboolean   expecting_body_data = FALSE;
3731     volatile   guint32    is_truncated = FALSE;
3732
3733     write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3734                              "MCH: ",
3735                              p_mac_lte_info->subframeNumber);
3736
3737     /* Add hidden item to filter on */
3738     hidden_root_ti = proto_tree_add_string_format(tree, hf_mac_lte_mch, tvb,
3739                                                   offset, 0, "", "Hidden header");
3740     PROTO_ITEM_SET_HIDDEN(hidden_root_ti);
3741
3742     /* Add PDU block header subtree */
3743     pdu_header_ti = proto_tree_add_string_format(tree, hf_mac_lte_mch_header,
3744                                                  tvb, offset, 0,
3745                                                  "",
3746                                                  "MAC PDU Header");
3747     pdu_header_tree = proto_item_add_subtree(pdu_header_ti, ett_mac_lte_mch_header);
3748
3749
3750     /************************************************************************/
3751     /* Dissect each sub-header.                                             */
3752     do {
3753         guint8 reserved;
3754         guint64 length = 0;
3755         proto_item *pdu_subheader_ti;
3756         proto_tree *pdu_subheader_tree;
3757         proto_item *lcid_ti;
3758         proto_item *ti;
3759         gint       offset_start_subheader = offset;
3760         guint8 first_byte = tvb_get_guint8(tvb, offset);
3761
3762         /* Add PDU block header subtree.
3763            Default with length of 1 byte. */
3764         pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
3765                                                         hf_mac_lte_mch_subheader,
3766                                                         tvb, offset, 1,
3767                                                         "",
3768                                                         "Sub-header");
3769         pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
3770                                                     ett_mac_lte_mch_subheader);
3771
3772         /* Check 1st 2 reserved bits */
3773         reserved = (first_byte & 0xc0) >> 6;
3774         ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_reserved,
3775                                  tvb, offset, 1, ENC_BIG_ENDIAN);
3776         if (reserved != 0) {
3777             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
3778                                    "MCH header Reserved bits not zero");
3779         }
3780
3781         /* Extended bit */
3782         extension = (first_byte & 0x20) >> 5;
3783         proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_extended,
3784                             tvb, offset, 1, ENC_BIG_ENDIAN);
3785
3786         /* LCID */
3787         lcids[number_of_headers] = first_byte & 0x1f;
3788         lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_lcid,
3789                                       tvb, offset, 1, ENC_BIG_ENDIAN);
3790         write_pdu_label_and_info(pdu_ti, NULL, pinfo,
3791                                  "(%s",
3792                                  val_to_str_const(lcids[number_of_headers],
3793                                                   mch_lcid_vals, "(Unknown LCID)"));
3794         offset++;
3795
3796         /* Remember if we've seen a data subheader */
3797         if (lcids[number_of_headers] <= 28) {
3798             have_seen_data_header = TRUE;
3799             expecting_body_data = TRUE;
3800         }
3801
3802         /* Show an expert item if a contol subheader (except Padding) appears
3803            *after* a data PDU */
3804         if (have_seen_data_header &&
3805             (lcids[number_of_headers] > 28) && (lcids[number_of_headers] != PADDING_LCID)) {
3806             expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
3807                                    "MCH Control subheaders should not appear after data subheaders");
3808             return;
3809         }
3810
3811         /* Should not see padding after non-padding control... */
3812         if ((lcids[number_of_headers] > 28) &&
3813             (lcids[number_of_headers] == PADDING_LCID) &&
3814             extension)
3815         {
3816             number_of_padding_subheaders++;
3817             if (number_of_padding_subheaders > 2) {
3818                 expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_WARN,
3819                                        "Should not see more than 2 padding subheaders in one frame");
3820             }
3821
3822             if (have_seen_non_padding_control) {
3823                 expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
3824                                        "Padding should come before other control subheaders!");
3825             }
3826         }
3827
3828         /* Remember that we've seen non-padding control */
3829         if ((lcids[number_of_headers] > 28) &&
3830             (lcids[number_of_headers] != PADDING_LCID)) {
3831             have_seen_non_padding_control = TRUE;
3832         }
3833
3834
3835
3836         /********************************************************************/
3837         /* Length field follows if not the last header or for a fixed-sized
3838            control element */
3839         if (!extension) {
3840             /* Last one... */
3841             pdu_lengths[number_of_headers] = -1;
3842         }
3843         else {
3844             /* Not the last one */
3845             if (lcids[number_of_headers] != PADDING_LCID) {
3846
3847                 guint8  format;
3848
3849                 /* F(ormat) bit tells us how long the length field is */
3850                 format = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
3851                 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_mch_format,
3852                                     tvb, offset, 1, ENC_BIG_ENDIAN);
3853
3854                 /* Now read length field itself */
3855                 if (format) {
3856                     /* >= 128 - use 15 bits */
3857                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
3858                                                 tvb, offset*8 + 1, 15, &length, ENC_BIG_ENDIAN);
3859
3860                     offset += 2;
3861                 }
3862                 else {
3863                     /* Less than 128 - only 7 bits */
3864                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_mch_length,
3865                                                 tvb, offset*8 + 1, 7, &length, ENC_BIG_ENDIAN);
3866                     offset++;
3867                 }
3868                 if ((lcids[number_of_headers] == MCH_SCHEDULING_INFO_LCID) && (length & 0x01)) {
3869                     expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_WARN,
3870                                            "MCH Scheduling Information MAC Control Element should have an even size");
3871                 }
3872                 pdu_lengths[number_of_headers] = (gint16)length;
3873             }
3874             else {
3875                 pdu_lengths[number_of_headers] = 0;
3876             }
3877         }
3878
3879
3880         /* Close off description in info column */
3881         switch (pdu_lengths[number_of_headers]) {
3882             case 0:
3883                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ") ");
3884                 break;
3885             case -1:
3886                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":remainder) ");
3887                 break;
3888             default:
3889                 write_pdu_label_and_info(pdu_ti, NULL, pinfo, ":%u bytes) ",
3890                                          pdu_lengths[number_of_headers]);
3891                 break;
3892         }
3893
3894         /* Append summary to subheader root */
3895         proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
3896                                val_to_str_const(lcids[number_of_headers],
3897                                                 mch_lcid_vals, "Unknown"));
3898
3899         switch (pdu_lengths[number_of_headers]) {
3900             case -1:
3901                 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
3902                 proto_item_append_text(pdu_header_ti, " (%s:remainder)",
3903                                        val_to_str_const(lcids[number_of_headers],
3904                                                         mch_lcid_vals,
3905                                                         "Unknown"));
3906                 break;
3907             case 0:
3908                 proto_item_append_text(pdu_subheader_ti, ")");
3909                 proto_item_append_text(pdu_header_ti, " (%s)",
3910                                        val_to_str_const(lcids[number_of_headers],
3911                                                         mch_lcid_vals,
3912                                                         "Unknown"));
3913                 break;
3914             default:
3915                 proto_item_append_text(pdu_subheader_ti, ", length=%u)",
3916                                        pdu_lengths[number_of_headers]);
3917                 proto_item_append_text(pdu_header_ti, " (%s:%u)",
3918                                        val_to_str_const(lcids[number_of_headers],
3919                                                         mch_lcid_vals,
3920                                                         "Unknown"),
3921                                        pdu_lengths[number_of_headers]);
3922                 break;
3923         }
3924
3925
3926         /* Flag unknown lcid values in expert info */
3927         if (match_strval(lcids[number_of_headers],mch_lcid_vals) == NULL) {
3928             expert_add_info_format(pinfo, pdu_subheader_ti, PI_MALFORMED, PI_ERROR,
3929                                    "MCH: Unexpected LCID received (%u)",
3930                                    lcids[number_of_headers]);
3931         }
3932
3933         /* Set length of this subheader */
3934         proto_item_set_len(pdu_subheader_ti, offset - offset_start_subheader);
3935
3936         number_of_headers++;
3937     } while ((number_of_headers < MAX_HEADERS_IN_PDU) && extension);
3938
3939     /* Check that we didn't reach the end of the subheader array... */
3940     if (number_of_headers >= MAX_HEADERS_IN_PDU) {
3941         proto_item *ti = proto_tree_add_text(tree, tvb, offset, 1,
3942                                              "Reached %u subheaders - frame obviously malformed",
3943                                              MAX_HEADERS_IN_PDU);
3944         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
3945                                "Reached %u subheaders - frame obviously malformed",
3946                                MAX_HEADERS_IN_PDU);
3947         return;
3948     }
3949
3950
3951     /* Append summary to overall PDU header root */
3952     proto_item_append_text(pdu_header_ti, " (%u subheaders)",
3953                            number_of_headers);
3954
3955     /* And set its length to offset */
3956     proto_item_set_len(pdu_header_ti, offset);
3957
3958
3959     /************************************************************************/
3960     /* Dissect SDUs / control elements / padding.                           */
3961     /************************************************************************/
3962
3963     /* Dissect control element bodies first */
3964
3965     for (n=0; n < number_of_headers; n++) {
3966         /* Get out of loop once see any data SDU subheaders */
3967         if (lcids[n] <= 28) {
3968             break;
3969         }
3970
3971         /* Process what should be a valid control PDU type */
3972         switch (lcids[n]) {
3973             case MCH_SCHEDULING_INFO_LCID:
3974                 {
3975                     guint32 curr_offset = offset;
3976                     gint16 i;
3977                     guint16 stop_mtch_val;
3978                     proto_item *mch_sched_info_ti, *ti;
3979                     proto_tree *mch_sched_info_tree;
3980
3981                     mch_sched_info_ti = proto_tree_add_string_format(tree,
3982                                                                      hf_mac_lte_control_mch_scheduling_info,
3983                                                                      tvb, curr_offset, pdu_lengths[n],
3984                                                                      "",
3985                                                                      "MCH Scheduling Information");
3986                     mch_sched_info_tree = proto_item_add_subtree(mch_sched_info_ti, ett_mac_lte_mch_scheduling_info);
3987
3988                     for (i=0; i<(pdu_lengths[n]/2); i++) {
3989                         proto_tree_add_item(mch_sched_info_tree, hf_mac_lte_control_mch_scheduling_info_lcid,
3990                                             tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3991                         stop_mtch_val = tvb_get_ntohs(tvb, curr_offset) & 0x7ff;
3992                         ti = proto_tree_add_item(mch_sched_info_tree, hf_mac_lte_control_mch_scheduling_info_stop_mtch,
3993                                                  tvb, curr_offset, 2, ENC_BIG_ENDIAN);
3994                         if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) {
3995                             proto_item_append_text(ti, " (reserved)");
3996                         }
3997                         else if (stop_mtch_val == 2047) {
3998                             proto_item_append_text(ti, " (MTCH is not scheduled)");
3999                         }
4000                         curr_offset += 2;
4001                     }
4002
4003                     offset += pdu_lengths[n];
4004                 }
4005                 break;
4006             case PADDING_LCID:
4007                 /* No payload (in this position) */
4008                 break;
4009
4010             default:
4011                 break;
4012         }
4013     }
4014
4015
4016     /* There might not be any data, if only headers (plus control data) were logged */
4017     is_truncated = ((tvb_length_remaining(tvb, offset) == 0) && expecting_body_data);
4018     truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_mch_header_only, tvb, 0, 0,
4019                                        is_truncated);
4020     if (is_truncated) {
4021         PROTO_ITEM_SET_GENERATED(truncated_ti);
4022         expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
4023                                "MAC PDU SDUs have been omitted");
4024         return;
4025     }
4026     else {
4027         PROTO_ITEM_SET_HIDDEN(truncated_ti);
4028     }
4029
4030
4031     /* Now process remaining bodies, which should all be data */
4032     for (; n < number_of_headers; n++) {
4033
4034         proto_item *sdu_ti;
4035         const guint8 *pdu_data;
4036         volatile guint16 data_length;
4037         int i;
4038         char buff[64];
4039
4040         /* Break out if meet padding */
4041         if (lcids[n] == PADDING_LCID) {
4042             break;
4043         }
4044
4045         /* Work out length */
4046         data_length = (pdu_lengths[n] == -1) ?
4047                             tvb_length_remaining(tvb, offset) :
4048                             pdu_lengths[n];
4049
4050         /* Dissect SDU as raw bytes */
4051         sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_mch_sdu, tvb, offset, pdu_lengths[n],
4052                                              NULL, "SDU (%s, length=%u bytes): ",
4053                                              val_to_str_const(lcids[n], mch_lcid_vals, "Unknown"),
4054                                              data_length);
4055         /* Show bytes too.  There must be a nicer way of doing this! */
4056         pdu_data = tvb_get_ptr(tvb, offset, pdu_lengths[n]);
4057         for (i=0; i < data_length; i++) {
4058             g_snprintf(buff+(i*2), 3, "%02x",  pdu_data[i]);
4059             if (i >= 30) {
4060                 g_snprintf(buff+(i*2), 4, "...");
4061                 break;
4062             }
4063         }
4064         proto_item_append_text(sdu_ti, "%s", buff);
4065
4066         offset += data_length;
4067     }
4068
4069     /* Now padding, if present, extends to the end of the PDU */
4070     if (lcids[number_of_headers-1] == PADDING_LCID) {
4071         if (tvb_length_remaining(tvb, offset) > 0) {
4072             proto_tree_add_item(tree, hf_mac_lte_padding_data,
4073                                 tvb, offset, -1, ENC_NA);
4074         }
4075         padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
4076                                                tvb, offset, 0,
4077                                                p_mac_lte_info->length - offset);
4078         PROTO_ITEM_SET_GENERATED(padding_length_ti);
4079
4080         /* Make sure the PDU isn't bigger than reported! */
4081         if (offset > p_mac_lte_info->length) {
4082             expert_add_info_format(pinfo, padding_length_ti, PI_MALFORMED, PI_ERROR,
4083                                    "MAC PDU is longer than reported length (reported=%u, actual=%u)",
4084                                    p_mac_lte_info->length, offset);
4085         }
4086     }
4087     else {
4088         /* There is no padding at the end of the frame */
4089         if (!is_truncated && (offset < p_mac_lte_info->length)) {
4090             /* There is a problem if we haven't used all of the PDU */
4091             expert_add_info_format(pinfo, pdu_ti, PI_MALFORMED, PI_ERROR,
4092                                    "PDU is shorter than reported length (reported=%u, actual=%u)",
4093                                    p_mac_lte_info->length, offset);
4094         }
4095
4096         if (!is_truncated && (offset > p_mac_lte_info->length)) {
4097             /* There is a problem if the PDU is longer than rpeported */
4098             expert_add_info_format(pinfo, pdu_ti, PI_MALFORMED, PI_ERROR,
4099                                    "PDU is longer than reported length (reported=%u, actual=%u)",
4100                                    p_mac_lte_info->length, offset);
4101         }
4102     }
4103 }
4104
4105
4106 /*****************************/
4107 /* Main dissection function. */
4108 void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4109 {
4110     proto_tree          *mac_lte_tree;
4111     proto_item          *pdu_ti;
4112     proto_tree          *context_tree;
4113     proto_item          *context_ti;
4114     proto_item          *retx_ti        = NULL;
4115     proto_item          *ti;
4116     gint                 offset         = 0;
4117     struct mac_lte_info *p_mac_lte_info = NULL;
4118     gint                 n;
4119
4120     /* Allocate and zero tap struct */
4121     mac_lte_tap_info *tap_info = ep_alloc0(sizeof(mac_lte_tap_info));
4122
4123     /* Set protocol name */
4124     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
4125
4126     /* Create protocol tree. */
4127     pdu_ti = proto_tree_add_item(tree, proto_mac_lte, tvb, offset, -1, ENC_NA);
4128     proto_item_append_text(pdu_ti, " ");
4129     mac_lte_tree = proto_item_add_subtree(pdu_ti, ett_mac_lte);
4130
4131
4132     /* Look for packet info! */
4133     p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte);
4134
4135     /* Can't dissect anything without it... */
4136     if (p_mac_lte_info == NULL) {
4137         proto_item *tii =
4138             proto_tree_add_text(mac_lte_tree, tvb, offset, -1,
4139                                 "Can't dissect LTE MAC frame because no per-frame info was attached!");
4140         PROTO_ITEM_SET_GENERATED(tii);
4141         return;
4142     }
4143
4144     /* Clear info column */
4145     col_clear(pinfo->cinfo, COL_INFO);
4146
4147
4148     /*****************************************/
4149     /* Show context information              */
4150
4151     /* Create context root */
4152     context_ti = proto_tree_add_string_format(mac_lte_tree, hf_mac_lte_context,
4153                                               tvb, offset, 0, "", "Context");
4154     context_tree = proto_item_add_subtree(context_ti, ett_mac_lte_context);
4155     PROTO_ITEM_SET_GENERATED(context_ti);
4156
4157     ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_radio_type,
4158                              tvb, 0, 0, p_mac_lte_info->radioType);
4159     PROTO_ITEM_SET_GENERATED(ti);
4160
4161     ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_direction,
4162                              tvb, 0, 0, p_mac_lte_info->direction);
4163     PROTO_ITEM_SET_GENERATED(ti);
4164
4165     if (p_mac_lte_info->ueid != 0) {
4166         ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_ueid,
4167                                  tvb, 0, 0, p_mac_lte_info->ueid);
4168         PROTO_ITEM_SET_GENERATED(ti);
4169     }
4170
4171     /* There are several out-of-band MAC events that may be indicated in the context info. */
4172     /* Handle them here */
4173     if (p_mac_lte_info->length == 0) {
4174         proto_item *preamble_ti;
4175         proto_tree *preamble_tree;
4176
4177         switch (p_mac_lte_info->oob_event) {
4178             case ltemac_send_preamble:
4179                 preamble_ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_send_preamble,
4180                                                   tvb, 0, 0, ENC_ASCII|ENC_NA);
4181                 preamble_tree = proto_item_add_subtree(preamble_ti, ett_mac_lte_oob);
4182                 PROTO_ITEM_SET_GENERATED(ti);
4183
4184                 ti = proto_tree_add_uint(preamble_tree, hf_mac_lte_context_rapid,
4185                                          tvb, 0, 0, p_mac_lte_info->rapid);
4186                 PROTO_ITEM_SET_GENERATED(ti);
4187
4188                 ti = proto_tree_add_uint(preamble_tree, hf_mac_lte_context_rach_attempt_number,
4189                                          tvb, 0, 0, p_mac_lte_info->rach_attempt_number);
4190                 PROTO_ITEM_SET_GENERATED(ti);
4191
4192                 /* Info column */
4193                 write_pdu_label_and_info(pdu_ti, preamble_ti, pinfo,
4194                                          "RACH Preamble sent for UE %u (RAPID=%u, attempt=%u)",
4195                                          p_mac_lte_info->ueid, p_mac_lte_info->rapid, p_mac_lte_info->rach_attempt_number);
4196
4197                 /* Add expert info (a note, unless attempt > 1) */
4198                 expert_add_info_format(pinfo, ti, PI_SEQUENCE,
4199                                        (p_mac_lte_info->rach_attempt_number > 1) ? PI_WARN : PI_NOTE,
4200                                        "RACH Preamble sent for UE %u (RAPID=%u, attempt=%u)",
4201                                        p_mac_lte_info->ueid, p_mac_lte_info->rapid,
4202                                        p_mac_lte_info->rach_attempt_number);
4203                 break;
4204             case ltemac_send_sr:
4205                     /* Count of SRs */
4206                     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_number_of_srs,
4207                                              tvb, 0, 0, p_mac_lte_info->number_of_srs);
4208                     PROTO_ITEM_SET_GENERATED(ti);
4209
4210
4211                 for (n=0; n < p_mac_lte_info->number_of_srs; n++) {
4212                     proto_item *sr_ti;
4213                     proto_tree *sr_tree;
4214
4215                     /* SR event is subtree */
4216                     sr_ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_send_sr,
4217                                                 tvb, 0, 0, ENC_NA);
4218                     sr_tree = proto_item_add_subtree(sr_ti, ett_mac_lte_oob);
4219                     PROTO_ITEM_SET_GENERATED(sr_ti);
4220
4221
4222                     /* RNTI */
4223                     ti = proto_tree_add_uint(sr_tree, hf_mac_lte_context_rnti,
4224                                              tvb, 0, 0, p_mac_lte_info->oob_rnti[n]);
4225                     PROTO_ITEM_SET_GENERATED(ti);
4226
4227                     /* UEID */
4228                     ti = proto_tree_add_uint(sr_tree, hf_mac_lte_context_ueid,
4229                                              tvb, 0, 0, p_mac_lte_info->oob_ueid[n]);
4230                     PROTO_ITEM_SET_GENERATED(ti);
4231
4232                     /* Add summary to root. */
4233                     proto_item_append_text(sr_ti, " (UE=%u C-RNTI=%u)",
4234                                            p_mac_lte_info->oob_ueid[n],
4235                                            p_mac_lte_info->oob_rnti[n]);
4236
4237                     /* Info column */
4238                     if (n == 0) {
4239                         write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4240                                                 "Scheduling Requests (%u) sent: (UE=%u C-RNTI=%u)",
4241                                                 p_mac_lte_info->number_of_srs,
4242                                                 p_mac_lte_info->oob_ueid[n],
4243                                                 p_mac_lte_info->oob_rnti[n]);
4244                     }
4245                     else {
4246                         write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4247                                                 " (UE=%u C-RNTI=%u)",
4248                                                 p_mac_lte_info->oob_ueid[n],
4249                                                 p_mac_lte_info->oob_rnti[n]);
4250                     }
4251
4252                     /* Add expert info (a note) */
4253                     expert_add_info_format(pinfo, sr_ti, PI_SEQUENCE, PI_NOTE,
4254                                            "Scheduling Request sent for UE %u (RNTI %u)",
4255                                            p_mac_lte_info->oob_ueid[n],
4256                                            p_mac_lte_info->oob_rnti[n]);
4257
4258                     /* Update SR status for this UE */
4259                     if (global_mac_lte_track_sr) {
4260                         TrackSRInfo(SR_Request, pinfo, mac_lte_tree, tvb, p_mac_lte_info, n, sr_ti);
4261                     }
4262                 }
4263                 break;
4264             case ltemac_sr_failure:
4265                 ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti,
4266                                          tvb, 0, 0, p_mac_lte_info->rnti);
4267                 PROTO_ITEM_SET_GENERATED(ti);
4268
4269                 ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_sr_failure,
4270                                          tvb, 0, 0, ENC_NA);
4271                 PROTO_ITEM_SET_GENERATED(ti);
4272
4273                 /* Info column */
4274                 write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4275                                          "Scheduling Request FAILED for UE %u (C-RNTI=%u)",
4276                                          p_mac_lte_info->ueid,
4277                                          p_mac_lte_info->rnti);
4278
4279                 /* Add expert info (an error) */
4280                 expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_ERROR,
4281                                        "Scheduling Request failed for UE %u (RNTI %u)",
4282                                        p_mac_lte_info->ueid,
4283                                        p_mac_lte_info->rnti);
4284
4285                 /* Update SR status */
4286                 if (global_mac_lte_track_sr) {
4287                     TrackSRInfo(SR_Failure, pinfo, mac_lte_tree, tvb, p_mac_lte_info, 0, ti);
4288                 }
4289
4290                 break;
4291         }
4292
4293         /* Our work here is done */
4294         return;
4295     }
4296
4297     ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_sysframe_number,
4298                              tvb, 0, 0, p_mac_lte_info->sysframeNumber);
4299     PROTO_ITEM_SET_GENERATED(ti);
4300
4301     ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_subframe_number,
4302                              tvb, 0, 0, p_mac_lte_info->subframeNumber);
4303     PROTO_ITEM_SET_GENERATED(ti);
4304     if (p_mac_lte_info->subframeNumber > 9) {
4305         /* N.B. if we set it to valid value, it won't trigger when we rescan
4306            (at least with DCT2000 files where the context struct isn't re-read). */
4307         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4308                                "Subframe number (%u) was out of range - valid range is 0-9",
4309                                p_mac_lte_info->subframeNumber);
4310     }
4311
4312     if (p_mac_lte_info->subframeNumberOfGrantPresent) {
4313         ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_grant_subframe_number,
4314                                  tvb, 0, 0, p_mac_lte_info->subframeNumberOfGrant);
4315         PROTO_ITEM_SET_GENERATED(ti);
4316     }
4317
4318     if (p_mac_lte_info->rntiType != NO_RNTI) {
4319         ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti,
4320                                  tvb, 0, 0, p_mac_lte_info->rnti);
4321         PROTO_ITEM_SET_GENERATED(ti);
4322     }
4323
4324     ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_rnti_type,
4325                              tvb, 0, 0, p_mac_lte_info->rntiType);
4326     PROTO_ITEM_SET_GENERATED(ti);
4327
4328     /* Check that RNTI value is consistent with given RNTI type */
4329     switch (p_mac_lte_info->rntiType) {
4330         case M_RNTI:
4331             if (p_mac_lte_info->rnti != 0xFFFD) {
4332                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4333                       "M-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
4334                       p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFD);
4335                 return;
4336             }
4337             break;
4338         case P_RNTI:
4339             if (p_mac_lte_info->rnti != 0xFFFE) {
4340                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4341                       "P-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
4342                       p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFE);
4343                 return;
4344             }
4345             break;
4346         case SI_RNTI:
4347             if (p_mac_lte_info->rnti != 0xFFFF) {
4348                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4349                       "SI-RNTI indicated, but value is %u (0x%x) (must be 0x%x)",
4350                       p_mac_lte_info->rnti, p_mac_lte_info->rnti, 0xFFFE);
4351                 return;
4352             }
4353             break;
4354         case RA_RNTI:
4355             if ((p_mac_lte_info->rnti < 0x0001) || (p_mac_lte_info->rnti > 0x003C)) {
4356                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4357                       "RA_RNTI indicated, but given value %u (0x%x)is out of range",
4358                       p_mac_lte_info->rnti, p_mac_lte_info->rnti);
4359                 return;
4360             }
4361             break;
4362         case C_RNTI:
4363         case SPS_RNTI:
4364             if ((p_mac_lte_info->rnti < 0x0001) || (p_mac_lte_info->rnti > 0xFFF3)) {
4365                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4366                       "%s indicated, but given value %u (0x%x)is out of range",
4367                       val_to_str_const(p_mac_lte_info->rntiType,  rnti_type_vals, "Unknown"),
4368                       p_mac_lte_info->rnti, p_mac_lte_info->rnti);
4369                 return;
4370             }
4371             break;
4372
4373         default:
4374             break;
4375     }
4376
4377     ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_predefined_frame,
4378                              tvb, 0, 0, p_mac_lte_info->isPredefinedData);
4379     if (p_mac_lte_info->isPredefinedData) {
4380         PROTO_ITEM_SET_GENERATED(ti);
4381     }
4382     else {
4383         PROTO_ITEM_SET_HIDDEN(ti);
4384     }
4385
4386     ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_length,
4387                              tvb, 0, 0, p_mac_lte_info->length);
4388     PROTO_ITEM_SET_GENERATED(ti);
4389     /* Infer uplink grant size */
4390     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
4391         ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_ul_grant_size,
4392                                  tvb, 0, 0, p_mac_lte_info->length);
4393         PROTO_ITEM_SET_GENERATED(ti);
4394     }
4395
4396     /* Retx count goes in top-level tree to make it more visible */
4397     if (p_mac_lte_info->reTxCount) {
4398         proto_item *retx_reason_ti;
4399         retx_ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_count,
4400                                  tvb, 0, 0, p_mac_lte_info->reTxCount);
4401         PROTO_ITEM_SET_GENERATED(retx_ti);
4402
4403         if (p_mac_lte_info->reTxCount >= global_mac_lte_retx_counter_trigger) {
4404             expert_add_info_format(pinfo, retx_ti, PI_SEQUENCE, PI_WARN,
4405                                    "UE %u: UL MAC frame ReTX no. %u",
4406                                    p_mac_lte_info->ueid, p_mac_lte_info->reTxCount);
4407         }
4408
4409         retx_reason_ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_reason,
4410                                              tvb, 0, 0, p_mac_lte_info->isPHICHNACK);
4411         PROTO_ITEM_SET_GENERATED(retx_reason_ti);
4412     }
4413
4414     if (p_mac_lte_info->crcStatusValid) {
4415         /* Set status */
4416         ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_crc_status,
4417                                  tvb, 0, 0, p_mac_lte_info->detailed_phy_info.dl_info.crc_status);
4418         PROTO_ITEM_SET_GENERATED(ti);
4419
4420         /* Report non-success */
4421         if (p_mac_lte_info->detailed_phy_info.dl_info.crc_status != crc_success) {
4422             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4423                                    "%s Frame has CRC error problem (%s)",
4424                                    (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL",
4425                                    val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.crc_status,
4426                                                     crc_status_vals,
4427                                                     "Unknown"));
4428             write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4429                                      "%s: <CRC %s> UEId=%u %s=%u ",
4430                                      (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL",
4431                                      val_to_str_const(p_mac_lte_info->detailed_phy_info.dl_info.crc_status,
4432                                                     crc_status_vals,
4433                                                     "Unknown"),
4434                                      p_mac_lte_info->ueid,
4435                                      val_to_str_const(p_mac_lte_info->rntiType, rnti_type_vals,
4436                                                       "Unknown RNTI type"),
4437                                      p_mac_lte_info->rnti);
4438         }
4439     }
4440
4441     /* May also have extra Physical layer attributes set for this frame */
4442     show_extra_phy_parameters(pinfo, tvb, mac_lte_tree, p_mac_lte_info);
4443
4444     /* Set context-info parts of tap struct */
4445     tap_info->rnti = p_mac_lte_info->rnti;
4446     tap_info->ueid = p_mac_lte_info->ueid;
4447     tap_info->rntiType = p_mac_lte_info->rntiType;
4448     tap_info->isPredefinedData = p_mac_lte_info->isPredefinedData;
4449     tap_info->isPHYRetx = (p_mac_lte_info->reTxCount >= 1);
4450     tap_info->crcStatusValid = p_mac_lte_info->crcStatusValid;
4451     tap_info->crcStatus = p_mac_lte_info->detailed_phy_info.dl_info.crc_status;
4452     tap_info->direction = p_mac_lte_info->direction;
4453
4454     tap_info->time = pinfo->fd->abs_ts;
4455
4456     /* Also set total number of bytes (won't be used for UL/DL-SCH) */
4457     tap_info->single_number_of_bytes = tvb_length_remaining(tvb, offset);
4458
4459     /* If we know its predefined data, don't try to decode any further */
4460     if (p_mac_lte_info->isPredefinedData) {
4461         proto_tree_add_item(mac_lte_tree, hf_mac_lte_predefined_pdu, tvb, offset, -1, ENC_NA);
4462         write_pdu_label_and_info(pdu_ti, NULL, pinfo,
4463                                  "Predefined data (%u bytes%s)",
4464                                  p_mac_lte_info->length,
4465                                  (p_mac_lte_info->length > tvb_length_remaining(tvb, offset) ?
4466                                      " - truncated" :
4467                                      ""));
4468
4469         /* Queue tap info */
4470         if (!pinfo->flags.in_error_pkt) {
4471             tap_queue_packet(mac_lte_tap, pinfo, tap_info);
4472         }
4473
4474         return;
4475     }
4476
4477     /* IF CRC status failed, just do decode as raw bytes */
4478     if (!global_mac_lte_dissect_crc_failures &&
4479         (p_mac_lte_info->crcStatusValid &&
4480          (p_mac_lte_info->detailed_phy_info.dl_info.crc_status != crc_success))) {
4481
4482         proto_tree_add_item(mac_lte_tree, hf_mac_lte_raw_pdu, tvb, offset, -1, ENC_NA);
4483         write_pdu_label_and_info(pdu_ti, NULL, pinfo, "Raw data (%u bytes)", tvb_length_remaining(tvb, offset));
4484
4485         /* Queue tap info.
4486            TODO: unfortunately DL retx detection won't get done if we return here... */
4487         if (!pinfo->flags.in_error_pkt) {
4488             tap_queue_packet(mac_lte_tap, pinfo, tap_info);
4489         }
4490
4491         return;
4492     }
4493
4494     /* Reset this counter */
4495     s_number_of_rlc_pdus_shown = 0;
4496
4497     /* Dissect the MAC PDU itself. Format depends upon RNTI type. */
4498     switch (p_mac_lte_info->rntiType) {
4499
4500         case P_RNTI:
4501             /* PCH PDU */
4502             dissect_pch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info->direction);
4503             break;
4504
4505         case RA_RNTI:
4506             /* RAR PDU */
4507             dissect_rar(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, tap_info);
4508             break;
4509
4510         case C_RNTI:
4511         case SPS_RNTI:
4512             /* Can be UL-SCH or DL-SCH */
4513             dissect_ulsch_or_dlsch(tvb, pinfo, mac_lte_tree, pdu_ti, offset,
4514                                    p_mac_lte_info->direction, p_mac_lte_info, tap_info,
4515                                    retx_ti, context_tree);
4516             break;
4517
4518         case SI_RNTI:
4519             /* BCH over DL-SCH */
4520             dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
4521             break;
4522
4523         case M_RNTI:
4524             /* MCH PDU */
4525             dissect_mch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
4526             break;
4527
4528         case NO_RNTI:
4529             /* Must be BCH over BCH... */
4530             dissect_bch(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info);
4531             break;
4532
4533
4534         default:
4535             break;
4536     }
4537
4538     /* Queue tap info */
4539     tap_queue_packet(mac_lte_tap, pinfo, tap_info);
4540 }
4541
4542
4543
4544
4545 /* Initializes the hash tables each time a new
4546  * file is loaded or re-loaded in wireshark */
4547 static void mac_lte_init_protocol(void)
4548 {
4549     /* Destroy any existing tables. */
4550     if (mac_lte_msg3_hash) {
4551         g_hash_table_destroy(mac_lte_msg3_hash);
4552     }
4553     if (mac_lte_cr_result_hash) {
4554         g_hash_table_destroy(mac_lte_cr_result_hash);
4555     }
4556
4557     if (mac_lte_dl_harq_hash) {
4558         g_hash_table_destroy(mac_lte_dl_harq_hash);
4559     }
4560     if (mac_lte_dl_harq_result_hash) {
4561         g_hash_table_destroy(mac_lte_dl_harq_result_hash);
4562     }
4563     if (mac_lte_ul_harq_hash) {
4564         g_hash_table_destroy(mac_lte_ul_harq_hash);
4565     }
4566     if (mac_lte_ul_harq_result_hash) {
4567         g_hash_table_destroy(mac_lte_ul_harq_result_hash);
4568     }
4569     if (mac_lte_ue_sr_state) {
4570         g_hash_table_destroy(mac_lte_ue_sr_state);
4571     }
4572     if (mac_lte_sr_request_hash) {
4573         g_hash_table_destroy(mac_lte_sr_request_hash);
4574     }
4575     if (mac_lte_tti_info_result_hash) {
4576         g_hash_table_destroy(mac_lte_tti_info_result_hash);
4577     }
4578
4579     /* Reset structs */
4580     memset(&UL_tti_info, 0, sizeof(UL_tti_info));
4581     UL_tti_info.subframe = 0xff;  /* Invalid value */
4582     memset(&DL_tti_info, 0, sizeof(DL_tti_info));
4583     DL_tti_info.subframe = 0xff;  /* Invalid value */
4584
4585     /* Now create them over */
4586     mac_lte_msg3_hash = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
4587     mac_lte_cr_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
4588
4589     mac_lte_dl_harq_hash = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
4590     mac_lte_dl_harq_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
4591
4592     mac_lte_ul_harq_hash = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
4593     mac_lte_ul_harq_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
4594
4595     mac_lte_ue_sr_state = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
4596     mac_lte_sr_request_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
4597
4598     mac_lte_tti_info_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
4599 }
4600
4601
4602 static void* lcid_drb_mapping_copy_cb(void* dest, const void* orig, size_t len _U_)
4603 {
4604     const lcid_drb_mapping_t *o = orig;
4605     lcid_drb_mapping_t       *d = dest;
4606
4607     /* Copy all items over */
4608     d->lcid = o->lcid;
4609     d->drbid = o->drbid;
4610     d->channel_type = o->channel_type;
4611
4612     return d;
4613 }
4614
4615
4616
4617 void proto_register_mac_lte(void)
4618 {
4619     static hf_register_info hf[] =
4620     {
4621         /**********************************/
4622         /* Items for decoding context     */
4623         { &hf_mac_lte_context,
4624             { "Context",
4625               "mac-lte.context", FT_STRING, BASE_NONE, NULL, 0x0,
4626               NULL, HFILL
4627             }
4628         },
4629         { &hf_mac_lte_context_radio_type,
4630             { "Radio Type",
4631               "mac-lte.radio-type", FT_UINT8, BASE_DEC, VALS(radio_type_vals), 0x0,
4632               NULL, HFILL
4633             }
4634         },
4635         { &hf_mac_lte_context_direction,
4636             { "Direction",
4637               "mac-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
4638               "Direction of message", HFILL
4639             }
4640         },
4641         { &hf_mac_lte_context_rnti,
4642             { "RNTI",
4643               "mac-lte.rnti", FT_UINT16, BASE_DEC, 0, 0x0,
4644               "RNTI associated with message", HFILL
4645             }
4646         },
4647         { &hf_mac_lte_context_rnti_type,
4648             { "RNTI Type",
4649               "mac-lte.rnti-type", FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0,
4650               "Type of RNTI associated with message", HFILL
4651             }
4652         },
4653         { &hf_mac_lte_context_ueid,
4654             { "UEId",
4655               "mac-lte.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
4656               "User Equipment Identifier associated with message", HFILL
4657             }
4658         },
4659         { &hf_mac_lte_context_sysframe_number,
4660             { "System Frame Number",
4661               "mac-lte.sfn", FT_UINT16, BASE_DEC, 0, 0x0,
4662               "System Frame Number associated with message", HFILL
4663             }
4664         },
4665         { &hf_mac_lte_context_subframe_number,
4666             { "Subframe",
4667               "mac-lte.subframe", FT_UINT16, BASE_DEC, 0, 0x0,
4668               "Subframe number associated with message", HFILL
4669             }
4670         },
4671         { &hf_mac_lte_context_grant_subframe_number,
4672             { "Grant Subframe",
4673               "mac-lte.grant-subframe", FT_UINT16, BASE_DEC, 0, 0x0,
4674               "Subframe when grant for this PDU was received", HFILL
4675             }
4676         },
4677         { &hf_mac_lte_context_predefined_frame,
4678             { "Predefined frame",
4679               "mac-lte.is-predefined-frame", FT_UINT8, BASE_DEC, VALS(predefined_frame_vals), 0x0,
4680               "Predefined test frame (or real MAC PDU)", HFILL
4681             }
4682         },
4683         { &hf_mac_lte_context_length,
4684             { "Length of frame",
4685               "mac-lte.length", FT_UINT8, BASE_DEC, 0, 0x0,
4686               "Original length of frame (including SDUs and padding)", HFILL
4687             }
4688         },
4689         { &hf_mac_lte_context_ul_grant_size,
4690             { "Uplink grant size",
4691               "mac-lte.ul-grant-size", FT_UINT8, BASE_DEC, 0, 0x0,
4692               "Uplink grant size (in bytes)", HFILL
4693             }
4694         },
4695         { &hf_mac_lte_context_bch_transport_channel,
4696             { "Transport channel",
4697               "mac-lte.bch-transport-channel", FT_UINT8, BASE_DEC, VALS(bch_transport_channel_vals), 0x0,
4698               "Transport channel BCH data was carried on", HFILL
4699             }
4700         },
4701         { &hf_mac_lte_context_retx_count,
4702             { "ReTX count",
4703               "mac-lte.retx-count", FT_UINT8, BASE_DEC, 0, 0x0,
4704               "Number of times this PDU has been retransmitted", HFILL
4705             }
4706         },
4707         { &hf_mac_lte_context_retx_reason,
4708             { "ReTX reason",
4709               "mac-lte.retx-reason", FT_UINT8, BASE_DEC, VALS(ul_retx_grant_vals), 0x0,
4710               "Type of UL ReTx grant", HFILL
4711             }
4712         },
4713         { &hf_mac_lte_context_crc_status,
4714             { "CRC Status",
4715               "mac-lte.crc-status", FT_UINT8, BASE_DEC, VALS(crc_status_vals), 0x0,
4716               "CRC Status as reported by PHY", HFILL
4717             }
4718         },
4719         { &hf_mac_lte_context_rapid,
4720             { "RAPID",
4721               "mac-lte.preamble-sent.rapid", FT_UINT8, BASE_DEC, 0, 0x0,
4722               "RAPID sent in RACH preamble", HFILL
4723             }
4724         },
4725         { &hf_mac_lte_context_rach_attempt_number,
4726             { "RACH Attempt Number",
4727               "mac-lte.preamble-sent.attempt", FT_UINT8, BASE_DEC, 0, 0x0,
4728               NULL, HFILL
4729             }
4730         },
4731
4732         { &hf_mac_lte_ues_ul_per_tti,
4733             { "UL UE in TTI",
4734               "mac-lte.ul-tti-count", FT_UINT8, BASE_DEC, 0, 0x0,
4735               "In this TTI, this is the nth UL grant", HFILL
4736             }
4737         },
4738         { &hf_mac_lte_ues_dl_per_tti,
4739             { "DL UE in TTI",
4740               "mac-lte.dl-tti-count", FT_UINT8, BASE_DEC, 0, 0x0,
4741               "In this TTI, this is the nth DL PDU", HFILL
4742             }
4743         },
4744
4745
4746         /* Extra PHY context */
4747         { &hf_mac_lte_context_phy_ul,
4748             { "UL PHY attributes",
4749               "mac-lte.ul-phy", FT_STRING, BASE_NONE, 0, 0x0,
4750               NULL, HFILL
4751             }
4752         },
4753         { &hf_mac_lte_context_phy_ul_modulation_type,
4754             { "Modulation type",
4755               "mac-lte.ul-phy.modulation-type", FT_UINT8, BASE_DEC, VALS(modulation_type_vals), 0x0,
4756               NULL, HFILL
4757             }
4758         },
4759         { &hf_mac_lte_context_phy_ul_tbs_index,
4760             { "TBs Index",
4761               "mac-lte.ul-phy.tbs-index", FT_UINT8, BASE_DEC, 0, 0x0,
4762               NULL, HFILL
4763             }
4764         },
4765         { &hf_mac_lte_context_phy_ul_resource_block_length,
4766             { "Resource Block Length",
4767               "mac-lte.ul-phy.resource-block-length", FT_UINT8, BASE_DEC, 0, 0x0,
4768               NULL, HFILL
4769             }
4770         },
4771         { &hf_mac_lte_context_phy_ul_resource_block_start,
4772             { "Resource Block Start",
4773               "mac-lte.ul-phy.resource-block-start", FT_UINT8, BASE_DEC, 0, 0x0,
4774               NULL, HFILL
4775             }
4776         },
4777         { &hf_mac_lte_context_phy_ul_harq_id,
4778             { "HARQ Id",
4779               "mac-lte.ul-phy.harq-id", FT_UINT8, BASE_DEC, 0, 0x0,
4780               NULL, HFILL
4781             }
4782         },
4783         { &hf_mac_lte_context_phy_ul_ndi,
4784             { "NDI",
4785               "mac-lte.ul-phy.ndi", FT_UINT8, BASE_DEC, 0, 0x0,
4786               "UL New Data Indicator", HFILL
4787             }
4788         },
4789
4790         { &hf_mac_lte_context_phy_dl,
4791             { "DL PHY attributes",
4792               "mac-lte.dl-phy", FT_STRING, BASE_NONE, 0, 0x0,
4793               NULL, HFILL
4794             }
4795         },
4796         { &hf_mac_lte_context_phy_dl_dci_format,
4797             { "DCI format",
4798               "mac-lte.dl-phy.dci-format", FT_UINT8, BASE_DEC, VALS(dci_format_vals), 0x0,
4799               NULL, HFILL
4800             }
4801         },
4802         { &hf_mac_lte_context_phy_dl_resource_allocation_type,
4803             { "Resource Allocation Type",
4804               "mac-lte.dl-phy.resource-allocation-type", FT_UINT8, BASE_DEC, 0, 0x0,
4805               NULL, HFILL
4806             }
4807         },
4808         { &hf_mac_lte_context_phy_dl_aggregation_level,
4809             { "Aggregation Level",
4810               "mac-lte.dl-phy.aggregation-level", FT_UINT8, BASE_DEC, VALS(aggregation_level_vals), 0x0,
4811               NULL, HFILL
4812             }
4813         },
4814         { &hf_mac_lte_context_phy_dl_mcs_index,
4815             { "MCS Index",
4816               "mac-lte.dl-phy.mcs-index", FT_UINT8, BASE_DEC, 0, 0x0,
4817               NULL, HFILL
4818             }
4819         },
4820         { &hf_mac_lte_context_phy_dl_redundancy_version_index,
4821             { "RV Index",
4822               "mac-lte.dl-phy.rv-index", FT_UINT8, BASE_DEC, 0, 0x0,
4823               NULL, HFILL
4824             }
4825         },
4826         { &hf_mac_lte_context_phy_dl_retx,
4827             { "DL Retx",
4828               "mac-lte.dl-phy.dl-retx", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4829               NULL, HFILL
4830             }
4831         },
4832         { &hf_mac_lte_context_phy_dl_resource_block_length,
4833             { "RB Length",
4834               "mac-lte.dl-phy.rb-length", FT_UINT8, BASE_DEC, 0, 0x0,
4835               NULL, HFILL
4836             }
4837         },
4838         { &hf_mac_lte_context_phy_dl_crc_status,
4839             { "CRC Status",
4840               "mac-lte.dl-phy.crc-status", FT_UINT8, BASE_DEC, VALS(crc_status_vals), 0x0,
4841               NULL, HFILL
4842             }
4843         },
4844         { &hf_mac_lte_context_phy_dl_harq_id,
4845             { "HARQ Id",
4846               "mac-lte.dl-phy.harq-id", FT_UINT8, BASE_DEC, 0, 0x0,
4847               NULL, HFILL
4848             }
4849         },
4850         { &hf_mac_lte_context_phy_dl_ndi,
4851             { "NDI",
4852               "mac-lte.dl-phy.ndi", FT_UINT8, BASE_DEC, 0, 0x0,
4853               "New Data Indicator", HFILL
4854             }
4855         },
4856         { &hf_mac_lte_context_phy_dl_tb,
4857             { "TB",
4858               "mac-lte.dl-phy.tb", FT_UINT8, BASE_DEC, 0, 0x0,
4859               "Transport Block (antenna #)", HFILL
4860             }
4861         },
4862
4863         /* Out-of-band events */
4864         { &hf_mac_lte_oob_send_preamble,
4865             { "PRACH",
4866               "mac-lte.preamble-sent", FT_STRING, BASE_NONE, NULL, 0x0,
4867               NULL, HFILL
4868             }
4869         },
4870         { &hf_mac_lte_oob_send_sr,
4871             { "Scheduling Request sent",
4872               "mac-lte.sr-req", FT_NONE, BASE_NONE, NULL, 0x0,
4873               NULL, HFILL
4874             }
4875         },
4876         { &hf_mac_lte_number_of_srs,
4877             { "Number of SRs",
4878               "mac-lte.sr-req.count", FT_UINT32, BASE_DEC, 0, 0x0,
4879               "Number of UEs doing SR in this frame", HFILL
4880             }
4881         },
4882         { &hf_mac_lte_oob_sr_failure,
4883             { "Scheduling Request failure",
4884               "mac-lte.sr-failure", FT_NONE, BASE_NONE, NULL, 0x0,
4885               NULL, HFILL
4886             }
4887         },
4888
4889         /*******************************************/
4890         /* MAC shared channel header fields        */
4891         { &hf_mac_lte_ulsch,
4892             { "UL-SCH",
4893               "mac-lte.ulsch", FT_STRING, BASE_NONE, NULL, 0x0,
4894               NULL, HFILL
4895             }
4896         },
4897         { &hf_mac_lte_ulsch_header,
4898             { "UL-SCH Header",
4899               "mac-lte.ulsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
4900               NULL, HFILL
4901             }
4902         },
4903         { &hf_mac_lte_dlsch_header,
4904             { "DL-SCH Header",
4905               "mac-lte.dlsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
4906               NULL, HFILL
4907             }
4908         },
4909         { &hf_mac_lte_dlsch,
4910             { "DL-SCH",
4911               "mac-lte.dlsch", FT_STRING, BASE_NONE, NULL, 0x0,
4912               NULL, HFILL
4913             }
4914         },
4915         { &hf_mac_lte_sch_subheader,
4916             { "SCH sub-header",
4917               "mac-lte.sch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
4918               NULL, HFILL
4919             }
4920         },
4921         { &hf_mac_lte_mch,
4922             { "MCH",
4923               "mac-lte.mch", FT_STRING, BASE_NONE, NULL, 0x0,
4924               NULL, HFILL
4925             }
4926         },
4927         { &hf_mac_lte_mch_header,
4928             { "MCH Header",
4929               "mac-lte.mch.header", FT_STRING, BASE_NONE, NULL, 0x0,
4930               NULL, HFILL
4931             }
4932         },
4933         { &hf_mac_lte_mch_subheader,
4934             { "MCH sub-header",
4935               "mac-lte.mch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
4936               NULL, HFILL
4937             }
4938         },
4939         { &hf_mac_lte_sch_reserved,
4940             { "SCH reserved bits",
4941               "mac-lte.sch.reserved", FT_UINT8, BASE_HEX, NULL, 0xc0,
4942               NULL, HFILL
4943             }
4944         },
4945         { &hf_mac_lte_sch_extended,
4946             { "Extension",
4947               "mac-lte.sch.extended", FT_UINT8, BASE_HEX, 0, 0x20,
4948               "Extension - i.e. further headers after this one", HFILL
4949             }
4950         },
4951         { &hf_mac_lte_dlsch_lcid,
4952             { "LCID",
4953               "mac-lte.dlsch.lcid", FT_UINT8, BASE_HEX, VALS(dlsch_lcid_vals), 0x1f,
4954               "DL-SCH Logical Channel Identifier", HFILL
4955             }
4956         },
4957         { &hf_mac_lte_ulsch_lcid,
4958             { "LCID",
4959               "mac-lte.ulsch.lcid", FT_UINT8, BASE_HEX, VALS(ulsch_lcid_vals), 0x1f,
4960               "UL-SCH Logical Channel Identifier", HFILL
4961             }
4962         },
4963         { &hf_mac_lte_sch_format,
4964             { "Format",
4965               "mac-lte.sch.format", FT_UINT8, BASE_HEX, VALS(format_vals), 0x80,
4966               NULL, HFILL
4967             }
4968         },
4969         { &hf_mac_lte_sch_length,
4970             { "Length",
4971               "mac-lte.sch.length", FT_UINT16, BASE_DEC, 0, 0x0,
4972               "Length of MAC SDU or MAC control element", HFILL
4973             }
4974         },
4975         { &hf_mac_lte_mch_reserved,
4976             { "MCH reserved bits",
4977               "mac-lte.mch.reserved", FT_UINT8, BASE_HEX, NULL, 0xc0,
4978               NULL, HFILL
4979             }
4980         },
4981         { &hf_mac_lte_mch_extended,
4982             { "Extension",
4983               "mac-lte.mch.extended", FT_UINT8, BASE_HEX, 0, 0x20,
4984               "Extension - i.e. further headers after this one", HFILL
4985             }
4986         },
4987         { &hf_mac_lte_mch_lcid,
4988             { "LCID",
4989               "mac-lte.mch.lcid", FT_UINT8, BASE_HEX, VALS(mch_lcid_vals), 0x1f,
4990               "MCH Logical Channel Identifier", HFILL
4991             }
4992         },
4993         { &hf_mac_lte_mch_format,
4994             { "Format",
4995               "mac-lte.mch.format", FT_UINT8, BASE_HEX, VALS(format_vals), 0x80,
4996               NULL, HFILL
4997             }
4998         },
4999         { &hf_mac_lte_mch_length,
5000             { "Length",
5001               "mac-lte.mch.length", FT_UINT16, BASE_DEC, 0, 0x0,
5002               "Length of MAC SDU or MAC control element", HFILL
5003             }
5004         },
5005         { &hf_mac_lte_sch_header_only,
5006             { "MAC PDU Header only",
5007               "mac-lte.sch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
5008               NULL, HFILL
5009             }
5010         },
5011         { &hf_mac_lte_mch_header_only,
5012             { "MAC PDU Header only",
5013               "mac-lte.mch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
5014               NULL, HFILL
5015             }
5016         },
5017
5018         /********************************/
5019         /* Data                         */
5020         { &hf_mac_lte_sch_sdu,
5021             { "SDU",
5022               "mac-lte.sch.sdu", FT_BYTES, BASE_NONE, 0, 0x0,
5023               "Shared channel SDU", HFILL
5024             }
5025         },
5026         { &hf_mac_lte_mch_sdu,
5027             { "SDU",
5028               "mac-lte.mch.sdu", FT_BYTES, BASE_NONE, 0, 0x0,
5029               "Multicast channel SDU", HFILL
5030             }
5031         },
5032         { &hf_mac_lte_bch_pdu,
5033             { "BCH PDU",
5034               "mac-lte.bch.pdu", FT_BYTES, BASE_NONE, 0, 0x0,
5035               NULL, HFILL
5036             }
5037         },
5038         { &hf_mac_lte_pch_pdu,
5039             { "PCH PDU",
5040               "mac-lte.pch.pdu", FT_BYTES, BASE_NONE, 0, 0x0,
5041               NULL, HFILL
5042             }
5043         },
5044         { &hf_mac_lte_predefined_pdu,
5045             { "Predefined data",
5046               "mac-lte.predefined-data", FT_BYTES, BASE_NONE, 0, 0x0,
5047               "Predefined test data", HFILL
5048             }
5049         },
5050         { &hf_mac_lte_raw_pdu,
5051             { "Raw data",
5052               "mac-lte.raw-data", FT_BYTES, BASE_NONE, 0, 0x0,
5053               "Raw bytes of PDU (e.g. if CRC error)", HFILL
5054             }
5055         },
5056         { &hf_mac_lte_padding_data,
5057             { "Padding data",
5058               "mac-lte.padding-data", FT_BYTES, BASE_NONE, 0, 0x0,
5059               NULL, HFILL
5060             }
5061         },
5062         { &hf_mac_lte_padding_length,
5063             { "Padding length",
5064               "mac-lte.padding-length", FT_INT32, BASE_DEC, 0, 0x0,
5065               "Length of padding data not included at end of frame", HFILL
5066             }
5067         },
5068
5069
5070
5071         /*********************************/
5072         /* RAR fields                    */
5073         { &hf_mac_lte_rar,
5074             { "RAR",
5075               "mac-lte.rar", FT_NONE, BASE_NONE, NULL, 0x0,
5076               NULL, HFILL
5077             }
5078         },
5079         { &hf_mac_lte_rar_headers,
5080             { "RAR Headers",
5081               "mac-lte.rar.headers", FT_STRING, BASE_NONE, NULL, 0x0,
5082               NULL, HFILL
5083             }
5084         },
5085         { &hf_mac_lte_rar_header,
5086             { "RAR Header",
5087               "mac-lte.rar.header", FT_STRING, BASE_NONE, NULL, 0x0,
5088               NULL, HFILL
5089             }
5090         },
5091         { &hf_mac_lte_rar_extension,
5092             { "Extension",
5093               "mac-lte.rar.e", FT_UINT8, BASE_HEX, 0, 0x80,
5094               "Extension - i.e. further RAR headers after this one", HFILL
5095             }
5096         },
5097         { &hf_mac_lte_rar_t,
5098             { "Type",
5099               "mac-lte.rar.t", FT_UINT8, BASE_HEX, VALS(rar_type_vals), 0x40,
5100               "Type field indicating whether the payload is RAPID or BI", HFILL
5101             }
5102         },
5103         { &hf_mac_lte_rar_bi,
5104             { "BI",
5105               "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_vals), 0x0f,
5106               "Backoff Indicator (ms)", HFILL
5107             }
5108         },
5109         { &hf_mac_lte_rar_rapid,
5110             { "RAPID",
5111               "mac-lte.rar.rapid", FT_UINT8, BASE_HEX_DEC, 0, 0x3f,
5112               "Random Access Preamble IDentifier", HFILL
5113             }
5114         },
5115         { &hf_mac_lte_rar_reserved,
5116             { "Reserved",
5117               "mac-lte.rar.reserved", FT_UINT8, BASE_HEX, 0, 0x30,
5118               "Reserved bits in RAR header - should be 0", HFILL
5119             }
5120         },
5121
5122         { &hf_mac_lte_rar_body,
5123             { "RAR Body",
5124               "mac-lte.rar.body", FT_STRING, BASE_NONE, NULL, 0x0,
5125               NULL, HFILL
5126             }
5127         },
5128         { &hf_mac_lte_rar_reserved2,
5129             { "Reserved",
5130               "mac-lte.rar.reserved2", FT_UINT8, BASE_HEX, 0, 0x80,
5131               "Reserved bit in RAR body - should be 0", HFILL
5132             }
5133         },
5134         { &hf_mac_lte_rar_ta,
5135             { "Timing Advance",
5136               "mac-lte.rar.ta", FT_UINT16, BASE_DEC, 0, 0x7ff0,
5137               "Required adjustment to uplink transmission timing", HFILL
5138             }
5139         },
5140         { &hf_mac_lte_rar_ul_grant,
5141             { "UL Grant",
5142               "mac-lte.rar.ul-grant", FT_UINT24, BASE_DEC, 0, 0x0fffff,
5143               "Size of UL Grant", HFILL
5144             }
5145         },
5146         { &hf_mac_lte_rar_ul_grant_hopping,
5147             { "Hopping Flag",
5148               "mac-lte.rar.ul-grant.hopping", FT_UINT8, BASE_DEC, 0, 0x08,
5149               NULL, HFILL
5150             }
5151         },
5152         { &hf_mac_lte_rar_ul_grant_fsrba,
5153             { "Fixed sized resource block assignment",
5154               "mac-lte.rar.ul-grant.fsrba", FT_UINT16, BASE_DEC, 0, 0x07fe,
5155               NULL, HFILL
5156             }
5157         },
5158         { &hf_mac_lte_rar_ul_grant_tmcs,
5159             { "Truncated Modulation and coding scheme",
5160               "mac-lte.rar.ul-grant.tmcs", FT_UINT16, BASE_DEC, 0, 0x01e0,
5161               NULL, HFILL
5162             }
5163         },
5164         { &hf_mac_lte_rar_ul_grant_tcsp,
5165             { "TPC command for scheduled PUSCH",
5166               "mac-lte.rar.ul-grant.tcsp", FT_UINT8, BASE_DEC, 0, 0x01c,
5167               NULL, HFILL
5168             }
5169         },
5170         { &hf_mac_lte_rar_ul_grant_ul_delay,
5171             { "UL Delay",
5172               "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, 0, 0x02,
5173               NULL, HFILL
5174             }
5175         },
5176         { &hf_mac_lte_rar_ul_grant_cqi_request,
5177             { "CQI Request",
5178               "mac-lte.rar.ul-grant.cqi-request", FT_UINT8, BASE_DEC, 0, 0x01,
5179               NULL, HFILL
5180             }
5181         },
5182         { &hf_mac_lte_rar_temporary_crnti,
5183             { "Temporary C-RNTI",
5184               "mac-lte.rar.temporary-crnti", FT_UINT16, BASE_DEC, 0, 0x0,
5185               NULL, HFILL
5186             }
5187         },
5188
5189         /**********************/
5190         /* Control PDU fields */
5191         { &hf_mac_lte_control_bsr,
5192             { "BSR",
5193               "mac-lte.control.bsr", FT_STRING, BASE_NONE, 0, 0x0,
5194               "Buffer Status Report", HFILL
5195             }
5196         },
5197         { &hf_mac_lte_control_bsr_lcg_id,
5198             { "Logical Channel Group ID",
5199               "mac-lte.control.bsr.lcg-id", FT_UINT8, BASE_DEC, 0, 0xc0,
5200               NULL, HFILL
5201             }
5202         },
5203         { &hf_mac_lte_control_short_bsr_buffer_size,
5204             { "Buffer Size",
5205               "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
5206               "Buffer Size available in all channels in group", HFILL
5207             }
5208         },
5209         { &hf_mac_lte_control_long_bsr_buffer_size_0,
5210             { "Buffer Size 0",
5211               "mac-lte.control.bsr.buffer-size-0", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0xfc,
5212               "Buffer Size available in logical channel group 0", HFILL
5213             }
5214         },
5215         { &hf_mac_lte_control_long_bsr_buffer_size_1,
5216             { "Buffer Size 1",
5217               "mac-lte.control.bsr.buffer-size-1", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x03f0,
5218               "Buffer Size available in logical channel group 1", HFILL
5219             }
5220         },
5221         { &hf_mac_lte_control_long_bsr_buffer_size_2,
5222             { "Buffer Size 2",
5223               "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x0fc0,
5224               "Buffer Size available in logical channel group 2", HFILL
5225             }
5226         },
5227         { &hf_mac_lte_control_long_bsr_buffer_size_3,
5228             { "Buffer Size 3",
5229               "mac-lte.control.bsr.buffer-size-3", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &buffer_size_vals_ext, 0x3f,
5230               "Buffer Size available in logical channel group 3", HFILL
5231             }
5232         },
5233         { &hf_mac_lte_control_short_ext_bsr_buffer_size,
5234             { "Buffer Size",
5235               "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x3f,
5236               "Buffer Size available in all channels in group", HFILL
5237             }
5238         },
5239         { &hf_mac_lte_control_long_ext_bsr_buffer_size_0,
5240             { "Buffer Size 0",
5241               "mac-lte.control.bsr.buffer-size-0", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0xfc,
5242               "Buffer Size available in logical channel group 0", HFILL
5243             }
5244         },
5245         { &hf_mac_lte_control_long_ext_bsr_buffer_size_1,
5246             { "Buffer Size 1",
5247               "mac-lte.control.bsr.buffer-size-1", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x03f0,
5248               "Buffer Size available in logical channel group 1", HFILL
5249             }
5250         },
5251         { &hf_mac_lte_control_long_ext_bsr_buffer_size_2,
5252             { "Buffer Size 2",
5253               "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x0fc0,
5254               "Buffer Size available in logical channel group 2", HFILL
5255             }
5256         },
5257         { &hf_mac_lte_control_long_ext_bsr_buffer_size_3,
5258             { "Buffer Size 3",
5259               "mac-lte.control.bsr.buffer-size-3", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ext_buffer_size_vals_ext, 0x3f,
5260               "Buffer Size available in logical channel group 3", HFILL
5261             }
5262         },
5263         { &hf_mac_lte_control_crnti,
5264             { "C-RNTI",
5265               "mac-lte.control.crnti", FT_UINT16, BASE_DEC, 0, 0x0,
5266               "C-RNTI for the UE", HFILL
5267             }
5268         },
5269         { &hf_mac_lte_control_timing_advance,
5270             { "Timing Advance",
5271               "mac-lte.control.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
5272               "Timing Advance (0-1282 - see 36.213, 4.2.3)", HFILL
5273             }
5274         },
5275         { &hf_mac_lte_control_timing_advance_reserved,
5276             { "Reserved",
5277               "mac-lte.control.timing-advance.reserved", FT_UINT8, BASE_HEX, 0, 0xc0,
5278               "Reserved bits", HFILL
5279             }
5280         },
5281         { &hf_mac_lte_control_ue_contention_resolution,
5282             { "UE Contention Resolution",
5283               "mac-lte.control.ue-contention-resolution", FT_STRING, BASE_NONE, 0, 0x0,
5284               NULL, HFILL
5285             }
5286         },
5287         { &hf_mac_lte_control_ue_contention_resolution_identity,
5288             { "UE Contention Resolution Identity",
5289               "mac-lte.control.ue-contention-resolution.identity", FT_BYTES, BASE_NONE, 0, 0x0,
5290               NULL, HFILL
5291             }
5292         },
5293         { &hf_mac_lte_control_ue_contention_resolution_msg3,
5294             { "Msg3",
5295               "mac-lte.control.ue-contention-resolution.msg3", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5296               NULL, HFILL
5297             }
5298         },
5299         { &hf_mac_lte_control_ue_contention_resolution_msg3_matched,
5300             { "UE Contention Resolution Matches Msg3",
5301               "mac-lte.control.ue-contention-resolution.matches-msg3", FT_BOOLEAN, BASE_NONE, 0, 0x0,
5302               NULL, HFILL
5303             }
5304         },
5305         { &hf_mac_lte_control_ue_contention_resolution_time_since_msg3,
5306             { "Time since Msg3",
5307               "mac-lte.control.ue-contention-resolution.time-since-msg3", FT_UINT32, BASE_DEC, 0, 0x0,
5308               "Time in ms since corresponding Msg3", HFILL
5309             }
5310         },
5311
5312         { &hf_mac_lte_control_power_headroom,
5313             { "Power Headroom",
5314               "mac-lte.control.power-headroom", FT_STRING, BASE_NONE, 0, 0x0,
5315               NULL, HFILL
5316             }
5317         },
5318         { &hf_mac_lte_control_power_headroom_reserved,
5319             { "Reserved",
5320               "mac-lte.control.power-headroom.reserved", FT_UINT8, BASE_DEC, 0, 0xc0,
5321               "Reserved bits, should be 0", HFILL
5322             }
5323         },
5324         { &hf_mac_lte_control_power_headroom_level,
5325             { "Power Headroom Level",
5326               "mac-lte.control.power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
5327                &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
5328             }
5329         },
5330
5331         { &hf_mac_lte_control_ext_power_headroom,
5332             { "Extended Power Headroom",
5333               "mac-lte.control.ext-power-headroom", FT_STRING, BASE_NONE,
5334               0, 0x0, NULL, HFILL
5335             }
5336         },
5337         { &hf_mac_lte_control_ext_power_headroom_c7,
5338             { "SCell Index 7 Power Headroom",
5339               "mac-lte.control.ext-power-headroom.c7", FT_BOOLEAN, 8,
5340               TFS(&mac_lte_scell_ph_vals), 0x80, NULL, HFILL
5341             }
5342         },
5343         { &hf_mac_lte_control_ext_power_headroom_c6,
5344             { "SCell Index 6 Power Headroom",
5345               "mac-lte.control.ext-power-headroom.c6", FT_BOOLEAN, 8,
5346               TFS(&mac_lte_scell_ph_vals), 0x40, NULL, HFILL
5347             }
5348         },
5349         { &hf_mac_lte_control_ext_power_headroom_c5,
5350             { "SCell Index 5 Power Headroom",
5351               "mac-lte.control.ext-power-headroom.c5", FT_BOOLEAN, 8,
5352               TFS(&mac_lte_scell_ph_vals), 0x20, NULL, HFILL
5353             }
5354         },
5355         { &hf_mac_lte_control_ext_power_headroom_c4,
5356             { "SCell Index 4 Power Headroom",
5357               "mac-lte.control.ext-power-headroom.c4", FT_BOOLEAN, 8,
5358               TFS(&mac_lte_scell_ph_vals), 0x10, NULL, HFILL
5359             }
5360         },
5361         { &hf_mac_lte_control_ext_power_headroom_c3,
5362             { "SCell Index 3 Power Headroom",
5363               "mac-lte.control.ext-power-headroom.c3", FT_BOOLEAN, 8,
5364               TFS(&mac_lte_scell_ph_vals), 0x08, NULL, HFILL
5365             }
5366         },
5367         { &hf_mac_lte_control_ext_power_headroom_c2,
5368             { "SCell Index 2 Power Headroom",
5369               "mac-lte.control.ext-power-headroom.c2", FT_BOOLEAN, 8,
5370               TFS(&mac_lte_scell_ph_vals), 0x04, NULL, HFILL
5371             }
5372         },
5373         { &hf_mac_lte_control_ext_power_headroom_c1,
5374             { "SCell Index 1 Power Headroom",
5375               "mac-lte.control.ext-power-headroom.c1", FT_BOOLEAN, 8,
5376               TFS(&mac_lte_scell_ph_vals), 0x02, NULL, HFILL
5377             }
5378         },
5379         { &hf_mac_lte_control_ext_power_headroom_reserved,
5380             { "Reserved",
5381               "mac-lte.control.ext-power-headroom.reserved", FT_UINT8, BASE_DEC,
5382               0, 0x01, "Reserved bit, should be 0", HFILL
5383             }
5384         },
5385         { &hf_mac_lte_control_ext_power_headroom_power_backoff,
5386             { "Power Backoff",
5387               "mac-lte.control.ext-power-headroom.power-backoff", FT_BOOLEAN, 8,
5388                TFS(&mac_lte_power_backoff_vals), 0x80, NULL, HFILL
5389             }
5390         },
5391         { &hf_mac_lte_control_ext_power_headroom_value,
5392             { "Power Headroom Value",
5393               "mac-lte.control.ext-power-headroom.power-headroom-value", FT_BOOLEAN, 8,
5394                TFS(&mac_lte_ph_value_vals), 0x40, NULL, HFILL
5395             }
5396         },
5397         { &hf_mac_lte_control_ext_power_headroom_level,
5398             { "Power Headroom Level",
5399               "mac-lte.control.ext-power-headroom.level", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
5400                &power_headroom_vals_ext, 0x3f, "Power Headroom Level in dB", HFILL
5401             }
5402         },
5403         { &hf_mac_lte_control_ext_power_headroom_reserved2,
5404             { "Reserved",
5405               "mac-lte.control.ext-power-headroom.reserved2", FT_UINT8, BASE_DEC,
5406               0, 0xc0, "Reserved bits, should be 0", HFILL
5407             }
5408         },
5409         { &hf_mac_lte_control_ext_power_headroom_pcmaxc,
5410             { "Configured UE Transmit Power",
5411               "mac-lte.control.ext-power-headroom.pcmaxc", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
5412                &pcmaxc_vals_ext, 0x3f, "Pcmax,c in dBm", HFILL
5413             }
5414         },
5415
5416         { &hf_mac_lte_control_activation_deactivation,
5417             { "Activation/Deactivation",
5418               "mac-lte.control.activation-deactivation", FT_STRING, BASE_NONE,
5419               0, 0x0, NULL, HFILL
5420             }
5421         },
5422         { &hf_mac_lte_control_activation_deactivation_c7,
5423             { "SCell Index 7 Status",
5424               "mac-lte.control.activation-deactivation.c7", FT_BOOLEAN, 8,
5425               TFS(&mac_lte_scell_status_vals), 0x80, NULL, HFILL
5426             }
5427         },
5428         { &hf_mac_lte_control_activation_deactivation_c6,
5429             { "SCell Index 6 Status",
5430               "mac-lte.control.activation-deactivation.c6", FT_BOOLEAN, 8,
5431               TFS(&mac_lte_scell_status_vals), 0x40, NULL, HFILL
5432             }
5433         },
5434         { &hf_mac_lte_control_activation_deactivation_c5,
5435             { "SCell Index 5 Status",
5436               "mac-lte.control.activation-deactivation.c5", FT_BOOLEAN, 8,
5437               TFS(&mac_lte_scell_status_vals), 0x20, NULL, HFILL
5438             }
5439         },
5440         { &hf_mac_lte_control_activation_deactivation_c4,
5441             { "SCell Index 4 Status",
5442               "mac-lte.control.activation-deactivation.c4", FT_BOOLEAN, 8,
5443               TFS(&mac_lte_scell_status_vals), 0x10, NULL, HFILL
5444             }
5445         },
5446         { &hf_mac_lte_control_activation_deactivation_c3,
5447             { "SCell Index 3 Status",
5448               "mac-lte.control.activation-deactivation.c3", FT_BOOLEAN, 8,
5449               TFS(&mac_lte_scell_status_vals), 0x08, NULL, HFILL
5450             }
5451         },
5452         { &hf_mac_lte_control_activation_deactivation_c2,
5453             { "SCell Index 2 Status",
5454               "mac-lte.control.activation-deactivation.c2", FT_BOOLEAN, 8,
5455               TFS(&mac_lte_scell_status_vals), 0x04, NULL, HFILL
5456             }
5457         },
5458         { &hf_mac_lte_control_activation_deactivation_c1,
5459             { "SCell Index 1 Status",
5460               "mac-lte.control.activation-deactivation.c1", FT_BOOLEAN, 8,
5461               TFS(&mac_lte_scell_status_vals), 0x02, NULL, HFILL
5462             }
5463         },
5464         { &hf_mac_lte_control_activation_deactivation_reserved,
5465             { "Reserved",
5466               "mac-lte.control.activation-deactivation.reserved", FT_UINT8, BASE_DEC,
5467               0, 0x01, "Reserved bit, should be 0", HFILL
5468             }
5469         },
5470
5471         { &hf_mac_lte_control_mch_scheduling_info,
5472             { "MCH Scheduling Information",
5473               "mac-lte.control.mch_scheduling_info", FT_STRING, BASE_NONE, 0, 0x0,
5474               NULL, HFILL
5475             }
5476         },
5477         { &hf_mac_lte_control_mch_scheduling_info_lcid,
5478             { "LCID",
5479               "mac-lte.control.mch_scheduling_info.lcid", FT_UINT8, BASE_HEX, VALS(mch_lcid_vals), 0xf8,
5480               "Logical Channel ID of the MTCH", HFILL
5481             }
5482         },
5483         { &hf_mac_lte_control_mch_scheduling_info_stop_mtch,
5484             { "Stop MTCH",
5485               "mac-lte.control.mch_scheduling_info.stop_mtch", FT_UINT16, BASE_DEC, 0, 0x07ff,
5486               "Ordinal number of the subframe where the corresponding MTCH stops", HFILL
5487             }
5488         },
5489
5490         /* Generated fields */
5491         { &hf_mac_lte_dl_harq_resend_original_frame,
5492             { "Frame with previous tx",
5493               "mac-lte.dlsch.retx.original-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5494               NULL, HFILL
5495             }
5496         },
5497         { &hf_mac_lte_dl_harq_resend_time_since_previous_frame,
5498             { "Time since previous tx (ms)",
5499               "mac-lte.dlsch.retx.time-since-previous", FT_UINT16, BASE_DEC, 0, 0x0,
5500               NULL, HFILL
5501             }
5502         },
5503         { &hf_mac_lte_dl_harq_resend_next_frame,
5504             { "Frame with next tx",
5505               "mac-lte.dlsch.retx.next-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5506               NULL, HFILL
5507             }
5508         },
5509         { &hf_mac_lte_dl_harq_resend_time_until_next_frame,
5510             { "Time until next tx (ms)",
5511               "mac-lte.dlsch.retx.time-until-next", FT_UINT16, BASE_DEC, 0, 0x0,
5512               NULL, HFILL
5513             }
5514         },
5515
5516         { &hf_mac_lte_ul_harq_resend_original_frame,
5517             { "Frame with previous tx",
5518               "mac-lte.ulsch.retx.original-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5519               NULL, HFILL
5520             }
5521         },
5522         { &hf_mac_lte_ul_harq_resend_time_since_previous_frame,
5523             { "Time since previous tx (ms)",
5524               "mac-lte.ulsch.retx.time-since-previous", FT_UINT16, BASE_DEC, 0, 0x0,
5525               NULL, HFILL
5526             }
5527         },
5528         { &hf_mac_lte_ul_harq_resend_next_frame,
5529             { "Frame with next tx",
5530               "mac-lte.ulsch.retx.next-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5531               NULL, HFILL
5532             }
5533         },
5534         { &hf_mac_lte_ul_harq_resend_time_until_next_frame,
5535             { "Time until next tx (ms)",
5536               "mac-lte.ulsch.retx.time-until-next", FT_UINT16, BASE_DEC, 0, 0x0,
5537               NULL, HFILL
5538             }
5539         },
5540
5541         { &hf_mac_lte_grant_answering_sr,
5542             { "First Grant Following SR from",
5543               "mac-lte.ulsch.grant-answering-sr", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5544               NULL, HFILL
5545             }
5546         },
5547         { &hf_mac_lte_failure_answering_sr,
5548             { "SR which failed",
5549               "mac-lte.ulsch.failure-answering-sr", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5550               NULL, HFILL
5551             }
5552         },
5553         { &hf_mac_lte_sr_leading_to_failure,
5554             { "This SR fails",
5555               "mac-lte.ulsch.failure-answering-sr-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5556               NULL, HFILL
5557             }
5558         },
5559         { &hf_mac_lte_sr_leading_to_grant,
5560             { "This SR results in a grant here",
5561               "mac-lte.ulsch.grant-answering-sr-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
5562               NULL, HFILL
5563             }
5564         },
5565         { &hf_mac_lte_sr_invalid_event,
5566             { "Invalid event",
5567               "mac-lte.ulsch.sr-invalid-event", FT_NONE, BASE_NONE, 0, 0x0,
5568               NULL, HFILL
5569             }
5570         },
5571         { &hf_mac_lte_sr_time_since_request,
5572             { "Time since SR (ms)",
5573               "mac-lte.ulsch.time-since-sr", FT_UINT32, BASE_DEC, 0, 0x0,
5574               NULL, HFILL
5575             }
5576         },
5577         { &hf_mac_lte_sr_time_until_answer,
5578             { "Time until answer (ms)",
5579               "mac-lte.ulsch.time-until-sr-answer", FT_UINT32, BASE_DEC, 0, 0x0,
5580               NULL, HFILL
5581             }
5582         },
5583
5584     };
5585
5586     static gint *ett[] =
5587     {
5588         &ett_mac_lte,
5589         &ett_mac_lte_context,
5590         &ett_mac_lte_phy_context,
5591         &ett_mac_lte_rar_headers,
5592         &ett_mac_lte_rar_header,
5593         &ett_mac_lte_rar_body,
5594         &ett_mac_lte_rar_ul_grant,
5595         &ett_mac_lte_ulsch_header,
5596         &ett_mac_lte_dlsch_header,
5597         &ett_mac_lte_mch_header,
5598         &ett_mac_lte_sch_subheader,
5599         &ett_mac_lte_mch_subheader,
5600         &ett_mac_lte_bch,
5601         &ett_mac_lte_bsr,
5602         &ett_mac_lte_pch,
5603         &ett_mac_lte_activation_deactivation,
5604         &ett_mac_lte_contention_resolution,
5605         &ett_mac_lte_power_headroom,
5606         &ett_mac_lte_extended_power_headroom,
5607         &ett_mac_lte_extended_power_headroom_cell,
5608         &ett_mac_lte_mch_scheduling_info,
5609         &ett_mac_lte_oob
5610     };
5611
5612     static enum_val_t show_info_col_vals[] = {
5613         {"show-phy", "PHY Info", ShowPHYLayer},
5614         {"show-mac", "MAC Info", ShowMACLayer},
5615         {"show-rlc", "RLC Info", ShowRLCLayer},
5616         {NULL, NULL, -1}
5617     };
5618
5619     static enum_val_t lcid_drb_source_vals[] = {
5620         {"from-static-stable",          "From static table",           FromStaticTable},
5621         {"from-configuration-protocol", "From configuration protocol", FromConfigurationProtocol},
5622         {NULL, NULL, -1}
5623     };
5624
5625
5626     module_t *mac_lte_module;
5627
5628     static uat_field_t lcid_drb_mapping_flds[] = {
5629         UAT_FLD_VS(lcid_drb_mappings, lcid, "lcid", drb_lcid_vals, "The MAC LCID"),
5630         UAT_FLD_DEC(lcid_drb_mappings, drbid,"drb id (1-32)", "Identifier of logical data channel"),
5631         UAT_FLD_VS(lcid_drb_mappings, channel_type, "RLC Channel Type", rlc_channel_type_vals, "The MAC LCID"),
5632         UAT_END_FIELDS
5633     };
5634
5635     /* Register protocol. */
5636     proto_mac_lte = proto_register_protocol("MAC-LTE", "MAC-LTE", "mac-lte");
5637     proto_register_field_array(proto_mac_lte, hf, array_length(hf));
5638     proto_register_subtree_array(ett, array_length(ett));
5639
5640     /* Allow other dissectors to find this one by name. */
5641     register_dissector("mac-lte", dissect_mac_lte, proto_mac_lte);
5642
5643     /* Register the tap name */
5644     mac_lte_tap = register_tap("mac-lte");
5645
5646     /* Preferences */
5647     mac_lte_module = prefs_register_protocol(proto_mac_lte, NULL);
5648
5649     /* Obsolete preferences */
5650     prefs_register_obsolete_preference(mac_lte_module, "single_rar");
5651     prefs_register_obsolete_preference(mac_lte_module, "check_reserved_bits");
5652     prefs_register_obsolete_preference(mac_lte_module, "decode_rar_ul_grant");
5653     prefs_register_obsolete_preference(mac_lte_module, "show_rlc_info_column");
5654     prefs_register_obsolete_preference(mac_lte_module, "attempt_to_detect_dl_harq_resend");
5655     prefs_register_obsolete_preference(mac_lte_module, "attempt_to_track_ul_harq_resend");
5656
5657     prefs_register_uint_preference(mac_lte_module, "retx_count_warn",
5658         "Number of Re-Transmits before expert warning triggered",
5659         "Number of Re-Transmits before expert warning triggered",
5660         10, &global_mac_lte_retx_counter_trigger);
5661
5662     prefs_register_bool_preference(mac_lte_module, "attempt_rrc_decode",
5663         "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
5664         "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
5665         &global_mac_lte_attempt_rrc_decode);
5666
5667     prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_crc_failures",
5668         "Dissect frames that have failed CRC check",
5669         "Attempt to dissect frames that have failed CRC check",
5670         &global_mac_lte_dissect_crc_failures);
5671
5672     prefs_register_bool_preference(mac_lte_module, "heuristic_mac_lte_over_udp",
5673         "Try Heuristic LTE-MAC over UDP framing",
5674         "When enabled, use heuristic dissector to find MAC-LTE frames sent with "
5675         "UDP framing",
5676         &global_mac_lte_heur);
5677
5678     prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_srb_sdus",
5679         "Attempt to dissect LCID 1&2 as srb1&2",
5680         "Will call LTE RLC dissector with standard settings as per RRC spec",
5681         &global_mac_lte_attempt_srb_decode);
5682
5683     prefs_register_enum_preference(mac_lte_module, "lcid_to_drb_mapping_source",
5684         "Source of LCID -> drb channel settings",
5685         "Set whether LCID -> drb Table is taken from static table (below) or from "
5686         "info learned from control protocol (e.g. RRC)",
5687         &global_mac_lte_lcid_drb_source, lcid_drb_source_vals, FALSE);
5688
5689     lcid_drb_mappings_uat = uat_new("Static LCID -> drb Table",
5690                                     sizeof(lcid_drb_mapping_t),
5691                                     "drb_logchans",
5692                                     TRUE,
5693                                     (void*) &lcid_drb_mappings,
5694                                     &num_lcid_drb_mappings,
5695                                     UAT_CAT_FFMT,
5696                                     "",  /* TODO: is this ref to help manual? */
5697                                     lcid_drb_mapping_copy_cb,
5698                                     NULL,
5699                                     NULL,
5700                                     NULL,
5701                                     lcid_drb_mapping_flds );
5702
5703     prefs_register_uat_preference(mac_lte_module,
5704                                   "drb_table",
5705                                   "LCID -> DRB Mappings Table",
5706                                   "A table that maps from configurable lcids -> RLC logical channels",
5707                                   lcid_drb_mappings_uat);
5708
5709     prefs_register_uint_preference(mac_lte_module, "bsr_warn_threshold",
5710         "BSR size when warning should be issued (0 - 63)",
5711         "If any BSR report is >= this number, an expert warning will be added",
5712         10, &global_mac_lte_bsr_warn_threshold);
5713
5714     prefs_register_bool_preference(mac_lte_module, "track_sr",
5715         "Track status of SRs within UEs",
5716         "Track status of SRs, providing links between requests, failure indications and grants",
5717         &global_mac_lte_track_sr);
5718
5719     prefs_register_enum_preference(mac_lte_module, "layer_to_show",
5720         "Which layer info to show in Info column",
5721         "Can show PHY, MAC or RLC layer info in Info column",
5722         &global_mac_lte_layer_to_show, show_info_col_vals, FALSE);
5723
5724     register_init_routine(&mac_lte_init_protocol);
5725 }
5726
5727
5728 /* Set LCID -> RLC channel mappings from signalling protocol (i.e. RRC or similar).
5729    TODO: not using UEID yet - assume all UEs configured identically... */
5730 void set_mac_lte_channel_mapping(guint16 ueid _U_, guint8 lcid,
5731                                  guint8  srbid, guint8 drbid,
5732                                  guint8  rlcMode, guint8 um_sn_length,
5733                                  guint8  ul_priority)
5734 {
5735     /* Don't bother setting srb details - we just assume AM */
5736     if (srbid != 0) {
5737         return;
5738     }
5739
5740     /* Ignore if LCID is out of range */
5741     if ((lcid < 3) || (lcid > 10)) {
5742         return;
5743     }
5744
5745     /* Set array entry */
5746     dynamic_lcid_drb_mapping[lcid].valid = TRUE;
5747     dynamic_lcid_drb_mapping[lcid].drbid = drbid;
5748     dynamic_lcid_drb_mapping[lcid].ul_priority = ul_priority;
5749
5750     switch (rlcMode) {
5751         case RLC_AM_MODE:
5752             dynamic_lcid_drb_mapping[lcid].channel_type = rlcAM;
5753             break;
5754         case RLC_UM_MODE:
5755             if (um_sn_length == 5) {
5756                 dynamic_lcid_drb_mapping[lcid].channel_type = rlcUM5;
5757             }
5758             else {
5759                 dynamic_lcid_drb_mapping[lcid].channel_type = rlcUM10;
5760             }
5761             break;
5762
5763         default:
5764             break;
5765     }
5766 }
5767
5768 /* Return the configured UL priority for the channel */
5769 static guint8 get_mac_lte_channel_priority(guint16 ueid _U_, guint8 lcid,
5770                                            guint8 direction)
5771 {
5772     /* Priority only affects UL */
5773     if (direction == DIRECTION_DOWNLINK) {
5774         return 0;
5775     }
5776
5777     /* Won't report value if channel not configured */
5778     if (!dynamic_lcid_drb_mapping[lcid].valid) {
5779         return 0;
5780     }
5781     else {
5782         return dynamic_lcid_drb_mapping[lcid].ul_priority;
5783     }
5784 }
5785
5786 /* Function to be called from outside this module (e.g. in a plugin) to get per-packet data */
5787 mac_lte_info *get_mac_lte_proto_data(packet_info *pinfo)
5788 {
5789     return p_get_proto_data(pinfo->fd, proto_mac_lte);
5790 }
5791
5792 /* Function to be called from outside this module (e.g. in a plugin) to set per-packet data */
5793 void set_mac_lte_proto_data(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
5794 {
5795     p_add_proto_data(pinfo->fd, proto_mac_lte, p_mac_lte_info);
5796 }
5797
5798 void proto_reg_handoff_mac_lte(void)
5799 {
5800     static dissector_handle_t mac_lte_handle;
5801     if (!mac_lte_handle) {
5802         mac_lte_handle = find_dissector("mac-lte");
5803
5804         /* Add as a heuristic UDP dissector */
5805         heur_dissector_add("udp", dissect_mac_lte_heur, proto_mac_lte);
5806     }
5807 }
5808