Obselete a couple of preferences that can always be on.
[obnox/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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 8)
41  */
42
43
44 /* TODO:
45    - TDD mode?
46    - add a preference so that padding can be verified against an expected pattern?
47    - include detected DL retransmits in stats?
48 */
49
50 /* Initialize the protocol and registered fields. */
51 int proto_mac_lte = -1;
52
53 static int mac_lte_tap = -1;
54
55 /* Decoding context */
56 static int hf_mac_lte_context_radio_type = -1;
57 static int hf_mac_lte_context_direction = -1;
58 static int hf_mac_lte_context_rnti = -1;
59 static int hf_mac_lte_context_rnti_type = -1;
60 static int hf_mac_lte_context_ueid = -1;
61 static int hf_mac_lte_context_subframe_number = -1;
62 static int hf_mac_lte_context_predefined_frame = -1;
63 static int hf_mac_lte_context_length = -1;
64 static int hf_mac_lte_context_ul_grant_size = -1;
65 static int hf_mac_lte_context_bch_transport_channel = -1;
66 static int hf_mac_lte_context_retx_count = -1;
67 static int hf_mac_lte_context_crc_status = -1;
68 static int hf_mac_lte_context_rapid = -1;
69 static int hf_mac_lte_context_rach_attempt_number = -1;
70
71 /* Out-of-band events */
72 static int hf_mac_lte_oob_send_preamble = -1;
73 static int hf_mac_lte_oob_send_sr = -1;
74 static int hf_mac_lte_oob_sr_failure = -1;
75
76 /* MAC SCH header fields */
77 static int hf_mac_lte_ulsch_header = -1;
78 static int hf_mac_lte_dlsch_header = -1;
79 static int hf_mac_lte_sch_subheader = -1;
80
81 static int hf_mac_lte_sch_reserved = -1;
82 static int hf_mac_lte_dlsch_lcid = -1;
83 static int hf_mac_lte_ulsch_lcid = -1;
84 static int hf_mac_lte_sch_extended = -1;
85 static int hf_mac_lte_sch_format = -1;
86 static int hf_mac_lte_sch_length = -1;
87
88 static int hf_mac_lte_sch_header_only = -1;
89
90 /* Data */
91 static int hf_mac_lte_sch_sdu = -1;
92 static int hf_mac_lte_bch_pdu = -1;
93 static int hf_mac_lte_pch_pdu = -1;
94 static int hf_mac_lte_predefined_pdu = -1;
95 static int hf_mac_lte_raw_pdu = -1;
96 static int hf_mac_lte_padding_data = -1;
97 static int hf_mac_lte_padding_length = -1;
98
99
100 /* RAR fields */
101 static int hf_mac_lte_rar = -1;
102 static int hf_mac_lte_rar_headers = -1;
103 static int hf_mac_lte_rar_header = -1;
104 static int hf_mac_lte_rar_extension = -1;
105 static int hf_mac_lte_rar_t = -1;
106 static int hf_mac_lte_rar_bi = -1;
107 static int hf_mac_lte_rar_rapid = -1;
108 static int hf_mac_lte_rar_reserved = -1;
109 static int hf_mac_lte_rar_body = -1;
110 static int hf_mac_lte_rar_reserved2 = -1;
111 static int hf_mac_lte_rar_ta = -1;
112 static int hf_mac_lte_rar_ul_grant = -1;
113 static int hf_mac_lte_rar_ul_grant_hopping = -1;
114 static int hf_mac_lte_rar_ul_grant_fsrba = -1;
115 static int hf_mac_lte_rar_ul_grant_tmcs = -1;
116 static int hf_mac_lte_rar_ul_grant_tcsp = -1;
117 static int hf_mac_lte_rar_ul_grant_ul_delay = -1;
118 static int hf_mac_lte_rar_ul_grant_cqi_request = -1;
119 static int hf_mac_lte_rar_temporary_crnti = -1;
120
121 /* Common channel control values */
122 static int hf_mac_lte_control_bsr = -1;
123 static int hf_mac_lte_control_bsr_lcg_id = -1;
124 static int hf_mac_lte_control_short_bsr_buffer_size = -1;
125 static int hf_mac_lte_control_long_bsr_buffer_size_0 = -1;
126 static int hf_mac_lte_control_long_bsr_buffer_size_1 = -1;
127 static int hf_mac_lte_control_long_bsr_buffer_size_2 = -1;
128 static int hf_mac_lte_control_long_bsr_buffer_size_3 = -1;
129 static int hf_mac_lte_control_crnti = -1;
130 static int hf_mac_lte_control_timing_advance = -1;
131 static int hf_mac_lte_control_timing_advance_reserved = -1;
132 static int hf_mac_lte_control_ue_contention_resolution = -1;
133 static int hf_mac_lte_control_ue_contention_resolution_identity = -1;
134 static int hf_mac_lte_control_ue_contention_resolution_msg3 = -1;
135 static int hf_mac_lte_control_ue_contention_resolution_msg3_matched = -1;
136 static int hf_mac_lte_control_power_headroom = -1;
137 static int hf_mac_lte_control_power_headroom_reserved = -1;
138 static int hf_mac_lte_control_power_headroom_level = -1;
139 static int hf_mac_lte_control_padding = -1;
140
141 static int hf_mac_lte_suspected_dl_harq_resend = -1;
142 static int hf_mac_lte_suspected_dl_harq_resend_original_frame = -1;
143
144 static int hf_mac_lte_ul_harq_resend_original_frame = -1;
145
146
147 /* Subtrees. */
148 static int ett_mac_lte = -1;
149 static int ett_mac_lte_context = -1;
150 static int ett_mac_lte_ulsch_header = -1;
151 static int ett_mac_lte_dlsch_header = -1;
152 static int ett_mac_lte_sch_subheader = -1;
153 static int ett_mac_lte_rar_headers = -1;
154 static int ett_mac_lte_rar_header = -1;
155 static int ett_mac_lte_rar_body = -1;
156 static int ett_mac_lte_rar_ul_grant = -1;
157 static int ett_mac_lte_bsr = -1;
158 static int ett_mac_lte_bch = -1;
159 static int ett_mac_lte_pch = -1;
160 static int ett_mac_lte_contention_resolution = -1;
161 static int ett_mac_lte_power_headroom = -1;
162
163
164
165 /* Constants and value strings */
166
167 static const value_string radio_type_vals[] =
168 {
169     { FDD_RADIO,      "FDD"},
170     { TDD_RADIO,      "TDD"},
171     { 0, NULL }
172 };
173
174
175 static const value_string direction_vals[] =
176 {
177     { DIRECTION_UPLINK,      "Uplink"},
178     { DIRECTION_DOWNLINK,    "Downlink"},
179     { 0, NULL }
180 };
181
182
183 static const value_string rnti_type_vals[] =
184 {
185     { NO_RNTI,     "NO-RNTI"},
186     { P_RNTI,      "P-RNTI"},
187     { RA_RNTI,     "RA-RNTI"},
188     { C_RNTI,      "C-RNTI"},
189     { SI_RNTI,     "SI-RNTI"},
190     { SPS_RNTI,    "SPS-RNTI"},
191     { 0, NULL }
192 };
193
194 static const value_string bch_transport_channel_vals[] =
195 {
196     { SI_RNTI,      "DL-SCH"},
197     { NO_RNTI,      "BCH"},
198     { 0, NULL }
199 };
200
201 static const value_string crc_status_vals[] =
202 {
203     { 0,      "CRC Status Failed"},
204     { 1,      "CRC Status OK"},
205     { 0, NULL }
206 };
207
208
209
210 #define UE_CONTENTION_RESOLUTION_IDENTITY_LCID 0x1c
211 #define TIMING_ADVANCE_LCID                    0x1d
212 #define DRX_COMMAND_LCID                       0x1e
213 #define PADDING_LCID                           0x1f
214
215 static const value_string dlsch_lcid_vals[] =
216 {
217     { 0,                                        "CCCH"},
218     { 1,                                        "1"},
219     { 2,                                        "2"},
220     { 3,                                        "3"},
221     { 4,                                        "4"},
222     { 5,                                        "5"},
223     { 6,                                        "6"},
224     { 7,                                        "7"},
225     { 8,                                        "8"},
226     { 9,                                        "9"},
227     { 10,                                       "10"},
228     { UE_CONTENTION_RESOLUTION_IDENTITY_LCID,   "UE Contention Resolution Identity"},
229     { TIMING_ADVANCE_LCID                   ,   "Timing Advance"},
230     { DRX_COMMAND_LCID                      ,   "DRX Command"},
231     { PADDING_LCID                          ,   "Padding" },
232     { 0, NULL }
233 };
234
235 #define POWER_HEADROOM_REPORT_LCID    0x1a
236 #define CRNTI_LCID                    0x1b
237 #define TRUNCATED_BSR_LCID            0x1c
238 #define SHORT_BSR_LCID                0x1d
239 #define LONG_BSR_LCID                 0x1e
240
241 static const value_string ulsch_lcid_vals[] =
242 {
243     { 0,                            "CCCH"},
244     { 1,                            "1"},
245     { 2,                            "2"},
246     { 3,                            "3"},
247     { 4,                            "4"},
248     { 5,                            "5"},
249     { 6,                            "6"},
250     { 7,                            "7"},
251     { 8,                            "8"},
252     { 9,                            "9"},
253     { 10,                           "10"},
254     { POWER_HEADROOM_REPORT_LCID,   "Power Headroom Report"},
255     { CRNTI_LCID,                   "C-RNTI"},
256     { TRUNCATED_BSR_LCID,           "Truncated BSR"},
257     { SHORT_BSR_LCID,               "Short BSR"},
258     { LONG_BSR_LCID,                "Long BSR"},
259     { PADDING_LCID,                 "Padding" },
260     { 0, NULL }
261 };
262
263
264 static const value_string format_vals[] =
265 {
266     { 0,      "Data length is < 128 bytes"},
267     { 1,      "Data length is >= 128 bytes"},
268     { 0, NULL }
269 };
270
271
272 static const value_string rar_type_vals[] =
273 {
274     { 0,      "Backoff Indicator present"},
275     { 1,      "RAPID present"},
276     { 0, NULL }
277 };
278
279
280 static const value_string rar_bi_vals[] =
281 {
282     { 0,      "0"},
283     { 1,      "10"},
284     { 2,      "20"},
285     { 3,      "30"},
286     { 4,      "40"},
287     { 5,      "60"},
288     { 6,      "80"},
289     { 7,      "120"},
290     { 8,      "160"},
291     { 9,      "240"},
292     { 10,     "320"},
293     { 11,     "480"},
294     { 12,     "960"},
295     { 0, NULL }
296 };
297
298
299 static const value_string buffer_size_vals[] =
300 {
301     { 0,      "BS = 0"},
302     { 1,      "0   < BS <= 10"},
303     { 2,      "10  < BS <= 12"},
304     { 3,      "12  < BS <= 14"},
305     { 4,      "14  < BS <= 17"},
306     { 5,      "17  < BS <= 19"},
307     { 6,      "19  < BS <= 22"},
308     { 7,      "22  < BS <= 26"},
309     { 8,      "26  < BS <= 31"},
310     { 9,      "31  < BS <= 36"},
311     { 10,     "36  < BS <= 42"},
312     { 11,     "42  < BS <= 49"},
313     { 12,     "49  < BS <= 57"},
314     { 13,     "47  < BS <= 67"},
315     { 14,     "67  < BS <= 78"},
316     { 15,     "78  < BS <= 91"},
317     { 16,     "91  < BS <= 107"},
318     { 17,     "107 < BS <= 125"},
319     { 18,     "125 < BS <= 146"},
320     { 19,     "146 < BS <= 171"},
321     { 20,     "171 < BS <= 200"},
322     { 21,     "200 < BS <= 234"},
323     { 22,     "234 < BS <= 274"},
324     { 23,     "274 < BS <= 321"},
325     { 24,     "321 < BS <= 376"},
326     { 25,     "376 < BS <= 440"},
327     { 26,     "440 < BS <= 515"},
328     { 27,     "515 < BS <= 603"},
329     { 28,     "603 < BS <= 706"},
330     { 29,     "706 < BS <= 826"},
331     { 30,     "826 < BS <= 967"},
332     { 31,     "967  < BS <= 1132"},
333     { 32,     "1132 < BS <= 1326"},
334     { 33,     "1326 < BS <= 1552"},
335     { 34,     "1552 < BS <= 1817"},
336     { 35,     "1817 < BS <= 2127"},
337     { 36,     "2127 < BS <= 2490"},
338     { 37,     "2490 < BS <= 2915"},
339     { 38,     "2915 < BS <= 3413"},
340     { 39,     "3413 < BS <= 3995"},
341     { 40,     "3995 < BS <= 4677"},
342     { 41,     "4677 < BS <= 5476"},
343     { 42,     "5476 < BS <= 6411"},
344     { 43,     "6411 < BS <= 7505"},
345     { 44,     "7505 < BS <= 8787"},
346     { 45,     "8787 < BS <= 10276"},
347     { 46,     "10287 < BS <= 12043"},
348     { 47,     "12043 < BS <= 14099"},
349     { 48,     "14099 < BS <= 16507"},
350     { 49,     "16507 < BS <= 19325"},
351     { 50,     "19325 < BS <= 22624"},
352     { 51,     "22624 < BS <= 26487"},
353     { 52,     "26487 < BS <= 31009"},
354     { 53,     "31009 < BS <= 36304"},
355     { 54,     "36304 < BS <= 42502"},
356     { 55,     "42502 < BS <= 49759"},
357     { 56,     "49759 < BS <= 58255"},
358     { 57,     "58255 < BS <= 68201"},
359     { 58,     "68201 < BS <= 79846"},
360     { 59,     "79846 < BS <= 93479"},
361     { 60,     "93479 < BS <= 109439"},
362     { 61,     "109439 < BS <= 128125"},
363     { 62,     "128125 < BS <= 150000"},
364     { 63,     "BS > 150000"},
365     { 0, NULL }
366 };
367
368 static const value_string header_only_vals[] =
369 {
370     { 0,      "MAC PDU Headers and body present"},
371     { 1,      "MAC PDU Headers only"},
372     { 0, NULL }
373 };
374
375 static const value_string predefined_frame_vals[] =
376 {
377     { 0,      "Real MAC PDU present - will dissect"},
378     { 1,      "Predefined frame present - will not dissect"},
379     { 0, NULL }
380 };
381
382
383 /* If this PDU has been NACK'd (by HARQ) more than a certain number of times,
384    we trigger an expert warning. */
385 static gint global_mac_lte_retx_counter_trigger = 3;
386
387 /* By default try to decode transparent data (BCH, PCH and CCCH) data using LTE RRC dissector */
388 static gboolean global_mac_lte_attempt_rrc_decode = TRUE;
389
390 /* Whether should attempt to dissect frames failing CRC check */
391 static gboolean global_mac_lte_dissect_crc_failures = FALSE;
392
393 /* Whether should attempt to decode lcid 1&2 SDUs as srb1/2 (i.e. AM RLC) */
394 static gboolean global_mac_lte_attempt_srb_decode = FALSE;
395
396 /* Whether should attempt to detect and flag DL HARQ resends */
397 static gboolean global_mac_lte_attempt_dl_harq_resend_detect = TRUE;
398
399 /* Whether should attempt to track UL HARQ resends */
400 static gboolean global_mac_lte_attempt_ul_harq_resend_track = TRUE;
401
402 /* Threshold for warning in expert info about high BSR values */
403 static gint global_mac_lte_bsr_warn_threshold = 50; /* default is 19325 -> 22624 */
404
405
406 /***********************************************************************/
407 /* How to dissect lcid 3-10 (presume drb logical channels)             */
408
409 static const value_string drb_lcid_vals[] = {
410     { 3,  "LCID 3"},
411     { 4,  "LCID 4"},
412     { 5,  "LCID 5"},
413     { 6,  "LCID 6"},
414     { 7,  "LCID 7"},
415     { 8,  "LCID 8"},
416     { 9,  "LCID 9"},
417     { 10, "LCID 10"},
418     { 0, NULL }
419 };
420
421 typedef enum rlc_channel_type_t {
422     rlcRaw,
423     rlcTM,
424     rlcUM5,
425     rlcUM10,
426     rlcAM
427 } rlc_channel_type_t;
428
429 static const value_string rlc_channel_type_vals[] = {
430     { rlcTM,    "TM"},
431     { rlcUM5 ,  "UM, SN Len=5"},
432     { rlcUM10,  "UM, SN Len=10"},
433     { rlcAM  ,  "AM"},
434     { 0, NULL }
435 };
436
437
438 /* Mapping type */
439 typedef struct drb_mapping_t {
440     guint16 lcid;
441     gint drbid;
442     rlc_channel_type_t channel_type;
443 } lcid_drb_mapping_t;
444
445 /* Mapping entity */
446 static lcid_drb_mapping_t *lcid_drb_mappings = NULL;
447 static guint num_lcid_drb_mappings = 0;
448
449 UAT_VS_DEF(lcid_drb_mappings, lcid, lcid_drb_mapping_t, 3, "LCID 3")
450 UAT_DEC_CB_DEF(lcid_drb_mappings, drbid, lcid_drb_mapping_t)
451 UAT_VS_DEF(lcid_drb_mappings, channel_type, lcid_drb_mapping_t, 2, "AM")
452
453 /* UAT object */
454 static uat_t* lcid_drb_mappings_uat;
455
456 extern int proto_rlc_lte;
457
458 /***************************************************************/
459
460
461
462 /***************************************************************/
463 /* Keeping track of Msg3 bodies so they can be compared with   */
464 /* Contention Resolution bodies.                               */
465
466 typedef struct Msg3Data {
467     guint8  data[6];
468     guint32 framenum;
469 } Msg3Data;
470
471
472 /* This table stores (RNTI -> Msg3Data*).  Will be populated when
473    Msg3 frames are first read.  */
474 static GHashTable *mac_lte_msg3_hash = NULL;
475
476 /* Hash table functions for mac_lte_msg3_hash.  Hash is just the (RNTI) key */
477 static gint mac_lte_rnti_hash_equal(gconstpointer v, gconstpointer v2)
478 {
479     return (v == v2);
480 }
481
482 static guint mac_lte_rnti_hash_func(gconstpointer v)
483 {
484     return GPOINTER_TO_UINT(v);
485 }
486
487
488
489 typedef enum ContentionResolutionStatus {
490     NoMsg3,
491     Msg3Match,
492     Msg3NoMatch
493 } ContentionResolutionStatus;
494
495 typedef struct ContentionResolutionResult {
496     ContentionResolutionStatus status;
497     guint                      msg3FrameNum;
498 } ContentionResolutionResult;
499
500
501 /* This table stores (CRFrameNum -> CRResult).  It is assigned during the first
502    pass and used thereafter */
503 static GHashTable *mac_lte_cr_result_hash = NULL;
504
505 /* Hash table functions for mac_lte_cr_result_hash.  Hash is just the (framenum) key */
506 static gint mac_lte_framenum_hash_equal(gconstpointer v, gconstpointer v2)
507 {
508     return (v == v2);
509 }
510
511 static guint mac_lte_framenum_hash_func(gconstpointer v)
512 {
513     return GPOINTER_TO_UINT(v);
514 }
515
516 /**************************************************************************/
517
518
519
520 /****************************************************************/
521 /* Keeping track of last DL frames per C-RNTI so can guess when */
522 /* there has been a HARQ retransmission                         */
523
524 /* Could be bigger, but more than enough to flag suspected resends */
525 #define MAX_EXPECTED_PDU_LENGTH 2048
526
527 typedef struct LastFrameData {
528     gboolean inUse;
529     guint32  framenum;
530     guint    subframeNumber;
531     nstime_t received_time;
532     gint     length;
533     guint8   data[MAX_EXPECTED_PDU_LENGTH];
534 } LastFrameData;
535
536 typedef struct LastFrameDataAllSubframes {
537     LastFrameData subframe[10];
538 } LastFrameDataAllSubframes;
539
540
541 /* This table stores (RNTI -> LastFrameDataAllSubframes*).  Will be populated when
542    DL frames are first read.  */
543 static GHashTable *mac_lte_dl_harq_hash = NULL;
544
545 typedef struct DLHARQResult {
546     gboolean    status;
547     guint       previousFrameNum;
548 } DLHARQResult;
549
550
551 /* This table stores (CRFrameNum -> DLHARQResult).  It is assigned during the first
552    pass and used thereafter */
553 static GHashTable *mac_lte_dl_harq_result_hash = NULL;
554
555 /**************************************************************************/
556
557
558 /*****************************************************************/
559 /* Keeping track of last UL frames per C-RNTI so can verify when */
560 /* told that a frame is a retx                                   */
561
562 /* This table stores (RNTI -> LastFrameDataAllSubframes*).  Will be populated when
563    UL frames are first read.  */
564 static GHashTable *mac_lte_ul_harq_hash = NULL;
565
566 typedef struct ULHARQResult {
567     guint       previousFrameNum;
568 } ULHARQResult;
569
570
571 /* This table stores (CRFrameNum -> ULHARQResult).  It is assigned during the first
572    pass and used thereafter */
573 static GHashTable *mac_lte_ul_harq_result_hash = NULL;
574
575 /**************************************************************************/
576
577
578
579
580
581
582 /* Forward declarations */
583 void proto_reg_handoff_mac_lte(void);
584 void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
585
586
587 /* Heuristic dissection */
588 static gboolean global_mac_lte_heur = FALSE;
589
590 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
591 static gboolean dissect_mac_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
592                                      proto_tree *tree)
593 {
594     gint                 offset = 0;
595     struct mac_lte_info  *p_mac_lte_info;
596     tvbuff_t             *mac_tvb;
597     guint8               tag = 0;
598     gboolean             infoAlreadySet = FALSE;
599
600     /* This is a heuristic dissector, which means we get all the UDP
601      * traffic not sent to a known dissector and not claimed by
602      * a heuristic dissector called before us!
603      */
604
605     if (!global_mac_lte_heur) {
606         return FALSE;
607     }
608
609     /* If redissecting, use previous info struct (if available) */
610     p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte);
611     if (p_mac_lte_info == NULL) {
612         /* Allocate new info struct for this frame */
613         p_mac_lte_info = se_alloc0(sizeof(struct mac_lte_info));
614         if (p_mac_lte_info == NULL) {
615             return FALSE;
616         }
617         infoAlreadySet = FALSE;
618     }
619     else {
620         infoAlreadySet = TRUE;
621     }
622
623     /* Do this again on re-dissection to re-discover offset of actual PDU */
624     
625     /* Needs to be at least as long as:
626        - the signature string
627        - fixed header bytes
628        - tag for data
629        - at least one byte of MAC PDU payload */
630     if ((size_t)tvb_length_remaining(tvb, offset) < (strlen(MAC_LTE_START_STRING)+3+2)) {
631         return FALSE;
632     }
633
634     /* OK, compare with signature string */
635     if (tvb_strneql(tvb, offset, MAC_LTE_START_STRING, (gint)strlen(MAC_LTE_START_STRING)) != 0) {
636         return FALSE;
637     }
638     offset += (gint)strlen(MAC_LTE_START_STRING);
639
640     /* Read fixed fields */
641     p_mac_lte_info->radioType = tvb_get_guint8(tvb, offset++);
642     p_mac_lte_info->direction = tvb_get_guint8(tvb, offset++);
643     p_mac_lte_info->rntiType = tvb_get_guint8(tvb, offset++);
644
645     /* Read optional fields */
646     while (tag != MAC_LTE_PAYLOAD_TAG) {
647         /* Process next tag */
648         tag = tvb_get_guint8(tvb, offset++);
649         switch (tag) {
650             case MAC_LTE_RNTI_TAG:
651                 p_mac_lte_info->rnti = tvb_get_ntohs(tvb, offset);
652                 offset += 2;
653                 break;
654             case MAC_LTE_UEID_TAG:
655                 p_mac_lte_info->ueid = tvb_get_ntohs(tvb, offset);
656                 offset += 2;
657                 break;
658             case MAC_LTE_SUBFRAME_TAG:
659                 p_mac_lte_info->subframeNumber = tvb_get_ntohs(tvb, offset);
660                 offset += 2;
661                 break;
662             case MAC_LTE_PREDFINED_DATA_TAG:
663                 p_mac_lte_info->isPredefinedData = tvb_get_guint8(tvb, offset);
664                 offset++;
665                 break;
666             case MAC_LTE_RETX_TAG:
667                 p_mac_lte_info->reTxCount = tvb_get_guint8(tvb, offset);
668                 offset++;
669                 break;
670             case MAC_LTE_CRC_STATUS_TAG:
671                 p_mac_lte_info->crcStatusValid = TRUE;
672                 p_mac_lte_info->crcStatus = tvb_get_guint8(tvb, offset);
673                 offset++;
674                 break;
675
676             case MAC_LTE_PAYLOAD_TAG:
677                 /* Have reached data, so set payload length and get out of loop */
678                 p_mac_lte_info->length= tvb_length_remaining(tvb, offset);
679                 continue;
680
681             default:
682                 /* It must be a recognised tag */
683                 return FALSE;
684         }
685
686         if (!infoAlreadySet) {
687             /* Store info in packet */
688             p_add_proto_data(pinfo->fd, proto_mac_lte, p_mac_lte_info);
689         }
690     }
691
692
693     /**************************************/
694     /* OK, now dissect as MAC LTE         */
695
696     /* Create tvb that starts at actual MAC PDU */
697     mac_tvb = tvb_new_subset(tvb, offset, -1, tvb_reported_length(tvb)-offset);
698     dissect_mac_lte(mac_tvb, pinfo, tree);
699     return TRUE;
700 }
701
702 /* Dissect a single Random Access Reponse body */
703 static gint dissect_rar_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
704                               gint offset, guint8 rapid)
705 {
706     guint8 reserved;
707     guint start_body_offset = offset;
708     proto_item *ti;
709     proto_item *rar_body_ti;
710     proto_tree *rar_body_tree;
711     proto_tree *ul_grant_tree;
712     proto_item *ul_grant_ti;
713     guint16 timing_advance;
714     guint32 ul_grant;
715     guint16 temp_crnti;
716
717     /* Create tree for this Body */
718     rar_body_ti = proto_tree_add_item(tree,
719                                       hf_mac_lte_rar_body,
720                                       tvb, offset, 0, FALSE);
721     rar_body_tree = proto_item_add_subtree(rar_body_ti, ett_mac_lte_rar_body);
722
723     /* Dissect an RAR entry */
724
725     /* Check reserved bit */
726     reserved = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
727     ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_reserved2, tvb, offset, 1, FALSE);
728     if (reserved != 0) {
729             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
730                       "RAR body Reserved bit not zero (found 0x%x)", reserved);
731     }
732
733     /* Timing Advance */
734     timing_advance = (tvb_get_ntohs(tvb, offset) & 0x7ff0) >> 4;
735     ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ta, tvb, offset, 2, FALSE);
736     if (timing_advance != 0) {
737         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
738                                "RAR Timing advance not zero (%u)", timing_advance);
739     }
740     offset++;
741
742     /* UL Grant */
743     ul_grant = (tvb_get_ntohl(tvb, offset) & 0x0fffff00) >> 8;
744     ul_grant_ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ul_grant, tvb, offset, 3, FALSE);
745
746     /* Break these 20 bits down as described in 36.213, section 6.2 */
747     /* Create subtree for UL grant break-down */
748     ul_grant_tree = proto_item_add_subtree(ul_grant_ti, ett_mac_lte_rar_ul_grant);
749
750     /* Hopping flag (1 bit) */
751     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_hopping,
752                         tvb, offset, 1, FALSE);
753
754     /* Fixed sized resource block assignment (10 bits) */
755     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_fsrba,
756                         tvb, offset, 2, FALSE);
757
758     /* Truncated Modulation and coding scheme (4 bits) */
759     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tmcs,
760                         tvb, offset+1, 2, FALSE);
761
762     /* TPC command for scheduled PUSCH (3 bits) */
763     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tcsp,
764                         tvb, offset+2, 1, FALSE);
765
766     /* UL delay (1 bit) */
767     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_delay,
768                         tvb, offset+2, 1, FALSE);
769
770     /* CQI request (1 bit) */
771     proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_cqi_request,
772                         tvb, offset+2, 1, FALSE);
773
774     offset += 3;
775
776     /* Temporary C-RNTI */
777     temp_crnti = tvb_get_ntohs(tvb, offset);
778     proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_temporary_crnti, tvb, offset, 2, FALSE);
779     offset += 2;
780
781     proto_item_append_text(rar_body_ti, " RAPID=%u (TA=%u, UL-Grant=%u, Temp C-RNTI=%u)",
782                            rapid, timing_advance, ul_grant, temp_crnti);
783
784     col_append_fstr(pinfo->cinfo, COL_INFO, "(RAPID=%u: TA=%u, UL-Grant=%u, Temp C-RNTI=%u) ",
785                     rapid, timing_advance, ul_grant, temp_crnti);
786
787     proto_item_set_len(rar_body_ti, offset-start_body_offset);
788
789     return offset;
790 }
791
792
793 /* Dissect Random Access Reponse (RAR) PDU */
794 static void dissect_rar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *pdu_ti,
795                         gint offset, mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info)
796 {
797     gint     number_of_rars = 0;   /* No of RAR bodies expected following headers */
798     guint8   rapids[64];
799     gboolean backoff_indicator_seen = FALSE;
800     guint8   backoff_indicator = 0;
801     guint8   extension;
802     gint     n;
803     proto_tree *rar_headers_tree;
804     proto_item *ti;
805     proto_item *rar_headers_ti;
806     int        start_headers_offset = offset;
807
808     col_append_fstr(pinfo->cinfo, COL_INFO, "RAR (RA-RNTI=%u, SF=%u) ",
809                     p_mac_lte_info->rnti, p_mac_lte_info->subframeNumber);
810
811     /* Create hidden 'virtual root' so can filter on mac-lte.rar */
812     ti = proto_tree_add_item(tree, hf_mac_lte_rar, tvb, offset, -1, FALSE);
813     PROTO_ITEM_SET_HIDDEN(ti);
814
815     /* Create headers tree */
816     rar_headers_ti = proto_tree_add_item(tree,
817                                          hf_mac_lte_rar_headers,
818                                          tvb, offset, 0, FALSE);
819     rar_headers_tree = proto_item_add_subtree(rar_headers_ti, ett_mac_lte_rar_headers);
820
821
822     /***************************/
823     /* Read the header entries */
824     do {
825         int start_header_offset = offset;
826         proto_tree *rar_header_tree;
827         proto_item *rar_header_ti;
828         guint8 type_value;
829         guint8 first_byte = tvb_get_guint8(tvb, offset);
830
831         /* Create tree for this header */
832         rar_header_ti = proto_tree_add_item(rar_headers_tree,
833                                             hf_mac_lte_rar_header,
834                                             tvb, offset, 0, FALSE);
835         rar_header_tree = proto_item_add_subtree(rar_header_ti, ett_mac_lte_rar_header);
836
837         /* Extension */
838         extension = (first_byte & 0x80) >> 7;
839         proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_extension, tvb, offset, 1, FALSE);
840
841         /* Type */
842         type_value = (first_byte & 0x40) >> 6;
843         proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_t, tvb, offset, 1, FALSE);
844
845         if (type_value == 0) {
846             /* Backoff Indicator (BI) case */
847
848             guint8 reserved;
849             proto_item *ti;
850             proto_item *bi_ti;
851
852             /* 2 Reserved bits */
853             reserved = (tvb_get_guint8(tvb, offset) & 0x30) >> 4;
854             ti = proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_reserved, tvb, offset, 1, FALSE);
855             if (reserved != 0) {
856                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
857                                        "RAR header Reserved bits not zero (found 0x%x)", reserved);
858             }
859
860             /* Backoff Indicator */
861             backoff_indicator = tvb_get_guint8(tvb, offset) & 0x0f;
862             bi_ti = proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_bi, tvb, offset, 1, FALSE);
863
864             /* As of March 2009 spec, it must be first, and may only appear once */
865             if (backoff_indicator_seen) {
866                 expert_add_info_format(pinfo, bi_ti, PI_MALFORMED, PI_ERROR,
867                                        "MAC RAR PDU has > 1 Backoff Indicator subheader present");
868             }
869             backoff_indicator_seen = TRUE;
870
871             proto_item_append_text(rar_header_ti, "(Backoff Indicator=%sms)",
872                                    val_to_str(backoff_indicator, rar_bi_vals, "Illegal-value "));
873
874             col_append_fstr(pinfo->cinfo, COL_INFO, "(Backoff Indicator=%s ms) ",
875                             val_to_str(backoff_indicator, rar_bi_vals, "Illegal-value"));
876
877             /* If present, it must be the first subheader */
878             if (number_of_rars > 0) {
879                 expert_add_info_format(pinfo, bi_ti, PI_MALFORMED, PI_WARN,
880                                        "Backoff Indicator must appear as first subheader");
881             }
882
883         }
884         else {
885             /* RAPID case */
886             /* TODO: complain if the same RAPID appears twice in same frame? */
887             rapids[number_of_rars] = tvb_get_guint8(tvb, offset) & 0x3f;
888             proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_rapid, tvb, offset, 1, FALSE);
889
890             proto_item_append_text(rar_header_ti, "(RAPID=%u)", rapids[number_of_rars]);
891
892             number_of_rars++;
893         }
894
895         offset++;
896
897         /* Finalise length of header tree selection */
898         proto_item_set_len(rar_header_ti, offset - start_header_offset);
899
900     } while (extension);
901
902     /* Append summary to headers root */
903     proto_item_append_text(rar_headers_ti, " (%u RARs", number_of_rars);
904     if (backoff_indicator_seen) {
905         proto_item_append_text(rar_headers_ti, ", BI=%sms)",
906                                val_to_str(backoff_indicator, rar_bi_vals, "Illegal-value "));
907     }
908     else {
909         proto_item_append_text(rar_headers_ti, ")");
910     }
911
912     /* Set length for headers root */
913     proto_item_set_len(rar_headers_ti, offset-start_headers_offset);
914
915
916     /***************************/
917     /* Read any indicated RARs */
918     for (n=0; n < number_of_rars; n++) {
919         offset = dissect_rar_entry(tvb, pinfo, tree, offset, rapids[n]);
920     }
921
922     /* Update TAP info */
923     tap_info->number_of_rars += number_of_rars;
924
925     /* Warn if we don't seem to have reached the end of the frame yet */
926     if (tvb_length_remaining(tvb, offset) != 0) {
927            expert_add_info_format(pinfo, pdu_ti, PI_MALFORMED, PI_ERROR,
928                                   "%u bytes remaining after RAR PDU dissected",
929                                   tvb_length_remaining(tvb, offset));
930     }
931 }
932
933
934 /* Dissect BCH PDU */
935 static void dissect_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
936                         int offset, mac_lte_info *p_mac_lte_info)
937 {
938     proto_item *ti;
939
940     col_append_fstr(pinfo->cinfo, COL_INFO, "BCH PDU (%u bytes, on %s transport)  ",
941                     tvb_length_remaining(tvb, offset),
942                     val_to_str(p_mac_lte_info->rntiType,
943                                bch_transport_channel_vals,
944                                "Unknown"));
945
946     /* Show which transport layer it came in on (inferred from RNTI type) */
947     ti = proto_tree_add_uint(tree, hf_mac_lte_context_bch_transport_channel,
948                              tvb, offset, 0, p_mac_lte_info->rntiType);
949     PROTO_ITEM_SET_GENERATED(ti);
950
951     /****************************************/
952     /* Whole frame is BCH data              */
953
954     /* Raw data */
955     ti = proto_tree_add_item(tree, hf_mac_lte_bch_pdu,
956                              tvb, offset, -1, FALSE);
957
958     if (global_mac_lte_attempt_rrc_decode) {
959         /* Attempt to decode payload using LTE RRC dissector */
960         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
961
962         /* Get appropriate dissector handle */
963         dissector_handle_t protocol_handle = 0;
964         if (p_mac_lte_info->rntiType == SI_RNTI) {
965             protocol_handle = find_dissector("lte-rrc.bcch.dl.sch");
966         }
967         else {
968             protocol_handle = find_dissector("lte-rrc.bcch.bch");
969         }
970
971         /* Hide raw view of bytes */
972         PROTO_ITEM_SET_HIDDEN(ti);
973
974         /* Call it (catch exceptions so that stats will be updated) */
975         /* TODO: couldn't avoid warnings for 'ti' by using volatile
976                  (with gcc 3.4.6)                                   */
977 /*        TRY {                                                         */
978             call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
979 /*        }                                                             */
980 /*        CATCH_ALL {                                                   */
981 /*        }                                                             */
982 /*        ENDTRY                                                        */
983     }
984
985     /* Check that this *is* downlink! */
986     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
987         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
988                                "BCH data should not be received in Uplink!");
989     }
990 }
991
992
993 /* Dissect PCH PDU */
994 static void dissect_pch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
995                         int offset, guint8 direction)
996 {
997     proto_item *ti;
998
999     col_append_fstr(pinfo->cinfo, COL_INFO, "PCH PDU (%u bytes)  ",
1000                     tvb_length_remaining(tvb, offset));
1001
1002     /****************************************/
1003     /* Whole frame is PCH data              */
1004
1005     /* Always show as raw data */
1006     ti = proto_tree_add_item(tree, hf_mac_lte_pch_pdu,
1007                              tvb, offset, -1, FALSE);
1008
1009     if (global_mac_lte_attempt_rrc_decode) {
1010
1011         /* Attempt to decode payload using LTE RRC dissector */
1012         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
1013
1014         /* Get appropriate dissector handle */
1015         dissector_handle_t protocol_handle = find_dissector("lte-rrc.pcch");
1016
1017         /* Hide raw view of bytes */
1018         PROTO_ITEM_SET_HIDDEN(ti);
1019
1020         /* Call it (catch exceptions so that stats will be updated) */
1021         TRY {
1022             call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
1023         }
1024         CATCH_ALL {
1025         }
1026         ENDTRY
1027     }
1028
1029     /* Check that this *is* downlink! */
1030     if (direction == DIRECTION_UPLINK) {
1031         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1032                                "PCH data should not be received in Uplink!");
1033     }
1034 }
1035
1036
1037 /* Does this header entry correspond to a fixed-sized control element? */
1038 static int is_fixed_sized_control_element(guint8 lcid, guint8 direction)
1039 {
1040     if (direction == DIRECTION_UPLINK) {
1041         /* Uplink */
1042         switch (lcid) {
1043             case POWER_HEADROOM_REPORT_LCID:
1044             case CRNTI_LCID:
1045             case TRUNCATED_BSR_LCID:
1046             case SHORT_BSR_LCID:
1047             case LONG_BSR_LCID:
1048                 return TRUE;
1049
1050             default:
1051                 return FALSE;
1052         }
1053     }
1054     else {
1055         /* Assume Downlink */
1056         switch (lcid) {
1057             case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
1058             case TIMING_ADVANCE_LCID:
1059             case DRX_COMMAND_LCID:
1060                 return TRUE;
1061
1062             default:
1063                 return FALSE;
1064         }
1065     }
1066 }
1067
1068
1069 /* Is this a BSR report header? */
1070 static int is_bsr_lcid(guint8 lcid)
1071 {
1072     return ((lcid == TRUNCATED_BSR_LCID) ||
1073             (lcid == SHORT_BSR_LCID) ||
1074             (lcid == LONG_BSR_LCID));
1075 }
1076
1077
1078 /* Helper function to call RLC dissector for SDUs (where channel params are known) */
1079 static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1080                                int offset, guint16 data_length,
1081                                guint8 mode, guint8 direction, guint16 ueid,
1082                                guint16 channelType, guint16 channelId,
1083                                guint8 UMSequenceNumberLength)
1084 {
1085     tvbuff_t *srb_tvb = tvb_new_subset(tvb, offset, data_length, data_length);
1086     struct rlc_lte_info *p_rlc_lte_info;
1087
1088     /* Get RLC dissector handle */
1089     volatile dissector_handle_t protocol_handle = find_dissector("rlc-lte");
1090
1091     /* Resuse or create RLC info */
1092     p_rlc_lte_info = p_get_proto_data(pinfo->fd, proto_rlc_lte);
1093     if (p_rlc_lte_info == NULL) {
1094         p_rlc_lte_info = se_alloc0(sizeof(struct rlc_lte_info));
1095     }
1096
1097     /* Fill in struct details for srb channels */
1098     p_rlc_lte_info->rlcMode = mode;
1099     p_rlc_lte_info->direction = direction;
1100     p_rlc_lte_info->priority = 0; /* ?? */
1101     p_rlc_lte_info->ueid = ueid;
1102     p_rlc_lte_info->channelType = channelType;
1103     p_rlc_lte_info->channelId = channelId;
1104     p_rlc_lte_info->pduLength = data_length;
1105     p_rlc_lte_info->UMSequenceNumberLength = UMSequenceNumberLength;
1106
1107     /* Store info in packet */
1108     p_add_proto_data(pinfo->fd, proto_rlc_lte, p_rlc_lte_info);
1109
1110     /* Don't want these columns replaced */
1111     col_set_writable(pinfo->cinfo, FALSE);
1112
1113     /* Call it (catch exceptions so that stats will be updated) */
1114     TRY {
1115         call_dissector_only(protocol_handle, srb_tvb, pinfo, tree);
1116     }
1117     CATCH_ALL {
1118     }
1119     ENDTRY
1120
1121     col_set_writable(pinfo->cinfo, TRUE);
1122 }
1123
1124
1125 /* Track DL frames, and look for likely cases of likely HARQ retx */
1126 static void DetectIfDLHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatile int offset,
1127                                  proto_tree *tree, mac_lte_info *p_mac_lte_info)
1128 {
1129     DLHARQResult *result = NULL;
1130     proto_item *result_ti;
1131
1132     if (!pinfo->fd->flags.visited) {
1133         /* First time, so set result and update DL harq table */
1134         LastFrameData *lastData = NULL;
1135         LastFrameData *thisData = NULL;
1136
1137         /* Look up entry for this UE/RNTI */
1138         LastFrameDataAllSubframes *ueData =
1139             g_hash_table_lookup(mac_lte_dl_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti));
1140         if (ueData != NULL) {
1141             /* Looking for a frame sent 8 subframes previously */
1142             lastData = &(ueData->subframe[(p_mac_lte_info->subframeNumber+2) % 10]);
1143             if (lastData->inUse) {
1144                 /* Compare time, sf, data to see if this looks like a retx */
1145                 if ((tvb_length_remaining(tvb, offset) == lastData->length) &&
1146                     (memcmp(lastData->data,
1147                             tvb_get_ptr(tvb, offset, lastData->length),
1148                             MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0)) {
1149
1150                     /* Work out gap between frames */
1151                     gint seconds_between_packets = (gint)
1152                           (pinfo->fd->abs_ts.secs - lastData->received_time.secs);
1153                     gint nseconds_between_packets =
1154                           pinfo->fd->abs_ts.nsecs - lastData->received_time.nsecs;
1155
1156                     gint total_gap = (seconds_between_packets*1000) +
1157                                      (nseconds_between_packets / 1000000);
1158
1159                     /* Should be 8 ms apart, but allow some leeway */
1160                     if ((total_gap >= 7) && (total_gap <= 9)) {
1161                         /* Resend detected!!! Store result */
1162                         result = se_alloc(sizeof(DLHARQResult));
1163                         result->previousFrameNum = lastData->framenum;
1164                         g_hash_table_insert(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num), result);
1165
1166                     }
1167                 }
1168             }
1169         }
1170         else {
1171             /* Allocate entry in table for this UE/RNTI */
1172             ueData = se_alloc0(sizeof(LastFrameDataAllSubframes));
1173             g_hash_table_insert(mac_lte_dl_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti), ueData);
1174         }
1175
1176         /* Store this frame's details in table */
1177         thisData = &(ueData->subframe[p_mac_lte_info->subframeNumber]);
1178         thisData->inUse = TRUE;
1179         thisData->length = tvb_length_remaining(tvb, offset);
1180         memcpy(thisData->data, tvb_get_ptr(tvb, offset, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH)), thisData->length);
1181         thisData->subframeNumber = p_mac_lte_info->subframeNumber;
1182         thisData->framenum = pinfo->fd->num;
1183         thisData->received_time = pinfo->fd->abs_ts;
1184     }
1185     else {
1186         /* Not first time, so just set whats already stored in result */
1187         result = g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
1188     }
1189
1190     /* Show result, with link back to original frame */
1191     result_ti = proto_tree_add_boolean(tree, hf_mac_lte_suspected_dl_harq_resend,
1192                                        tvb, 0, 0, (result != NULL));
1193     if (result != NULL) {
1194         proto_item *original_ti;
1195         expert_add_info_format(pinfo, result_ti, PI_SEQUENCE, PI_WARN,
1196                                "Suspected DL HARQ resend (UE=%u)", p_mac_lte_info->ueid);
1197         original_ti = proto_tree_add_uint(tree, hf_mac_lte_suspected_dl_harq_resend_original_frame,
1198                                          tvb, 0, 0, result->previousFrameNum);
1199         PROTO_ITEM_SET_GENERATED(original_ti);
1200     }
1201     else {
1202         /* Don't show negatives */
1203         PROTO_ITEM_SET_HIDDEN(result_ti);
1204     }
1205     PROTO_ITEM_SET_GENERATED(result_ti);
1206 }
1207
1208 /* Track UL frames, so that when a retx is indicated, we can search for
1209    the original tx.  We will either find it, and provide a link back to it,
1210    or flag that we couldn't find as an expert error */
1211 static void TrackReportedULHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatile int offset,
1212                                       proto_tree *tree, mac_lte_info *p_mac_lte_info,
1213                                       proto_item *retx_ti)
1214 {
1215     ULHARQResult *result = NULL;
1216
1217     if (!pinfo->fd->flags.visited) {
1218         /* First time, so set result and update UL harq table */
1219         LastFrameData *lastData = NULL;
1220         LastFrameData *thisData = NULL;
1221
1222         /* Look up entry for this UE/RNTI */
1223         LastFrameDataAllSubframes *ueData =
1224             g_hash_table_lookup(mac_lte_ul_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti));
1225         if (ueData != NULL) {
1226
1227             if (p_mac_lte_info->reTxCount >= 1) {
1228                 /* Looking for a frame sent 8 subframes previously */
1229                 lastData = &(ueData->subframe[(p_mac_lte_info->subframeNumber+2) % 10]);
1230                 if (lastData->inUse) {
1231                     /* Compare time, sf, data to see if this looks like a retx */
1232                     if ((tvb_length_remaining(tvb, offset) == lastData->length) &&
1233                         (memcmp(lastData->data,
1234                                 tvb_get_ptr(tvb, offset, lastData->length),
1235                                 MIN(lastData->length, MAX_EXPECTED_PDU_LENGTH)) == 0)) {
1236
1237                         /* Work out gap between frames */
1238                         gint seconds_between_packets = (gint)
1239                               (pinfo->fd->abs_ts.secs - lastData->received_time.secs);
1240                         gint nseconds_between_packets =
1241                               pinfo->fd->abs_ts.nsecs - lastData->received_time.nsecs;
1242
1243                         gint total_gap = (seconds_between_packets*1000) +
1244                                          (nseconds_between_packets / 1000000);
1245
1246                         /* Should be 8 ms apart, but allow some leeway */
1247                         if ((total_gap >= 7) && (total_gap <= 9)) {
1248                             /* Original detected!!! Store result */
1249                             result = se_alloc(sizeof(ULHARQResult));
1250                             result->previousFrameNum = lastData->framenum;
1251                             g_hash_table_insert(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num), result);
1252                         }
1253                     }
1254                 }
1255             }
1256         }
1257         else {
1258             /* Allocate entry in table for this UE/RNTI */
1259             ueData = se_alloc0(sizeof(LastFrameDataAllSubframes));
1260             g_hash_table_insert(mac_lte_ul_harq_hash, GUINT_TO_POINTER((guint)p_mac_lte_info->rnti), ueData);
1261         }
1262
1263         /* Store this frame's details in table */
1264         thisData = &(ueData->subframe[p_mac_lte_info->subframeNumber]);
1265         thisData->inUse = TRUE;
1266         thisData->length = tvb_length_remaining(tvb, offset);
1267         memcpy(thisData->data, tvb_get_ptr(tvb, offset, MIN(thisData->length, MAX_EXPECTED_PDU_LENGTH)), thisData->length);
1268         thisData->subframeNumber = p_mac_lte_info->subframeNumber;
1269         thisData->framenum = pinfo->fd->num;
1270         thisData->received_time = pinfo->fd->abs_ts;
1271     }
1272     else {
1273         /* Not first time, so just set whats already stored in result */
1274         result = g_hash_table_lookup(mac_lte_ul_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
1275     }
1276
1277     if (retx_ti != NULL) {
1278         if (result != NULL) {
1279             proto_item *original_ti;
1280
1281             original_ti = proto_tree_add_uint(tree, hf_mac_lte_ul_harq_resend_original_frame,
1282                                               tvb, 0, 0, result->previousFrameNum);
1283             PROTO_ITEM_SET_GENERATED(original_ti);
1284         }
1285         else {
1286             expert_add_info_format(pinfo, retx_ti, PI_SEQUENCE, PI_ERROR,
1287                                    "Original Tx of UL frame not found (UE %u) !!", p_mac_lte_info->ueid);
1288         }
1289     }
1290 }
1291
1292
1293
1294
1295
1296 #define MAX_HEADERS_IN_PDU 1024
1297
1298 /* UL-SCH and DL-SCH formats have much in common, so handle them in a common
1299    function */
1300 static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1301                                    proto_item *pdu_ti,
1302                                    volatile int offset, guint8 direction,
1303                                    mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info,
1304                                    proto_item *retx_ti)
1305 {
1306     guint8          extension;
1307     volatile guint8 n;
1308     proto_item      *truncated_ti;
1309     proto_item      *padding_length_ti;
1310
1311     /* Keep track of LCIDs and lengths as we dissect the header */
1312     volatile guint8 number_of_headers = 0;
1313     guint8  lcids[MAX_HEADERS_IN_PDU];
1314     gint16  pdu_lengths[MAX_HEADERS_IN_PDU];
1315
1316     proto_item *pdu_header_ti;
1317     proto_tree *pdu_header_tree;
1318
1319     gboolean   have_seen_data_header = FALSE;
1320     gboolean   have_seen_bsr = FALSE;
1321     gboolean   expecting_body_data = FALSE;
1322     volatile   guint32    is_truncated = FALSE;
1323
1324     col_append_fstr(pinfo->cinfo, COL_INFO, "%s: (SF=%u) UEId=%u ",
1325                     (direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
1326                     p_mac_lte_info->subframeNumber,
1327                     p_mac_lte_info->ueid);
1328
1329
1330     /* For downlink frames, can try to work out if this looks like a HARQ resend */
1331     if ((direction == DIRECTION_DOWNLINK) && global_mac_lte_attempt_dl_harq_resend_detect) {
1332         DetectIfDLHARQResend(pinfo, tvb, offset, tree, p_mac_lte_info);
1333     }
1334
1335
1336     /* For uplink frames, if this is logged as a resend, look for original tx */
1337     if ((direction == DIRECTION_UPLINK) && global_mac_lte_attempt_ul_harq_resend_track) {
1338         TrackReportedULHARQResend(pinfo, tvb, offset, tree, p_mac_lte_info, retx_ti);
1339     }
1340
1341
1342     /* Add PDU block header subtree */
1343     pdu_header_ti = proto_tree_add_string_format(tree,
1344                                                  (direction == DIRECTION_UPLINK) ?
1345                                                     hf_mac_lte_ulsch_header :
1346                                                     hf_mac_lte_dlsch_header,
1347                                                  tvb, offset, 0,
1348                                                  "",
1349                                                  "MAC PDU Header");
1350     pdu_header_tree = proto_item_add_subtree(pdu_header_ti,
1351                                              (direction == DIRECTION_UPLINK) ?
1352                                                     ett_mac_lte_ulsch_header :
1353                                                     ett_mac_lte_dlsch_header);
1354
1355
1356     /************************************************************************/
1357     /* Dissect each sub-header.                                             */
1358     do {
1359         guint8 reserved;
1360         guint64 length = 0;
1361         proto_item *pdu_subheader_ti;
1362         proto_tree *pdu_subheader_tree;
1363         proto_item *lcid_ti;
1364         proto_item *ti;
1365         gint       offset_start_subheader = offset;
1366         guint8 first_byte = tvb_get_guint8(tvb, offset);
1367
1368         /* Add PDU block header subtree */
1369         pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
1370                                                         hf_mac_lte_sch_subheader,
1371                                                         tvb, offset, 0,
1372                                                         "",
1373                                                         "Sub-header");
1374         pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
1375                                                     ett_mac_lte_sch_subheader);
1376
1377         /* Check 1st 2 reserved bits */
1378         reserved = (first_byte & 0xc0) >> 6;
1379         ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_reserved,
1380                                  tvb, offset, 1, FALSE);
1381         if (reserved != 0) {
1382             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1383                                    "U/DL-SCH header Reserved bits not zero");
1384         }
1385
1386         /* Extended bit */
1387         extension = (first_byte & 0x20) >> 5;
1388         proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_extended,
1389                             tvb, offset, 1, FALSE);
1390
1391         /* LCID.  Has different meaning depending upon direction. */
1392         lcids[number_of_headers] = first_byte & 0x1f;
1393         if (direction == DIRECTION_UPLINK) {
1394             lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_ulsch_lcid,
1395                                           tvb, offset, 1, FALSE);
1396             col_append_fstr(pinfo->cinfo, COL_INFO, "(%s",
1397                             val_to_str(lcids[number_of_headers],
1398                                        ulsch_lcid_vals, "(Unknown LCID)"));
1399         }
1400         else {
1401             lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_dlsch_lcid,
1402                                           tvb, offset, 1, FALSE);
1403             col_append_fstr(pinfo->cinfo, COL_INFO, "(%s",
1404                             val_to_str(lcids[number_of_headers],
1405                                        dlsch_lcid_vals, "(Unknown LCID)"));
1406         }
1407         offset++;
1408
1409         /* Remember if we've seen a data subheader */
1410         if (lcids[number_of_headers] <= 10) {
1411             have_seen_data_header = TRUE;
1412             expecting_body_data = TRUE;
1413         }
1414
1415         /* Show an expert item if a contol subheader (except Padding) appears
1416            *after* a data PDU */
1417         if (have_seen_data_header &&
1418             (lcids[number_of_headers] > 10) && (lcids[number_of_headers] != PADDING_LCID)) {
1419             expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
1420                                    "Control subheaders should not appear after data subheaders");
1421         }
1422
1423         /* Show an expert item if we're seeing more then one BSR in a frame */
1424         if ((direction == DIRECTION_UPLINK) && is_bsr_lcid(lcids[number_of_headers])) {
1425             if (have_seen_bsr) {
1426                 expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
1427                                       "There shouldn't be > 1 BSR in a frame");
1428             }
1429             have_seen_bsr = TRUE;
1430         }
1431
1432
1433         /********************************************************************/
1434         /* Length field follows if not the last header or for a fixed-sized
1435            control element */
1436         if (!extension) {
1437             if (is_fixed_sized_control_element(lcids[number_of_headers], direction)) {
1438                 pdu_lengths[number_of_headers] = 0;
1439             }
1440             else {
1441                 pdu_lengths[number_of_headers] = -1;
1442             }
1443         }
1444         else {
1445             if (!is_fixed_sized_control_element(lcids[number_of_headers], direction) &&
1446                 (lcids[number_of_headers] != PADDING_LCID)) {
1447
1448                 guint8  format;
1449
1450                 /* F(ormat) bit tells us how long the length field is */
1451                 format = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
1452                 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_format,
1453                                     tvb, offset, 1, FALSE);
1454
1455                 /* Now read length field itself */
1456                 if (format) {
1457                     /* >= 128 - use 15 bits */
1458                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
1459                                                 tvb, offset*8 + 1, 15, &length, FALSE);
1460
1461                     offset += 2;
1462                 }
1463                 else {
1464                     /* Less than 128 - only 7 bits */
1465                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
1466                                                 tvb, offset*8 + 1, 7, &length, FALSE);
1467                     offset++;
1468                 }
1469                 pdu_lengths[number_of_headers] = (gint16)length;
1470             }
1471             else {
1472                 pdu_lengths[number_of_headers] = 0;
1473             }
1474         }
1475
1476
1477         /* Close off description in info column */
1478         switch (pdu_lengths[number_of_headers]) {
1479             case 0:
1480                 col_append_str(pinfo->cinfo, COL_INFO, ") ");
1481                 break;
1482             case -1:
1483                 col_append_str(pinfo->cinfo, COL_INFO, ":remainder) ");
1484                 break;
1485             default:
1486                 col_append_fstr(pinfo->cinfo, COL_INFO, ":%u bytes) ",
1487                                 pdu_lengths[number_of_headers]);
1488                 break;
1489         }
1490
1491         /* Append summary to subheader root */
1492         proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
1493                                val_to_str(lcids[number_of_headers],
1494                                           (direction == DIRECTION_UPLINK) ?
1495                                               ulsch_lcid_vals :
1496                                               dlsch_lcid_vals,
1497                                           "Unknown"));
1498
1499         switch (pdu_lengths[number_of_headers]) {
1500             case -1:
1501                 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
1502                 break;
1503             case 0:
1504                 proto_item_append_text(pdu_subheader_ti, ")");
1505                 break;
1506             default:
1507                 proto_item_append_text(pdu_subheader_ti, ", length=%u)",
1508                                        pdu_lengths[number_of_headers]);
1509                 break;
1510         }
1511
1512
1513         /* Flag unknown lcid values in expert info */
1514         if (strncmp(val_to_str(lcids[number_of_headers],
1515                                (direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals,
1516                                "Unknown"),
1517                     "Unknown",
1518                     sizeof("Unknown")) == 0) {
1519             expert_add_info_format(pinfo, pdu_subheader_ti, PI_MALFORMED, PI_ERROR,
1520                                        "Unexpected LCID received (%u)", lcids[number_of_headers]);
1521         }
1522
1523         /* Set length of this subheader */
1524         proto_item_set_len(pdu_subheader_ti, offset- offset_start_subheader);
1525
1526         number_of_headers++;
1527     } while (extension);
1528
1529     /* Append summary to overall PDU header root */
1530     proto_item_append_text(pdu_header_ti, " (%u subheaders)",
1531                            number_of_headers);
1532
1533     /* And set its length to offset */
1534     proto_item_set_len(pdu_header_ti, offset);
1535
1536
1537
1538
1539     /************************************************************************/
1540     /* Dissect SDUs / control elements / padding.                           */
1541     /************************************************************************/
1542
1543     /* Dissect control element bodies first */
1544
1545     for (n=0; n < number_of_headers; n++) {
1546         /* Get out of loop once see any data SDU subheaders */
1547         if (lcids[n] <= 10) {
1548             break;
1549         }
1550
1551         /* Process what should be a valid control PDU type */
1552         if (direction == DIRECTION_DOWNLINK) {
1553
1554             /****************************/
1555             /* DL-SCH Control PDUs      */
1556             switch (lcids[n]) {
1557                 case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
1558                     {
1559                         proto_item *cr_ti;
1560                         proto_tree *cr_tree;
1561                         proto_item *ti;
1562                         ContentionResolutionResult *crResult;
1563
1564                         /* Create CR root */
1565                         cr_ti = proto_tree_add_string_format(tree,
1566                                                              hf_mac_lte_control_ue_contention_resolution,
1567                                                              tvb, offset, 6,
1568                                                              "",
1569                                                              "Contention Resolution");
1570                         cr_tree = proto_item_add_subtree(cr_ti, ett_mac_lte_contention_resolution);
1571
1572
1573                         proto_tree_add_item(cr_tree, hf_mac_lte_control_ue_contention_resolution_identity,
1574                                             tvb, offset, 6, FALSE);
1575
1576                         /* Get pointer to result struct for this frame */
1577                         crResult =  g_hash_table_lookup(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
1578                         if (crResult == NULL) {
1579
1580                             /* Need to set result by looking for and comparing with Msg3 */
1581                             Msg3Data *msg3Data;
1582                             guint msg3Key = p_mac_lte_info->rnti;
1583
1584                             /* Allocate result and add it to the table */
1585                             crResult = se_alloc(sizeof(ContentionResolutionResult));
1586                             g_hash_table_insert(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->fd->num), crResult);
1587
1588                             /* Look for Msg3 */
1589                             msg3Data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(msg3Key));
1590
1591                             /* Compare CCCH bytes */
1592                             if (msg3Data != NULL) {
1593                                 crResult->msg3FrameNum = msg3Data->framenum;
1594                                 if (memcmp(&msg3Data->data, tvb_get_ptr(tvb, offset, 6), 6) == 0) {
1595                                     crResult->status = Msg3Match;
1596                                 }
1597                                 else {
1598                                     crResult->status = Msg3NoMatch;
1599                                 }
1600                             }
1601                             else {
1602                                 crResult->status = NoMsg3;
1603                             }
1604                         }
1605
1606                         /* Now show CR result in tree */
1607                         switch (crResult->status) {
1608                             case NoMsg3:
1609                                 proto_item_append_text(cr_ti, " (no corresponding Msg3 found!)");
1610                                 break;
1611
1612                             case Msg3Match:
1613                                 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
1614                                                          tvb, 0, 0, crResult->msg3FrameNum);
1615                                 PROTO_ITEM_SET_GENERATED(ti);
1616                                 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
1617                                                             tvb, 0, 0, TRUE);
1618                                 PROTO_ITEM_SET_GENERATED(ti);
1619                                 proto_item_append_text(cr_ti, " (matches Msg3 from frame %u)", crResult->msg3FrameNum);
1620                                 break;
1621
1622                             case Msg3NoMatch:
1623                                 ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
1624                                                          tvb, 0, 0, crResult->msg3FrameNum);
1625                                 PROTO_ITEM_SET_GENERATED(ti);
1626                                 ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
1627                                                              tvb, 0, 0, FALSE);
1628                                 expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1629                                                        "CR body in Msg4 doesn't match Msg3 CCCH in frame %u",
1630                                                        crResult->msg3FrameNum);
1631                                 PROTO_ITEM_SET_GENERATED(ti);
1632                                 proto_item_append_text(cr_ti, " (doesn't match Msg3 from frame %u)", crResult->msg3FrameNum);
1633                                 break;
1634                         };
1635
1636                         offset += 6;
1637                     }
1638                     break;
1639                 case TIMING_ADVANCE_LCID:
1640                     {
1641                         proto_item *ta_ti;
1642                         proto_item *reserved_ti;
1643                         guint8      reserved;
1644                         guint8      ta_value;
1645
1646                         /* Check 2 reserved bits */
1647                         reserved = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
1648                         reserved_ti = proto_tree_add_item(tree, hf_mac_lte_control_timing_advance_reserved, tvb, offset, 1, FALSE);
1649                         if (reserved != 0) {
1650                             expert_add_info_format(pinfo, reserved_ti, PI_MALFORMED, PI_ERROR,
1651                                                    "Timing Advance Reserved bits not zero (found 0x%x)", reserved);
1652                         }
1653
1654                         /* TA value */
1655                         ta_value = tvb_get_guint8(tvb, offset) & 0x3f;
1656                         ta_ti = proto_tree_add_item(tree, hf_mac_lte_control_timing_advance,
1657                                                     tvb, offset, 1, FALSE);
1658                         expert_add_info_format(pinfo, ta_ti, PI_SEQUENCE, PI_WARN,
1659                                                "Timing Advance control element received (%u)",
1660                                                ta_value);
1661                         offset++;
1662                     }
1663                     break;
1664                 case DRX_COMMAND_LCID:
1665                     /* No payload */
1666                     break;
1667                 case PADDING_LCID:
1668                     /* No payload (in this position) */
1669                     break;
1670
1671                 default:
1672                     break;
1673             }
1674         }
1675         else {
1676
1677             /**********************************/
1678             /* UL-SCH Control PDUs            */
1679             switch (lcids[n]) {
1680                 case POWER_HEADROOM_REPORT_LCID:
1681                     {
1682                         proto_item *phr_ti;
1683                         proto_tree *phr_tree;
1684                         proto_item *ti;
1685                         guint8 reserved;
1686                         guint8 level;
1687
1688                         /* Create PHR root */
1689                         phr_ti = proto_tree_add_string_format(tree,
1690                                                               hf_mac_lte_control_power_headroom,
1691                                                               tvb, offset, 1,
1692                                                               "",
1693                                                               "Power Headroom");
1694                         phr_tree = proto_item_add_subtree(phr_ti, ett_mac_lte_power_headroom);
1695
1696                         /* Check 2 Reserved bits */
1697                         reserved = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
1698                         ti = proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_reserved,
1699                                                  tvb, offset, 1, FALSE);
1700                         if (reserved != 0) {
1701                             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1702                                                    "Power Headroom Reserved bits not zero (found 0x%x)", reserved);
1703                         }
1704
1705                         /* Level */
1706                         level = tvb_get_guint8(tvb, offset) & 0x3f;
1707                         proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_level,
1708                                             tvb, offset, 1, FALSE);
1709
1710                         /* Show value in root label */
1711                         proto_item_append_text(phr_ti, " (POWER_HEADROOM_%u)", level);
1712                         offset++;
1713                     }
1714
1715
1716                     break;
1717                 case CRNTI_LCID:
1718                     proto_tree_add_item(tree, hf_mac_lte_control_crnti,
1719                                         tvb, offset, 2, FALSE);
1720                     offset += 2;
1721                     break;
1722                 case TRUNCATED_BSR_LCID:
1723                 case SHORT_BSR_LCID:
1724                     {
1725                         proto_tree *bsr_tree;
1726                         proto_item *bsr_ti;
1727                         proto_item *buffer_size_ti;
1728                         guint8 lcgid;
1729                         guint8 buffer_size;
1730
1731                         bsr_ti = proto_tree_add_string_format(tree,
1732                                                               hf_mac_lte_control_bsr,
1733                                                               tvb, offset, 1,
1734                                                               "",
1735                                                               "Short BSR");
1736                         bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
1737
1738                         /* LCG ID */
1739                         lcgid = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
1740                         proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_lcg_id,
1741                                                     tvb, offset, 1, FALSE);
1742                         /* Buffer Size */
1743                         buffer_size = tvb_get_guint8(tvb, offset) & 0x3f;
1744                         buffer_size_ti = proto_tree_add_item(bsr_tree, hf_mac_lte_control_short_bsr_buffer_size,
1745                                                              tvb, offset, 1, FALSE);
1746                         offset++;
1747                         if (buffer_size >= global_mac_lte_bsr_warn_threshold) {
1748                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
1749                                                    "UE %u - BSR for LCG %u exceeds threshold: %u (%s)",
1750                                                    p_mac_lte_info->ueid,
1751                                                    lcgid,
1752                                                    buffer_size, val_to_str(buffer_size, buffer_size_vals, "Unknown"));
1753                         }
1754
1755
1756                         proto_item_append_text(bsr_ti, " (lcgid=%u  %s)",
1757                                                lcgid,
1758                                                val_to_str(buffer_size, buffer_size_vals, "Unknown"));
1759                     }
1760                     break;
1761                 case LONG_BSR_LCID:
1762                     {
1763                         proto_tree *bsr_tree;
1764                         proto_item *bsr_ti;
1765                         proto_item *buffer_size_ti;
1766                         guint8     buffer_size[4];
1767                         bsr_ti = proto_tree_add_string_format(tree,
1768                                                               hf_mac_lte_control_bsr,
1769                                                               tvb, offset, 3,
1770                                                               "",
1771                                                               "Long BSR");
1772                         bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
1773
1774                         /* LCID Group 0 */
1775                         buffer_size_ti = proto_tree_add_item(bsr_tree, hf_mac_lte_control_long_bsr_buffer_size_0,
1776                                                              tvb, offset, 1, FALSE);
1777                         buffer_size[0] = (tvb_get_guint8(tvb, offset) & 0xfc) >> 2;
1778                         if (buffer_size[0] >= global_mac_lte_bsr_warn_threshold) {
1779                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
1780                                                    "UE %u - BSR for LCG 0 exceeds threshold: %u (%s)",
1781                                                    p_mac_lte_info->ueid,
1782                                                    buffer_size[0], val_to_str(buffer_size[0], buffer_size_vals, "Unknown"));
1783                         }
1784
1785                         /* LCID Group 1 */
1786                         buffer_size_ti = proto_tree_add_item(bsr_tree, hf_mac_lte_control_long_bsr_buffer_size_1,
1787                                                              tvb, offset, 2, FALSE);
1788                         buffer_size[1] = ((tvb_get_guint8(tvb, offset) & 0x03) << 4) | ((tvb_get_guint8(tvb, offset+1) & 0xf0) >> 4);
1789                         offset++;
1790                         if (buffer_size[1] >= global_mac_lte_bsr_warn_threshold) {
1791                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
1792                                                    "UE %u - BSR for LCG 1 exceeds threshold: %u (%s)",
1793                                                    p_mac_lte_info->ueid,
1794                                                    buffer_size[1], val_to_str(buffer_size[1], buffer_size_vals, "Unknown"));
1795                         }
1796
1797                         /* LCID Group 2 */
1798                         buffer_size_ti = proto_tree_add_item(bsr_tree, hf_mac_lte_control_long_bsr_buffer_size_2,
1799                                                              tvb, offset, 2, FALSE);
1800
1801                         buffer_size[2] = ((tvb_get_guint8(tvb, offset) & 0x0f) << 2) | ((tvb_get_guint8(tvb, offset+1) & 0xc0) >> 6);
1802                         offset++;
1803                         if (buffer_size[2] >= global_mac_lte_bsr_warn_threshold) {
1804                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
1805                                                    "UE %u - BSR for LCG 2 exceeds threshold: %u (%s)",
1806                                                    p_mac_lte_info->ueid,
1807                                                    buffer_size[2], val_to_str(buffer_size[2], buffer_size_vals, "Unknown"));
1808                         }
1809
1810                         /* LCID Group 3 */
1811                         buffer_size_ti = proto_tree_add_item(bsr_tree, hf_mac_lte_control_long_bsr_buffer_size_3,
1812                                                              tvb, offset, 1, FALSE);
1813                         buffer_size[3] = tvb_get_guint8(tvb, offset) & 0x3f;
1814                         offset++;
1815                         if (buffer_size[3] >= global_mac_lte_bsr_warn_threshold) {
1816                             expert_add_info_format(pinfo, buffer_size_ti, PI_SEQUENCE, PI_WARN,
1817                                                    "UE %u - BSR for LCG 3 exceeds threshold: %u (%s)",
1818                                                    p_mac_lte_info->ueid,
1819                                                    buffer_size[3], val_to_str(buffer_size[3], buffer_size_vals, "Unknown"));
1820                         }
1821
1822                         /* Append summary to parent */
1823                         proto_item_append_text(bsr_ti, "   0:(%s)  1:(%s)  2:(%s)  3:(%s)",
1824                                                val_to_str(buffer_size[0], buffer_size_vals, "Unknown"),
1825                                                val_to_str(buffer_size[1], buffer_size_vals, "Unknown"),
1826                                                val_to_str(buffer_size[2], buffer_size_vals, "Unknown"),
1827                                                val_to_str(buffer_size[3], buffer_size_vals, "Unknown"));
1828                     }
1829                     break;
1830                 case PADDING_LCID:
1831                     /* No payload, in this position */
1832                     break;
1833
1834                 default:
1835                     break;
1836             }
1837         }
1838     }
1839
1840
1841     /* There might not be any data, if only headers (plus control data) were logged */
1842     is_truncated = ((tvb_length_remaining(tvb, offset) == 0) && expecting_body_data);
1843     truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_sch_header_only, tvb, 0, 0,
1844                                        is_truncated);
1845     if (is_truncated) {
1846         PROTO_ITEM_SET_GENERATED(truncated_ti);
1847         expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
1848                                "MAC PDU SDUs have been ommitted");
1849         return;
1850     }
1851     else {
1852         PROTO_ITEM_SET_HIDDEN(truncated_ti);
1853     }
1854
1855
1856     /* Now process remaining bodies, which should all be data */
1857     for (; n < number_of_headers; n++) {
1858
1859         /* Data SDUs treated identically for Uplink or downlink channels */
1860         proto_item *sdu_ti;
1861         volatile guint16 data_length;
1862
1863         /* Break out if meet padding */
1864         if (lcids[n] == PADDING_LCID) {
1865             break;
1866         }
1867
1868         /* Work out length */
1869         data_length = (pdu_lengths[n] == -1) ?
1870                             tvb_length_remaining(tvb, offset) :
1871                             pdu_lengths[n];
1872
1873         /* Dissect SDU as raw bytes */
1874         sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_sch_sdu, tvb, offset, pdu_lengths[n],
1875                                              tvb_get_ptr(tvb, offset, pdu_lengths[n]),
1876                                              "SDU (%s, length=%u bytes)",
1877                                              val_to_str(lcids[n],
1878                                                         (direction == DIRECTION_UPLINK) ?
1879                                                             ulsch_lcid_vals :
1880                                                             dlsch_lcid_vals,
1881                                                         "Unknown"),
1882                                              data_length);
1883
1884         /* Look for Msg3 data so that it may be compared with later
1885            Contention Resolution body */
1886         if ((lcids[n] == 0) && (direction == DIRECTION_UPLINK) && (data_length == 6)) {
1887             if (!pinfo->fd->flags.visited) {
1888                 guint key = p_mac_lte_info->rnti;
1889                 Msg3Data *data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(key));
1890
1891                 /* Look for previous entry for this UE */
1892                 if (data == NULL) {
1893                     /* Allocate space for data and add to table */
1894                     data = se_alloc(sizeof(Msg3Data));
1895                     g_hash_table_insert(mac_lte_msg3_hash, GUINT_TO_POINTER(key), data);
1896                 }
1897
1898                 /* Fill in data details */
1899                 data->framenum = pinfo->fd->num;
1900                 memcpy(&data->data, tvb_get_ptr(tvb, offset, data_length), data_length);
1901             }
1902         }
1903
1904         /* CCCH frames can be dissected directly by LTE RRC... */
1905         if ((lcids[n] == 0) && global_mac_lte_attempt_rrc_decode) {
1906             tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, data_length, data_length);
1907
1908             /* Get appropriate dissector handle */
1909             volatile dissector_handle_t protocol_handle = 0;
1910             if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
1911                 protocol_handle = find_dissector("lte-rrc.ul.ccch");
1912             }
1913             else {
1914                 protocol_handle = find_dissector("lte-rrc.dl.ccch");
1915             }
1916
1917             /* Hide raw view of bytes */
1918             PROTO_ITEM_SET_HIDDEN(sdu_ti);
1919
1920             /* Call it (catch exceptions so that stats will be updated) */
1921             TRY {
1922                 call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
1923             }
1924             CATCH_ALL {
1925             }
1926             ENDTRY
1927         }
1928
1929         /* LCID 1 and 2 can be assumed to be srb1&2, so can dissect as RLC AM */
1930         if ((lcids[n] == 1) || (lcids[n] == 2)) {
1931             if (global_mac_lte_attempt_srb_decode) {
1932                 /* Call RLC dissector */
1933                 call_rlc_dissector(tvb, pinfo, tree, offset, data_length,
1934                                    RLC_AM_MODE, direction, p_mac_lte_info->ueid,
1935                                    CHANNEL_TYPE_SRB, lcids[n], 0);
1936
1937                 /* Hide raw view of bytes */
1938                 PROTO_ITEM_SET_HIDDEN(sdu_ti);
1939             }
1940         }
1941
1942         else if ((lcids[n] >= 2) && (lcids[n] <= 10)) {
1943
1944             /* Look for mapping for this LCID to drb channel set by UAT table */
1945             rlc_channel_type_t rlc_channel_type = rlcRaw;
1946             guint8 UM_seqnum_length = 0;
1947             gint drb_id = 0;
1948
1949             guint m;
1950             for (m=0; m < num_lcid_drb_mappings; m++) {
1951                 if (lcids[n] == lcid_drb_mappings[m].lcid) {
1952
1953                     rlc_channel_type = lcid_drb_mappings[m].channel_type;
1954
1955                     /* Set UM_seqnum_length */
1956                     switch (lcid_drb_mappings[m].channel_type) {
1957                         case rlcUM5:
1958                             UM_seqnum_length = 5;
1959                             break;
1960                         case rlcUM10:
1961                             UM_seqnum_length = 10;
1962                             break;
1963                         default:
1964                             break;
1965                     }
1966
1967                     /* Set drb_id */
1968                     drb_id = lcid_drb_mappings[m].drbid;
1969                     break;
1970                 }
1971             }
1972
1973             /* Dissect according to channel type */
1974             switch (rlc_channel_type) {
1975                 case rlcUM5:
1976                     call_rlc_dissector(tvb, pinfo, tree, offset, data_length,
1977                                        RLC_UM_MODE, direction, p_mac_lte_info->ueid,
1978                                        CHANNEL_TYPE_DRB, (guint16)drb_id, UM_seqnum_length);
1979                     break;
1980                 case rlcUM10:
1981                     call_rlc_dissector(tvb, pinfo, tree, offset, data_length,
1982                                        RLC_UM_MODE, direction, p_mac_lte_info->ueid,
1983                                        CHANNEL_TYPE_DRB, (guint16)drb_id, UM_seqnum_length);
1984                     break;
1985                 case rlcAM:
1986                     call_rlc_dissector(tvb, pinfo, tree, offset, data_length,
1987                                        RLC_AM_MODE, direction, p_mac_lte_info->ueid,
1988                                        CHANNEL_TYPE_DRB, (guint16)drb_id, 0);
1989                     break;
1990                 case rlcTM:
1991                     call_rlc_dissector(tvb, pinfo, tree, offset, data_length,
1992                                        RLC_TM_MODE, direction, p_mac_lte_info->ueid,
1993                                        CHANNEL_TYPE_DRB, (guint16)drb_id, 0);
1994                     break;
1995                 case rlcRaw:
1996                     /* Nothing to do! */
1997                     break;
1998             }
1999
2000             if (rlc_channel_type != rlcRaw) {
2001                 /* Hide raw view of bytes */
2002                 PROTO_ITEM_SET_HIDDEN(sdu_ti);
2003             }
2004
2005         }
2006
2007         offset += data_length;
2008
2009         /* Update tap byte count for this channel */
2010         tap_info->bytes_for_lcid[lcids[n]] += data_length;
2011         tap_info->sdus_for_lcid[lcids[n]]++;
2012     }
2013
2014     /* Now padding, if present, extends to the end of the PDU */
2015     if (lcids[number_of_headers-1] == PADDING_LCID) {
2016         if (tvb_length_remaining(tvb, offset) > 0) {
2017             proto_tree_add_item(tree, hf_mac_lte_padding_data,
2018                                 tvb, offset, -1, FALSE);
2019         }
2020         padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
2021                                                tvb, offset, 0,
2022                                                p_mac_lte_info->length - offset);
2023         PROTO_ITEM_SET_GENERATED(padding_length_ti);
2024
2025         /* Make sure the PDU isn't bigger than reported! */
2026         if (offset > p_mac_lte_info->length) {
2027             expert_add_info_format(pinfo, padding_length_ti, PI_MALFORMED, PI_ERROR,
2028                                    "MAC PDU is longer than reported length (reported=%u, actual=%u)",
2029                                    p_mac_lte_info->length, offset);
2030         }
2031     }
2032     else {
2033         /* There is no padding at the end of the frame */
2034         if (!is_truncated && (offset < p_mac_lte_info->length)) {
2035             /* There is a problem if we haven't used all of the PDU */
2036             expert_add_info_format(pinfo, pdu_ti, PI_MALFORMED, PI_ERROR,
2037                                    "MAC PDU is shorter than reported length (reported=%u, actual=%u)",
2038                                    p_mac_lte_info->length, offset);
2039         }
2040     }
2041
2042 }
2043
2044
2045
2046 /*****************************/
2047 /* Main dissection function. */
2048 void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2049 {
2050     proto_tree             *mac_lte_tree;
2051     proto_item             *pdu_ti;
2052     proto_item             *retx_ti = NULL;
2053     proto_item             *ti;
2054     gint                   offset = 0;
2055     struct mac_lte_info    *p_mac_lte_info = NULL;
2056
2057     /* Zero out tap */
2058     static mac_lte_tap_info tap_info;
2059     memset(&tap_info, 0, sizeof(mac_lte_tap_info));
2060
2061     /* Set protocol name */
2062     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
2063
2064     /* Create protocol tree. */
2065     pdu_ti = proto_tree_add_item(tree, proto_mac_lte, tvb, offset, -1, FALSE);
2066     mac_lte_tree = proto_item_add_subtree(pdu_ti, ett_mac_lte);
2067
2068
2069     /* Look for packet info! */
2070     p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte);
2071
2072     /* Can't dissect anything without it... */
2073     if (p_mac_lte_info == NULL) {
2074         proto_item *ti =
2075             proto_tree_add_text(mac_lte_tree, tvb, offset, -1,
2076                                 "Can't dissect LTE MAC frame because no per-frame info was attached!");
2077         PROTO_ITEM_SET_GENERATED(ti);
2078         return;
2079     }
2080
2081     /* Clear info column */
2082     col_clear(pinfo->cinfo, COL_INFO);
2083
2084
2085     /*****************************************/
2086     /* Show context information              */
2087
2088     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_radio_type,
2089                              tvb, 0, 0, p_mac_lte_info->radioType);
2090     PROTO_ITEM_SET_GENERATED(ti);
2091
2092     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_direction,
2093                              tvb, 0, 0, p_mac_lte_info->direction);
2094     PROTO_ITEM_SET_GENERATED(ti);
2095
2096     if (p_mac_lte_info->ueid != 0) {
2097         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_ueid,
2098                                  tvb, 0, 0, p_mac_lte_info->ueid);
2099         PROTO_ITEM_SET_GENERATED(ti);
2100     }
2101
2102     /* There are several out-of-band MAC events that may be indicated in the context info. */
2103     /* Handle them here */
2104     if (p_mac_lte_info->length == 0) {
2105         switch (p_mac_lte_info->oob_event) {
2106             case ltemac_send_preamble:
2107                 ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rapid,
2108                                          tvb, 0, 0, p_mac_lte_info->rapid);
2109                 PROTO_ITEM_SET_GENERATED(ti);
2110                 ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rach_attempt_number,
2111                                          tvb, 0, 0, p_mac_lte_info->rach_attempt_number);
2112                 PROTO_ITEM_SET_GENERATED(ti);
2113                 ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_send_preamble,
2114                                          tvb, 0, 0, FALSE);
2115                 PROTO_ITEM_SET_GENERATED(ti);
2116
2117                 /* Info column */
2118                 col_append_fstr(pinfo->cinfo, COL_INFO, "RACH Preamble sent for UE %u (RAPID=%u, attempt=%u)",
2119                                 p_mac_lte_info->ueid, p_mac_lte_info->rapid, p_mac_lte_info->rach_attempt_number);
2120
2121                 /* Add expert info (a note, unless attempt > 1) */
2122                 expert_add_info_format(pinfo, ti, PI_SEQUENCE,
2123                                        (p_mac_lte_info->rach_attempt_number > 1) ? PI_WARN : PI_NOTE,
2124                                        "RACH Preamble sent for UE %u (RAPID=%u, attempt=%u)",
2125                                        p_mac_lte_info->ueid, p_mac_lte_info->rapid,
2126                                        p_mac_lte_info->rach_attempt_number);
2127                 break;
2128             case ltemac_send_sr:
2129                 ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rnti,
2130                                          tvb, 0, 0, p_mac_lte_info->rnti);
2131                 PROTO_ITEM_SET_GENERATED(ti);
2132                 ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_send_sr,
2133                                          tvb, 0, 0, FALSE);
2134                 PROTO_ITEM_SET_GENERATED(ti);
2135
2136                 /* Info column */
2137                 col_append_fstr(pinfo->cinfo, COL_INFO, "Scheduling Request sent for UE %u (C-RNTI=%u)",
2138                                 p_mac_lte_info->ueid, p_mac_lte_info->rnti);
2139
2140                 /* Add expert info (an note) */
2141                 expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_NOTE,
2142                                        "Scheduling Request send for UE %u (RNTI %u)",
2143                                        p_mac_lte_info->ueid, p_mac_lte_info->rnti);
2144                 break;
2145             case ltemac_sr_failure:
2146                 ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rnti,
2147                                          tvb, 0, 0, p_mac_lte_info->rnti);
2148                 PROTO_ITEM_SET_GENERATED(ti);
2149                 ti = proto_tree_add_item(mac_lte_tree, hf_mac_lte_oob_sr_failure,
2150                                          tvb, 0, 0, FALSE);
2151                 PROTO_ITEM_SET_GENERATED(ti);
2152
2153                 /* Info column */
2154                 col_append_fstr(pinfo->cinfo, COL_INFO, "Scheduling Request FAILED (C-RNTI=%u)!",
2155                                 p_mac_lte_info->rnti);
2156
2157                 /* Add expert info (an error) */
2158                 expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_ERROR,
2159                                        "Scheduling Request failed for RNTI %u",
2160                                        p_mac_lte_info->rnti);
2161                 break;
2162         }
2163
2164         /* Our work here is done */
2165         return;
2166     }
2167
2168
2169     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_subframe_number,
2170                              tvb, 0, 0, p_mac_lte_info->subframeNumber);
2171     PROTO_ITEM_SET_GENERATED(ti);
2172
2173     if (p_mac_lte_info->rntiType != NO_RNTI) {
2174         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rnti,
2175                                  tvb, 0, 0, p_mac_lte_info->rnti);
2176         PROTO_ITEM_SET_GENERATED(ti);
2177     }
2178
2179     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rnti_type,
2180                              tvb, 0, 0, p_mac_lte_info->rntiType);
2181     PROTO_ITEM_SET_GENERATED(ti);
2182
2183     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_predefined_frame,
2184                              tvb, 0, 0, p_mac_lte_info->isPredefinedData);
2185     if (p_mac_lte_info->isPredefinedData) {
2186         PROTO_ITEM_SET_GENERATED(ti);
2187     }
2188     else {
2189         PROTO_ITEM_SET_HIDDEN(ti);
2190     }
2191
2192     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_length,
2193                              tvb, 0, 0, p_mac_lte_info->length);
2194     PROTO_ITEM_SET_GENERATED(ti);
2195     /* Infer uplink grant size */
2196     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
2197         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_ul_grant_size,
2198                                  tvb, 0, 0, p_mac_lte_info->length);
2199         PROTO_ITEM_SET_GENERATED(ti);
2200     }
2201
2202
2203     if (p_mac_lte_info->reTxCount) {
2204         retx_ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_count,
2205                                  tvb, 0, 0, p_mac_lte_info->reTxCount);
2206         PROTO_ITEM_SET_GENERATED(retx_ti);
2207
2208         if (p_mac_lte_info->reTxCount >= global_mac_lte_retx_counter_trigger) {
2209             expert_add_info_format(pinfo, retx_ti, PI_SEQUENCE, PI_ERROR,
2210                                    "UE %u: UL MAC frame ReTX no. %u",
2211                                    p_mac_lte_info->ueid, p_mac_lte_info->reTxCount);
2212         }
2213     }
2214
2215     if (p_mac_lte_info->crcStatusValid) {
2216         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_crc_status,
2217                                  tvb, 0, 0, p_mac_lte_info->crcStatus);
2218         PROTO_ITEM_SET_GENERATED(ti);
2219         if (p_mac_lte_info->crcStatus != TRUE) {
2220             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
2221                                    "%s Frame has CRC error",
2222                                    (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL");
2223             col_append_fstr(pinfo->cinfo, COL_INFO, "%s: <CRC FAILURE> UEId=%u %s=%u ",
2224                             (p_mac_lte_info->direction == DIRECTION_UPLINK) ? "UL" : "DL",
2225                             p_mac_lte_info->ueid,
2226                             val_to_str(p_mac_lte_info->rntiType, rnti_type_vals,
2227                                        "Unknown RNTI type"),
2228                             p_mac_lte_info->rnti);
2229         }
2230     }
2231
2232
2233     /* Set context-info parts of tap struct */
2234     tap_info.rnti = p_mac_lte_info->rnti;
2235     tap_info.rntiType = p_mac_lte_info->rntiType;
2236     tap_info.isPredefinedData = p_mac_lte_info->isPredefinedData;
2237     tap_info.reTxCount = p_mac_lte_info->reTxCount;
2238     tap_info.crcStatusValid = p_mac_lte_info->crcStatusValid;
2239     tap_info.crcStatus = p_mac_lte_info->crcStatus;
2240     tap_info.direction = p_mac_lte_info->direction;
2241
2242     /* Also set total number of bytes (won't be used for UL/DL-SCH) */
2243     tap_info.single_number_of_bytes = tvb_length_remaining(tvb, offset);
2244
2245     /* If we know its predefined data, don't try to decode any further */
2246     if (p_mac_lte_info->isPredefinedData) {
2247         proto_tree_add_item(mac_lte_tree, hf_mac_lte_predefined_pdu, tvb, offset, -1, FALSE);
2248         col_append_fstr(pinfo->cinfo, COL_INFO, "Predefined data (%u bytes)", tvb_length_remaining(tvb, offset));
2249
2250         /* Queue tap info */
2251         if (!pinfo->in_error_pkt) {
2252             tap_queue_packet(mac_lte_tap, pinfo, &tap_info);
2253         }
2254
2255         return;
2256     }
2257
2258     /* IF CRC status failed, just do decode as raw bytes */
2259     if (!global_mac_lte_dissect_crc_failures &&
2260         (p_mac_lte_info->crcStatusValid && !p_mac_lte_info->crcStatus)) {
2261
2262         proto_tree_add_item(mac_lte_tree, hf_mac_lte_raw_pdu, tvb, offset, -1, FALSE);
2263         col_append_fstr(pinfo->cinfo, COL_INFO, "Raw data (%u bytes)", tvb_length_remaining(tvb, offset));
2264
2265         /* Queue tap info */
2266         if (!pinfo->in_error_pkt) {
2267             tap_queue_packet(mac_lte_tap, pinfo, &tap_info);
2268         }
2269
2270         return;
2271     }
2272
2273
2274
2275     /* Dissect the MAC PDU itself. Format depends upon RNTI type. */
2276     switch (p_mac_lte_info->rntiType) {
2277
2278         case P_RNTI:
2279             /* PCH PDU */
2280             dissect_pch(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info->direction);
2281             break;
2282
2283         case RA_RNTI:
2284             /* RAR PDU */
2285             dissect_rar(tvb, pinfo, mac_lte_tree, pdu_ti, offset, p_mac_lte_info, &tap_info);
2286             break;
2287
2288         case C_RNTI:
2289         case SPS_RNTI:
2290             /* Can be UL-SCH or DL-SCH */
2291             dissect_ulsch_or_dlsch(tvb, pinfo, mac_lte_tree, pdu_ti, offset,
2292                                    p_mac_lte_info->direction, p_mac_lte_info, &tap_info,
2293                                    retx_ti);
2294             break;
2295
2296         case SI_RNTI:
2297             /* BCH over DL-SCH */
2298             dissect_bch(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info);
2299             break;
2300
2301         case NO_RNTI:
2302             /* Must be BCH over BCH... */
2303             dissect_bch(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info);
2304             break;
2305
2306
2307         default:
2308             break;
2309     }
2310
2311     /* Queue tap info */
2312     /* TODO: if any of above (esp RRC dissection) throws exception, this isn't reached,
2313        but if call too early, won't have details... */
2314     tap_queue_packet(mac_lte_tap, pinfo, &tap_info);
2315 }
2316
2317
2318
2319
2320 /* Initializes the hash table and the mem_chunk area each time a new
2321  * file is loaded or re-loaded in wireshark */
2322 static void
2323 mac_lte_init_protocol(void)
2324 {
2325     /* Destroy any existing tables. */
2326     if (mac_lte_msg3_hash) {
2327         g_hash_table_destroy(mac_lte_msg3_hash);
2328     }
2329     if (mac_lte_cr_result_hash) {
2330         g_hash_table_destroy(mac_lte_cr_result_hash);
2331     }
2332
2333     if (mac_lte_dl_harq_hash) {
2334         g_hash_table_destroy(mac_lte_dl_harq_hash);
2335     }
2336     if (mac_lte_dl_harq_result_hash) {
2337         g_hash_table_destroy(mac_lte_dl_harq_result_hash);
2338     }
2339     if (mac_lte_ul_harq_hash) {
2340         g_hash_table_destroy(mac_lte_ul_harq_hash);
2341     }
2342     if (mac_lte_ul_harq_result_hash) {
2343         g_hash_table_destroy(mac_lte_ul_harq_result_hash);
2344     }
2345
2346
2347
2348     /* Now create them over */
2349     mac_lte_msg3_hash = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
2350     mac_lte_cr_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
2351
2352     mac_lte_dl_harq_hash = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
2353     mac_lte_dl_harq_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
2354
2355     mac_lte_ul_harq_hash = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
2356     mac_lte_ul_harq_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
2357 }
2358
2359
2360 static void* lcid_drb_mapping_copy_cb(void* dest, const void* orig, unsigned len _U_) 
2361 {
2362     const lcid_drb_mapping_t *o = orig;
2363     lcid_drb_mapping_t *d = dest;
2364
2365     /* Copy all items over */
2366     d->lcid = o->lcid;
2367     d->drbid = o->drbid;
2368     d->channel_type = o->channel_type;
2369
2370     return d;
2371 }
2372
2373
2374
2375 void proto_register_mac_lte(void)
2376 {
2377     static hf_register_info hf[] =
2378     {
2379         /**********************************/
2380         /* Items for decoding context     */
2381         { &hf_mac_lte_context_radio_type,
2382             { "Radio Type",
2383               "mac-lte.radio-type", FT_UINT8, BASE_DEC, VALS(radio_type_vals), 0x0,
2384               NULL, HFILL
2385             }
2386         },
2387         { &hf_mac_lte_context_direction,
2388             { "Direction",
2389               "mac-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
2390               "Direction of message", HFILL
2391             }
2392         },
2393         { &hf_mac_lte_context_rnti,
2394             { "RNTI",
2395               "mac-lte.rnti", FT_UINT16, BASE_DEC, 0, 0x0,
2396               "RNTI associated with message", HFILL
2397             }
2398         },
2399         { &hf_mac_lte_context_rnti_type,
2400             { "RNTI Type",
2401               "mac-lte.rnti-type", FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0,
2402               "Type of RNTI associated with message", HFILL
2403             }
2404         },
2405         { &hf_mac_lte_context_ueid,
2406             { "UEId",
2407               "mac-lte.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
2408               "User Equipment Identifier associated with message", HFILL
2409             }
2410         },
2411         { &hf_mac_lte_context_subframe_number,
2412             { "Subframe",
2413               "mac-lte.subframe", FT_UINT16, BASE_DEC, 0, 0x0,
2414               "Subframe number associate with message", HFILL
2415             }
2416         },
2417         { &hf_mac_lte_context_predefined_frame,
2418             { "Predefined frame",
2419               "mac-lte.is-predefined-frame", FT_UINT8, BASE_DEC, VALS(predefined_frame_vals), 0x0,
2420               "Predefined test frame (or real MAC PDU)", HFILL
2421             }
2422         },
2423         { &hf_mac_lte_context_length,
2424             { "Length of frame",
2425               "mac-lte.length", FT_UINT8, BASE_DEC, 0, 0x0,
2426               "Original length of frame (including SDUs and padding)", HFILL
2427             }
2428         },
2429         { &hf_mac_lte_context_ul_grant_size,
2430             { "Uplink grant size",
2431               "mac-lte.ul-grant-size", FT_UINT8, BASE_DEC, 0, 0x0,
2432               "Uplink grant size (in bytes)", HFILL
2433             }
2434         },
2435         { &hf_mac_lte_context_bch_transport_channel,
2436             { "Transport channel",
2437               "mac-lte.bch-transport-channel", FT_UINT8, BASE_DEC, VALS(bch_transport_channel_vals), 0x0,
2438               "Transport channel BCH data was carried on", HFILL
2439             }
2440         },
2441         { &hf_mac_lte_context_retx_count,
2442             { "ReTX count",
2443               "mac-lte.retx-count", FT_UINT8, BASE_DEC, 0, 0x0,
2444               "Number of times this PDU has been retransmitted", HFILL
2445             }
2446         },
2447         { &hf_mac_lte_context_crc_status,
2448             { "CRC Status",
2449               "mac-lte.crc-status", FT_UINT8, BASE_DEC, VALS(crc_status_vals), 0x0,
2450               "CRC Status as reported by PHY", HFILL
2451             }
2452         },
2453         { &hf_mac_lte_context_rapid,
2454             { "RAPID",
2455               "mac-lte.preamble-sent.rapid", FT_UINT8, BASE_DEC, 0, 0x0,
2456               "RAPID sent in RACH preamble", HFILL
2457             }
2458         },
2459         { &hf_mac_lte_context_rach_attempt_number,
2460             { "RACH Attempt Number",
2461               "mac-lte.preamble-sent.attempt", FT_UINT8, BASE_DEC, 0, 0x0,
2462               "RACH attempt number", HFILL
2463             }
2464         },
2465
2466         /* Out-of-band events */
2467         { &hf_mac_lte_oob_send_preamble,
2468             { "RACH Preamble sent",
2469               "mac-lte.preamble-sent", FT_NONE, BASE_NONE, NULL, 0x0,
2470               NULL, HFILL
2471             }
2472         },
2473         { &hf_mac_lte_oob_send_sr,
2474             { "Scheduling Request sent",
2475               "mac-lte.sr-req", FT_NONE, BASE_NONE, NULL, 0x0,
2476               NULL, HFILL
2477             }
2478         },
2479         { &hf_mac_lte_oob_sr_failure,
2480             { "Scheduling Request Failure",
2481               "mac-lte.sr-failure", FT_NONE, BASE_NONE, NULL, 0x0,
2482               NULL, HFILL
2483             }
2484         },
2485
2486         /*******************************************/
2487         /* MAC shared channel header fields        */
2488         { &hf_mac_lte_ulsch_header,
2489             { "UL-SCH Header",
2490               "mac-lte.ulsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
2491               NULL, HFILL
2492             }
2493         },
2494         { &hf_mac_lte_dlsch_header,
2495             { "DL-SCH Header",
2496               "mac-lte.dlsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
2497               NULL, HFILL
2498             }
2499         },
2500         { &hf_mac_lte_sch_subheader,
2501             { "SCH sub-header",
2502               "mac-lte.sch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
2503               NULL, HFILL
2504             }
2505         },
2506         { &hf_mac_lte_sch_reserved,
2507             { "SCH reserved bits",
2508               "mac-lte.sch.reserved", FT_UINT8, BASE_HEX, NULL, 0xc0,
2509               NULL, HFILL
2510             }
2511         },
2512         { &hf_mac_lte_sch_extended,
2513             { "Extension",
2514               "mac-lte.sch.extended", FT_UINT8, BASE_HEX, 0, 0x20,
2515               "Extension - i.e. further headers after this one", HFILL
2516             }
2517         },
2518         { &hf_mac_lte_dlsch_lcid,
2519             { "LCID",
2520               "mac-lte.dlsch.lcid", FT_UINT8, BASE_HEX, VALS(dlsch_lcid_vals), 0x1f,
2521               "DL-SCH Logical Channel Identifier", HFILL
2522             }
2523         },
2524         { &hf_mac_lte_ulsch_lcid,
2525             { "LCID",
2526               "mac-lte.ulsch.lcid", FT_UINT8, BASE_HEX, VALS(ulsch_lcid_vals), 0x1f,
2527               "UL-SCH Logical Channel Identifier", HFILL
2528             }
2529         },
2530         { &hf_mac_lte_sch_format,
2531             { "Format",
2532               "mac-lte.sch.format", FT_UINT8, BASE_HEX, VALS(format_vals), 0x80,
2533               NULL, HFILL
2534             }
2535         },
2536         { &hf_mac_lte_sch_length,
2537             { "Length",
2538               "mac-lte.sch.length", FT_UINT16, BASE_DEC, 0, 0x0,
2539               "Length of MAC SDU or MAC control element", HFILL
2540             }
2541         },
2542         { &hf_mac_lte_sch_header_only,
2543             { "MAC PDU Header only",
2544               "mac-lte.sch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
2545               NULL, HFILL
2546             }
2547         },
2548
2549         /********************************/
2550         /* Data                         */
2551         { &hf_mac_lte_sch_sdu,
2552             { "SDU",
2553               "mac-lte.sch.sdu", FT_BYTES, BASE_NONE, 0, 0x0,
2554               "Shared channel SDU", HFILL
2555             }
2556         },
2557         { &hf_mac_lte_bch_pdu,
2558             { "BCH PDU",
2559               "mac-lte.bch.pdu", FT_BYTES, BASE_NONE, 0, 0x0,
2560               NULL, HFILL
2561             }
2562         },
2563         { &hf_mac_lte_pch_pdu,
2564             { "PCH PDU",
2565               "mac-lte.pch.pdu", FT_BYTES, BASE_NONE, 0, 0x0,
2566               NULL, HFILL
2567             }
2568         },
2569         { &hf_mac_lte_predefined_pdu,
2570             { "Predefined data",
2571               "mac-lte.predefined-data", FT_BYTES, BASE_NONE, 0, 0x0,
2572               "Predefined test data", HFILL
2573             }
2574         },
2575         { &hf_mac_lte_raw_pdu,
2576             { "Raw data",
2577               "mac-lte.raw-data", FT_BYTES, BASE_NONE, 0, 0x0,
2578               "Raw bytes of PDU (e.g. if CRC failed)", HFILL
2579             }
2580         },
2581         { &hf_mac_lte_padding_data,
2582             { "Padding data",
2583               "mac-lte.padding-data", FT_BYTES, BASE_NONE, 0, 0x0,
2584               NULL, HFILL
2585             }
2586         },
2587         { &hf_mac_lte_padding_length,
2588             { "Padding length",
2589               "mac-lte.padding-length", FT_INT32, BASE_DEC, 0, 0x0,
2590               "Length of padding data not included at end of frame", HFILL
2591             }
2592         },
2593
2594
2595
2596         /*********************************/
2597         /* RAR fields                    */
2598         { &hf_mac_lte_rar,
2599             { "RAR",
2600               "mac-lte.rar", FT_NONE, BASE_NONE, NULL, 0x0,
2601               NULL, HFILL
2602             }
2603         },
2604         { &hf_mac_lte_rar_headers,
2605             { "RAR Headers",
2606               "mac-lte.rar.headers", FT_STRING, BASE_NONE, NULL, 0x0,
2607               NULL, HFILL
2608             }
2609         },
2610         { &hf_mac_lte_rar_header,
2611             { "RAR Header",
2612               "mac-lte.rar.header", FT_STRING, BASE_NONE, NULL, 0x0,
2613               NULL, HFILL
2614             }
2615         },
2616         { &hf_mac_lte_rar_extension,
2617             { "Extension",
2618               "mac-lte.rar.e", FT_UINT8, BASE_HEX, 0, 0x80,
2619               "Extension - i.e. further RAR headers after this one", HFILL
2620             }
2621         },
2622         { &hf_mac_lte_rar_t,
2623             { "Type",
2624               "mac-lte.rar.t", FT_UINT8, BASE_HEX, VALS(rar_type_vals), 0x40,
2625               "Type field indicating whether the payload is RAPID or BI", HFILL
2626             }
2627         },
2628         { &hf_mac_lte_rar_bi,
2629             { "BI",
2630               "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_vals), 0x0f,
2631               "Backoff Indicator (ms)", HFILL
2632             }
2633         },
2634         { &hf_mac_lte_rar_rapid,
2635             { "RAPID",
2636               "mac-lte.rar.rapid", FT_UINT8, BASE_HEX_DEC, 0, 0x3f,
2637               "Random Access Preamble IDentifier", HFILL
2638             }
2639         },
2640         { &hf_mac_lte_rar_reserved,
2641             { "Reserved",
2642               "mac-lte.rar.reserved", FT_UINT8, BASE_HEX, 0, 0x30,
2643               "Reserved bits in RAR header - should be 0", HFILL
2644             }
2645         },
2646
2647         { &hf_mac_lte_rar_body,
2648             { "RAR Body",
2649               "mac-lte.rar.body", FT_STRING, BASE_NONE, NULL, 0x0,
2650               NULL, HFILL
2651             }
2652         },
2653         { &hf_mac_lte_rar_reserved2,
2654             { "Reserved",
2655               "mac-lte.rar.reserved2", FT_UINT8, BASE_HEX, 0, 0x80,
2656               "Reserved bit in RAR body - should be 0", HFILL
2657             }
2658         },
2659         { &hf_mac_lte_rar_ta,
2660             { "Timing Advance",
2661               "mac-lte.rar.ta", FT_UINT16, BASE_DEC, 0, 0x7ff0,
2662               "Required adjustment to uplink transmission timing", HFILL
2663             }
2664         },
2665         { &hf_mac_lte_rar_ul_grant,
2666             { "UL Grant",
2667               "mac-lte.rar.ul-grant", FT_UINT24, BASE_DEC, 0, 0x0fffff,
2668               "Size of UL Grant", HFILL
2669             }
2670         },
2671         { &hf_mac_lte_rar_ul_grant_hopping,
2672             { "Hopping Flag",
2673               "mac-lte.rar.ul-grant.hopping", FT_UINT8, BASE_DEC, 0, 0x08,
2674               "Size of UL Grant", HFILL
2675             }
2676         },
2677         { &hf_mac_lte_rar_ul_grant_fsrba,
2678             { "Fixed sized resource block assignment",
2679               "mac-lte.rar.ul-grant.fsrba", FT_UINT16, BASE_DEC, 0, 0x07fe,
2680               NULL, HFILL
2681             }
2682         },
2683         { &hf_mac_lte_rar_ul_grant_tmcs,
2684             { "Truncated Modulation and coding scheme",
2685               "mac-lte.rar.ul-grant.tmcs", FT_UINT16, BASE_DEC, 0, 0x01e0,
2686               NULL, HFILL
2687             }
2688         },
2689         { &hf_mac_lte_rar_ul_grant_tcsp,
2690             { "TPC command for scheduled PUSCH",
2691               "mac-lte.rar.ul-grant.tcsp", FT_UINT8, BASE_DEC, 0, 0x01c,
2692               NULL, HFILL
2693             }
2694         },
2695         { &hf_mac_lte_rar_ul_grant_ul_delay,
2696             { "UL Delay",
2697               "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, 0, 0x02,
2698               NULL, HFILL
2699             }
2700         },
2701         { &hf_mac_lte_rar_ul_grant_cqi_request,
2702             { "CQI Request",
2703               "mac-lte.rar.ul-grant.cqi-request", FT_UINT8, BASE_DEC, 0, 0x01,
2704               NULL, HFILL
2705             }
2706         },
2707         { &hf_mac_lte_rar_temporary_crnti,
2708             { "Temporary C-RNTI",
2709               "mac-lte.rar.temporary-crnti", FT_UINT16, BASE_DEC, 0, 0x0,
2710               NULL, HFILL
2711             }
2712         },
2713
2714         /**********************/
2715         /* Control PDU fields */
2716         { &hf_mac_lte_control_bsr,
2717             { "BSR",
2718               "mac-lte.control.bsr", FT_STRING, BASE_NONE, 0, 0x0,
2719               "Buffer Status Report", HFILL
2720             }
2721         },
2722         { &hf_mac_lte_control_bsr_lcg_id,
2723             { "Logical Channel Group ID",
2724               "mac-lte.control.bsr.lcg-id", FT_UINT8, BASE_DEC, 0, 0xc0,
2725               NULL, HFILL
2726             }
2727         },
2728         { &hf_mac_lte_control_short_bsr_buffer_size,
2729             { "Buffer Size",
2730               "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC, VALS(buffer_size_vals), 0x3f,
2731               "Buffer Size available in all channels in group", HFILL
2732             }
2733         },
2734         { &hf_mac_lte_control_long_bsr_buffer_size_0,
2735             { "Buffer Size 0",
2736               "mac-lte.control.bsr.buffer-size-0", FT_UINT8, BASE_DEC, VALS(buffer_size_vals), 0xfc,
2737               "Buffer Size available in logical channel group 0", HFILL
2738             }
2739         },
2740         { &hf_mac_lte_control_long_bsr_buffer_size_1,
2741             { "Buffer Size 1",
2742               "mac-lte.control.bsr.buffer-size-1", FT_UINT16, BASE_DEC, VALS(buffer_size_vals), 0x03f0,
2743               "Buffer Size available in logical channel group 1", HFILL
2744             }
2745         },
2746         { &hf_mac_lte_control_long_bsr_buffer_size_2,
2747             { "Buffer Size 2",
2748               "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC, VALS(buffer_size_vals), 0x0fc0,
2749               "Buffer Size available in logical channel group 2", HFILL
2750             }
2751         },
2752         { &hf_mac_lte_control_long_bsr_buffer_size_3,
2753             { "Buffer Size 3",
2754               "mac-lte.control.bsr.buffer-size-3", FT_UINT8, BASE_DEC, VALS(buffer_size_vals), 0x3f,
2755               "Buffer Size available in logical channel group 3", HFILL
2756             }
2757         },
2758         { &hf_mac_lte_control_crnti,
2759             { "C-RNTI",
2760               "mac-lte.control.crnti", FT_UINT16, BASE_DEC, 0, 0x0,
2761               "C-RNTI for the UE", HFILL
2762             }
2763         },
2764         { &hf_mac_lte_control_timing_advance,
2765             { "Timing Advance",
2766               "mac-lte.control.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
2767               "Timing Advance (0-1282 - see 36.213, 4.2.3)", HFILL
2768             }
2769         },
2770         { &hf_mac_lte_control_timing_advance_reserved,
2771             { "Reserved",
2772               "mac-lte.control.timing-advance.reserved", FT_UINT8, BASE_DEC, 0, 0xc0,
2773               "Reserved bits", HFILL
2774             }
2775         },
2776         { &hf_mac_lte_control_ue_contention_resolution,
2777             { "UE Contention Resolution",
2778               "mac-lte.control.ue-contention-resolution", FT_STRING, BASE_NONE, 0, 0x0,
2779               NULL, HFILL
2780             }
2781         },
2782         { &hf_mac_lte_control_ue_contention_resolution_identity,
2783             { "UE Contention Resolution Identity",
2784               "mac-lte.control.ue-contention-resolution.identity", FT_BYTES, BASE_NONE, 0, 0x0,
2785               NULL, HFILL
2786             }
2787         },
2788         { &hf_mac_lte_control_ue_contention_resolution_msg3,
2789             { "Msg3",
2790               "mac-lte.control.ue-contention-resolution.msg3", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2791               NULL, HFILL
2792             }
2793         },
2794         { &hf_mac_lte_control_ue_contention_resolution_msg3_matched,
2795             { "UE Contention Resolution Matches Msg3",
2796               "mac-lte.control.ue-contention-resolution.matches-msg3", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2797               NULL, HFILL
2798             }
2799         },
2800
2801         { &hf_mac_lte_control_power_headroom,
2802             { "Power Headroom",
2803               "mac-lte.control.power-headroom", FT_STRING, BASE_NONE, 0, 0x0,
2804               NULL, HFILL
2805             }
2806         },
2807         { &hf_mac_lte_control_power_headroom_reserved,
2808             { "Reserved",
2809               "mac-lte.control.power-headroom.reserved", FT_UINT8, BASE_DEC, 0, 0xc0,
2810               "Reserved bits, should be 0", HFILL
2811             }
2812         },
2813         { &hf_mac_lte_control_power_headroom_level,
2814             { "Power Headroom Level",
2815               "mac-lte.control.power-headroom.level", FT_UINT8, BASE_DEC, 0, 0x3f,
2816               NULL, HFILL
2817             }
2818         },
2819
2820         { &hf_mac_lte_control_padding,
2821             { "Padding",
2822               "mac-lte.control.padding", FT_NONE, BASE_NONE, 0, 0x0,
2823               NULL, HFILL
2824             }
2825         },
2826
2827         { &hf_mac_lte_suspected_dl_harq_resend,
2828             { "Suspected DL HARQ resend",
2829               "mac-lte.dlsch.suspected-harq-resend", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2830               NULL, HFILL
2831             }
2832         },
2833         { &hf_mac_lte_suspected_dl_harq_resend_original_frame,
2834             { "Frame with previous tx",
2835               "mac-lte.dlsch.suspected-harq-resend-original_frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2836               NULL, HFILL
2837             }
2838         },
2839
2840         { &hf_mac_lte_ul_harq_resend_original_frame,
2841             { "Frame with previous tx",
2842               "mac-lte.ulsch.harq-resend-original_frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2843               NULL, HFILL
2844             }
2845         },
2846     };
2847
2848     static gint *ett[] =
2849     {
2850         &ett_mac_lte,
2851         &ett_mac_lte_context,
2852         &ett_mac_lte_rar_headers,
2853         &ett_mac_lte_rar_header,
2854         &ett_mac_lte_rar_body,
2855         &ett_mac_lte_rar_ul_grant,
2856         &ett_mac_lte_ulsch_header,
2857         &ett_mac_lte_dlsch_header,
2858         &ett_mac_lte_sch_subheader,
2859         &ett_mac_lte_bch,
2860         &ett_mac_lte_bsr,
2861         &ett_mac_lte_pch,
2862         &ett_mac_lte_contention_resolution,
2863         &ett_mac_lte_power_headroom
2864     };
2865
2866     module_t *mac_lte_module;
2867
2868     static uat_field_t lcid_drb_mapping_flds[] = {
2869         UAT_FLD_VS(lcid_drb_mappings, lcid, "lcid", drb_lcid_vals, "The MAC LCID"),
2870         UAT_FLD_DEC(lcid_drb_mappings, drbid,"drb id (1-32)", "Identifier of logical data channel"),
2871         UAT_FLD_VS(lcid_drb_mappings, channel_type, "RLC Channel Type", rlc_channel_type_vals, "The MAC LCID"),
2872         UAT_END_FIELDS
2873     };
2874
2875
2876     /* Register protocol. */
2877     proto_mac_lte = proto_register_protocol("MAC-LTE", "MAC-LTE", "mac-lte");
2878     proto_register_field_array(proto_mac_lte, hf, array_length(hf));
2879     proto_register_subtree_array(ett, array_length(ett));
2880
2881     /* Allow other dissectors to find this one by name. */
2882     register_dissector("mac-lte", dissect_mac_lte, proto_mac_lte);
2883
2884     /* Register the tap name */
2885     mac_lte_tap = register_tap("mac-lte");
2886
2887     /* Preferences */
2888     mac_lte_module = prefs_register_protocol(proto_mac_lte, NULL);
2889
2890     /* Obsolete preferences */
2891     prefs_register_obsolete_preference(mac_lte_module, "single_rar");
2892     prefs_register_obsolete_preference(mac_lte_module, "check_reserved_bits");
2893     prefs_register_obsolete_preference(mac_lte_module, "decode_rar_ul_grant");
2894
2895     prefs_register_uint_preference(mac_lte_module, "retx_count_warn",
2896         "Number of Re-Transmits before expert warning triggered",
2897         "Number of Re-Transmits before expert warning triggered",
2898         10, &global_mac_lte_retx_counter_trigger);
2899
2900     prefs_register_bool_preference(mac_lte_module, "attempt_rrc_decode",
2901         "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
2902         "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
2903         &global_mac_lte_attempt_rrc_decode);
2904
2905     prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_crc_failures",
2906         "Dissect frames that have failed CRC check",
2907         "Attempt to dissect frames that have failed CRC check",
2908         &global_mac_lte_dissect_crc_failures);
2909
2910     prefs_register_bool_preference(mac_lte_module, "heuristic_mac_lte_over_udp",
2911         "Try Heuristic LTE-MAC over UDP framing",
2912         "When enabled, use heuristic dissector to find MAC-LTE frames sent with "
2913         "UDP framing",
2914         &global_mac_lte_heur);
2915
2916     prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_srb_sdus",
2917         "Attempt to dissect LCID 1&2 as srb1&2",
2918         "Will call LTE RLC dissector with standard settings as per RRC spec",
2919         &global_mac_lte_attempt_srb_decode);
2920
2921     lcid_drb_mappings_uat = uat_new("LCID -> drb Table",
2922                                sizeof(lcid_drb_mapping_t),
2923                                "drb_logchans",
2924                                TRUE,
2925                                (void*) &lcid_drb_mappings,
2926                                &num_lcid_drb_mappings,
2927                                UAT_CAT_FFMT,
2928                                "",  /* TODO: is this ref to help manual? */
2929                                lcid_drb_mapping_copy_cb,
2930                                NULL,
2931                                NULL,
2932                                lcid_drb_mapping_flds );
2933
2934     prefs_register_uat_preference(mac_lte_module,
2935                                   "drb_table",
2936                                   "LCID -> DRB Mappings Table",
2937                                   "A table that maps from configurable lcids -> RLC logical channels",
2938                                   lcid_drb_mappings_uat);
2939
2940     prefs_register_bool_preference(mac_lte_module, "attempt_to_detect_dl_harq_resend",
2941         "Attempt to detect DL HARQ resends",
2942         "Attempt to detect DL HARQ resends (useful if logging UE side so need to infer)",
2943         &global_mac_lte_attempt_dl_harq_resend_detect);
2944
2945     prefs_register_bool_preference(mac_lte_module, "attempt_to_track_ul_harq_resend",
2946         "Attempt to track UL HARQ resends",
2947         "When logging at UE side, will look for original transmission",
2948         &global_mac_lte_attempt_ul_harq_resend_track);
2949
2950     prefs_register_uint_preference(mac_lte_module, "bsr_warn_threshold",
2951         "BSR size when warning should be issued (0 - 63)",
2952         "If any BSR report is >= this number, an expert warning will be added",
2953         10, &global_mac_lte_bsr_warn_threshold);
2954
2955     register_init_routine(&mac_lte_init_protocol);
2956 }
2957
2958 void
2959 proto_reg_handoff_mac_lte(void)
2960 {
2961     static dissector_handle_t mac_lte_handle;
2962     if (!mac_lte_handle) {
2963         mac_lte_handle = find_dissector("mac-lte");
2964
2965         /* Add as a heuristic UDP dissector */
2966         heur_dissector_add("udp", dissect_mac_lte_heur, proto_mac_lte);
2967     }
2968 }
2969