Show CRC errors for RARs.
[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
33 #include "packet-mac-lte.h"
34
35
36 /* Described in:
37  * 3GPP TS 36.321 Evolved Universal Terrestrial Radio Access (E-UTRA)
38  *                Medium Access Control (MAC) protocol specification (Release 8)
39  */
40
41
42 /* TODO:
43    - TDD mode?
44    - add a preference so that padding can be verified against an expected pattern?
45 */
46
47 /* Initialize the protocol and registered fields. */
48 int proto_mac_lte = -1;
49
50 static int mac_lte_tap = -1;
51
52 /* Decoding context */
53 static int hf_mac_lte_context_radio_type = -1;
54 static int hf_mac_lte_context_direction = -1;
55 static int hf_mac_lte_context_rnti = -1;
56 static int hf_mac_lte_context_rnti_type = -1;
57 static int hf_mac_lte_context_ueid = -1;
58 static int hf_mac_lte_context_subframe_number = -1;
59 static int hf_mac_lte_context_predefined_frame = -1;
60 static int hf_mac_lte_context_length = -1;
61 static int hf_mac_lte_context_bch_transport_channel = -1;
62 static int hf_mac_lte_context_retx_count = -1;
63 static int hf_mac_lte_context_crc_status = -1;
64
65 /* MAC SCH header fields */
66 static int hf_mac_lte_ulsch_header = -1;
67 static int hf_mac_lte_dlsch_header = -1;
68 static int hf_mac_lte_sch_subheader = -1;
69
70 static int hf_mac_lte_sch_reserved = -1;
71 static int hf_mac_lte_dlsch_lcid = -1;
72 static int hf_mac_lte_ulsch_lcid = -1;
73 static int hf_mac_lte_sch_extended = -1;
74 static int hf_mac_lte_sch_format = -1;
75 static int hf_mac_lte_sch_length = -1;
76
77 static int hf_mac_lte_sch_header_only = -1;
78
79 /* Data */
80 static int hf_mac_lte_sch_sdu = -1;
81 static int hf_mac_lte_bch_pdu = -1;
82 static int hf_mac_lte_pch_pdu = -1;
83 static int hf_mac_lte_predefined_pdu = -1;
84 static int hf_mac_lte_raw_pdu = -1;
85 static int hf_mac_lte_padding_data = -1;
86 static int hf_mac_lte_padding_length = -1;
87
88
89 /* RAR fields */
90 static int hf_mac_lte_rar = -1;
91 static int hf_mac_lte_rar_headers = -1;
92 static int hf_mac_lte_rar_header = -1;
93 static int hf_mac_lte_rar_extension = -1;
94 static int hf_mac_lte_rar_t = -1;
95 static int hf_mac_lte_rar_bi = -1;
96 static int hf_mac_lte_rar_rapid = -1;
97 static int hf_mac_lte_rar_reserved = -1;
98 static int hf_mac_lte_rar_body = -1;
99 static int hf_mac_lte_rar_reserved2 = -1;
100 static int hf_mac_lte_rar_ta = -1;
101 static int hf_mac_lte_rar_ul_grant = -1;
102 static int hf_mac_lte_rar_ul_grant_hopping = -1;
103 static int hf_mac_lte_rar_ul_grant_fsrba = -1;
104 static int hf_mac_lte_rar_ul_grant_tmcs = -1;
105 static int hf_mac_lte_rar_ul_grant_tcsp = -1;
106 static int hf_mac_lte_rar_ul_grant_ul_delay = -1;
107 static int hf_mac_lte_rar_ul_grant_cqi_request = -1;
108 static int hf_mac_lte_rar_temporary_crnti = -1;
109
110 /* Common channel control values */
111 static int hf_mac_lte_control_bsr = -1;
112 static int hf_mac_lte_control_bsr_lcg_id = -1;
113 static int hf_mac_lte_control_bsr_buffer_size = -1;
114 static int hf_mac_lte_control_bsr_buffer_size_1 = -1;
115 static int hf_mac_lte_control_bsr_buffer_size_2 = -1;
116 static int hf_mac_lte_control_bsr_buffer_size_3 = -1;
117 static int hf_mac_lte_control_bsr_buffer_size_4 = -1;
118 static int hf_mac_lte_control_crnti = -1;
119 static int hf_mac_lte_control_timing_advance = -1;
120 static int hf_mac_lte_control_timing_advance_reserved = -1;
121 static int hf_mac_lte_control_ue_contention_resolution = -1;
122 static int hf_mac_lte_control_ue_contention_resolution_identity = -1;
123 static int hf_mac_lte_control_ue_contention_resolution_msg3 = -1;
124 static int hf_mac_lte_control_ue_contention_resolution_msg3_matched = -1;
125 static int hf_mac_lte_control_power_headroom = -1;
126 static int hf_mac_lte_control_power_headroom_reserved = -1;
127 static int hf_mac_lte_control_power_headroom_level = -1;
128 static int hf_mac_lte_control_padding = -1;
129
130
131 /* Subtrees. */
132 static int ett_mac_lte = -1;
133 static int ett_mac_lte_context = -1;
134 static int ett_mac_lte_ulsch_header = -1;
135 static int ett_mac_lte_dlsch_header = -1;
136 static int ett_mac_lte_sch_subheader = -1;
137 static int ett_mac_lte_rar_headers = -1;
138 static int ett_mac_lte_rar_header = -1;
139 static int ett_mac_lte_rar_body = -1;
140 static int ett_mac_lte_rar_ul_grant = -1;
141 static int ett_mac_lte_bsr = -1;
142 static int ett_mac_lte_bch = -1;
143 static int ett_mac_lte_pch = -1;
144 static int ett_mac_lte_contention_resolution = -1;
145 static int ett_mac_lte_power_headroom = -1;
146
147
148
149 /* Constants and value strings */
150
151 static const value_string radio_type_vals[] =
152 {
153     { FDD_RADIO,      "FDD"},
154     { TDD_RADIO,      "TDD"},
155     { 0, NULL }
156 };
157
158
159 static const value_string direction_vals[] =
160 {
161     { DIRECTION_UPLINK,      "Uplink"},
162     { DIRECTION_DOWNLINK,    "Downlink"},
163     { 0, NULL }
164 };
165
166
167 static const value_string rnti_type_vals[] =
168 {
169     { NO_RNTI,     "NO-RNTI"},
170     { P_RNTI,      "P-RNTI"},
171     { RA_RNTI,     "RA-RNTI"},
172     { C_RNTI,      "C-RNTI"},
173     { SI_RNTI,     "SI-RNTI"},
174     { 0, NULL }
175 };
176
177 static const value_string bch_transport_channel_vals[] =
178 {
179     { SI_RNTI,      "DL-SCH"},
180     { NO_RNTI,      "BCH"},
181     { 0, NULL }
182 };
183
184 static const value_string crc_status_vals[] =
185 {
186     { 0,      "CRC Status Failed"},
187     { 1,      "CRC Status OK"},
188     { 0, NULL }
189 };
190
191
192
193 #define UE_CONTENTION_RESOLUTION_IDENTITY_LCID 0x1c
194 #define TIMING_ADVANCE_LCID                    0x1d
195 #define DRX_COMMAND_LCID                       0x1e
196 #define PADDING_LCID                           0x1f
197
198 static const value_string dlsch_lcid_vals[] =
199 {
200     { 0,                                        "CCCH"},
201     { 1,                                        "1"},
202     { 2,                                        "2"},
203     { 3,                                        "3"},
204     { 4,                                        "4"},
205     { 5,                                        "5"},
206     { 6,                                        "6"},
207     { 7,                                        "7"},
208     { 8,                                        "8"},
209     { 9,                                        "9"},
210     { 10,                                       "10"},
211     { UE_CONTENTION_RESOLUTION_IDENTITY_LCID,   "UE Contention Resolution Identity"},
212     { TIMING_ADVANCE_LCID                   ,   "Timing Advance"},
213     { DRX_COMMAND_LCID                      ,   "DRX Command"},
214     { PADDING_LCID                          ,   "Padding" },
215     { 0, NULL }
216 };
217
218 #define POWER_HEADROOM_REPORT_LCID    0x1a
219 #define CRNTI_LCID                    0x1b
220 #define TRUNCATED_BSR_LCID            0x1c
221 #define SHORT_BSR_LCID                0x1d
222 #define LONG_BSR_LCID                 0x1e
223
224 static const value_string ulsch_lcid_vals[] =
225 {
226     { 0,                            "CCCH"},
227     { 1,                            "1"},
228     { 2,                            "2"},
229     { 3,                            "3"},
230     { 4,                            "4"},
231     { 5,                            "5"},
232     { 6,                            "6"},
233     { 7,                            "7"},
234     { 8,                            "8"},
235     { 9,                            "9"},
236     { 10,                           "10"},
237     { POWER_HEADROOM_REPORT_LCID,   "Power Headroom Report"},
238     { CRNTI_LCID,                   "C-RNTI"},
239     { TRUNCATED_BSR_LCID,           "Truncated BSR"},
240     { SHORT_BSR_LCID,               "Short BSR"},
241     { LONG_BSR_LCID,                "Long BSR"},
242     { PADDING_LCID,                 "Padding" },
243     { 0, NULL }
244 };
245
246
247 static const value_string format_vals[] =
248 {
249     { 0,      "Data length is < 128 bytes"},
250     { 1,      "Data length is >= 128 bytes"},
251     { 0, NULL }
252 };
253
254
255 static const value_string rar_type_vals[] =
256 {
257     { 0,      "Backoff Indicator present"},
258     { 1,      "RAPID present"},
259     { 0, NULL }
260 };
261
262
263 static const value_string rar_bi_vals[] =
264 {
265     { 0,      "0"},
266     { 1,      "10"},
267     { 2,      "20"},
268     { 3,      "30"},
269     { 4,      "40"},
270     { 5,      "60"},
271     { 6,      "80"},
272     { 7,      "120"},
273     { 8,      "160"},
274     { 9,      "240"},
275     { 10,     "320"},
276     { 11,     "480"},
277     { 12,     "960"},
278     { 0, NULL }
279 };
280
281
282 static const value_string buffer_size_vals[] =
283 {
284     { 0,      "BS = 0"},
285     { 1,      "0   < BS <= 10"},
286     { 2,      "10  < BS <= 12"},
287     { 3,      "12  < BS <= 14"},
288     { 4,      "14  < BS <= 17"},
289     { 5,      "17  < BS <= 19"},
290     { 6,      "19  < BS <= 22"},
291     { 7,      "22  < BS <= 26"},
292     { 8,      "26  < BS <= 31"},
293     { 9,      "31  < BS <= 36"},
294     { 10,     "36  < BS <= 42"},
295     { 11,     "42  < BS <= 49"},
296     { 12,     "49  < BS <= 57"},
297     { 13,     "47  < BS <= 67"},
298     { 14,     "67  < BS <= 78"},
299     { 15,     "78  < BS <= 91"},
300     { 16,     "91  < BS <= 107"},
301     { 17,     "107 < BS <= 125"},
302     { 18,     "125 < BS <= 146"},
303     { 19,     "146 < BS <= 171"},
304     { 20,     "171 < BS <= 200"},
305     { 21,     "200 < BS <= 234"},
306     { 22,     "234 < BS <= 274"},
307     { 23,     "274 < BS <= 321"},
308     { 24,     "321 < BS <= 376"},
309     { 25,     "376 < BS <= 440"},
310     { 26,     "440 < BS <= 515"},
311     { 27,     "515 < BS <= 603"},
312     { 28,     "603 < BS <= 706"},
313     { 29,     "706 < BS <= 826"},
314     { 30,     "826 < BS <= 967"},
315     { 31,     "967  < BS <= 1132"},
316     { 32,     "1132 < BS <= 1326"},
317     { 33,     "1326 < BS <= 1552"},
318     { 34,     "1552 < BS <= 1817"},
319     { 35,     "1817 < BS <= 2127"},
320     { 36,     "2127 < BS <= 2490"},
321     { 37,     "2490 < BS <= 2915"},
322     { 38,     "2915 < BS <= 3413"},
323     { 39,     "3413 < BS <= 3995"},
324     { 40,     "3995 < BS <= 4677"},
325     { 41,     "4677 < BS <= 5476"},
326     { 42,     "5476 < BS <= 6411"},
327     { 43,     "6411 < BS <= 7505"},
328     { 44,     "7505 < BS <= 8787"},
329     { 45,     "8787 < BS <= 10276"},
330     { 46,     "10287 < BS <= 12043"},
331     { 47,     "12043 < BS <= 14099"},
332     { 48,     "14099 < BS <= 16507"},
333     { 49,     "16507 < BS <= 19325"},
334     { 50,     "19325 < BS <= 22624"},
335     { 51,     "22624 < BS <= 26487"},
336     { 52,     "26487 < BS <= 31009"},
337     { 53,     "31009 < BS <= 36304"},
338     { 54,     "36304 < BS <= 42502"},
339     { 55,     "42502 < BS <= 49759"},
340     { 56,     "49759 < BS <= 58255"},
341     { 57,     "58255 < BS <= 68201"},
342     { 58,     "68201 < BS <= 79846"},
343     { 59,     "79846 < BS <= 93479"},
344     { 60,     "93479 < BS <= 109439"},
345     { 61,     "109439 < BS <= 128125"},
346     { 62,     "128125 < BS <= 150000"},
347     { 63,     "BS > 150000"},
348     { 0, NULL }
349 };
350
351 static const value_string header_only_vals[] =
352 {
353     { 0,      "MAC PDU Headers and body present"},
354     { 1,      "MAC PDU Headers only"},
355     { 0, NULL }
356 };
357
358 static const value_string predefined_frame_vals[] =
359 {
360     { 0,      "Real MAC PDU present - will dissect"},
361     { 1,      "Predefined frame present - will not dissect"},
362     { 0, NULL }
363 };
364
365
366 /* By default check and warn about reserved bits not being zero.
367    December '08 spec says they should be ignored... */
368 static gboolean global_mac_lte_check_reserved_bits = TRUE;
369
370 /* If this PDU has been NACK'd (by HARQ) more than a certain number of times,
371    we trigger an expert warning. */
372 static gint global_mac_lte_retx_counter_trigger = 3;
373
374 /* By default try to decode transparent data (BCH, PCH and CCCH) data using LTE RRC dissector */
375 static gboolean global_mac_lte_attempt_rrc_decode = TRUE;
376
377 /* Control whether decoding details of RAR UL grant or not */
378 static gboolean global_mac_lte_decode_rar_ul_grant = TRUE;
379
380 /* Whether should attempt to dissect frames failing CRC check */
381 static gboolean global_mac_lte_dissect_crc_failures = FALSE;
382
383
384
385 /***************************************************************/
386 /* Keeping track of Msg3 bodies so they can be compared with   */
387 /* Contention Resolution bodies.                               */
388
389 typedef struct Msg3Data {
390     guint8  data[6];
391     guint32 framenum;
392 } Msg3Data;
393
394
395 /* This table stores (RNTI -> Msg3Data*).  Will be populated when
396    Msg3 frames are first read.  */
397 static GHashTable *mac_lte_msg3_hash = NULL;
398
399 /* Hash table functions for mac_lte_msg3_hash.  Hash is just the (RNTI) key */
400 static gint mac_lte_msg3_hash_equal(gconstpointer v, gconstpointer v2)
401 {
402     return (v == v2);
403 }
404
405 static guint mac_lte_msg3_hash_func(gconstpointer v)
406 {
407     return GPOINTER_TO_UINT(v);
408 }
409
410
411
412
413 typedef enum ContentionResolutionStatus {
414     NoMsg3,
415     Msg3Match,
416     Msg3NoMatch
417 } ContentionResolutionStatus;
418
419 typedef struct ContentionResolutionResult {
420     ContentionResolutionStatus status;
421     guint                      msg3FrameNum;
422 } ContentionResolutionResult;
423
424
425 /* This table stores (CRFrameNum -> CRResult).  It is assigned during the first
426    pass and used thereafter */
427 static GHashTable *mac_lte_cr_result_hash = NULL;
428
429 /* Hash table functions for mac_lte_cr_result_hash.  Hash is just the (framenum) key */
430 static gint mac_lte_cr_result_hash_equal(gconstpointer v, gconstpointer v2)
431 {
432     return (v == v2);
433 }
434
435 static guint mac_lte_cr_result_hash_func(gconstpointer v)
436 {
437     return GPOINTER_TO_UINT(v);
438 }
439
440
441
442 /**************************************************************************/
443
444
445
446 /* Forward declarations */
447 void proto_reg_handoff_mac_lte(void);
448 void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
449
450
451 /* Heuristic dissection */
452 static gboolean global_mac_lte_heur = FALSE;
453
454 static gboolean dissect_mac_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
455                                      proto_tree *tree)
456 {
457     gint                 offset = 0;
458     struct mac_lte_info  *p_mac_lte_info;
459     tvbuff_t             *mac_tvb;
460     guint8               tag = 0;
461     gboolean             infoAlreadySet = FALSE;
462
463     /* This is a heuristic dissector, which means we get all the UDP
464      * traffic not sent to a known dissector and not claimed by
465      * a heuristic dissector called before us!
466      */
467
468     if (!global_mac_lte_heur) {
469         return FALSE;
470     }
471
472     /* If redissecting, use previous info struct (if available) */
473     p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte);
474     if (p_mac_lte_info == NULL) {
475         /* Allocate new info struct for this frame */
476         p_mac_lte_info = se_alloc0(sizeof(struct mac_lte_info));
477         if (p_mac_lte_info == NULL) {
478             return FALSE;
479         }
480         infoAlreadySet = FALSE;
481     }
482     else {
483         infoAlreadySet = TRUE;
484     }
485
486     /* Do this again on re-dissection to re-discover offset of actual PDU */
487     
488     /* Needs to be at least as long as:
489        - the signature string
490        - fixed header bytes
491        - tag for data
492        - at least one byte of MAC PDU payload */
493     if ((size_t)tvb_length_remaining(tvb, offset) < (strlen(MAC_LTE_START_STRING)+3+2)) {
494         return FALSE;
495     }
496
497     /* OK, compare with signature string */
498     if (tvb_strneql(tvb, offset, MAC_LTE_START_STRING, (gint)strlen(MAC_LTE_START_STRING)) != 0) {
499         return FALSE;
500     }
501     offset += (gint)strlen(MAC_LTE_START_STRING);
502
503     /* Read fixed fields */
504     p_mac_lte_info->radioType = tvb_get_guint8(tvb, offset++);
505     p_mac_lte_info->direction = tvb_get_guint8(tvb, offset++);
506     p_mac_lte_info->rntiType = tvb_get_guint8(tvb, offset++);
507
508     /* Read optional fields */
509     while (tag != MAC_LTE_PAYLOAD_TAG) {
510         /* Process next tag */
511         tag = tvb_get_guint8(tvb, offset++);
512         switch (tag) {
513             case MAC_LTE_RNTI_TAG:
514                 p_mac_lte_info->rnti = tvb_get_ntohs(tvb, offset);
515                 offset += 2;
516                 break;
517             case MAC_LTE_UEID_TAG:
518                 p_mac_lte_info->ueid = tvb_get_ntohs(tvb, offset);
519                 offset += 2;
520                 break;
521             case MAC_LTE_SUBFRAME_TAG:
522                 p_mac_lte_info->subframeNumber = tvb_get_ntohs(tvb, offset);
523                 offset += 2;
524                 break;
525             case MAC_LTE_PREDFINED_DATA_TAG:
526                 p_mac_lte_info->isPredefinedData = tvb_get_guint8(tvb, offset);
527                 offset++;
528                 break;
529             case MAC_LTE_RETX_TAG:
530                 p_mac_lte_info->reTxCount = tvb_get_guint8(tvb, offset);
531                 offset++;
532                 break;
533             case MAC_LTE_CRC_STATUS_TAG:
534                 p_mac_lte_info->crcStatusValid = TRUE;
535                 p_mac_lte_info->crcStatus = tvb_get_guint8(tvb, offset);
536                 offset++;
537                 break;
538
539             case MAC_LTE_PAYLOAD_TAG:
540                 /* Have reached data, so set payload length and get out of loop */
541                 p_mac_lte_info->length= tvb_length_remaining(tvb, offset);
542                 continue;
543
544             default:
545                 /* It must be a recognised tag */
546                 return FALSE;
547         }
548
549         if (!infoAlreadySet) {
550             /* Store info in packet */
551             p_add_proto_data(pinfo->fd, proto_mac_lte, p_mac_lte_info);
552         }
553     }
554
555
556     /**************************************/
557     /* OK, now dissect as MAC LTE         */
558
559     /* Create tvb that starts at actual MAC PDU */
560     mac_tvb = tvb_new_subset(tvb, offset, -1, tvb_reported_length(tvb)-offset);
561     dissect_mac_lte(mac_tvb, pinfo, tree);
562     return TRUE;
563 }
564
565 /* Dissect a single Random Access Reponse body */
566 static gint dissect_rar_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
567                               gint offset, guint8 rapid)
568 {
569     guint8 reserved;
570     guint start_body_offset = offset;
571     proto_item *ti;
572     proto_item *rar_body_ti;
573     proto_tree *rar_body_tree;
574     proto_item *ul_grant_ti;
575     guint16 timing_advance;
576     guint32 ul_grant;
577     guint16 temp_crnti;
578
579     /* Create tree for this Body */
580     rar_body_ti = proto_tree_add_item(tree,
581                                       hf_mac_lte_rar_body,
582                                       tvb, offset, 0, FALSE);
583     rar_body_tree = proto_item_add_subtree(rar_body_ti, ett_mac_lte_rar_body);
584
585     /* Dissect an RAR entry */
586
587     /* Check reserved bit */
588     reserved = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
589     ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_reserved2, tvb, offset, 1, FALSE);
590     if (global_mac_lte_check_reserved_bits && (reserved != 0)) {
591             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
592                       "RAR body Reserved bit not zero (found 0x%x)", reserved);
593     }
594
595     /* Timing Advance */
596     timing_advance = (tvb_get_ntohs(tvb, offset) & 0x7ff0) >> 4;
597     proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ta, tvb, offset, 2, FALSE);
598     offset++;
599
600     /* UL Grant */
601     ul_grant = (tvb_get_ntohl(tvb, offset) & 0x0fffff00) >> 8;
602     ul_grant_ti = proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_ul_grant, tvb, offset, 3, FALSE);
603
604     /* Break these 20 bits down as described in 36.213, section 6.2 */
605     if (global_mac_lte_decode_rar_ul_grant) {
606         /* Create subtree for UL grant break-down */
607         proto_tree *ul_grant_tree = proto_item_add_subtree(ul_grant_ti, ett_mac_lte_rar_ul_grant);
608
609         /* Hopping flag (1 bit) */
610         proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_hopping,
611                             tvb, offset, 1, FALSE);
612
613         /* Fixed sized resource block assignment (10 bits) */
614         proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_fsrba,
615                             tvb, offset, 2, FALSE);
616
617         /* Truncated Modulation and coding scheme (4 bits) */
618         proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tmcs,
619                             tvb, offset+1, 2, FALSE);
620
621         /* TPC command for scheduled PUSCH (3 bits) */
622         proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_tcsp,
623                             tvb, offset+2, 1, FALSE);
624
625         /* UL delay (1 bit) */
626         proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_ul_delay,
627                             tvb, offset+2, 1, FALSE);
628
629         /* CQI request (1 bit) */
630         proto_tree_add_item(ul_grant_tree, hf_mac_lte_rar_ul_grant_cqi_request,
631                             tvb, offset+2, 1, FALSE);
632     }
633
634     offset += 3;
635
636     /* Temporary C-RNTI */
637     temp_crnti = tvb_get_ntohs(tvb, offset);
638     proto_tree_add_item(rar_body_tree, hf_mac_lte_rar_temporary_crnti, tvb, offset, 2, FALSE);
639     offset += 2;
640
641     proto_item_append_text(rar_body_ti, " RAPID=%u (TA=%u, UL-Grant=%u, Temp C-RNTI=%u)",
642                            rapid, timing_advance, ul_grant, temp_crnti);
643
644     col_append_fstr(pinfo->cinfo, COL_INFO, "(RAPID=%u: TA=%u, UL-Grant=%u, Temp C-RNTI=%u) ",
645                     rapid, timing_advance, ul_grant, temp_crnti);
646
647     proto_item_set_len(rar_body_ti, offset-start_body_offset);
648
649     return offset;
650 }
651
652
653 /* Dissect Random Access Reponse (RAR) PDU */
654 static void dissect_rar(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
655                         gint offset, mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info)
656 {
657     gint     number_of_rars = 0;   /* No of RAR bodies expected following headers */
658     guint8   rapids[64];
659     gboolean backoff_indicator_seen = FALSE;
660     guint8   backoff_indicator = 0;
661     guint8   extension;
662     gint     n;
663     proto_tree *rar_headers_tree;
664     proto_item *ti;
665     proto_item *rar_headers_ti;
666     int        start_headers_offset = offset;
667
668     col_append_fstr(pinfo->cinfo, COL_INFO, "RAR (RA-RNTI=%u, SF=%u) ",
669                     p_mac_lte_info->rnti, p_mac_lte_info->subframeNumber);
670
671     /* Create hidden 'virtual root' so can filter on mac-lte.rar */
672     ti = proto_tree_add_item(tree, hf_mac_lte_rar, tvb, offset, -1, FALSE);
673     PROTO_ITEM_SET_HIDDEN(ti);
674
675     /* Create headers tree */
676     rar_headers_ti = proto_tree_add_item(tree,
677                                          hf_mac_lte_rar_headers,
678                                          tvb, offset, 0, FALSE);
679     rar_headers_tree = proto_item_add_subtree(rar_headers_ti, ett_mac_lte_rar_headers);
680
681
682     /***************************/
683     /* Read the header entries */
684     do {
685         int start_header_offset = offset;
686         proto_tree *rar_header_tree;
687         proto_item *rar_header_ti;
688         guint8 type_value;
689         guint8 first_byte = tvb_get_guint8(tvb, offset);
690
691         /* Create tree for this header */
692         rar_header_ti = proto_tree_add_item(rar_headers_tree,
693                                             hf_mac_lte_rar_header,
694                                             tvb, offset, 0, FALSE);
695         rar_header_tree = proto_item_add_subtree(rar_header_ti, ett_mac_lte_rar_header);
696
697         /* Extension */
698         extension = (first_byte & 0x80) >> 7;
699         proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_extension, tvb, offset, 1, FALSE);
700
701         /* Type */
702         type_value = (first_byte & 0x40) >> 6;
703         proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_t, tvb, offset, 1, FALSE);
704
705         if (type_value == 0) {
706             /* Backoff Indicator (BI) case */
707
708             guint8 reserved;
709             proto_item *ti;
710             proto_item *bi_ti;
711
712             /* 2 Reserved bits */
713             reserved = (tvb_get_guint8(tvb, offset) & 0x30) >> 4;
714             ti = proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_reserved, tvb, offset, 1, FALSE);
715             if (global_mac_lte_check_reserved_bits && (reserved != 0)) {
716                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
717                                        "RAR header Reserved bits not zero (found 0x%x)", reserved);
718             }
719
720             /* Backoff Indicator */
721             backoff_indicator = tvb_get_guint8(tvb, offset) & 0x0f;
722             bi_ti = proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_bi, tvb, offset, 1, FALSE);
723
724             /* As of March 2009 spec, it must be first, and may only appear once */
725             if (backoff_indicator_seen) {
726                 expert_add_info_format(pinfo, bi_ti, PI_MALFORMED, PI_ERROR,
727                                        "MAC RAR PDU has > 1 Backoff Indicator subheader present");
728             }
729             backoff_indicator_seen = TRUE;
730
731             proto_item_append_text(rar_header_ti, "(Backoff Indicator=%sms)",
732                                    val_to_str(backoff_indicator, rar_bi_vals, "Illegal-value "));
733
734             col_append_fstr(pinfo->cinfo, COL_INFO, "(Backoff Indicator=%s ms) ",
735                             val_to_str(backoff_indicator, rar_bi_vals, "Illegal-value"));
736
737             /* If present, it must be the first subheader */
738             if (number_of_rars > 0) {
739                 expert_add_info_format(pinfo, bi_ti, PI_MALFORMED, PI_WARN,
740                                        "Backoff Indicator must appear as first subheader");
741             }
742
743         }
744         else {
745             /* RAPID case */
746             /* TODO: complain if the same RAPID appears twice in same frame? */
747             rapids[number_of_rars] = tvb_get_guint8(tvb, offset) & 0x3f;
748             proto_tree_add_item(rar_header_tree, hf_mac_lte_rar_rapid, tvb, offset, 1, FALSE);
749
750             proto_item_append_text(rar_header_ti, "(RAPID=%u)", rapids[number_of_rars]);
751
752             number_of_rars++;
753         }
754
755         offset++;
756
757         /* Finalise length of header tree selection */
758         proto_item_set_len(rar_header_ti, offset - start_header_offset);
759
760     } while (extension);
761
762     /* Append summary to headers root */
763     proto_item_append_text(rar_headers_ti, " (%u RARs", number_of_rars);
764     if (backoff_indicator_seen) {
765         proto_item_append_text(rar_headers_ti, ", BI=%sms)",
766                                val_to_str(backoff_indicator, rar_bi_vals, "Illegal-value "));
767     }
768     else {
769         proto_item_append_text(rar_headers_ti, ")");
770     }
771
772     /* Set length for headers root */
773     proto_item_set_len(rar_headers_ti, offset-start_headers_offset);
774
775
776     /***************************/
777     /* Read any indicated RARs */
778     for (n=0; n < number_of_rars; n++) {
779         offset = dissect_rar_entry(tvb, pinfo, tree, offset, rapids[n]);
780     }
781
782     /* Update TAP info */
783     tap_info->number_of_rars += number_of_rars;
784
785     /* Warn if we don't seem to have reached the end of the frame yet */
786     if (tvb_length_remaining(tvb, offset) != 0) {
787            expert_add_info_format(pinfo, rar_headers_ti, PI_MALFORMED, PI_ERROR,
788                                   "%u bytes remaining after RAR PDU dissected",
789                                   tvb_length_remaining(tvb, offset));
790     }
791 }
792
793
794 /* Dissect BCH PDU */
795 static void dissect_bch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
796                         int offset, mac_lte_info *p_mac_lte_info)
797 {
798     proto_item *ti;
799
800     col_append_fstr(pinfo->cinfo, COL_INFO, "BCH PDU (%u bytes, on %s transport)  ",
801                     tvb_length_remaining(tvb, offset),
802                     val_to_str(p_mac_lte_info->rntiType,
803                                bch_transport_channel_vals,
804                                "Unknown"));
805
806     /* Show which transport layer it came in on (inferred from RNTI type) */
807     ti = proto_tree_add_uint(tree, hf_mac_lte_context_bch_transport_channel,
808                              tvb, offset, 0, p_mac_lte_info->rntiType);
809     PROTO_ITEM_SET_GENERATED(ti);
810
811     /****************************************/
812     /* Whole frame is BCH data              */
813
814     /* Raw data */
815     ti = proto_tree_add_item(tree, hf_mac_lte_bch_pdu,
816                              tvb, offset, -1, FALSE);
817
818     if (global_mac_lte_attempt_rrc_decode) {
819         /* Attempt to decode payload using LTE RRC dissector */
820         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
821
822         /* Get appropriate dissector handle */
823         dissector_handle_t protocol_handle = 0;
824         if (p_mac_lte_info->rntiType == SI_RNTI) {
825             protocol_handle = find_dissector("lte-rrc.bcch.dl.sch");
826         }
827         else {
828             protocol_handle = find_dissector("lte-rrc.bcch.bch");
829         }
830
831         /* Hide raw view of bytes */
832         PROTO_ITEM_SET_HIDDEN(ti);
833
834         /* Call it (catch exceptions so that stats will be updated) */
835         /* TODO: couldn't avoid warnings for 'ti' by using volatile
836                  (with gcc 3.4.6)                                   */
837 /*        TRY {                                                         */
838             call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
839 /*        }                                                             */
840 /*        CATCH_ALL {                                                   */
841 /*        }                                                             */
842 /*        ENDTRY                                                        */
843     }
844
845     /* Check that this *is* downlink! */
846     if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
847         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
848                                "BCH data should not be received in Uplink!");
849     }
850 }
851
852
853 /* Dissect PCH PDU */
854 static void dissect_pch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
855                         int offset, guint8 direction)
856 {
857     proto_item *ti;
858
859     col_append_fstr(pinfo->cinfo, COL_INFO, "PCH PDU (%u bytes)  ",
860                     tvb_length_remaining(tvb, offset));
861
862     /****************************************/
863     /* Whole frame is PCH data              */
864
865     /* Always show as raw data */
866     ti = proto_tree_add_item(tree, hf_mac_lte_pch_pdu,
867                              tvb, offset, -1, FALSE);
868
869     if (global_mac_lte_attempt_rrc_decode) {
870
871         /* Attempt to decode payload using LTE RRC dissector */
872         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
873
874         /* Get appropriate dissector handle */
875         dissector_handle_t protocol_handle = find_dissector("lte-rrc.pcch");
876
877         /* Hide raw view of bytes */
878         PROTO_ITEM_SET_HIDDEN(ti);
879
880         /* Call it (catch exceptions so that stats will be updated) */
881         TRY {
882             call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
883         }
884         CATCH_ALL {
885         }
886         ENDTRY
887     }
888
889     /* Check that this *is* downlink! */
890     if (direction == DIRECTION_UPLINK) {
891         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
892                                "PCH data should not be received in Uplink!");
893     }
894 }
895
896
897 /* Does this header entry correspond to a fixed-sized control element? */
898 static int is_fixed_sized_control_element(guint8 lcid, guint8 direction)
899 {
900     if (direction == DIRECTION_UPLINK) {
901         /* Uplink */
902         switch (lcid) {
903             case POWER_HEADROOM_REPORT_LCID:
904             case CRNTI_LCID:
905             case TRUNCATED_BSR_LCID:
906             case SHORT_BSR_LCID:
907             case LONG_BSR_LCID:
908                 return TRUE;
909
910             default:
911                 return FALSE;
912         }
913     }
914     else {
915         /* Assume Downlink */
916         switch (lcid) {
917             case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
918             case TIMING_ADVANCE_LCID:
919             case DRX_COMMAND_LCID:
920                 return TRUE;
921
922             default:
923                 return FALSE;
924         }
925     }
926 }
927
928
929 /* Is this a BSR report header? */
930 static int is_bsr_lcid(guint8 lcid)
931 {
932     return ((lcid == TRUNCATED_BSR_LCID) ||
933             (lcid == SHORT_BSR_LCID) ||
934             (lcid == LONG_BSR_LCID));
935 }
936
937
938 #define MAX_HEADERS_IN_PDU 1024
939
940 /* UL-SCH and DL-SCH formats have much in common, so handle them in a common
941    function */
942 static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
943                                    volatile int offset, guint8 direction,
944                                    mac_lte_info *p_mac_lte_info, mac_lte_tap_info *tap_info)
945 {
946     guint8          extension;
947     volatile guint8 n;
948     proto_item      *truncated_ti;
949     proto_item      *padding_length_ti;
950
951     /* Keep track of LCIDs and lengths as we dissect the header */
952     volatile guint8 number_of_headers = 0;
953     guint8  lcids[MAX_HEADERS_IN_PDU];
954     gint16  pdu_lengths[MAX_HEADERS_IN_PDU];
955
956     proto_item *pdu_header_ti;
957     proto_tree *pdu_header_tree;
958
959     gboolean   have_seen_data_header = FALSE;
960     gboolean   have_seen_bsr = FALSE;
961     gboolean   expecting_body_data = FALSE;
962
963     col_append_fstr(pinfo->cinfo, COL_INFO, "%s: (SF=%u) ",
964                     (direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
965                     p_mac_lte_info->subframeNumber);
966
967     /* Add PDU block header subtree */
968     pdu_header_ti = proto_tree_add_string_format(tree,
969                                                  (direction == DIRECTION_UPLINK) ?
970                                                     hf_mac_lte_ulsch_header :
971                                                     hf_mac_lte_dlsch_header,
972                                                  tvb, offset, 0,
973                                                  "",
974                                                  "MAC PDU Header");
975     pdu_header_tree = proto_item_add_subtree(pdu_header_ti,
976                                              (direction == DIRECTION_UPLINK) ?
977                                                     ett_mac_lte_ulsch_header :
978                                                     ett_mac_lte_dlsch_header);
979
980
981     /************************************************************************/
982     /* Dissect each sub-header.                                             */
983     do {
984         guint8 reserved;
985         guint64 length = 0;
986         proto_item *pdu_subheader_ti;
987         proto_tree *pdu_subheader_tree;
988         proto_item *lcid_ti;
989         proto_item *ti;
990         gint       offset_start_subheader = offset;
991         guint8 first_byte = tvb_get_guint8(tvb, offset);
992
993         /* Add PDU block header subtree */
994         pdu_subheader_ti = proto_tree_add_string_format(pdu_header_tree,
995                                                         hf_mac_lte_sch_subheader,
996                                                         tvb, offset, 0,
997                                                         "",
998                                                         "Sub-header");
999         pdu_subheader_tree = proto_item_add_subtree(pdu_subheader_ti,
1000                                                     ett_mac_lte_sch_subheader);
1001
1002         /* Check 1st 2 reserved bits */
1003         reserved = (first_byte & 0xc0) >> 6;
1004         ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_reserved,
1005                                  tvb, offset, 1, FALSE);
1006         if (global_mac_lte_check_reserved_bits && (reserved != 0)) {
1007             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1008                                    "U/DL-SCH header Reserved bits not zero");
1009         }
1010
1011         /* Extended bit */
1012         extension = (first_byte & 0x20) >> 5;
1013         proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_extended,
1014                             tvb, offset, 1, FALSE);
1015
1016         /* LCID.  Has different meaning depending upon direction. */
1017         lcids[number_of_headers] = first_byte & 0x1f;
1018         if (direction == DIRECTION_UPLINK) {
1019             lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_ulsch_lcid,
1020                                           tvb, offset, 1, FALSE);
1021             col_append_fstr(pinfo->cinfo, COL_INFO, "(%s",
1022                             val_to_str(lcids[number_of_headers],
1023                                        ulsch_lcid_vals, "(Unknown LCID)"));
1024         }
1025         else {
1026             lcid_ti = proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_dlsch_lcid,
1027                                           tvb, offset, 1, FALSE);
1028             col_append_fstr(pinfo->cinfo, COL_INFO, "(%s",
1029                             val_to_str(lcids[number_of_headers],
1030                                        dlsch_lcid_vals, "(Unknown LCID)"));
1031         }
1032         offset++;
1033
1034         /* Remember if we've seen a data subheader */
1035         if (lcids[number_of_headers] <= 10) {
1036             have_seen_data_header = TRUE;
1037             expecting_body_data = TRUE;
1038         }
1039
1040         /* Show an expert item if a contol subheader (except Padding) appears
1041            *after* a data PDU */
1042         if (have_seen_data_header &&
1043             (lcids[number_of_headers] > 10) && (lcids[number_of_headers] != PADDING_LCID)) {
1044             expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
1045                                    "Control subheaders should not appear after data subheaders");
1046         }
1047
1048         /* Show an expert item if we're seeing more then one BSR in a frame */
1049         if ((direction == DIRECTION_UPLINK) && is_bsr_lcid(lcids[number_of_headers])) {
1050             if (have_seen_bsr) {
1051                 expert_add_info_format(pinfo, lcid_ti, PI_MALFORMED, PI_ERROR,
1052                                       "There shouldn't be > 1 BSR in a frame");
1053             }
1054             have_seen_bsr = TRUE;
1055         }
1056
1057
1058         /********************************************************************/
1059         /* Length field follows if not the last header or for a fixed-sized
1060            control element */
1061         if (!extension) {
1062             if (is_fixed_sized_control_element(lcids[number_of_headers], direction)) {
1063                 pdu_lengths[number_of_headers] = 0;
1064             }
1065             else {
1066                 pdu_lengths[number_of_headers] = -1;
1067             }
1068         }
1069         else {
1070             if (!is_fixed_sized_control_element(lcids[number_of_headers], direction) &&
1071                 (lcids[number_of_headers] != PADDING_LCID)) {
1072
1073                 guint8  format;
1074
1075                 /* F(ormat) bit tells us how long the length field is */
1076                 format = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
1077                 proto_tree_add_item(pdu_subheader_tree, hf_mac_lte_sch_format,
1078                                     tvb, offset, 1, FALSE);
1079
1080                 /* Now read length field itself */
1081                 if (format) {
1082                     /* >= 128 - use 15 bits */
1083                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
1084                                                 tvb, offset*8 + 1, 15, &length, FALSE);
1085
1086                     offset += 2;
1087                 }
1088                 else {
1089                     /* Less than 128 - only 7 bits */
1090                     proto_tree_add_bits_ret_val(pdu_subheader_tree, hf_mac_lte_sch_length,
1091                                                 tvb, offset*8 + 1, 7, &length, FALSE);
1092                     offset++;
1093                 }
1094                 pdu_lengths[number_of_headers] = (gint16)length;
1095             }
1096             else {
1097                 pdu_lengths[number_of_headers] = 0;
1098             }
1099         }
1100
1101
1102         /* Close off description in info column */
1103         switch (pdu_lengths[number_of_headers]) {
1104             case 0:
1105                 col_append_str(pinfo->cinfo, COL_INFO, ") ");
1106                 break;
1107             case -1:
1108                 col_append_str(pinfo->cinfo, COL_INFO, ":remainder) ");
1109                 break;
1110             default:
1111                 col_append_fstr(pinfo->cinfo, COL_INFO, ":%u bytes) ",
1112                                 pdu_lengths[number_of_headers]);
1113                 break;
1114         }
1115
1116         /* Append summary to subheader root */
1117         proto_item_append_text(pdu_subheader_ti, " (lcid=%s",
1118                                val_to_str(lcids[number_of_headers],
1119                                           (direction == DIRECTION_UPLINK) ?
1120                                               ulsch_lcid_vals :
1121                                               dlsch_lcid_vals,
1122                                           "Unknown"));
1123
1124         switch (pdu_lengths[number_of_headers]) {
1125             case -1:
1126                 proto_item_append_text(pdu_subheader_ti, ", length is remainder)");
1127                 break;
1128             case 0:
1129                 proto_item_append_text(pdu_subheader_ti, ")");
1130                 break;
1131             default:
1132                 proto_item_append_text(pdu_subheader_ti, ", length=%u)",
1133                                        pdu_lengths[number_of_headers]);
1134                 break;
1135         }
1136
1137
1138         /* Flag unknown lcid values in expert info */
1139         if (strncmp(val_to_str(lcids[number_of_headers],
1140                                (direction == DIRECTION_UPLINK) ? ulsch_lcid_vals : dlsch_lcid_vals,
1141                                "Unknown"),
1142                     "Unknown",
1143                     sizeof("Unknown")) == 0) {
1144             expert_add_info_format(pinfo, pdu_subheader_ti, PI_MALFORMED, PI_ERROR,
1145                                        "Unexpected LCID received (%u)", lcids[number_of_headers]);
1146         }
1147
1148         /* Set length of this subheader */
1149         proto_item_set_len(pdu_subheader_ti, offset- offset_start_subheader);
1150
1151         number_of_headers++;
1152     } while (extension);
1153
1154     /* Append summary to overall PDU header root */
1155     proto_item_append_text(pdu_header_ti, " (%u subheaders)",
1156                            number_of_headers);
1157
1158     /* And set its length to offset */
1159     proto_item_set_len(pdu_header_ti, offset);
1160
1161
1162     /* TODO: some valid PDUs don't have any bodies, so don't want expert info.
1163        Use expecting_body_data to track this */
1164
1165     /* There might not be any data, if only headers were logged */
1166     truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_sch_header_only, tvb, 0, 0,
1167                                        tvb_length_remaining(tvb, offset) == 0);
1168     if (tvb_length_remaining(tvb, offset) == 0) {
1169         PROTO_ITEM_SET_GENERATED(truncated_ti);
1170         expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
1171                                "MAC PDU SDUs have been ommitted");
1172         return;
1173     }
1174     else {
1175         PROTO_ITEM_SET_HIDDEN(truncated_ti);
1176     }
1177
1178
1179     /************************************************************************/
1180     /* Dissect SDUs / control elements / padding.                           */
1181     /************************************************************************/
1182
1183     for (n=0; n < number_of_headers; n++) {
1184
1185         /* Data SDUs treated identically for Uplink or downlink channels */
1186         if (lcids[n] <= 10) {
1187             proto_item *sdu_ti;
1188             volatile guint16 data_length = (pdu_lengths[n] == -1) ?
1189                                                 tvb_length_remaining(tvb, offset) :
1190                                                 pdu_lengths[n];
1191
1192             /* Dissect SDU */
1193             sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_sch_sdu, tvb, offset, pdu_lengths[n],
1194                                                  tvb_get_ptr(tvb, offset, pdu_lengths[n]),
1195                                                  "SDU (%s, length=%u bytes)",
1196                                                  val_to_str(lcids[n],
1197                                                             (direction == DIRECTION_UPLINK) ?
1198                                                                 ulsch_lcid_vals :
1199                                                                 dlsch_lcid_vals,
1200                                                             "Unknown"),
1201                                                  data_length);
1202
1203             /* Look for Msg3 data so that it may be compared with later
1204                Contention Resolution body */
1205             if ((lcids[n] == 0) && (direction == DIRECTION_UPLINK) && (data_length == 6)) {
1206                 if (!pinfo->fd->flags.visited) {
1207                     guint key = p_mac_lte_info->rnti;
1208                     Msg3Data *data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(key));
1209
1210                     /* Look for previous entry for this UE */
1211                     if (data == NULL) {
1212                         /* Allocate space for data and add to table */
1213                         data = se_alloc(sizeof(Msg3Data));
1214                         g_hash_table_insert(mac_lte_msg3_hash, GUINT_TO_POINTER(key), data);
1215                     }
1216
1217                     /* Fill in data details */
1218                     data->framenum = pinfo->fd->num;
1219                     memcpy(&data->data, tvb_get_ptr(tvb, offset, data_length), data_length);
1220                 }
1221             }
1222
1223             /* CCCH frames can be dissected directly by LTE RRC... */
1224             if ((lcids[n] == 0) && global_mac_lte_attempt_rrc_decode) {
1225                 tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, data_length, data_length);
1226
1227                 /* Get appropriate dissector handle */
1228                 volatile dissector_handle_t protocol_handle = 0;
1229                 if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
1230                     protocol_handle = find_dissector("lte-rrc.ul.ccch");
1231                 }
1232                 else {
1233                     protocol_handle = find_dissector("lte-rrc.dl.ccch");
1234                 }
1235
1236                 /* Hide raw view of bytes */
1237                 PROTO_ITEM_SET_HIDDEN(sdu_ti);
1238
1239                 /* Call it (catch exceptions so that stats will be updated) */
1240                 TRY {
1241                     call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
1242                 }
1243                 CATCH_ALL {
1244                 }
1245                 ENDTRY
1246             }
1247
1248             offset += data_length;
1249
1250             /* Update tap byte count for this channel */
1251             tap_info->bytes_for_lcid[lcids[n]] += data_length;
1252             tap_info->sdus_for_lcid[lcids[n]]++;
1253         }
1254         else {
1255             /* See if its a control PDU type */
1256             if (direction == DIRECTION_DOWNLINK) {
1257
1258                 /****************************/
1259                 /* DL-SCH Control PDUs      */
1260                 switch (lcids[n]) {
1261                     case UE_CONTENTION_RESOLUTION_IDENTITY_LCID:
1262                         {
1263                             proto_item *cr_ti;
1264                             proto_tree *cr_tree;
1265                             proto_item *ti;
1266                             ContentionResolutionResult *crResult;
1267
1268                             /* Create CR root */
1269                             cr_ti = proto_tree_add_string_format(tree,
1270                                                                  hf_mac_lte_control_ue_contention_resolution,
1271                                                                  tvb, offset, 6,
1272                                                                  "",
1273                                                                  "Contention Resolution");
1274                             cr_tree = proto_item_add_subtree(cr_ti, ett_mac_lte_contention_resolution);
1275
1276
1277                             proto_tree_add_item(cr_tree, hf_mac_lte_control_ue_contention_resolution_identity,
1278                                                 tvb, offset, 6, FALSE);
1279
1280                             /* Get pointer to result struct for this frame */
1281                             crResult =  g_hash_table_lookup(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->fd->num));
1282                             if (crResult == NULL) {
1283
1284                                 /* Need to set result by looking for and comparing with Msg3 */
1285                                 Msg3Data *msg3Data;
1286                                 guint msg3Key = p_mac_lte_info->rnti;
1287
1288                                 /* Allocate result and add it to the table */
1289                                 crResult = se_alloc(sizeof(ContentionResolutionResult));
1290                                 g_hash_table_insert(mac_lte_cr_result_hash, GUINT_TO_POINTER(pinfo->fd->num), crResult);
1291
1292                                 /* Look for Msg3 */
1293                                 msg3Data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(msg3Key));
1294
1295                                 /* Compare CCCH bytes */
1296                                 if (msg3Data != NULL) {
1297                                     crResult->msg3FrameNum = msg3Data->framenum;
1298                                     if (memcmp(&msg3Data->data, tvb_get_ptr(tvb, offset, 6), 6) == 0) {
1299                                         crResult->status = Msg3Match;
1300                                     }
1301                                     else {
1302                                         crResult->status = Msg3NoMatch;
1303                                     }
1304                                 }
1305                                 else {
1306                                     crResult->status = NoMsg3;
1307                                 }
1308                             }
1309
1310                             /* Now show CR result in tree */
1311                             switch (crResult->status) {
1312                                 case NoMsg3:
1313                                     proto_item_append_text(cr_ti, " (no corresponding Msg3 found!)");
1314                                     break;
1315
1316                                 case Msg3Match:
1317                                     ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
1318                                                              tvb, 0, 0, crResult->msg3FrameNum);
1319                                     PROTO_ITEM_SET_GENERATED(ti);
1320                                     ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
1321                                                                 tvb, 0, 0, TRUE);
1322                                     PROTO_ITEM_SET_GENERATED(ti);
1323                                     proto_item_append_text(cr_ti, " (matches Msg3 from frame %u)", crResult->msg3FrameNum);
1324                                     break;
1325
1326                                 case Msg3NoMatch:
1327                                     ti = proto_tree_add_uint(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3,
1328                                                              tvb, 0, 0, crResult->msg3FrameNum);
1329                                     PROTO_ITEM_SET_GENERATED(ti);
1330                                     ti = proto_tree_add_boolean(cr_tree, hf_mac_lte_control_ue_contention_resolution_msg3_matched,
1331                                                                  tvb, 0, 0, FALSE);
1332                                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1333                                                            "CR body in Msg4 doesn't match Msg3 CCCH in frame %u",
1334                                                            crResult->msg3FrameNum);
1335                                     PROTO_ITEM_SET_GENERATED(ti);
1336                                     proto_item_append_text(cr_ti, " (doesn't match Msg3 from frame %u)", crResult->msg3FrameNum);
1337                                     break;
1338                             };
1339
1340                             offset += 6;
1341                         }
1342                         break;
1343                     case TIMING_ADVANCE_LCID:
1344                         {
1345                             proto_item *reserved_ti;
1346                             guint8      reserved;
1347
1348                             /* Check 2 reserved bits */
1349                             reserved = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
1350                             reserved_ti = proto_tree_add_item(tree, hf_mac_lte_control_timing_advance_reserved, tvb, offset, 1, FALSE);
1351                             if (global_mac_lte_check_reserved_bits && (reserved != 0)) {
1352                                 expert_add_info_format(pinfo, reserved_ti, PI_MALFORMED, PI_ERROR,
1353                                                        "Timing Advance Reserved bits not zero (found 0x%x)", reserved);
1354                             }
1355                             proto_tree_add_item(tree, hf_mac_lte_control_timing_advance,
1356                                                 tvb, offset, 1, FALSE);
1357                             offset++;
1358                         }
1359                         break;
1360                     case DRX_COMMAND_LCID:
1361                         /* No payload */
1362                         break;
1363                     case PADDING_LCID:
1364                         /* No payload, unless its the last subheader, in which case
1365                            it extends to the end of the PDU */
1366                         if (n == (number_of_headers-1)) {
1367                             if (tvb_length_remaining(tvb, offset) > 0) {
1368                                 proto_tree_add_item(tree, hf_mac_lte_padding_data,
1369                                                     tvb, offset, -1, FALSE);
1370                             }
1371                             padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
1372                                                                    tvb, offset, 0,
1373                                                                    p_mac_lte_info->length - offset);
1374                             PROTO_ITEM_SET_GENERATED(padding_length_ti);
1375
1376                             /* Make sure the PDU isn't bigger than reported! */
1377                             if (offset > p_mac_lte_info->length) {
1378                                 expert_add_info_format(pinfo, padding_length_ti, PI_MALFORMED, PI_ERROR,
1379                                                        "MAC PDU is longer than reported length (reported=%u, actual=%u)",
1380                                                        p_mac_lte_info->length, offset);
1381                             }
1382                         }
1383                         break;
1384
1385                     default:
1386                         break;
1387                 }
1388             }
1389             else {
1390
1391                 /**********************************/
1392                 /* UL-SCH Control PDUs            */
1393                 switch (lcids[n]) {
1394                     case POWER_HEADROOM_REPORT_LCID:
1395                         {
1396                             proto_item *phr_ti;
1397                             proto_tree *phr_tree;
1398                             proto_item *ti;
1399                             guint8 reserved;
1400                             guint8 level;
1401
1402                             /* Create PHR root */
1403                             phr_ti = proto_tree_add_string_format(tree,
1404                                                                   hf_mac_lte_control_power_headroom,
1405                                                                   tvb, offset, 1,
1406                                                                   "",
1407                                                                   "Power Headroom");
1408                             phr_tree = proto_item_add_subtree(phr_ti, ett_mac_lte_power_headroom);
1409
1410                             /* Check 2 Reserved bits */
1411                             reserved = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
1412                             ti = proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_reserved,
1413                                                      tvb, offset, 1, FALSE);
1414                             if (global_mac_lte_check_reserved_bits && (reserved != 0)) {
1415                                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1416                                                        "Power Headroom Reserved bits not zero (found 0x%x)", reserved);
1417                             }
1418
1419                             /* Level */
1420                             level = tvb_get_guint8(tvb, offset) & 0x3f;
1421                             proto_tree_add_item(phr_tree, hf_mac_lte_control_power_headroom_level,
1422                                                 tvb, offset, 1, FALSE);
1423
1424                             /* Show value in root label */
1425                             proto_item_append_text(phr_ti, " (POWER_HEADROOM_%u)", level);
1426                             offset++;
1427                         }
1428
1429
1430                         break;
1431                     case CRNTI_LCID:
1432                         proto_tree_add_item(tree, hf_mac_lte_control_crnti,
1433                                             tvb, offset, 2, FALSE);
1434                         offset += 2;
1435                         break;
1436                     case TRUNCATED_BSR_LCID:
1437                     case SHORT_BSR_LCID:
1438                         {
1439                             proto_tree *bsr_tree;
1440                             proto_item *bsr_ti;
1441                             guint8 lcgid;
1442                             guint8 buffer_size;
1443
1444                             bsr_ti = proto_tree_add_string_format(tree,
1445                                                                   hf_mac_lte_control_bsr,
1446                                                                   tvb, offset, 1,
1447                                                                   "",
1448                                                                   "BSR");
1449                             bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
1450
1451                             /* LCG ID */
1452                             lcgid = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
1453                             proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_lcg_id,
1454                                                         tvb, offset, 1, FALSE);
1455                             /* Buffer Size */
1456                             buffer_size = tvb_get_guint8(tvb, offset) & 0x3f;
1457                             proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_buffer_size,
1458                                                 tvb, offset, 1, FALSE);
1459                             offset++;
1460
1461                             proto_item_append_text(bsr_ti, " (lcgid=%u  %s)",
1462                                                    lcgid,
1463                                                    val_to_str(buffer_size, buffer_size_vals, "Unknown"));
1464                         }
1465                         break;
1466                     case LONG_BSR_LCID:
1467                         {
1468                             proto_tree *bsr_tree;
1469                             proto_item *bsr_ti;
1470                             bsr_ti = proto_tree_add_string_format(tree,
1471                                                                   hf_mac_lte_control_bsr,
1472                                                                   tvb, offset, 3,
1473                                                                   "",
1474                                                                   "Long BSR");
1475                             bsr_tree = proto_item_add_subtree(bsr_ti, ett_mac_lte_bsr);
1476
1477                             proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_buffer_size_1,
1478                                                 tvb, offset, 1, FALSE);
1479                             proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_buffer_size_2,
1480                                                 tvb, offset, 1, FALSE);
1481                             offset++;
1482                             proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_buffer_size_3,
1483                                                 tvb, offset, 1, FALSE);
1484                             offset++;
1485                             proto_tree_add_item(bsr_tree, hf_mac_lte_control_bsr_buffer_size_4,
1486                                                 tvb, offset, 1, FALSE);
1487                             offset++;
1488                         }
1489                         break;
1490                     case PADDING_LCID:
1491                         /* No payload, unless its the last subheader, in which case
1492                            it extends to the end of the PDU */
1493                         if (n == (number_of_headers-1)) {
1494                             if (tvb_length_remaining(tvb, offset) > 0) {
1495                                 proto_tree_add_item(tree, hf_mac_lte_padding_data,
1496                                                     tvb, offset, -1, FALSE);
1497                             }
1498                             padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
1499                                                                    tvb, offset, 0,
1500                                                                    p_mac_lte_info->length - offset);
1501                             PROTO_ITEM_SET_GENERATED(padding_length_ti);
1502
1503                             /* Make sure the PDU isn't bigger than reported! */
1504                             if (offset > p_mac_lte_info->length) {
1505                                 expert_add_info_format(pinfo, padding_length_ti, PI_MALFORMED, PI_ERROR,
1506                                                        "MAC PDU is longer than reported length (reported=%u, actual=%u)",
1507                                                        p_mac_lte_info->length, offset);
1508                             }
1509                         }
1510
1511                         break;
1512
1513                     default:
1514                         break;
1515                 }
1516             }
1517         }
1518     }
1519 }
1520
1521
1522
1523 /*****************************/
1524 /* Main dissection function. */
1525 void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1526 {
1527     proto_tree             *mac_lte_tree;
1528     proto_item             *ti;
1529     gint                   offset = 0;
1530     struct mac_lte_info   *p_mac_lte_info = NULL;
1531
1532     static mac_lte_tap_info tap_info;
1533     memset(&tap_info, 0, sizeof(mac_lte_tap_info));
1534
1535     /* Set protocol name */
1536     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC-LTE");
1537
1538     /* Create protocol tree. */
1539     ti = proto_tree_add_item(tree, proto_mac_lte, tvb, offset, -1, FALSE);
1540     mac_lte_tree = proto_item_add_subtree(ti, ett_mac_lte);
1541
1542
1543     /* Look for packet info! */
1544     p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte);
1545
1546     /* Can't dissect anything without it... */
1547     if (p_mac_lte_info == NULL) {
1548         proto_item *ti =
1549             proto_tree_add_text(mac_lte_tree, tvb, offset, -1,
1550                                 "Can't dissect LTE MAC frame because no per-frame info was attached!");
1551         PROTO_ITEM_SET_GENERATED(ti);
1552         return;
1553     }
1554
1555     /* Clear info column */
1556     col_clear(pinfo->cinfo, COL_INFO);
1557
1558
1559     /*****************************************/
1560     /* Show context information              */
1561
1562     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_radio_type,
1563                              tvb, 0, 0, p_mac_lte_info->radioType);
1564     PROTO_ITEM_SET_GENERATED(ti);
1565
1566     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_direction,
1567                              tvb, 0, 0, p_mac_lte_info->direction);
1568     PROTO_ITEM_SET_GENERATED(ti);
1569
1570     if (p_mac_lte_info->ueid != 0) {
1571         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_ueid,
1572                                  tvb, 0, 0, p_mac_lte_info->ueid);
1573         PROTO_ITEM_SET_GENERATED(ti);
1574     }
1575
1576     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_subframe_number,
1577                              tvb, 0, 0, p_mac_lte_info->subframeNumber);
1578     PROTO_ITEM_SET_GENERATED(ti);
1579
1580     if (p_mac_lte_info->rntiType != NO_RNTI) {
1581         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rnti,
1582                                  tvb, 0, 0, p_mac_lte_info->rnti);
1583         PROTO_ITEM_SET_GENERATED(ti);
1584     }
1585
1586     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_rnti_type,
1587                              tvb, 0, 0, p_mac_lte_info->rntiType);
1588     PROTO_ITEM_SET_GENERATED(ti);
1589
1590     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_predefined_frame,
1591                              tvb, 0, 0, p_mac_lte_info->isPredefinedData);
1592     if (p_mac_lte_info->isPredefinedData) {
1593         PROTO_ITEM_SET_GENERATED(ti);
1594     }
1595     else {
1596         PROTO_ITEM_SET_HIDDEN(ti);
1597     }
1598
1599     ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_length,
1600                              tvb, 0, 0, p_mac_lte_info->length);
1601     PROTO_ITEM_SET_GENERATED(ti);
1602
1603     if (p_mac_lte_info->reTxCount) {
1604         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_retx_count,
1605                                  tvb, 0, 0, p_mac_lte_info->reTxCount);
1606         PROTO_ITEM_SET_GENERATED(ti);
1607
1608         if (p_mac_lte_info->reTxCount >= global_mac_lte_retx_counter_trigger) {
1609             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_ERROR,
1610                                    "Frame has now been NACK'd %u times",
1611                                    p_mac_lte_info->reTxCount);
1612         }
1613     }
1614
1615     if (p_mac_lte_info->crcStatusValid) {
1616         ti = proto_tree_add_uint(mac_lte_tree, hf_mac_lte_context_crc_status,
1617                                  tvb, 0, 0, p_mac_lte_info->crcStatus);
1618         PROTO_ITEM_SET_GENERATED(ti);
1619         if (p_mac_lte_info->crcStatus != TRUE) {
1620             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1621                                    "Frame has CRC error");
1622             col_append_fstr(pinfo->cinfo, COL_INFO, "<CRC FAILURE> on %s %u ",
1623                             val_to_str(p_mac_lte_info->rntiType, rnti_type_vals,
1624                                        "Unknown RNTI type"),
1625                             p_mac_lte_info->rnti);
1626         }
1627     }
1628
1629
1630     /* Set context-info parts of tap struct */
1631     tap_info.rnti = p_mac_lte_info->rnti;
1632     tap_info.rntiType = p_mac_lte_info->rntiType;
1633     tap_info.isPredefinedData = p_mac_lte_info->isPredefinedData;
1634     tap_info.reTxCount = p_mac_lte_info->reTxCount;
1635     tap_info.crcStatusValid = p_mac_lte_info->crcStatusValid;
1636     tap_info.crcStatus = p_mac_lte_info->crcStatus;
1637     tap_info.direction = p_mac_lte_info->direction;
1638
1639     /* Also set total number of bytes (won't be used for UL/DL-SCH) */
1640     tap_info.single_number_of_bytes = tvb_length_remaining(tvb, offset);
1641
1642     /* If we know its predefined data, don't try to decode any further */
1643     if (p_mac_lte_info->isPredefinedData) {
1644         proto_tree_add_item(mac_lte_tree, hf_mac_lte_predefined_pdu, tvb, offset, -1, FALSE);
1645         col_append_fstr(pinfo->cinfo, COL_INFO, "Predefined data (%u bytes)", tvb_length_remaining(tvb, offset));
1646
1647         /* Queue tap info */
1648         if (!pinfo->in_error_pkt) {
1649             tap_queue_packet(mac_lte_tap, pinfo, &tap_info);
1650         }
1651
1652         return;
1653     }
1654
1655     /* IF CRC status failed, just do decode as raw bytes */
1656     if (!global_mac_lte_dissect_crc_failures &&
1657         (p_mac_lte_info->crcStatusValid && !p_mac_lte_info->crcStatus)) {
1658
1659         proto_tree_add_item(mac_lte_tree, hf_mac_lte_raw_pdu, tvb, offset, -1, FALSE);
1660         col_append_fstr(pinfo->cinfo, COL_INFO, "Raw data (%u bytes)", tvb_length_remaining(tvb, offset));
1661
1662         /* Queue tap info */
1663         if (!pinfo->in_error_pkt) {
1664             tap_queue_packet(mac_lte_tap, pinfo, &tap_info);
1665         }
1666
1667         return;
1668     }
1669
1670
1671
1672     /* Dissect the MAC PDU itself. Format depends upon RNTI type. */
1673     switch (p_mac_lte_info->rntiType) {
1674
1675         case P_RNTI:
1676             /* PCH PDU */
1677             dissect_pch(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info->direction);
1678             break;
1679
1680         case RA_RNTI:
1681             /* RAR PDU */
1682             dissect_rar(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info, &tap_info);
1683             break;
1684
1685         case C_RNTI:
1686             /* Can be UL-SCH or DL-SCH */
1687             dissect_ulsch_or_dlsch(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info->direction,
1688                                    p_mac_lte_info, &tap_info);
1689             break;
1690
1691         case SI_RNTI:
1692             /* BCH over DL-SCH */
1693             dissect_bch(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info);
1694             break;
1695
1696         case NO_RNTI:
1697             /* Must be BCH over BCH... */
1698             dissect_bch(tvb, pinfo, mac_lte_tree, offset, p_mac_lte_info);
1699             break;
1700
1701
1702         default:
1703             break;
1704     }
1705
1706     /* Queue tap info */
1707     /* TODO: if any of above (esp RRC dissection) throws exception, this isn't reached,
1708        but if call too early, won't have details... */
1709     tap_queue_packet(mac_lte_tap, pinfo, &tap_info);
1710 }
1711
1712
1713
1714 /* Initializes the hash table and the mem_chunk area each time a new
1715  * file is loaded or re-loaded in wireshark */
1716 static void
1717 mac_lte_init_protocol(void)
1718 {
1719     /* Destroy any existing tables. */
1720     if (mac_lte_msg3_hash) {
1721         g_hash_table_destroy(mac_lte_msg3_hash);
1722     }
1723     if (mac_lte_cr_result_hash) {
1724         g_hash_table_destroy(mac_lte_cr_result_hash);
1725     }
1726
1727     /* Now create them over */
1728     mac_lte_msg3_hash = g_hash_table_new(mac_lte_msg3_hash_func, mac_lte_msg3_hash_equal);
1729     mac_lte_cr_result_hash = g_hash_table_new(mac_lte_cr_result_hash_func, mac_lte_cr_result_hash_equal);
1730 }
1731
1732
1733 void proto_register_mac_lte(void)
1734 {
1735     static hf_register_info hf[] =
1736     {
1737         /**********************************/
1738         /* Items for decoding context     */
1739         { &hf_mac_lte_context_radio_type,
1740             { "Radio Type",
1741               "mac-lte.radio-type", FT_UINT8, BASE_DEC, VALS(radio_type_vals), 0x0,
1742               NULL, HFILL
1743             }
1744         },
1745         { &hf_mac_lte_context_direction,
1746             { "Direction",
1747               "mac-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
1748               "Direction of message", HFILL
1749             }
1750         },
1751         { &hf_mac_lte_context_rnti,
1752             { "RNTI",
1753               "mac-lte.rnti", FT_UINT16, BASE_DEC, 0, 0x0,
1754               "RNTI associated with message", HFILL
1755             }
1756         },
1757         { &hf_mac_lte_context_rnti_type,
1758             { "RNTI Type",
1759               "mac-lte.rnti-type", FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0,
1760               "Type of RNTI associated with message", HFILL
1761             }
1762         },
1763         { &hf_mac_lte_context_ueid,
1764             { "UEId",
1765               "mac-lte.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
1766               "User Equipment Identifier associated with message", HFILL
1767             }
1768         },
1769         { &hf_mac_lte_context_subframe_number,
1770             { "Subframe",
1771               "mac-lte.subframe", FT_UINT16, BASE_DEC, 0, 0x0,
1772               "Subframe number associate with message", HFILL
1773             }
1774         },
1775         { &hf_mac_lte_context_predefined_frame,
1776             { "Predefined frame",
1777               "mac-lte.is-predefined-frame", FT_UINT8, BASE_DEC, VALS(predefined_frame_vals), 0x0,
1778               "Predefined test frame (or real MAC PDU)", HFILL
1779             }
1780         },
1781         { &hf_mac_lte_context_length,
1782             { "Length of frame",
1783               "mac-lte.length", FT_UINT8, BASE_DEC, 0, 0x0,
1784               "Original length of frame (including SDUs and padding)", HFILL
1785             }
1786         },
1787         { &hf_mac_lte_context_bch_transport_channel,
1788             { "Transport channel",
1789               "mac-lte.bch-transport-channel", FT_UINT8, BASE_DEC, VALS(bch_transport_channel_vals), 0x0,
1790               "Transport channel BCH data was carried on", HFILL
1791             }
1792         },
1793         { &hf_mac_lte_context_retx_count,
1794             { "ReTX count",
1795               "mac-lte.retx-count", FT_UINT8, BASE_DEC, 0, 0x0,
1796               "Number of times this PDU has been retransmitted", HFILL
1797             }
1798         },
1799         { &hf_mac_lte_context_crc_status,
1800             { "CRC Status",
1801               "mac-lte.crc-status", FT_UINT8, BASE_DEC, VALS(crc_status_vals), 0x0,
1802               "CRC Status as reported by PHY", HFILL
1803             }
1804         },
1805
1806
1807         /*******************************************/
1808         /* MAC shared channel header fields        */
1809         { &hf_mac_lte_ulsch_header,
1810             { "UL-SCH Header",
1811               "mac-lte.ulsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
1812               NULL, HFILL
1813             }
1814         },
1815         { &hf_mac_lte_dlsch_header,
1816             { "DL-SCH Header",
1817               "mac-lte.dlsch.header", FT_STRING, BASE_NONE, NULL, 0x0,
1818               NULL, HFILL
1819             }
1820         },
1821         { &hf_mac_lte_sch_subheader,
1822             { "SCH sub-header",
1823               "mac-lte.sch.subheader", FT_STRING, BASE_NONE, NULL, 0x0,
1824               NULL, HFILL
1825             }
1826         },
1827         { &hf_mac_lte_sch_reserved,
1828             { "SCH reserved bits",
1829               "mac-lte.sch.reserved", FT_UINT8, BASE_HEX, NULL, 0xc0,
1830               NULL, HFILL
1831             }
1832         },
1833         { &hf_mac_lte_sch_extended,
1834             { "Extension",
1835               "mac-lte.sch.extended", FT_UINT8, BASE_HEX, 0, 0x20,
1836               "Extension - i.e. further headers after this one", HFILL
1837             }
1838         },
1839         { &hf_mac_lte_dlsch_lcid,
1840             { "LCID",
1841               "mac-lte.dlsch.lcid", FT_UINT8, BASE_HEX, VALS(dlsch_lcid_vals), 0x1f,
1842               "DL-SCH Logical Channel Identifier", HFILL
1843             }
1844         },
1845         { &hf_mac_lte_ulsch_lcid,
1846             { "LCID",
1847               "mac-lte.ulsch.lcid", FT_UINT8, BASE_HEX, VALS(ulsch_lcid_vals), 0x1f,
1848               "UL-SCH Logical Channel Identifier", HFILL
1849             }
1850         },
1851         { &hf_mac_lte_sch_format,
1852             { "Format",
1853               "mac-lte.sch.format", FT_UINT8, BASE_HEX, VALS(format_vals), 0x80,
1854               NULL, HFILL
1855             }
1856         },
1857         { &hf_mac_lte_sch_length,
1858             { "Length",
1859               "mac-lte.sch.length", FT_UINT16, BASE_DEC, 0, 0x0,
1860               "Length of MAC SDU or MAC control element", HFILL
1861             }
1862         },
1863         { &hf_mac_lte_sch_header_only,
1864             { "MAC PDU Header only",
1865               "mac-lte.sch.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
1866               NULL, HFILL
1867             }
1868         },
1869
1870         /********************************/
1871         /* Data                         */
1872         { &hf_mac_lte_sch_sdu,
1873             { "SDU",
1874               "mac-lte.sch.sdu", FT_BYTES, BASE_NONE, 0, 0x0,
1875               "Shared channel SDU", HFILL
1876             }
1877         },
1878         { &hf_mac_lte_bch_pdu,
1879             { "BCH PDU",
1880               "mac-lte.bch.pdu", FT_BYTES, BASE_NONE, 0, 0x0,
1881               NULL, HFILL
1882             }
1883         },
1884         { &hf_mac_lte_pch_pdu,
1885             { "PCH PDU",
1886               "mac-lte.pch.pdu", FT_BYTES, BASE_NONE, 0, 0x0,
1887               NULL, HFILL
1888             }
1889         },
1890         { &hf_mac_lte_predefined_pdu,
1891             { "Predefined data",
1892               "mac-lte.predefined-data", FT_BYTES, BASE_NONE, 0, 0x0,
1893               "Predefined test data", HFILL
1894             }
1895         },
1896         { &hf_mac_lte_raw_pdu,
1897             { "Raw data",
1898               "mac-lte.raw-data", FT_BYTES, BASE_NONE, 0, 0x0,
1899               "Raw bytes of PDU (e.g. if CRC failed)", HFILL
1900             }
1901         },
1902         { &hf_mac_lte_padding_data,
1903             { "Padding data",
1904               "mac-lte.padding-data", FT_BYTES, BASE_NONE, 0, 0x0,
1905               NULL, HFILL
1906             }
1907         },
1908         { &hf_mac_lte_padding_length,
1909             { "Padding length",
1910               "mac-lte.padding-length", FT_INT32, BASE_DEC, 0, 0x0,
1911               "Length of padding data not included at end of frame", HFILL
1912             }
1913         },
1914
1915
1916
1917         /*********************************/
1918         /* RAR fields                    */
1919         { &hf_mac_lte_rar,
1920             { "RAR",
1921               "mac-lte.rar", FT_NONE, BASE_NONE, NULL, 0x0,
1922               NULL, HFILL
1923             }
1924         },
1925         { &hf_mac_lte_rar_headers,
1926             { "RAR Headers",
1927               "mac-lte.rar.headers", FT_STRING, BASE_NONE, NULL, 0x0,
1928               NULL, HFILL
1929             }
1930         },
1931         { &hf_mac_lte_rar_header,
1932             { "RAR Header",
1933               "mac-lte.rar.header", FT_STRING, BASE_NONE, NULL, 0x0,
1934               NULL, HFILL
1935             }
1936         },
1937         { &hf_mac_lte_rar_extension,
1938             { "Extension",
1939               "mac-lte.rar.e", FT_UINT8, BASE_HEX, 0, 0x80,
1940               "Extension - i.e. further RAR headers after this one", HFILL
1941             }
1942         },
1943         { &hf_mac_lte_rar_t,
1944             { "Type",
1945               "mac-lte.rar.t", FT_UINT8, BASE_HEX, VALS(rar_type_vals), 0x40,
1946               "Type field indicating whether the payload is RAPID or BI", HFILL
1947             }
1948         },
1949         { &hf_mac_lte_rar_bi,
1950             { "BI",
1951               "mac-lte.rar.bi", FT_UINT8, BASE_HEX, VALS(rar_bi_vals), 0x0f,
1952               "Backoff Indicator (ms)", HFILL
1953             }
1954         },
1955         { &hf_mac_lte_rar_rapid,
1956             { "RAPID",
1957               "mac-lte.rar.rapid", FT_UINT8, BASE_HEX_DEC, 0, 0x3f,
1958               "Random Access Preamble IDentifier", HFILL
1959             }
1960         },
1961         { &hf_mac_lte_rar_reserved,
1962             { "Reserved",
1963               "mac-lte.rar.reserved", FT_UINT8, BASE_HEX, 0, 0x30,
1964               "Reserved bits in RAR header - should be 0", HFILL
1965             }
1966         },
1967
1968         { &hf_mac_lte_rar_body,
1969             { "RAR Body",
1970               "mac-lte.rar.body", FT_STRING, BASE_NONE, NULL, 0x0,
1971               NULL, HFILL
1972             }
1973         },
1974         { &hf_mac_lte_rar_reserved2,
1975             { "Reserved",
1976               "mac-lte.rar.reserved2", FT_UINT8, BASE_HEX, 0, 0x80,
1977               "Reserved bit in RAR body - should be 0", HFILL
1978             }
1979         },
1980         { &hf_mac_lte_rar_ta,
1981             { "Timing Advance",
1982               "mac-lte.rar.ta", FT_UINT16, BASE_DEC, 0, 0x7ff0,
1983               "Required adjustment to uplink transmission timing", HFILL
1984             }
1985         },
1986         { &hf_mac_lte_rar_ul_grant,
1987             { "UL Grant",
1988               "mac-lte.rar.ul-grant", FT_UINT24, BASE_DEC, 0, 0x0fffff,
1989               "Size of UL Grant", HFILL
1990             }
1991         },
1992         { &hf_mac_lte_rar_ul_grant_hopping,
1993             { "Hopping Flag",
1994               "mac-lte.rar.ul-grant.hopping", FT_UINT8, BASE_DEC, 0, 0x08,
1995               "Size of UL Grant", HFILL
1996             }
1997         },
1998         { &hf_mac_lte_rar_ul_grant_fsrba,
1999             { "Fixed sized resource block assignment",
2000               "mac-lte.rar.ul-grant.fsrba", FT_UINT16, BASE_DEC, 0, 0x07fe,
2001               NULL, HFILL
2002             }
2003         },
2004         { &hf_mac_lte_rar_ul_grant_tmcs,
2005             { "Truncated Modulation and coding scheme",
2006               "mac-lte.rar.ul-grant.tmcs", FT_UINT16, BASE_DEC, 0, 0x01e0,
2007               NULL, HFILL
2008             }
2009         },
2010         { &hf_mac_lte_rar_ul_grant_tcsp,
2011             { "TPC command for scheduled PUSCH",
2012               "mac-lte.rar.ul-grant.tcsp", FT_UINT8, BASE_DEC, 0, 0x01c,
2013               NULL, HFILL
2014             }
2015         },
2016         { &hf_mac_lte_rar_ul_grant_ul_delay,
2017             { "UL Delay",
2018               "mac-lte.rar.ul-grant.ul-delay", FT_UINT8, BASE_DEC, 0, 0x02,
2019               NULL, HFILL
2020             }
2021         },
2022         { &hf_mac_lte_rar_ul_grant_cqi_request,
2023             { "CQI Request",
2024               "mac-lte.rar.ul-grant.cqi-request", FT_UINT8, BASE_DEC, 0, 0x01,
2025               NULL, HFILL
2026             }
2027         },
2028         { &hf_mac_lte_rar_temporary_crnti,
2029             { "Temporary C-RNTI",
2030               "mac-lte.rar.temporary-crnti", FT_UINT16, BASE_DEC, 0, 0x0,
2031               NULL, HFILL
2032             }
2033         },
2034
2035         /**********************/
2036         /* Control PDU fields */
2037         { &hf_mac_lte_control_bsr,
2038             { "BSR",
2039               "mac-lte.control.bsr", FT_STRING, BASE_NONE, 0, 0x0,
2040               "Buffer Status Report", HFILL
2041             }
2042         },
2043         { &hf_mac_lte_control_bsr_lcg_id,
2044             { "Logical Channel Group ID",
2045               "mac-lte.control.bsr.lcg-id", FT_UINT8, BASE_DEC, 0, 0xc0,
2046               NULL, HFILL
2047             }
2048         },
2049         { &hf_mac_lte_control_bsr_buffer_size,
2050             { "Buffer Size",
2051               "mac-lte.control.bsr.buffer-size", FT_UINT8, BASE_DEC, VALS(buffer_size_vals), 0x3f,
2052               "Buffer Size available in all channels in group", HFILL
2053             }
2054         },
2055         { &hf_mac_lte_control_bsr_buffer_size_1,
2056             { "Buffer Size 1",
2057               "mac-lte.control.bsr.buffer-size-1", FT_UINT8, BASE_DEC, VALS(buffer_size_vals), 0xfc,
2058               "Buffer Size available in for 1st channel in group", HFILL
2059             }
2060         },
2061         { &hf_mac_lte_control_bsr_buffer_size_2,
2062             { "Buffer Size 2",
2063               "mac-lte.control.bsr.buffer-size-2", FT_UINT16, BASE_DEC, VALS(buffer_size_vals), 0x03c0,
2064               "Buffer Size available in for 2nd channel in group", HFILL
2065             }
2066         },
2067         { &hf_mac_lte_control_bsr_buffer_size_3,
2068             { "Buffer Size 3",
2069               "mac-lte.control.bsr.buffer-size-3", FT_UINT16, BASE_DEC, VALS(buffer_size_vals), 0x0fc0,
2070               "Buffer Size available in for 3rd channel in group", HFILL
2071             }
2072         },
2073         { &hf_mac_lte_control_bsr_buffer_size_4,
2074             { "Buffer Size 4",
2075               "mac-lte.control.bsr.buffer-size-4", FT_UINT8, BASE_DEC, VALS(buffer_size_vals), 0x3f,
2076               "Buffer Size available in for 4th channel in group", HFILL
2077             }
2078         },
2079         { &hf_mac_lte_control_crnti,
2080             { "C-RNTI",
2081               "mac-lte.control.crnti", FT_UINT16, BASE_DEC, 0, 0x0,
2082               "C-RNTI for the UE", HFILL
2083             }
2084         },
2085         { &hf_mac_lte_control_timing_advance,
2086             { "Timing Advance",
2087               "mac-lte.control.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
2088               "Timing Advance (0-1282 - see 36.213, 4.2.3)", HFILL
2089             }
2090         },
2091         { &hf_mac_lte_control_timing_advance_reserved,
2092             { "Reserved",
2093               "mac-lte.control.timing-advance.reserved", FT_UINT8, BASE_DEC, 0, 0xc0,
2094               "Reserved bits", HFILL
2095             }
2096         },
2097         { &hf_mac_lte_control_ue_contention_resolution,
2098             { "UE Contention Resolution",
2099               "mac-lte.control.ue-contention-resolution", FT_STRING, BASE_NONE, 0, 0x0,
2100               NULL, HFILL
2101             }
2102         },
2103         { &hf_mac_lte_control_ue_contention_resolution_identity,
2104             { "UE Contention Resolution Identity",
2105               "mac-lte.control.ue-contention-resolution.identity", FT_BYTES, BASE_NONE, 0, 0x0,
2106               NULL, HFILL
2107             }
2108         },
2109         { &hf_mac_lte_control_ue_contention_resolution_msg3,
2110             { "Msg3",
2111               "mac-lte.control.ue-contention-resolution.msg3", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2112               NULL, HFILL
2113             }
2114         },
2115         { &hf_mac_lte_control_ue_contention_resolution_msg3_matched,
2116             { "UE Contention Resolution Matches Msg3",
2117               "mac-lte.control.ue-contention-resolution.matches-msg3", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2118               NULL, HFILL
2119             }
2120         },
2121
2122         { &hf_mac_lte_control_power_headroom,
2123             { "Power Headroom",
2124               "mac-lte.control.power-headroom", FT_STRING, BASE_NONE, 0, 0x0,
2125               NULL, HFILL
2126             }
2127         },
2128         { &hf_mac_lte_control_power_headroom_reserved,
2129             { "Reserved",
2130               "mac-lte.control.power-headroom.reserved", FT_UINT8, BASE_DEC, 0, 0xc0,
2131               "Reserved bits, should be 0", HFILL
2132             }
2133         },
2134         { &hf_mac_lte_control_power_headroom_level,
2135             { "Power Headroom Level",
2136               "mac-lte.control.power-headroom.level", FT_UINT8, BASE_DEC, 0, 0x3f,
2137               NULL, HFILL
2138             }
2139         },
2140
2141         { &hf_mac_lte_control_padding,
2142             { "Padding",
2143               "mac-lte.control.padding", FT_NONE, BASE_NONE, 0, 0x0,
2144               NULL, HFILL
2145             }
2146         },
2147     };
2148
2149     static gint *ett[] =
2150     {
2151         &ett_mac_lte,
2152         &ett_mac_lte_context,
2153         &ett_mac_lte_rar_headers,
2154         &ett_mac_lte_rar_header,
2155         &ett_mac_lte_rar_body,
2156         &ett_mac_lte_rar_ul_grant,
2157         &ett_mac_lte_ulsch_header,
2158         &ett_mac_lte_dlsch_header,
2159         &ett_mac_lte_sch_subheader,
2160         &ett_mac_lte_bch,
2161         &ett_mac_lte_bsr,
2162         &ett_mac_lte_pch,
2163         &ett_mac_lte_contention_resolution,
2164         &ett_mac_lte_power_headroom
2165     };
2166
2167     module_t *mac_lte_module;
2168
2169     /* Register protocol. */
2170     proto_mac_lte = proto_register_protocol("MAC-LTE", "MAC-LTE", "mac-lte");
2171     proto_register_field_array(proto_mac_lte, hf, array_length(hf));
2172     proto_register_subtree_array(ett, array_length(ett));
2173
2174     /* Allow other dissectors to find this one by name. */
2175     register_dissector("mac-lte", dissect_mac_lte, proto_mac_lte);
2176
2177     /* Register the tap name */
2178     mac_lte_tap = register_tap("mac-lte");
2179
2180     /* Preferences */
2181     mac_lte_module = prefs_register_protocol(proto_mac_lte, NULL);
2182
2183     /* Obsolete this preference? (TODO: just delete since never in proper release?) */
2184     prefs_register_obsolete_preference(mac_lte_module, "single_rar");
2185
2186     prefs_register_bool_preference(mac_lte_module, "check_reserved_bits",
2187         "Warn if reserved bits are not 0",
2188         "When set, an expert warning will indicate if reserved bits are not zero",
2189         &global_mac_lte_check_reserved_bits);
2190
2191     prefs_register_uint_preference(mac_lte_module, "retx_count_warn",
2192         "Number of Re-Transmits before expert warning triggered",
2193         "Number of Re-Transmits before expert warning triggered",
2194         10, &global_mac_lte_retx_counter_trigger);
2195
2196     prefs_register_bool_preference(mac_lte_module, "attempt_rrc_decode",
2197         "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
2198         "Attempt to decode BCH, PCH and CCCH data using LTE RRC dissector",
2199         &global_mac_lte_attempt_rrc_decode);
2200
2201     prefs_register_bool_preference(mac_lte_module, "decode_rar_ul_grant",
2202         "Attempt to decode details of RAR UL grant field",
2203         "Attempt to decode details of RAR UL grant field",
2204         &global_mac_lte_decode_rar_ul_grant);
2205
2206     prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_crc_failures",
2207         "Dissect frames that have failed CRC check",
2208         "Attempt to dissect frames that have failed CRC check",
2209         &global_mac_lte_dissect_crc_failures);
2210
2211     prefs_register_bool_preference(mac_lte_module, "heuristic_mac_lte_over_udp",
2212         "Try Heuristic LTE-MAC over UDP framing",
2213         "When enabled, use heuristic dissector to find MAC-LTE frames sent with "
2214         "UDP framing",
2215         &global_mac_lte_heur);
2216
2217     register_init_routine(&mac_lte_init_protocol);
2218 }
2219
2220 void
2221 proto_reg_handoff_mac_lte(void)
2222 {
2223     static dissector_handle_t mac_lte_handle;
2224     if (!mac_lte_handle) {
2225         mac_lte_handle = find_dissector("mac-lte");
2226
2227         /* Add as a heuristic UDP dissector */
2228         heur_dissector_add("udp", dissect_mac_lte_heur, proto_mac_lte);
2229     }
2230 }
2231