Don't refer to file-static variables as extern (my gcc didn't like it).
[obnox/wireshark/wip.git] / epan / dissectors / packet-rlc-lte.c
1 /* Routines for LTE RLC 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  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <string.h>
31
32 #include <epan/packet.h>
33 #include <epan/expert.h>
34 #include <epan/prefs.h>
35 #include <epan/tap.h>
36
37 #include "packet-mac-lte.h"
38 #include "packet-rlc-lte.h"
39 #include "packet-pdcp-lte.h"
40
41
42 /* Described in:
43  * 3GPP TS 36.322 Evolved Universal Terrestial Radio Access (E-UTRA)
44  * Radio Link Control (RLC) Protocol specification
45  */
46
47 /* TODO:
48    - AM re-assembly?
49 */
50
51 /********************************/
52 /* Preference settings          */
53
54 #define SEQUENCE_ANALYSIS_MAC_ONLY 1
55 #define SEQUENCE_ANALYSIS_RLC_ONLY 2
56
57 /* By default don't try to analyse the sequence of messages for AM/UM channels */
58 static gint global_rlc_lte_am_sequence_analysis = FALSE;
59 static gint global_rlc_lte_um_sequence_analysis = FALSE;
60
61 /* By default don't call PDCP/RRC dissectors for SDU data */
62 static gboolean global_rlc_lte_call_pdcp = FALSE;
63 static gboolean global_rlc_lte_call_rrc = FALSE;
64
65 /* Preference to expect RLC headers without payloads */
66 static gboolean global_rlc_lte_headers_expected = FALSE;
67
68 /* Heuristic dissection */
69 static gboolean global_rlc_lte_heur = FALSE;
70
71
72 /**************************************************/
73 /* Initialize the protocol and registered fields. */
74 int proto_rlc_lte = -1;
75
76 extern int proto_mac_lte;
77 extern int proto_pdcp_lte;
78
79 static int rlc_lte_tap = -1;
80
81 /* Decoding context */
82 static int hf_rlc_lte_context = -1;
83 static int hf_rlc_lte_context_mode = -1;
84 static int hf_rlc_lte_context_direction = -1;
85 static int hf_rlc_lte_context_priority = -1;
86 static int hf_rlc_lte_context_ueid = -1;
87 static int hf_rlc_lte_context_channel_type = -1;
88 static int hf_rlc_lte_context_channel_id = -1;
89 static int hf_rlc_lte_context_pdu_length = -1;
90 static int hf_rlc_lte_context_um_sn_length = -1;
91
92 /* Transparent mode fields */
93 static int hf_rlc_lte_tm = -1;
94 static int hf_rlc_lte_tm_data = -1;
95
96 /* Unacknowledged mode fields */
97 static int hf_rlc_lte_um = -1;
98 static int hf_rlc_lte_um_header = -1;
99 static int hf_rlc_lte_um_fi = -1;
100 static int hf_rlc_lte_um_fixed_e = -1;
101 static int hf_rlc_lte_um_sn = -1;
102 static int hf_rlc_lte_um_fixed_reserved = -1;
103 static int hf_rlc_lte_um_data = -1;
104 static int hf_rlc_lte_extension_part = -1;
105
106 /* Extended header (common to UM and AM) */
107 static int hf_rlc_lte_extension_e = -1;
108 static int hf_rlc_lte_extension_li = -1;
109 static int hf_rlc_lte_extension_padding = -1;
110
111
112 /* Acknowledged mode fields */
113 static int hf_rlc_lte_am = -1;
114 static int hf_rlc_lte_am_header = -1;
115 static int hf_rlc_lte_am_data_control = -1;
116 static int hf_rlc_lte_am_rf = -1;
117 static int hf_rlc_lte_am_p = -1;
118 static int hf_rlc_lte_am_fi = -1;
119 static int hf_rlc_lte_am_fixed_e = -1;
120 static int hf_rlc_lte_am_fixed_sn = -1;
121 static int hf_rlc_lte_am_segment_lsf = -1;
122 static int hf_rlc_lte_am_segment_so = -1;
123 static int hf_rlc_lte_am_data = -1;
124
125 /* Control fields */
126 static int hf_rlc_lte_am_cpt = -1;
127 static int hf_rlc_lte_am_ack_sn = -1;
128 static int hf_rlc_lte_am_e1 = -1;
129 static int hf_rlc_lte_am_e2 = -1;
130 static int hf_rlc_lte_am_nack_sn = -1;
131 static int hf_rlc_lte_am_so_start = -1;
132 static int hf_rlc_lte_am_so_end = -1;
133
134 static int hf_rlc_lte_predefined_pdu = -1;
135 static int hf_rlc_lte_header_only = -1;
136
137 /* Sequence Analysis */
138 static int hf_rlc_lte_sequence_analysis = -1;
139 static int hf_rlc_lte_sequence_analysis_ok = -1;
140 static int hf_rlc_lte_sequence_analysis_previous_frame = -1;
141 static int hf_rlc_lte_sequence_analysis_expected_sn = -1;
142 static int hf_rlc_lte_sequence_analysis_framing_info_correct = -1;
143
144 static int hf_rlc_lte_sequence_analysis_mac_retx = -1;
145 static int hf_rlc_lte_sequence_analysis_retx = -1;
146 static int hf_rlc_lte_sequence_analysis_repeated = -1;
147 static int hf_rlc_lte_sequence_analysis_skipped = -1;
148
149 static int hf_rlc_lte_sequence_analysis_repeated_nack = -1;
150
151 /* Subtrees. */
152 static int ett_rlc_lte = -1;
153 static int ett_rlc_lte_context = -1;
154 static int ett_rlc_lte_um_header = -1;
155 static int ett_rlc_lte_am_header = -1;
156 static int ett_rlc_lte_extension_part = -1;
157 static int ett_rlc_lte_sequence_analysis = -1;
158
159 /* Value-strings */
160 static const value_string direction_vals[] =
161 {
162     { DIRECTION_UPLINK,      "Uplink"},
163     { DIRECTION_DOWNLINK,    "Downlink"},
164     { 0, NULL }
165 };
166
167 static const value_string rlc_mode_short_vals[] =
168 {
169     { RLC_TM_MODE,      "TM"},
170     { RLC_UM_MODE,      "UM"},
171     { RLC_AM_MODE,      "AM"},
172     { RLC_PREDEF,       "PREDEFINED"},
173     { 0, NULL }
174 };
175
176 static const value_string rlc_mode_vals[] =
177 {
178     { RLC_TM_MODE,      "Transparent Mode"},
179     { RLC_UM_MODE,      "Unacknowledged Mode"},
180     { RLC_AM_MODE,      "Acknowledged Mode"},
181     { 0, NULL }
182 };
183
184 static const value_string rlc_channel_type_vals[] =
185 {
186     { CHANNEL_TYPE_CCCH,     "CCCH"},
187     { CHANNEL_TYPE_BCCH,     "BCCH"},
188     { CHANNEL_TYPE_PCCH,     "PCCH"},
189     { CHANNEL_TYPE_SRB,      "SRB"},
190     { CHANNEL_TYPE_DRB,      "DRB"},
191     { 0, NULL }
192 };
193
194 static const value_string framing_info_vals[] =
195 {
196     { 0,      "First byte begins a RLC SDU and last byte ends a RLC SDU"},
197     { 1,      "First byte begins a RLC SDU and last byte does not end a RLC SDU"},
198     { 2,      "First byte does not begin a RLC SDU and last byte ends a RLC SDU"},
199     { 3,      "First byte does not begin a RLC SDU and last byte does not end a RLC SDU"},
200     { 0, NULL }
201 };
202
203 static const value_string fixed_extension_vals[] =
204 {
205     { 0,      "Data field follows from the octet following the fixed part of the header"},
206     { 1,      "A set of E field and LI field follows from the octet following the fixed part of the header"},
207     { 0, NULL }
208 };
209
210 static const value_string extension_extension_vals[] =
211 {
212     { 0,      "Data field follows from the octet following the LI field following this E field"},
213     { 1,      "A set of E field and LI field follows from the bit following the LI field following this E field"},
214     { 0, NULL }
215 };
216
217 static const value_string data_or_control_vals[] =
218 {
219     { 0,      "Control PDU"},
220     { 1,      "Data PDU"},
221     { 0, NULL }
222 };
223
224 static const value_string resegmentation_flag_vals[] =
225 {
226     { 0,      "AMD PDU"},
227     { 1,      "AMD PDU segment"},
228     { 0, NULL }
229 };
230
231 static const value_string polling_bit_vals[] =
232 {
233     { 0,      "Status report not requested"},
234     { 1,      "Status report is requested"},
235     { 0, NULL }
236 };
237
238 static const value_string lsf_vals[] =
239 {
240     { 0,      "Last byte of the AMD PDU segment does not correspond to the last byte of an AMD PDU"},
241     { 1,      "Last byte of the AMD PDU segment corresponds to the last byte of an AMD PDU"},
242     { 0, NULL }
243 };
244
245 static const value_string control_pdu_type_vals[] =
246 {
247     { 0,      "STATUS PDU"},
248     { 0, NULL }
249 };
250
251 static const value_string am_e1_vals[] =
252 {
253     { 0,      "A set of NACK_SN, E1 and E2 does not follow"},
254     { 1,      "A set of NACK_SN, E1 and E2 follows"},
255     { 0, NULL }
256 };
257
258 static const value_string am_e2_vals[] =
259 {
260     { 0,      "A set of SOstart and SOend does not follow for this NACK_SN"},
261     { 1,      "A set of SOstart and SOend follows for this NACK_SN"},
262     { 0, NULL }
263 };
264
265 static const value_string header_only_vals[] =
266 {
267     { 0,      "RLC PDU Headers and body present"},
268     { 1,      "RLC PDU Headers only"},
269     { 0, NULL }
270 };
271
272
273
274 /**********************************************************************************/
275 /* These are for keeping track of UM/AM extension headers, and the lengths found  */
276 /* in them                                                                        */
277 guint8  s_number_of_extensions = 0;
278 #define MAX_RLC_SDUS 64
279 guint16 s_lengths[MAX_RLC_SDUS];
280
281
282 /*********************************************************************/
283 /* UM/AM sequence analysis                                           */
284
285 /* Types for RLC channel hash table                                   */
286 /* This table is maintained during initial dissection of RLC          */
287 /* frames, mapping from rlc_channel_hash_key -> rlc_channel_status    */
288
289 /* Channel key */
290 typedef struct
291 {
292     guint16  ueId;
293     guint16  channelType;
294     guint16  channelId;
295     guint8   direction;
296 } rlc_channel_hash_key;
297
298 /* Conversation-type status for sequence analysis on channel */
299 typedef struct
300 {
301     guint8   rlcMode;
302
303     /* For UM, we always expect the SN to keep advancing, and these fields
304        keep track of this.
305        For AM, these correspond to new data */
306     guint16  previousSequenceNumber;
307     guint32  previousFrameNum;
308     gboolean previousSegmentIncomplete;
309 } rlc_channel_sequence_analysis_status;
310
311 /* The sequence analysis channel hash table */
312 static GHashTable *rlc_lte_sequence_analysis_channel_hash = NULL;
313
314
315 /* Types for sequence analysis frame report hash table                  */
316 /* This is a table from framenum -> state_report_in_frame               */
317 /* This is necessary because the per-packet info is already being used  */
318 /* for context information before the dissector is called               */
319
320 /* Info to attach to frame when first read, recording what to show about sequence */
321 typedef struct
322 {
323     gboolean  sequenceExpectedCorrect;
324     guint16   sequenceExpected;
325     guint32   previousFrameNum;
326     gboolean  previousSegmentIncomplete;
327
328     guint16   firstSN;
329     guint16   lastSN;
330
331     /* AM Only */
332     enum { SN_OK, SN_Repeated, SN_MAC_Retx, SN_Retx, SN_Missing} amState;
333 } state_sequence_analysis_report_in_frame;
334
335
336 /* The sequence analysis frame report hash table instance itself   */
337 static GHashTable *rlc_lte_frame_sequence_analysis_report_hash = NULL;
338
339
340 /******************************************************************/
341 /* Conversation-type status for repeated NACK checking on channel */
342 typedef struct
343 {
344     guint16         noOfNACKs;
345     guint16         NACKs[MAX_NACKs];
346 } rlc_channel_repeated_nack_status;
347
348 static GHashTable *rlc_lte_repeated_nack_channel_hash = NULL;
349
350 typedef struct {
351     guint16         noOfNACKsRepeated;
352     guint16         repeatedNACKs[MAX_NACKs];
353 } rlc_channel_repeated_nack_report_in_frame;
354
355 static GHashTable *rlc_lte_frame_repeated_nack_report_hash = NULL;
356
357
358
359 /********************************************************/
360 /* Forward declarations & functions                     */
361 void proto_reg_handoff_rlc_lte(void);
362 void dissect_rlc_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
363
364
365 /* Write the given formatted text to:
366    - the info column
367    - the top-level RLC PDU item
368    - another subtree item (if supplied) */
369 static void write_pdu_label_and_info(proto_item *pdu_ti, proto_item *sub_ti,
370                                      packet_info *pinfo, const char *format, ...)
371 {
372     #define MAX_INFO_BUFFER 256
373     static char info_buffer[MAX_INFO_BUFFER];
374     
375     va_list ap;
376
377     va_start(ap, format);
378     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
379     va_end(ap);
380
381     /* Add to indicated places */
382     col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
383     proto_item_append_text(pdu_ti, "%s", info_buffer);
384     if (sub_ti != NULL) {
385         proto_item_append_text(sub_ti, "%s", info_buffer);
386     }
387 }
388
389
390
391 /* Dissect extension headers (common to both UM and AM) */
392 static int dissect_rlc_lte_extension_header(tvbuff_t *tvb, packet_info *pinfo _U_,
393                                             proto_tree *tree,
394                                             int offset)
395 {
396     guint8  isOdd;
397     guint64 extension = 1;
398     guint64 length;
399
400     /* Reset this count */
401     s_number_of_extensions = 0;
402
403     while (extension && (s_number_of_extensions < MAX_RLC_SDUS)) {
404         proto_tree *extension_part_tree;
405         proto_item *extension_part_ti;
406
407         isOdd = (s_number_of_extensions % 2);
408
409         /* Extension part subtree */
410         extension_part_ti = proto_tree_add_string_format(tree,
411                                                          hf_rlc_lte_extension_part,
412                                                          tvb, offset, 2,
413                                                          "",
414                                                          "Extension Part");
415         extension_part_tree = proto_item_add_subtree(extension_part_ti,
416                                                      ett_rlc_lte_extension_part);
417
418         /* Read next extension */
419         proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_e, tvb,
420                                     (offset*8) + ((isOdd) ? 4 : 0),
421                                     1,
422                                     &extension, FALSE);
423
424         /* Read length field */
425         proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_li, tvb,
426                                     (offset*8) + ((isOdd) ? 5 : 1),
427                                     11,
428                                     &length, FALSE);
429
430         proto_item_append_text(extension_part_tree, " (length=%u)", (guint16)length);
431
432         /* Move on to byte of next extension */
433         if (isOdd) {
434             offset += 2;
435         } else {
436             offset++;
437         }
438
439         s_lengths[s_number_of_extensions++] = (guint16)length;
440     }
441
442     /* May need to skip padding after last extension part */
443     isOdd = (s_number_of_extensions % 2);
444     if (isOdd) {
445         guint8 padding;
446         proto_item *ti;
447
448         padding = tvb_get_guint8(tvb, offset) & 0x0f;
449         ti = proto_tree_add_item(tree, hf_rlc_lte_extension_padding,
450                                  tvb, offset, 1, FALSE);
451         offset++;
452     }
453
454     return offset;
455 }
456
457
458 /* Show in the info column how many bytes are in the UM/AM PDU, and indicate
459    whether or not the beginning and end are included in this packet */
460 static void show_PDU_in_info(packet_info *pinfo,
461                              proto_item *top_ti,
462                              guint16 length,
463                              gboolean first_includes_start,
464                              gboolean last_includes_end)
465 {
466     /* Reflect this PDU in the info column */
467     write_pdu_label_and_info(top_ti, NULL, pinfo,
468                              "  %s%u-byte%s%s",
469                              (first_includes_start) ? "[" : "..",
470                              length,
471                              (length > 1) ? "s" : "",
472                              (last_includes_end) ? "]" : "..");
473 }
474
475
476 /* Show an AM PDU.  If configured, pass to PDCP dissector */
477 static void show_AM_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, gint offset, gint length,
478                                 rlc_lte_info *rlc_info, gboolean whole_pdu)
479 {
480     proto_item *data_ti = proto_tree_add_item(tree, hf_rlc_lte_am_data, tvb, offset, length, FALSE);
481
482     /* Decode signalling PDUs as PDCP */
483     if (global_rlc_lte_call_pdcp && whole_pdu) {
484         if (rlc_info->channelType == CHANNEL_TYPE_SRB) {
485             /* Attempt to decode payload using LTE PDCP dissector */
486             tvbuff_t *pdcp_tvb = tvb_new_subset(tvb, offset, length, length);
487             volatile dissector_handle_t protocol_handle;
488
489             struct pdcp_lte_info *p_pdcp_lte_info;
490
491             /* Reuse or allocate struct */
492             p_pdcp_lte_info = p_get_proto_data(pinfo->fd, proto_pdcp_lte);
493             if (p_pdcp_lte_info == NULL) {
494                 p_pdcp_lte_info = se_alloc0(sizeof(struct pdcp_lte_info));
495                 /* Store info in packet */
496                 p_add_proto_data(pinfo->fd, proto_pdcp_lte, p_pdcp_lte_info);
497             }
498
499             p_pdcp_lte_info->channelType = Channel_DCCH;
500             p_pdcp_lte_info->direction = rlc_info->direction;
501             p_pdcp_lte_info->no_header_pdu = FALSE;
502             p_pdcp_lte_info->plane = SIGNALING_PLANE;
503
504             p_pdcp_lte_info->rohc_compression = FALSE;
505
506
507             /* Get dissector handle */
508             protocol_handle = find_dissector("pdcp-lte");
509
510             TRY {
511                 call_dissector_only(protocol_handle, pdcp_tvb, pinfo, tree);
512             }
513             CATCH_ALL {
514             }
515             ENDTRY
516
517             PROTO_ITEM_SET_HIDDEN(data_ti);
518         }
519     }
520 }
521
522 /* Hash table functions for RLC channels */
523
524 /* Equal keys */
525 static gint rlc_channel_equal(gconstpointer v, gconstpointer v2)
526 {
527     const rlc_channel_hash_key* val1 = v;
528     const rlc_channel_hash_key* val2 = v2;
529
530     /* All fields must match */
531     return ((val1->ueId        == val2->ueId) &&
532             (val1->channelType == val2->channelType) &&
533             (val1->channelId   == val2->channelId) &&
534             (val1->direction   == val2->direction));
535 }
536
537 /* Compute a hash value for a given key. */
538 static guint rlc_channel_hash_func(gconstpointer v)
539 {
540     const rlc_channel_hash_key* val1 = v;
541
542     /* TODO: check/reduce multipliers */
543     return ((val1->ueId * 1024) + (val1->channelType*64) + (val1->channelId*2) + val1->direction);
544 }
545
546
547
548 /* Hash table functions for frame reports */
549
550 /* Equal keys */
551 static gint rlc_frame_equal(gconstpointer v, gconstpointer v2)
552 {
553     return (v == v2);
554 }
555
556 /* Compute a hash value for a given key. */
557 static guint rlc_frame_hash_func(gconstpointer v)
558 {
559     return GPOINTER_TO_UINT(v);
560 }
561
562
563
564 /* Add to the tree values associated with sequence analysis for this frame */
565 static void addChannelSequenceInfo(state_sequence_analysis_report_in_frame *p,
566                                    rlc_lte_info *p_rlc_lte_info,
567                                    guint16   sequenceNumber,
568                                    gboolean  newSegmentStarted,
569                                    rlc_lte_tap_info *tap_info,
570                                    packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb)
571 {
572     proto_tree *seqnum_tree;
573     proto_item *seqnum_ti;
574     proto_item *ti;
575
576     /* Create subtree */
577     seqnum_ti = proto_tree_add_string_format(tree,
578                                              hf_rlc_lte_sequence_analysis,
579                                              tvb, 0, 0,
580                                              "", "Sequence Analysis");
581     seqnum_tree = proto_item_add_subtree(seqnum_ti,
582                                          ett_rlc_lte_sequence_analysis);
583     PROTO_ITEM_SET_GENERATED(seqnum_ti);
584
585     switch (p_rlc_lte_info->rlcMode) {
586         case RLC_AM_MODE:
587
588             /********************************************/
589             /* AM                                       */
590             /********************************************/
591
592             switch (p->amState) {
593                 case SN_OK:
594                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
595                                                 tvb, 0, 0, TRUE);
596                     PROTO_ITEM_SET_GENERATED(ti);
597                     proto_item_append_text(seqnum_ti, " - OK");
598                     break;
599
600                 case SN_MAC_Retx:
601                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
602                                                 tvb, 0, 0, FALSE);
603                     PROTO_ITEM_SET_GENERATED(ti);
604                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_mac_retx,
605                                                 tvb, 0, 0, TRUE);
606                     PROTO_ITEM_SET_GENERATED(ti);
607                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
608                                            "AM Frame retransmitted for %s on UE %u - due to MAC retx!",
609                                            val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
610                                            p_rlc_lte_info->ueid);
611                     break;
612
613                 case SN_Retx:
614                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
615                                                 tvb, 0, 0, FALSE);
616                     PROTO_ITEM_SET_GENERATED(ti);
617                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_retx,
618                                                 tvb, 0, 0, TRUE);
619                     PROTO_ITEM_SET_GENERATED(ti);
620                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
621                                            "AM Frame retransmitted for %s on UE %u - most likely in response to NACK",
622                                            val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
623                                            p_rlc_lte_info->ueid);
624                     proto_item_append_text(seqnum_ti, " - SN %u retransmitted", p->firstSN);
625                     break;
626
627                 case SN_Repeated:
628                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
629                                                 tvb, 0, 0, FALSE);
630                     PROTO_ITEM_SET_GENERATED(ti);
631                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_repeated,
632                                                 tvb, 0, 0, TRUE);
633                     PROTO_ITEM_SET_GENERATED(ti);
634                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
635                                            "AM SN Repeated for %s for UE %u - probably because didn't receive Status PDU?",
636                                            val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
637                                            p_rlc_lte_info->ueid);
638                     proto_item_append_text(seqnum_ti, "- SN %u Repeated",
639                                            p->sequenceExpected);
640                     break;
641
642                 case SN_Missing:
643                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
644                                                 tvb, 0, 0, FALSE);
645                     PROTO_ITEM_SET_GENERATED(ti);
646                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_skipped,
647                                                 tvb, 0, 0, TRUE);
648                     PROTO_ITEM_SET_GENERATED(ti);
649                     if (p->lastSN != p->firstSN) {
650                         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
651                                                "AM SNs (%u to %u) missing for %s on UE %u",
652                                                p->firstSN, p->lastSN,
653                                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
654                                                p_rlc_lte_info->ueid);
655                         proto_item_append_text(seqnum_ti, " - SNs missing (%u to %u)",
656                                                p->firstSN, p->lastSN);
657                         tap_info->missingSNs = ((p->lastSN - p->firstSN) % 1024) + 1;
658                     }
659                     else {
660                         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
661                                                "AM SN (%u) missing for %s on UE %u",
662                                                p->firstSN,
663                                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
664                                                p_rlc_lte_info->ueid);
665                         proto_item_append_text(seqnum_ti, " - SN missing (%u)",
666                                                p->firstSN);
667                         tap_info->missingSNs = 1;
668                     }
669                     break;
670             }
671             break;
672
673         case RLC_UM_MODE:
674
675             /********************************************/
676             /* UM                                       */
677             /********************************************/
678
679             /* Previous channel frame */
680             if (p->previousFrameNum != 0) {
681                 proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_previous_frame,
682                                     tvb, 0, 0, p->previousFrameNum);
683             }
684
685             /* Expected sequence number */
686             ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_expected_sn,
687                                     tvb, 0, 0, p->sequenceExpected);
688             PROTO_ITEM_SET_GENERATED(ti);
689
690             if (!p->sequenceExpectedCorrect) {
691                 /* Incorrect sequence number */
692                 expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
693                                        "Wrong Sequence Number for %s on UE %u - got %u, expected %u",
694                                        val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
695                                        p_rlc_lte_info->ueid, sequenceNumber, p->sequenceExpected);
696             }
697             else {
698                 /* Correct sequence number, so check frame indication bits consistent */
699                 if (p->previousSegmentIncomplete) {
700                     /* Previous segment was incomplete, so this PDU should continue it */
701                     if (newSegmentStarted) {
702                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
703                                                      tvb, 0, 0, FALSE);
704                         if (!p->sequenceExpectedCorrect) {
705                             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
706                                                    "Last segment of previous PDU was not continued for UE %u",
707                                                    p_rlc_lte_info->ueid);
708                         }
709                     }
710                     else {
711                        ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
712                                                    tvb, 0, 0, TRUE);
713                     }
714                 }
715                 else {
716                     /* Previous segment was complete, so this PDU should start a new one */
717                     if (!newSegmentStarted) {
718                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
719                                                     tvb, 0, 0, FALSE);
720                         if (!p->sequenceExpectedCorrect) {
721                             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
722                                                    "Last segment of previous PDU was complete, but new segment was not started");
723                         }
724                     }
725                     else {
726                        ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
727                                                    tvb, 0, 0, TRUE);
728                     }
729
730                 }
731                 PROTO_ITEM_SET_GENERATED(ti);
732             }
733     }
734 }
735
736 /* Update the channel status and set report for this frame */
737 static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb,
738                                      rlc_lte_info *p_rlc_lte_info,
739                                      guint16 sequenceNumber,
740                                      gboolean first_includes_start, gboolean last_includes_end,
741                                      gboolean is_resegmented _U_,
742                                      rlc_lte_tap_info *tap_info,
743                                      proto_tree *tree)
744 {
745     rlc_channel_hash_key   channel_key;
746     rlc_channel_hash_key   *p_channel_key;
747     rlc_channel_sequence_analysis_status     *p_channel_status;
748     state_sequence_analysis_report_in_frame  *p_report_in_frame = NULL;
749     gboolean               createdChannel = FALSE;
750     guint16                expectedSequenceNumber = 0;
751
752     /* If find stat_report_in_frame already, use that and get out */
753     if (pinfo->fd->flags.visited) {
754         p_report_in_frame = (state_sequence_analysis_report_in_frame*)g_hash_table_lookup(rlc_lte_frame_sequence_analysis_report_hash,
755                                                                                           &pinfo->fd->num);
756         if (p_report_in_frame != NULL) {
757             addChannelSequenceInfo(p_report_in_frame, p_rlc_lte_info,
758                                    sequenceNumber, first_includes_start,
759                                    tap_info, pinfo, tree, tvb);
760             return;
761         }
762         else {
763             /* Give up - we must have tried already... */
764             return;
765         }
766     }
767
768
769     /**************************************************/
770     /* Create or find an entry for this channel state */
771     channel_key.ueId = p_rlc_lte_info->ueid;
772     channel_key.channelType = p_rlc_lte_info->channelType;
773     channel_key.channelId = p_rlc_lte_info->channelId;
774     channel_key.direction = p_rlc_lte_info->direction;
775
776     /* Do the table lookup */
777     p_channel_status = (rlc_channel_sequence_analysis_status*)g_hash_table_lookup(rlc_lte_sequence_analysis_channel_hash, &channel_key);
778
779     /* Create table entry if necessary */
780     if (p_channel_status == NULL) {
781         createdChannel = TRUE;
782
783         /* Allocate a new key and value */
784         p_channel_key = se_alloc(sizeof(rlc_channel_hash_key));
785         p_channel_status = se_alloc0(sizeof(rlc_channel_sequence_analysis_status));
786
787         /* Copy key contents */
788         memcpy(p_channel_key, &channel_key, sizeof(rlc_channel_hash_key));
789
790         /* Set mode */
791         p_channel_status->rlcMode = p_rlc_lte_info->rlcMode;
792
793         /* Add entry */
794         g_hash_table_insert(rlc_lte_sequence_analysis_channel_hash, p_channel_key, p_channel_status);
795     }
796
797     /* Create space for frame state_report */
798     p_report_in_frame = se_alloc(sizeof(state_sequence_analysis_report_in_frame));
799
800     switch (p_channel_status->rlcMode) {
801         case RLC_UM_MODE:
802
803             /* Work out expected sequence number */
804             if (!createdChannel) {
805                 guint16  snLimit;
806                 if (p_rlc_lte_info->UMSequenceNumberLength == 5) {
807                     snLimit = 32;
808                 }
809                 else {
810                     snLimit = 1024;
811                 }
812                 expectedSequenceNumber = (p_channel_status->previousSequenceNumber + 1) % snLimit;
813             }
814
815             /* Set report for this frame */
816             /* For UM, sequence number is always expectedSequence number */
817             p_report_in_frame->sequenceExpectedCorrect = (sequenceNumber == expectedSequenceNumber);
818             p_report_in_frame->sequenceExpected = expectedSequenceNumber;
819             p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
820             p_report_in_frame->previousSegmentIncomplete = p_channel_status->previousSegmentIncomplete;
821
822             /* Update channel status to remember *this* frame */
823             p_channel_status->previousFrameNum = pinfo->fd->num;
824             p_channel_status->previousSequenceNumber = sequenceNumber;
825             p_channel_status->previousSegmentIncomplete = !last_includes_end;
826
827             break;
828
829         case RLC_AM_MODE:
830
831             /* Work out expected sequence number */
832             if (!createdChannel) {
833                 expectedSequenceNumber = (p_channel_status->previousSequenceNumber + 1) % 1024;
834             }
835
836             /* For AM, may be:
837                - expected Sequence number OR
838                - previous frame repeated
839                - old SN being sent (in response to NACK)
840                - new SN, but with frames missed out
841                Assume window whose front is at expectedSequenceNumber */
842
843             /* First of all, check to see whether frame is judged to be MAC Retx */
844             if (is_mac_lte_frame_retx(pinfo, p_rlc_lte_info->direction)) {
845                 /* Just report that this is a MAC Retx */
846                 p_report_in_frame->amState = SN_MAC_Retx;
847
848                 /* No channel state to update */
849             }
850
851
852             /* Expected? */
853             else if (sequenceNumber == expectedSequenceNumber) {
854
855                 /* Set report for this frame */
856                 p_report_in_frame->sequenceExpectedCorrect = TRUE;
857                 p_report_in_frame->sequenceExpected = expectedSequenceNumber;
858                 p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
859                 p_report_in_frame->previousSegmentIncomplete = p_channel_status->previousSegmentIncomplete;
860                 p_report_in_frame->amState = SN_OK;
861
862                 /* Update channel status */
863                 p_channel_status->previousSequenceNumber = sequenceNumber;
864                 p_channel_status->previousFrameNum = pinfo->fd->num;
865                 p_channel_status->previousSegmentIncomplete = !last_includes_end;
866             }
867
868             /* Previous subframe repeated? */
869             else if (((sequenceNumber+1) % 1024) == expectedSequenceNumber) {
870                 p_report_in_frame->amState = SN_Repeated;
871
872                 /* Set report for this frame */
873                 p_report_in_frame->sequenceExpectedCorrect = FALSE;
874                 p_report_in_frame->sequenceExpected = sequenceNumber;
875                 p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
876                 p_report_in_frame->previousSegmentIncomplete = p_channel_status->previousSegmentIncomplete;
877
878
879                 /* Really should be nothing to update... */
880                 p_channel_status->previousSequenceNumber = sequenceNumber;
881                 p_channel_status->previousFrameNum = pinfo->fd->num;
882                 p_channel_status->previousSegmentIncomplete = !last_includes_end;
883             }
884
885             else {
886                 /* Need to work out if new (with skips, or likely a retx (due to NACK)) */
887                 int delta  = (1024 + expectedSequenceNumber - sequenceNumber) % 1024;
888
889                 /* Rx window is 512, so check to see if this is a retx */
890                 if (delta < 512) {
891                     /* Probably a retx due to receiving NACK */
892                     p_report_in_frame->amState = SN_Retx;
893
894                     p_report_in_frame->firstSN = sequenceNumber;
895                     /* Don't update anything in channel state */
896                 }
897
898                 else {
899                     /* Ahead of expected SN. Assume frames have been missed */
900                     p_report_in_frame->amState = SN_Missing;
901
902                     p_report_in_frame->firstSN = expectedSequenceNumber;
903                     p_report_in_frame->lastSN = (1024 + sequenceNumber-1) % 1024;
904
905                     /* Update channel state - forget about missed SNs */
906                     p_report_in_frame->sequenceExpected = expectedSequenceNumber;
907                     p_channel_status->previousSequenceNumber = sequenceNumber;
908                     p_channel_status->previousFrameNum = pinfo->fd->num;
909                     p_channel_status->previousSegmentIncomplete = !last_includes_end;
910                 }
911             }
912             break;
913
914         default:
915             /* Shouldn't get here! */
916             return;
917     }
918
919     /* Associate with this frame number */
920     g_hash_table_insert(rlc_lte_frame_sequence_analysis_report_hash, &pinfo->fd->num, p_report_in_frame);
921
922     /* Add state report for this frame into tree */
923     addChannelSequenceInfo(p_report_in_frame, p_rlc_lte_info, sequenceNumber,
924                            first_includes_start, tap_info, pinfo, tree, tvb);
925 }
926
927
928 /* Add to the tree values associated with sequence analysis for this frame */
929 static void addChannelRepeatedNACKInfo(rlc_channel_repeated_nack_report_in_frame *p,
930                                        rlc_lte_info *p_rlc_lte_info _U_,
931                                        packet_info *pinfo, proto_tree *tree,
932                                        tvbuff_t *tvb)
933 {
934     proto_tree *seqnum_tree;
935     proto_item *seqnum_ti;
936     proto_item *ti;
937     gint       n;
938
939     /* Create subtree */
940     seqnum_ti = proto_tree_add_string_format(tree,
941                                              hf_rlc_lte_sequence_analysis,
942                                              tvb, 0, 0,
943                                              "", "Sequence Analysis");
944     seqnum_tree = proto_item_add_subtree(seqnum_ti,
945                                          ett_rlc_lte_sequence_analysis);
946     PROTO_ITEM_SET_GENERATED(seqnum_ti);
947
948     /* OK = FALSE */
949     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
950                                 tvb, 0, 0, FALSE);
951     PROTO_ITEM_SET_GENERATED(ti);
952
953     /* Add each repeated NACK as item & expert info */
954     for (n=0; n < p->noOfNACKsRepeated; n++) {
955
956         ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_repeated_nack,
957                                  tvb, 0, 0, p->repeatedNACKs[n]);
958         PROTO_ITEM_SET_GENERATED(ti);
959
960         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_ERROR,
961                                "Same SN  (%u) NACKd for %s on UE %u in successive Status PDUs",
962                                p->repeatedNACKs[n],
963                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
964                                p_rlc_lte_info->ueid);
965     }
966
967     /* Append count to sequence analysis root */
968     proto_item_append_text(seqnum_ti, " - %u SNs repeated from previous Status PDU",
969                            p->noOfNACKsRepeated);         
970 }
971
972
973 /* Update the channel repeated NACK status and set report for this frame */
974 static void checkChannelRepeatedNACKInfo(packet_info *pinfo,
975                                          rlc_lte_info *p_rlc_lte_info,
976                                          rlc_lte_tap_info *tap_info,
977                                          proto_tree *tree,
978                                          tvbuff_t *tvb)
979 {
980     rlc_channel_hash_key   channel_key;
981     rlc_channel_hash_key   *p_channel_key;
982     rlc_channel_repeated_nack_status     *p_channel_status;
983     rlc_channel_repeated_nack_report_in_frame  *p_report_in_frame = NULL;
984
985     guint16         noOfNACKsRepeated = 0;
986     guint16         repeatedNACKs[MAX_NACKs];
987     gint            n, i, j;
988
989     /* If find state_report_in_frame already, use that and get out */
990     if (pinfo->fd->flags.visited) {
991         p_report_in_frame = (rlc_channel_repeated_nack_report_in_frame*)g_hash_table_lookup(rlc_lte_frame_repeated_nack_report_hash,
992                                                                                             &pinfo->fd->num);
993         if (p_report_in_frame != NULL) {
994             addChannelRepeatedNACKInfo(p_report_in_frame, p_rlc_lte_info,
995                                        pinfo, tree, tvb);
996             return;
997         }
998         else {
999             /* Give up - we must have tried already... */
1000             return;
1001         }
1002     }
1003
1004
1005     /**************************************************/
1006     /* Create or find an entry for this channel state */
1007     channel_key.ueId = p_rlc_lte_info->ueid;
1008     channel_key.channelType = p_rlc_lte_info->channelType;
1009     channel_key.channelId = p_rlc_lte_info->channelId;
1010     channel_key.direction = p_rlc_lte_info->direction;
1011
1012     /* Do the table lookup */
1013     p_channel_status = (rlc_channel_repeated_nack_status*)g_hash_table_lookup(rlc_lte_repeated_nack_channel_hash, &channel_key);
1014
1015     /* Create table entry if necessary */
1016     if (p_channel_status == NULL) {
1017
1018         /* Allocate a new key and value */
1019         p_channel_key = se_alloc(sizeof(rlc_channel_hash_key));
1020         p_channel_status = se_alloc0(sizeof(rlc_channel_repeated_nack_status));
1021
1022         /* Copy key contents */
1023         memcpy(p_channel_key, &channel_key, sizeof(rlc_channel_hash_key));
1024
1025         /* Add entry to table */
1026         g_hash_table_insert(rlc_lte_repeated_nack_channel_hash, p_channel_key, p_channel_status);
1027     }
1028
1029     /* Compare NACKs in channel status with NACKs in tap_info.
1030        Note any that are repeated */
1031     for (i=0; i < p_channel_status->noOfNACKs; i++) {
1032         for (j=0; j < MIN(tap_info->noOfNACKs, MAX_NACKs); j++) {
1033             if (tap_info->NACKs[j] == p_channel_status->NACKs[i]) {
1034                 /* Don't add the same repeated NACK twice! */
1035                 if ((noOfNACKsRepeated == 0) ||
1036                     (repeatedNACKs[noOfNACKsRepeated-1] != p_channel_status->NACKs[i])) {
1037
1038                     repeatedNACKs[noOfNACKsRepeated++] = p_channel_status->NACKs[i];
1039                 }
1040             }
1041         }
1042     }
1043
1044     /* Copy NACKs from tap_info into channel status for next time! */
1045     p_channel_status->noOfNACKs = 0;
1046     for (n=0; n < MIN(tap_info->noOfNACKs, MAX_NACKs); n++) {
1047         p_channel_status->NACKs[p_channel_status->noOfNACKs++] = tap_info->NACKs[n];
1048     }
1049
1050     if (noOfNACKsRepeated >= 1) {
1051         /* Create space for frame state_report */
1052         p_report_in_frame = se_alloc(sizeof(rlc_channel_repeated_nack_report_in_frame));
1053
1054         /* Copy in found duplicates */
1055         for (n=0; n < MIN(tap_info->noOfNACKs, MAX_NACKs); n++) {
1056             p_report_in_frame->repeatedNACKs[n] = repeatedNACKs[n];
1057         }
1058         p_report_in_frame->noOfNACKsRepeated = noOfNACKsRepeated;
1059
1060         /* Associate with this frame number */
1061         g_hash_table_insert(rlc_lte_frame_repeated_nack_report_hash, &pinfo->fd->num, p_report_in_frame);
1062
1063         /* Add state report for this frame into tree */
1064         addChannelRepeatedNACKInfo(p_report_in_frame, p_rlc_lte_info,
1065                                    pinfo, tree, tvb);
1066     }
1067 }
1068
1069
1070
1071 /***************************************************/
1072 /* Transparent mode PDU. Call RRC if configured to */
1073 static void dissect_rlc_lte_tm(tvbuff_t *tvb, packet_info *pinfo,
1074                                proto_tree *tree,
1075                                int offset,
1076                                rlc_lte_info *p_rlc_lte_info,
1077                                proto_item *top_ti _U_)
1078 {
1079     proto_item *raw_tm_ti;
1080     proto_item *tm_ti;
1081
1082     /* Create hidden TM root */
1083     tm_ti = proto_tree_add_string_format(tree, hf_rlc_lte_tm,
1084                                          tvb, offset, 0, "", "UM");
1085     PROTO_ITEM_SET_HIDDEN(tm_ti);
1086
1087     /* Remaining bytes are all data */
1088     raw_tm_ti = proto_tree_add_item(tree, hf_rlc_lte_tm_data, tvb, offset, -1, FALSE);
1089     if (!global_rlc_lte_call_rrc) {
1090         write_pdu_label_and_info(top_ti, NULL, pinfo,
1091                                  "   [%u-bytes]", tvb_length_remaining(tvb, offset));
1092     }
1093
1094     if (global_rlc_lte_call_rrc) {
1095         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
1096         volatile dissector_handle_t protocol_handle = 0;
1097
1098         switch (p_rlc_lte_info->channelType) {
1099             case CHANNEL_TYPE_CCCH:
1100                 if (p_rlc_lte_info->direction == DIRECTION_UPLINK) {
1101                     protocol_handle = find_dissector("lte-rrc.ul.ccch");
1102                 }
1103                 else {
1104                     protocol_handle = find_dissector("lte-rrc.dl.ccch");
1105                 }
1106                 break;
1107
1108             case CHANNEL_TYPE_BCCH:
1109                 /* TODO: Problem is don't know which transport channel... */
1110                 return;
1111
1112             case CHANNEL_TYPE_PCCH:
1113                 protocol_handle = find_dissector("lte-rrc.pcch");
1114                 break;
1115
1116             case CHANNEL_TYPE_SRB:
1117             case CHANNEL_TYPE_DRB:
1118
1119             default:
1120                 /* Shouldn't happen, just return... */
1121                 return;
1122         }
1123
1124         /* Hide raw view of bytes */
1125         PROTO_ITEM_SET_HIDDEN(raw_tm_ti);
1126
1127         /* Call it (catch exceptions) */
1128         TRY {
1129             call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
1130         }
1131         CATCH_ALL {
1132         }
1133         ENDTRY
1134     }
1135 }
1136
1137
1138
1139 /***************************************************/
1140 /* Unacknowledged mode PDU                         */
1141 static void dissect_rlc_lte_um(tvbuff_t *tvb, packet_info *pinfo,
1142                                proto_tree *tree,
1143                                int offset,
1144                                rlc_lte_info *p_rlc_lte_info,
1145                                proto_item *top_ti,
1146                                rlc_lte_tap_info *tap_info)
1147 {
1148     guint64 framing_info;
1149     gboolean first_includes_start;
1150     gboolean last_includes_end;
1151     guint64 fixed_extension;
1152     guint64 sn;
1153     gint    start_offset = offset;
1154     proto_item *um_ti;
1155     proto_tree *um_header_tree;
1156     proto_item *um_header_ti;
1157     gboolean is_truncated;
1158     proto_item *truncated_ti;
1159
1160     /* Hidden UM root */
1161     um_ti = proto_tree_add_string_format(tree, hf_rlc_lte_um,
1162                                          tvb, offset, 0, "", "UM");
1163     PROTO_ITEM_SET_HIDDEN(um_ti);
1164
1165     /* Add UM header subtree */
1166     um_header_ti = proto_tree_add_string_format(tree, hf_rlc_lte_um_header,
1167                                                 tvb, offset, 0,
1168                                                 "", "UM header");
1169     um_header_tree = proto_item_add_subtree(um_header_ti,
1170                                             ett_rlc_lte_um_header);
1171
1172
1173     /*******************************/
1174     /* Fixed UM header             */
1175     if (p_rlc_lte_info->UMSequenceNumberLength == UM_SN_LENGTH_5_BITS) {
1176         /* Framing info (2 bits) */
1177         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fi,
1178                                     tvb, offset*8, 2,
1179                                     &framing_info, FALSE);
1180
1181         /* Extension (1 bit) */
1182         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fixed_e, tvb,
1183                                     (offset*8) + 2, 1,
1184                                     &fixed_extension, FALSE);
1185
1186         /* Sequence Number (5 bit) */
1187         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_sn, tvb,
1188                                     (offset*8) + 3, 5,
1189                                     &sn, FALSE);
1190         offset++;
1191     }
1192     else if (p_rlc_lte_info->UMSequenceNumberLength == UM_SN_LENGTH_10_BITS) {
1193         guint8 reserved;
1194         proto_item *ti;
1195
1196         /* Check 3 Reserved bits */
1197         reserved = (tvb_get_guint8(tvb, offset) & 0xe0) >> 5;
1198         ti = proto_tree_add_item(um_header_tree, hf_rlc_lte_um_fixed_reserved, tvb, offset, 1, FALSE);
1199         if (reserved != 0) {
1200             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1201                       "RLC UM Fixed header Reserved bits not zero (found 0x%x)", reserved);
1202         }
1203
1204         /* Framing info (2 bits) */
1205         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fi,
1206                                     tvb, (offset*8)+3, 2,
1207                                     &framing_info, FALSE);
1208
1209         /* Extension (1 bit) */
1210         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fixed_e, tvb,
1211                                     (offset*8) + 5, 1,
1212                                     &fixed_extension, FALSE);
1213
1214         /* Sequence Number (10 bits) */
1215         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_sn, tvb,
1216                                     (offset*8) + 6, 10,
1217                                     &sn, FALSE);
1218         offset += 2;
1219     }
1220     else {
1221         /* Invalid length of sequence number */
1222         proto_item *ti;
1223         ti = proto_tree_add_text(um_header_tree, tvb, 0, 0, "Invalid sequence number length (%u bits)",
1224                                  p_rlc_lte_info->UMSequenceNumberLength);
1225         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1226                                "Invalid sequence number length (%u bits)",
1227                                p_rlc_lte_info->UMSequenceNumberLength);
1228         return;
1229     }
1230
1231     tap_info->sequenceNumber = (guint16)sn;
1232
1233     /* Show SN in info column */
1234     write_pdu_label_and_info(top_ti, NULL, pinfo, "  SN=%04u", (guint16)sn);
1235
1236     proto_item_set_len(um_header_ti, offset-start_offset);
1237
1238
1239     /*************************************/
1240     /* UM header extension               */
1241     if (fixed_extension) {
1242         offset = dissect_rlc_lte_extension_header(tvb, pinfo, tree, offset);
1243     }
1244
1245     if (global_rlc_lte_headers_expected) {
1246         /* There might not be any data, if only headers (plus control data) were logged */
1247         is_truncated = (tvb_length_remaining(tvb, offset) == 0);
1248         truncated_ti = proto_tree_add_uint(tree, hf_rlc_lte_header_only, tvb, 0, 0,
1249                                            is_truncated);
1250         if (is_truncated) {
1251             PROTO_ITEM_SET_GENERATED(truncated_ti);
1252             expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
1253                                    "RLC PDU SDUs have been omitted");
1254             return;
1255         }
1256         else {
1257             PROTO_ITEM_SET_HIDDEN(truncated_ti);
1258         }
1259     }
1260
1261     /* Extract these 2 flags from framing_info */
1262     first_includes_start = ((guint8)framing_info & 0x02) == 0;
1263     last_includes_end =    ((guint8)framing_info & 0x01) == 0;
1264
1265
1266     /* Call sequence analysis function now */
1267     if (((global_rlc_lte_um_sequence_analysis == SEQUENCE_ANALYSIS_MAC_ONLY) &&
1268          (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL)) ||
1269         ((global_rlc_lte_um_sequence_analysis == SEQUENCE_ANALYSIS_RLC_ONLY) &&
1270          (p_get_proto_data(pinfo->fd, proto_mac_lte) == NULL))) {
1271
1272         checkChannelSequenceInfo(pinfo, tvb, p_rlc_lte_info,
1273                                 (guint16)sn, first_includes_start, last_includes_end,
1274                                 FALSE, /* UM doesn't re-segment */
1275                                 tap_info, um_header_tree);
1276     }
1277
1278
1279     /*************************************/
1280     /* Data                              */
1281     if (s_number_of_extensions > 0) {
1282         /* Show each data segment separately */
1283         int n;
1284         for (n=0; n < s_number_of_extensions; n++) {
1285             proto_tree_add_item(tree, hf_rlc_lte_um_data, tvb, offset, s_lengths[n], FALSE);
1286             show_PDU_in_info(pinfo, top_ti, s_lengths[n],
1287                              (n==0) ? first_includes_start : TRUE,
1288                              TRUE);
1289             tvb_ensure_bytes_exist(tvb, offset, s_lengths[n]);
1290             offset += s_lengths[n];
1291         }
1292     }
1293
1294     /* Final data element */
1295     proto_tree_add_item(tree, hf_rlc_lte_um_data, tvb, offset, -1, FALSE);
1296     show_PDU_in_info(pinfo, top_ti, (guint16)tvb_length_remaining(tvb, offset),
1297                      (s_number_of_extensions == 0) ? first_includes_start : TRUE,
1298                      last_includes_end);
1299 }
1300
1301
1302
1303 /* Dissect an AM STATUS PDU */
1304 static void dissect_rlc_lte_am_status_pdu(tvbuff_t *tvb,
1305                                           packet_info *pinfo,
1306                                           proto_tree *tree,
1307                                           proto_item *status_ti,
1308                                           int offset,
1309                                           proto_item *top_ti,
1310                                           rlc_lte_info *p_rlc_lte_info,
1311                                           rlc_lte_tap_info *tap_info)
1312 {
1313     guint8     cpt;
1314     guint64    ack_sn, nack_sn;
1315     guint16    nack_count = 0;
1316     guint64    e1 = 0, e2 = 0;
1317     guint64    so_start, so_end;
1318     int        bit_offset = offset * 8;
1319     proto_item *ti;
1320
1321     /****************************************************************/
1322     /* Part of RLC control PDU header                               */
1323
1324     /* Control PDU Type (CPT) */
1325     cpt = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
1326     ti = proto_tree_add_item(tree, hf_rlc_lte_am_cpt, tvb, offset, 1, FALSE);
1327     if (cpt != 0) {
1328         /* Protest and stop - only know about STATUS PDUs */
1329         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1330                                "RLC Control frame type %u not handled", cpt);
1331         return;
1332     }
1333
1334     /* The Status PDU itself starts 4 bits into the byte */
1335     bit_offset += 4;
1336
1337     /* ACK SN */
1338     proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_ack_sn, tvb,
1339                                 bit_offset, 10, &ack_sn, FALSE);
1340     bit_offset += 10;
1341     write_pdu_label_and_info(top_ti, status_ti, pinfo, "  ACK_SN=%u", (guint16)ack_sn);
1342
1343     tap_info->ACKNo = (guint16)ack_sn;
1344
1345     /* E1 */
1346     proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e1, tvb,
1347                                 bit_offset, 1, &e1, FALSE);
1348
1349     /* Skip another bit to byte-align the next bit... */
1350     bit_offset++;
1351
1352     /* Optional, extra fields */
1353     do {
1354         if (e1) {
1355             proto_item *nack_ti;
1356
1357             /****************************/
1358             /* Read NACK_SN, E1, E2     */
1359
1360             /* NACK_SN */
1361             nack_ti = proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_nack_sn, tvb,
1362                                                   bit_offset, 10, &nack_sn, FALSE);
1363             bit_offset += 10;
1364             write_pdu_label_and_info(top_ti, NULL, pinfo, "  NACK_SN=%u", (guint16)nack_sn);
1365
1366             /* Copy into struct, but don't exceed buffer */
1367             if (nack_count < MAX_NACKs) {
1368                 tap_info->NACKs[nack_count++] = (guint16)nack_sn;
1369             }
1370             else {
1371                 /* Let it get bigger than the array for accurate stats... */
1372                 nack_count++;
1373             }
1374
1375             /* E1 */
1376             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e1, tvb,
1377                                         bit_offset, 1, &e1, FALSE);
1378             bit_offset++;
1379
1380             /* E2 */
1381             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e2, tvb,
1382                                         bit_offset, 1, &e2, FALSE);
1383
1384             /* Report as expert info */
1385             if (e2) {
1386                 expert_add_info_format(pinfo, nack_ti, PI_SEQUENCE, PI_WARN,
1387                                        "Status PDU reports NACK (partial) on %s for UE %u",
1388                                        val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1389                                        p_rlc_lte_info->ueid);
1390             }
1391             else {
1392                 expert_add_info_format(pinfo, nack_ti, PI_SEQUENCE, PI_WARN,
1393                                        "Status PDU reports NACK on %s for UE %u",
1394                                        val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1395                                        p_rlc_lte_info->ueid);
1396             }
1397
1398             bit_offset++;
1399         }
1400
1401         if (e2) {
1402             /* Read SOstart, SOend */
1403             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_so_start, tvb,
1404                                         bit_offset, 15, &so_start, FALSE);
1405             bit_offset += 15;
1406
1407             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_so_end, tvb,
1408                                         bit_offset, 15, &so_end, FALSE);
1409             bit_offset += 15;
1410
1411
1412             if ((guint16)so_end == 0x7fff) {
1413                 write_pdu_label_and_info(top_ti, NULL, pinfo,
1414                                          "  (SOstart=%u SOend=<END-OF_PDU>)",
1415                                          (guint16)so_start);
1416             }
1417             else {
1418                 write_pdu_label_and_info(top_ti, NULL, pinfo,
1419                                          "  (SOstart=%u SOend=%u)",
1420                                          (guint16)so_start, (guint16)so_end);
1421             }
1422
1423             /* Reset this flag here */
1424             e2 = 0;
1425         }
1426     } while (e1 || e2);
1427
1428     if (nack_count > 0) {
1429         proto_item_append_text(status_ti, "  (%u NACKs)", nack_count);
1430         tap_info->noOfNACKs = nack_count;
1431     }
1432
1433     /* Check that we've reached the end of the PDU. If not, show malformed */
1434     offset = (bit_offset+7) / 8;
1435     if (tvb_length_remaining(tvb, offset) > 0) {
1436         expert_add_info_format(pinfo, status_ti, PI_MALFORMED, PI_ERROR,
1437                                "%cL %u bytes remaining after Status PDU complete",
1438                                (p_rlc_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D',
1439                                tvb_length_remaining(tvb, offset));
1440     }
1441
1442     /* Set selected length of control tree */
1443     proto_item_set_len(status_ti, offset);
1444
1445     /* Repeated NACK analysis */
1446     if (((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_MAC_ONLY) &&
1447          (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL)) ||
1448         ((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_RLC_ONLY) &&
1449          (p_get_proto_data(pinfo->fd, proto_mac_lte) == NULL))) {
1450
1451         if (!is_mac_lte_frame_retx(pinfo, p_rlc_lte_info->direction)) {
1452             checkChannelRepeatedNACKInfo(pinfo, p_rlc_lte_info, tap_info, tree, tvb);
1453         }
1454      }
1455 }
1456
1457
1458 /***************************************************/
1459 /* Acknowledged mode PDU                           */
1460 static void dissect_rlc_lte_am(tvbuff_t *tvb, packet_info *pinfo,
1461                                proto_tree *tree,
1462                                int offset,
1463                                rlc_lte_info *p_rlc_lte_info,
1464                                proto_item *top_ti,
1465                                rlc_lte_tap_info *tap_info)
1466 {
1467     guint8 is_data;
1468     guint8 is_resegmented;
1469     guint8 polling;
1470     guint8 fixed_extension;
1471     guint8 framing_info;
1472     gboolean first_includes_start;
1473     gboolean last_includes_end;
1474     proto_item *am_ti;
1475     proto_tree *am_header_tree;
1476     proto_item *am_header_ti;
1477     gint   start_offset = offset;
1478     guint16    sn;
1479     gboolean is_truncated;
1480     proto_item *truncated_ti;
1481
1482     /* Hidden AM root */
1483     am_ti = proto_tree_add_string_format(tree, hf_rlc_lte_am,
1484                                          tvb, offset, 0, "", "AM");
1485     PROTO_ITEM_SET_HIDDEN(am_ti);
1486
1487     /* Add AM header subtree */
1488     am_header_ti = proto_tree_add_string_format(tree, hf_rlc_lte_am_header,
1489                                                 tvb, offset, 0,
1490                                                 "", "AM Header ");
1491     am_header_tree = proto_item_add_subtree(am_header_ti,
1492                                             ett_rlc_lte_am_header);
1493
1494     /* First bit is Data/Control flag           */
1495     is_data = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
1496     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_data_control, tvb, offset, 1, FALSE);
1497     tap_info->isControlPDU = !is_data;
1498
1499     if (!is_data) {
1500         /**********************/
1501         /* Status PDU         */
1502         write_pdu_label_and_info(top_ti, NULL, pinfo, " [CONTROL]");
1503
1504         /* Control PDUs are a completely separate format  */
1505         dissect_rlc_lte_am_status_pdu(tvb, pinfo, am_header_tree, am_header_ti,
1506                                       offset, top_ti,
1507                                       p_rlc_lte_info, tap_info);
1508         return;
1509     }
1510
1511     /******************************/
1512     /* Data PDU fixed header      */
1513
1514     /* Re-segmentation Flag (RF) field */
1515     is_resegmented = (tvb_get_guint8(tvb, offset) & 0x40) >> 6;
1516     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_rf, tvb, offset, 1, FALSE);
1517     tap_info->isResegmented = is_resegmented;
1518
1519     write_pdu_label_and_info(top_ti, NULL, pinfo,
1520                              (is_resegmented) ? " [DATA-SEGMENT]" : " [DATA]");
1521
1522     /* Polling bit */
1523     polling = (tvb_get_guint8(tvb, offset) & 0x20) >> 5;
1524     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_p, tvb, offset, 1, FALSE);
1525
1526     write_pdu_label_and_info(top_ti, NULL, pinfo, (polling) ? " (P) " : "     ");
1527     if (polling) {
1528         proto_item_append_text(am_header_ti, " (P) ");
1529     }
1530
1531     /* Framing Info */
1532     framing_info = (tvb_get_guint8(tvb, offset) & 0x18) >> 3;
1533     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_fi, tvb, offset, 1, FALSE);
1534
1535     /* Extension bit */
1536     fixed_extension = (tvb_get_guint8(tvb, offset) & 0x04) >> 2;
1537     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_fixed_e, tvb, offset, 1, FALSE);
1538
1539     /* Sequence Number */
1540     sn = tvb_get_ntohs(tvb, offset) & 0x03ff;
1541     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_fixed_sn, tvb, offset, 2, FALSE);
1542     offset += 2;
1543     tap_info->sequenceNumber = sn;
1544
1545     write_pdu_label_and_info(top_ti, am_header_ti, pinfo, "sn=%u", sn);
1546
1547     /***************************************/
1548     /* Dissect extra segment header fields */
1549     if (is_resegmented) {
1550         guint16 segmentOffset;
1551
1552         /* Last Segment Field (LSF) */
1553         proto_tree_add_item(am_header_tree, hf_rlc_lte_am_segment_lsf, tvb, offset, 1, FALSE);
1554
1555         /* SO */
1556         segmentOffset = tvb_get_ntohs(tvb, offset) & 0x7fff;
1557         proto_tree_add_item(am_header_tree, hf_rlc_lte_am_segment_so, tvb, offset, 2, FALSE);
1558         write_pdu_label_and_info(top_ti, NULL, pinfo, " SO=%u ", segmentOffset);
1559         offset += 2;
1560     }
1561
1562     /*************************************/
1563     /* AM header extension               */
1564     if (fixed_extension) {
1565         offset = dissect_rlc_lte_extension_header(tvb, pinfo, tree, offset);
1566     }
1567
1568     /* There might not be any data, if only headers (plus control data) were logged */
1569     if (global_rlc_lte_headers_expected) {
1570         is_truncated = (tvb_length_remaining(tvb, offset) == 0);
1571         truncated_ti = proto_tree_add_uint(tree, hf_rlc_lte_header_only, tvb, 0, 0,
1572                                            is_truncated);
1573         if (is_truncated) {
1574             PROTO_ITEM_SET_GENERATED(truncated_ti);
1575             expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
1576                                    "RLC PDU SDUs have been omitted");
1577             return;
1578         }
1579         else {
1580             PROTO_ITEM_SET_HIDDEN(truncated_ti);
1581         }
1582     }
1583
1584     /* Head is now complete */
1585     proto_item_set_len(am_header_ti, offset-start_offset);
1586
1587     /* Extract these 2 flags from framing_info */
1588     first_includes_start = (framing_info & 0x02) == 0;
1589     last_includes_end =    (framing_info & 0x01) == 0;
1590
1591
1592     /* Call sequence analysis function now */
1593     if (((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_MAC_ONLY) &&
1594          (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL)) ||
1595         ((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_RLC_ONLY) &&
1596          (p_get_proto_data(pinfo->fd, proto_mac_lte) == NULL))) {
1597
1598         checkChannelSequenceInfo(pinfo, tvb, p_rlc_lte_info, (guint16)sn,
1599                                  first_includes_start, last_includes_end,
1600                                  is_resegmented, tap_info, tree);
1601     }
1602
1603
1604     /*************************************/
1605     /* Data                        */
1606     if (s_number_of_extensions > 0) {
1607         /* Show each data segment separately */
1608         int n;
1609         for (n=0; n < s_number_of_extensions; n++) {
1610             show_AM_PDU_in_tree(pinfo, tree, tvb, offset, s_lengths[n], p_rlc_lte_info,
1611                                 first_includes_start && last_includes_end);
1612             show_PDU_in_info(pinfo, top_ti, s_lengths[n],
1613                              (n==0) ? first_includes_start : TRUE,
1614                              TRUE);
1615             tvb_ensure_bytes_exist(tvb, offset, s_lengths[n]);
1616             offset += s_lengths[n];
1617         }
1618     }
1619
1620     /* Final data element */
1621     if (tvb_length_remaining(tvb, offset) > 0) {
1622         show_AM_PDU_in_tree(pinfo, tree, tvb, offset, -1, p_rlc_lte_info,
1623                             first_includes_start && last_includes_end);
1624         show_PDU_in_info(pinfo, top_ti, (guint16)tvb_length_remaining(tvb, offset),
1625                          (s_number_of_extensions == 0) ? first_includes_start : TRUE,
1626                          last_includes_end);
1627     }
1628     else {
1629         /* Report that expected data was missing (unless we know it might happen) */
1630         if (!global_rlc_lte_headers_expected) {
1631             if (s_number_of_extensions > 0) {
1632                 expert_add_info_format(pinfo, am_header_ti, PI_MALFORMED, PI_ERROR,
1633                                       "AM data PDU doesn't contain any data beyond extensions");
1634             }
1635             else {
1636                 expert_add_info_format(pinfo, am_header_ti, PI_MALFORMED, PI_ERROR,
1637                                       "AM data PDU doesn't contain any data");
1638             }
1639         }
1640     }
1641 }
1642
1643
1644 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
1645 static gboolean dissect_rlc_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
1646                                      proto_tree *tree)
1647 {
1648     gint                 offset = 0;
1649     struct rlc_lte_info  *p_rlc_lte_info;
1650     tvbuff_t             *rlc_tvb;
1651     guint8               tag = 0;
1652     gboolean             infoAlreadySet = FALSE;
1653     gboolean             umSeqNumLengthTagPresent = FALSE;
1654
1655     /* This is a heuristic dissector, which means we get all the UDP
1656      * traffic not sent to a known dissector and not claimed by
1657      * a heuristic dissector called before us!
1658      */
1659
1660     if (!global_rlc_lte_heur) {
1661         return FALSE;
1662     }
1663
1664     /* If redissecting, use previous info struct (if available) */
1665     p_rlc_lte_info = p_get_proto_data(pinfo->fd, proto_rlc_lte);
1666     if (p_rlc_lte_info == NULL) {
1667         /* Allocate new info struct for this frame */
1668         p_rlc_lte_info = se_alloc0(sizeof(struct rlc_lte_info));
1669         infoAlreadySet = FALSE;
1670     }
1671     else {
1672         infoAlreadySet = TRUE;
1673     }
1674
1675     /* Do this again on re-dissection to re-discover offset of actual PDU */
1676     
1677     /* Needs to be at least as long as:
1678        - the signature string
1679        - fixed header bytes
1680        - tag for data
1681        - at least one byte of RLC PDU payload */
1682     if ((size_t)tvb_length_remaining(tvb, offset) < (strlen(RLC_LTE_START_STRING)+1+2)) {
1683         return FALSE;
1684     }
1685
1686     /* OK, compare with signature string */
1687     if (tvb_strneql(tvb, offset, RLC_LTE_START_STRING, (gint)strlen(RLC_LTE_START_STRING)) != 0) {
1688         return FALSE;
1689     }
1690     offset += (gint)strlen(RLC_LTE_START_STRING);
1691
1692     /* Read fixed fields */
1693     p_rlc_lte_info->rlcMode = tvb_get_guint8(tvb, offset++);
1694
1695     /* Read optional fields */
1696     while (tag != RLC_LTE_PAYLOAD_TAG) {
1697         /* Process next tag */
1698         tag = tvb_get_guint8(tvb, offset++);
1699         switch (tag) {
1700             case RLC_LTE_UM_SN_LENGTH_TAG:
1701                 p_rlc_lte_info->UMSequenceNumberLength = tvb_get_guint8(tvb, offset);
1702                 offset++;
1703                 umSeqNumLengthTagPresent = TRUE;
1704                 break;
1705             case RLC_LTE_DIRECTION_TAG:
1706                 p_rlc_lte_info->direction = tvb_get_guint8(tvb, offset);
1707                 offset++;
1708                 break;
1709             case RLC_LTE_PRIORITY_TAG:
1710                 p_rlc_lte_info->priority = tvb_get_guint8(tvb, offset);
1711                 offset++;
1712                 break;
1713             case RLC_LTE_UEID_TAG:
1714                 p_rlc_lte_info->ueid = tvb_get_ntohs(tvb, offset);
1715                 offset += 2;
1716                 break;
1717             case RLC_LTE_CHANNEL_TYPE_TAG:
1718                 p_rlc_lte_info->channelType = tvb_get_ntohs(tvb, offset);
1719                 offset += 2;
1720                 break;
1721             case RLC_LTE_CHANNEL_ID_TAG:
1722                 p_rlc_lte_info->channelId = tvb_get_ntohs(tvb, offset);
1723                 offset += 2;
1724                 break;
1725
1726             case RLC_LTE_PAYLOAD_TAG:
1727                 /* Have reached data, so set payload length and get out of loop */
1728                 p_rlc_lte_info->pduLength= tvb_length_remaining(tvb, offset);
1729                 continue;
1730
1731             default:
1732                 /* It must be a recognised tag */
1733                 return FALSE;
1734         }
1735     }
1736
1737     if ((p_rlc_lte_info->rlcMode == RLC_UM_MODE) && (umSeqNumLengthTagPresent == FALSE)) {
1738         /* Conditional field is not present */
1739         return FALSE;
1740     }
1741
1742     if (!infoAlreadySet) {
1743         /* Store info in packet */
1744         p_add_proto_data(pinfo->fd, proto_rlc_lte, p_rlc_lte_info);
1745     }
1746
1747     /**************************************/
1748     /* OK, now dissect as RLC LTE         */
1749
1750     /* Create tvb that starts at actual RLC PDU */
1751     rlc_tvb = tvb_new_subset(tvb, offset, -1, tvb_reported_length(tvb)-offset);
1752     dissect_rlc_lte(rlc_tvb, pinfo, tree);
1753     return TRUE;
1754 }
1755
1756
1757 /*****************************/
1758 /* Main dissection function. */
1759 /*****************************/
1760
1761 void dissect_rlc_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1762 {
1763     proto_tree             *rlc_lte_tree;
1764     proto_tree             *context_tree;
1765     proto_item             *top_ti;
1766     proto_item             *context_ti;
1767     proto_item             *ti;
1768     proto_item             *mode_ti;
1769     gint                   offset = 0;
1770     struct rlc_lte_info    *p_rlc_lte_info = NULL;
1771
1772     /* Zero out tap */
1773     static rlc_lte_tap_info tap_info;
1774     memset(&tap_info, 0, sizeof(rlc_lte_tap_info));
1775
1776     /* Set protocol name */
1777     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC-LTE");
1778
1779     /* Create protocol tree. */
1780     top_ti = proto_tree_add_item(tree, proto_rlc_lte, tvb, offset, -1, FALSE);
1781     rlc_lte_tree = proto_item_add_subtree(top_ti, ett_rlc_lte);
1782
1783
1784     /* Look for packet info! */
1785     p_rlc_lte_info = p_get_proto_data(pinfo->fd, proto_rlc_lte);
1786
1787     /* Can't dissect anything without it... */
1788     if (p_rlc_lte_info == NULL) {
1789         ti = proto_tree_add_text(rlc_lte_tree, tvb, offset, -1,
1790                                  "Can't dissect LTE RLC frame because no per-frame info was attached!");
1791         PROTO_ITEM_SET_GENERATED(ti);
1792         return;
1793     }
1794
1795     /*****************************************/
1796     /* Show context information              */
1797
1798     /* Create context root */
1799     context_ti = proto_tree_add_string_format(rlc_lte_tree, hf_rlc_lte_context,
1800                                               tvb, offset, 0, "", "Context");
1801     context_tree = proto_item_add_subtree(context_ti, ett_rlc_lte_context);
1802     PROTO_ITEM_SET_GENERATED(context_ti);
1803
1804     ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_direction,
1805                              tvb, 0, 0, p_rlc_lte_info->direction);
1806     PROTO_ITEM_SET_GENERATED(ti);
1807
1808     mode_ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_mode,
1809                                   tvb, 0, 0, p_rlc_lte_info->rlcMode);
1810     PROTO_ITEM_SET_GENERATED(mode_ti);
1811
1812     if (p_rlc_lte_info->ueid != 0) {
1813         ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_ueid,
1814                                  tvb, 0, 0, p_rlc_lte_info->ueid);
1815         PROTO_ITEM_SET_GENERATED(ti);
1816     }
1817
1818     ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_priority,
1819                              tvb, 0, 0, p_rlc_lte_info->priority);
1820     PROTO_ITEM_SET_GENERATED(ti);
1821
1822     ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_channel_type,
1823                              tvb, 0, 0, p_rlc_lte_info->channelType);
1824     PROTO_ITEM_SET_GENERATED(ti);
1825
1826     if ((p_rlc_lte_info->channelType == CHANNEL_TYPE_SRB) ||
1827         (p_rlc_lte_info->channelType == CHANNEL_TYPE_DRB)) {
1828         ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_channel_id,
1829                                  tvb, 0, 0, p_rlc_lte_info->channelId);
1830         PROTO_ITEM_SET_GENERATED(ti);
1831     }
1832
1833     ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_pdu_length,
1834                              tvb, 0, 0, p_rlc_lte_info->pduLength);
1835     PROTO_ITEM_SET_GENERATED(ti);
1836
1837     if (p_rlc_lte_info->rlcMode == RLC_UM_MODE) {
1838         ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_um_sn_length,
1839                                  tvb, 0, 0, p_rlc_lte_info->UMSequenceNumberLength);
1840         PROTO_ITEM_SET_GENERATED(ti);
1841     }
1842
1843     /* Append highlights to top-level item */
1844     if (p_rlc_lte_info->ueid != 0) {
1845         proto_item_append_text(top_ti, "   UEId=%u", p_rlc_lte_info->ueid);
1846     }
1847
1848     if (p_rlc_lte_info->channelId == 0) {
1849         proto_item_append_text(top_ti, " (%s) ",
1850                                val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"));
1851     }
1852     else {
1853         proto_item_append_text(top_ti, " (%s:%u) ",
1854                                val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"),
1855                                p_rlc_lte_info->channelId);
1856     }
1857     proto_item_append_text(top_ti, "[%s] ",
1858                            val_to_str_const(p_rlc_lte_info->rlcMode, rlc_mode_short_vals, "Unknown"));
1859
1860
1861     /* Append context highlights to info column */
1862     write_pdu_label_and_info(top_ti, NULL, pinfo,
1863                              "[%s] [%s] ",
1864                              (p_rlc_lte_info->direction == 0) ? "UL" : "DL",
1865                              val_to_str_const(p_rlc_lte_info->rlcMode, rlc_mode_short_vals, "Unknown"));
1866     if (p_rlc_lte_info->ueid != 0) {
1867         col_append_fstr(pinfo->cinfo, COL_INFO, "UEId=%u ", p_rlc_lte_info->ueid);
1868     }
1869     if (p_rlc_lte_info->channelId == 0) {
1870         write_pdu_label_and_info(top_ti, NULL, pinfo, "%s",
1871                                  val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"));
1872     }
1873     else {
1874         write_pdu_label_and_info(top_ti, NULL, pinfo, "%s:%u",
1875                                  val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"),
1876                                  p_rlc_lte_info->channelId);
1877     }
1878
1879     /* Set context-info parts of tap struct */
1880     tap_info.rlcMode = p_rlc_lte_info->rlcMode;
1881     tap_info.direction = p_rlc_lte_info->direction;
1882     tap_info.priority = p_rlc_lte_info->priority;
1883     tap_info.ueid = p_rlc_lte_info->ueid;
1884     tap_info.channelType = p_rlc_lte_info->channelType;
1885     tap_info.channelId = p_rlc_lte_info->channelId;
1886     tap_info.pduLength = p_rlc_lte_info->pduLength;
1887     tap_info.UMSequenceNumberLength = p_rlc_lte_info->UMSequenceNumberLength;
1888     tap_info.loggedInMACFrame = (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL);
1889
1890     /* Reset this count */
1891     s_number_of_extensions = 0;
1892
1893     /* Dissect the RLC PDU itself. Format depends upon mode... */
1894     switch (p_rlc_lte_info->rlcMode) {
1895
1896         case RLC_TM_MODE:
1897             dissect_rlc_lte_tm(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti);
1898             break;
1899
1900         case RLC_UM_MODE:
1901             dissect_rlc_lte_um(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti,
1902                                &tap_info);
1903             break;
1904
1905         case RLC_AM_MODE:
1906             dissect_rlc_lte_am(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti,
1907                                &tap_info);
1908             break;
1909
1910         case RLC_PREDEF:
1911             /* Predefined data (i.e. not containing a valid RLC header */
1912             proto_tree_add_item(rlc_lte_tree, hf_rlc_lte_predefined_pdu, tvb, offset, -1, FALSE);
1913             write_pdu_label_and_info(top_ti, NULL, pinfo, "   [%u-bytes]",
1914                                      tvb_length_remaining(tvb, offset));
1915             break;
1916
1917         default:
1918             /* Error - unrecognised mode */
1919             expert_add_info_format(pinfo, mode_ti, PI_MALFORMED, PI_ERROR,
1920                                    "Unrecognised RLC Mode set (%u)", p_rlc_lte_info->rlcMode);
1921             break;
1922     }
1923
1924     /* Queue tap info */
1925     if (!pinfo->in_error_pkt) {
1926         tap_queue_packet(rlc_lte_tap, pinfo, &tap_info);
1927     }
1928 }
1929
1930
1931
1932 /* Initializes the hash table and the mem_chunk area each time a new
1933  * file is loaded or re-loaded in wireshark */
1934 static void
1935 rlc_lte_init_protocol(void)
1936 {
1937     /* Destroy any existing hashes. */
1938     if (rlc_lte_sequence_analysis_channel_hash) {
1939         g_hash_table_destroy(rlc_lte_sequence_analysis_channel_hash);
1940     }
1941     if (rlc_lte_frame_sequence_analysis_report_hash) {
1942         g_hash_table_destroy(rlc_lte_frame_sequence_analysis_report_hash);
1943     }
1944     if (rlc_lte_repeated_nack_channel_hash) {
1945         g_hash_table_destroy(rlc_lte_repeated_nack_channel_hash);
1946     }
1947     if (rlc_lte_frame_repeated_nack_report_hash) {
1948         g_hash_table_destroy(rlc_lte_frame_repeated_nack_report_hash);
1949     }
1950
1951
1952     /* Now create them over */
1953     rlc_lte_sequence_analysis_channel_hash = g_hash_table_new(rlc_channel_hash_func, rlc_channel_equal);
1954     rlc_lte_frame_sequence_analysis_report_hash = g_hash_table_new(rlc_frame_hash_func, rlc_frame_equal);
1955
1956     rlc_lte_repeated_nack_channel_hash = g_hash_table_new(rlc_channel_hash_func, rlc_channel_equal);
1957     rlc_lte_frame_repeated_nack_report_hash = g_hash_table_new(rlc_frame_hash_func, rlc_frame_equal);
1958 }
1959
1960
1961
1962
1963 void proto_register_rlc_lte(void)
1964 {
1965     static hf_register_info hf[] =
1966     {
1967         /**********************************/
1968         /* Items for decoding context     */
1969         { &hf_rlc_lte_context,
1970             { "Context",
1971               "rlc-lte.context", FT_STRING, BASE_NONE, NULL, 0x0,
1972               NULL, HFILL
1973             }
1974         },
1975         { &hf_rlc_lte_context_mode,
1976             { "RLC Mode",
1977               "rlc-lte.mode", FT_UINT8, BASE_DEC, VALS(rlc_mode_vals), 0x0,
1978               NULL, HFILL
1979             }
1980         },
1981         { &hf_rlc_lte_context_direction,
1982             { "Direction",
1983               "rlc-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
1984               "Direction of message", HFILL
1985             }
1986         },
1987         { &hf_rlc_lte_context_priority,
1988             { "Priority",
1989               "rlc-lte.priority", FT_UINT8, BASE_DEC, 0, 0x0,
1990               NULL, HFILL
1991             }
1992         },
1993         { &hf_rlc_lte_context_ueid,
1994             { "UEId",
1995               "rlc-lte.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
1996               "User Equipment Identifier associated with message", HFILL
1997             }
1998         },
1999         { &hf_rlc_lte_context_channel_type,
2000             { "Channel Type",
2001               "rlc-lte.channel-type", FT_UINT16, BASE_DEC, VALS(rlc_channel_type_vals), 0x0,
2002               "Channel Type associated with message", HFILL
2003             }
2004         },
2005         { &hf_rlc_lte_context_channel_id,
2006             { "Channel ID",
2007               "rlc-lte.channel-id", FT_UINT16, BASE_DEC, 0, 0x0,
2008               "Channel ID associated with message", HFILL
2009             }
2010         },
2011         { &hf_rlc_lte_context_pdu_length,
2012             { "PDU Length",
2013               "rlc-lte.pdu_length", FT_UINT16, BASE_DEC, 0, 0x0,
2014               "Length of PDU (in bytes)", HFILL
2015             }
2016         },
2017         { &hf_rlc_lte_context_um_sn_length,
2018             { "UM Sequence number length",
2019               "rlc-lte.um-seqnum-length", FT_UINT8, BASE_DEC, 0, 0x0,
2020               "Length of UM sequence number in bits", HFILL
2021             }
2022         },
2023
2024
2025         /* Transparent mode fields */
2026         { &hf_rlc_lte_tm,
2027             { "TM",
2028               "rlc-lte.tm", FT_STRING, BASE_NONE, NULL, 0x0,
2029               "Transparent Mode", HFILL
2030             }
2031         },
2032         { &hf_rlc_lte_tm_data,
2033             { "TM Data",
2034               "rlc-lte.tm.data", FT_BYTES, BASE_NONE, 0, 0x0,
2035               "Transparent Mode Data", HFILL
2036             }
2037         },
2038
2039         /* Unacknowledged mode fields */
2040         { &hf_rlc_lte_um,
2041             { "UM",
2042               "rlc-lte.um", FT_STRING, BASE_NONE, NULL, 0x0,
2043               "Unackowledged Mode", HFILL
2044             }
2045         },
2046         { &hf_rlc_lte_um_header,
2047             { "UM Header",
2048               "rlc-lte.um.header", FT_STRING, BASE_NONE, NULL, 0x0,
2049               "Unackowledged Mode Header", HFILL
2050             }
2051         },
2052         { &hf_rlc_lte_um_fi,
2053             { "Framing Info",
2054               "rlc-lte.um.fi", FT_UINT8, BASE_HEX, VALS(framing_info_vals), 0x0,
2055               NULL, HFILL
2056             }
2057         },
2058         { &hf_rlc_lte_um_fixed_e,
2059             { "Extension",
2060               "rlc-lte.um.fixed.e", FT_UINT8, BASE_HEX, VALS(fixed_extension_vals), 0x0,
2061               "Extension in fixed part of UM header", HFILL
2062             }
2063         },
2064         { &hf_rlc_lte_um_sn,
2065             { "Sequence number",
2066               "rlc-lte.um.sn", FT_UINT8, BASE_DEC, 0, 0x0,
2067               "Unacknowledged Mode Sequence Number", HFILL
2068             }
2069         },
2070         { &hf_rlc_lte_um_fixed_reserved,
2071             { "Reserved",
2072               "rlc-lte.um.reserved", FT_UINT8, BASE_DEC, 0, 0xe0,
2073               "Unacknowledged Mode Fixed header reserved bits", HFILL
2074             }
2075         },
2076         { &hf_rlc_lte_um_data,
2077             { "UM Data",
2078               "rlc-lte.um.data", FT_BYTES, BASE_NONE, 0, 0x0,
2079               "Unacknowledged Mode Data", HFILL
2080             }
2081         },
2082         { &hf_rlc_lte_extension_part,
2083             { "Extension Part",
2084               "rlc-lte.extension-part", FT_STRING, BASE_NONE, 0, 0x0,
2085               NULL, HFILL
2086             }
2087         },
2088
2089
2090         { &hf_rlc_lte_extension_e,
2091             { "Extension",
2092               "rlc-lte.extension.e", FT_UINT8, BASE_HEX, VALS(extension_extension_vals), 0x0,
2093               "Extension in extended part of the header", HFILL
2094             }
2095         },
2096         { &hf_rlc_lte_extension_li,
2097             { "Length Indicator",
2098               "rlc-lte.extension.li", FT_UINT16, BASE_DEC, 0, 0x0,
2099               NULL, HFILL
2100             }
2101         },
2102         { &hf_rlc_lte_extension_padding,
2103             { "Padding",
2104               "rlc-lte.extension.padding", FT_UINT8, BASE_HEX, 0, 0x0f,
2105               "Extension header padding", HFILL
2106             }
2107         },
2108
2109         { &hf_rlc_lte_am,
2110             { "AM",
2111               "rlc-lte.am", FT_STRING, BASE_NONE, NULL, 0x0,
2112               "Ackowledged Mode", HFILL
2113             }
2114         },
2115         { &hf_rlc_lte_am_header,
2116             { "AM Header",
2117               "rlc-lte.am.header", FT_STRING, BASE_NONE, NULL, 0x0,
2118               "Ackowledged Mode Header", HFILL
2119             }
2120         },
2121         { &hf_rlc_lte_am_data_control,
2122             { "Frame type",
2123               "rlc-lte.am.frame_type", FT_UINT8, BASE_HEX, VALS(data_or_control_vals), 0x80,
2124               "AM Frame Type (Control or Data)", HFILL
2125             }
2126         },
2127         { &hf_rlc_lte_am_rf,
2128             { "Re-segmentation Flag",
2129               "rlc-lte.am.rf", FT_UINT8, BASE_HEX, VALS(resegmentation_flag_vals), 0x40,
2130               "AM Re-segmentation Flag", HFILL
2131             }
2132         },
2133         { &hf_rlc_lte_am_p,
2134             { "Polling Bit",
2135               "rlc-lte.am.p", FT_UINT8, BASE_HEX, VALS(polling_bit_vals), 0x20,
2136               NULL, HFILL
2137             }
2138         },
2139         { &hf_rlc_lte_am_fi,
2140             { "Framing Info",
2141               "rlc-lte.am.fi", FT_UINT8, BASE_HEX, VALS(framing_info_vals), 0x18,
2142               "AM Framing Info", HFILL
2143             }
2144         },
2145         { &hf_rlc_lte_am_fixed_e,
2146             { "Extension",
2147               "rlc-lte.am.fixed.e", FT_UINT8, BASE_HEX, VALS(fixed_extension_vals), 0x04,
2148               "Fixed Extension Bit", HFILL
2149             }
2150         },
2151         { &hf_rlc_lte_am_fixed_sn,
2152             { "Sequence Number",
2153               "rlc-lte.am.fixed.sn", FT_UINT16, BASE_DEC, 0, 0x03ff,
2154               "AM Fixed Sequence Number", HFILL
2155             }
2156         },
2157         { &hf_rlc_lte_am_segment_lsf,
2158             { "Last Segment Flag",
2159               "rlc-lte.am.segment.lsf", FT_UINT8, BASE_HEX, VALS(lsf_vals), 0x80,
2160               NULL, HFILL
2161             }
2162         },
2163         { &hf_rlc_lte_am_segment_so,
2164             { "Segment Offset",
2165               "rlc-lte.am.segment.offset", FT_UINT16, BASE_DEC, 0, 0x7fff,
2166               NULL, HFILL
2167             }
2168         },
2169         { &hf_rlc_lte_am_data,
2170             { "AM Data",
2171               "rlc-lte.am.data", FT_BYTES, BASE_NONE, 0, 0x0,
2172               "Acknowledged Mode Data", HFILL
2173             }
2174         },
2175
2176
2177         { &hf_rlc_lte_am_cpt,
2178             { "Control PDU Type",
2179               "rlc-lte.am.cpt", FT_UINT8, BASE_HEX, VALS(control_pdu_type_vals), 0x70,
2180               "AM Control PDU Type", HFILL
2181             }
2182         },
2183         { &hf_rlc_lte_am_ack_sn,
2184             { "ACK Sequence Number",
2185               "rlc-lte.am.ack-sn", FT_UINT16, BASE_DEC, 0, 0x0,
2186               "Sequence Number we expect to receive next", HFILL
2187             }
2188         },
2189         { &hf_rlc_lte_am_e1,
2190             { "Extension bit 1",
2191               "rlc-lte.am.e1", FT_UINT8, BASE_HEX, VALS(am_e1_vals), 0x0,
2192               NULL, HFILL
2193             }
2194         },
2195         { &hf_rlc_lte_am_e2,
2196             { "Extension bit 2",
2197               "rlc-lte.am.e2", FT_UINT8, BASE_HEX, VALS(am_e2_vals), 0x0,
2198               NULL, HFILL
2199             }
2200         },
2201         { &hf_rlc_lte_am_nack_sn,
2202             { "NACK Sequence Number",
2203               "rlc-lte.am.nack-sn", FT_UINT16, BASE_DEC, 0, 0x0,
2204               "Negative Acknowledgement Sequence Number", HFILL
2205             }
2206         },
2207         { &hf_rlc_lte_am_so_start,
2208             { "SO Start",
2209               "rlc-lte.am.so-start", FT_UINT16, BASE_DEC, 0, 0x0,
2210               NULL, HFILL
2211             }
2212         },
2213         { &hf_rlc_lte_am_so_end,
2214             { "SO End",
2215               "rlc-lte.am.so-end", FT_UINT16, BASE_DEC, 0, 0x0,
2216               NULL, HFILL
2217             }
2218         },
2219
2220         { &hf_rlc_lte_predefined_pdu,
2221             { "Predefined data",
2222               "rlc-lte.predefined-data", FT_BYTES, BASE_NONE, 0, 0x0,
2223               "Predefined test data", HFILL
2224             }
2225         },
2226
2227         { &hf_rlc_lte_sequence_analysis,
2228             { "Sequence Analysis",
2229               "rlc-lte.sequence-analysis", FT_STRING, BASE_NONE, 0, 0x0,
2230               NULL, HFILL
2231             }
2232         },
2233         { &hf_rlc_lte_sequence_analysis_ok,
2234             { "OK",
2235               "rlc-lte.sequence-analysis.ok", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2236               NULL, HFILL
2237             }
2238         },
2239         { &hf_rlc_lte_sequence_analysis_previous_frame,
2240             { "Previous frame for channel",
2241               "rlc-lte.sequence-analysis.previous-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
2242               NULL, HFILL
2243             }
2244         },
2245         { &hf_rlc_lte_sequence_analysis_expected_sn,
2246             { "Expected SN",
2247               "rlc-lte.sequence-analysis.expected-sn", FT_UINT16, BASE_DEC, 0, 0x0,
2248               NULL, HFILL
2249             }
2250         },
2251         { &hf_rlc_lte_sequence_analysis_framing_info_correct,
2252             { "Frame info continued correctly",
2253               "rlc-lte.sequence-analysis.framing-info-correct", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2254               NULL, HFILL
2255             }
2256         },
2257         { &hf_rlc_lte_sequence_analysis_mac_retx,
2258             { "Frame retransmitted by MAC",
2259               "rlc-lte.sequence-analysis.mac-retx", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2260               NULL, HFILL
2261             }
2262         },
2263         { &hf_rlc_lte_sequence_analysis_retx,
2264             { "Retransmitted frame",
2265               "rlc-lte.sequence-analysis.retx", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2266               NULL, HFILL
2267             }
2268         },
2269         { &hf_rlc_lte_sequence_analysis_skipped,
2270             { "Skipped frames",
2271               "rlc-lte.sequence-analysis.skipped-frames", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2272               NULL, HFILL
2273             }
2274         },
2275         { &hf_rlc_lte_sequence_analysis_repeated,
2276             { "Repeated frame",
2277               "rlc-lte.sequence-analysis.repeated-frame", FT_BOOLEAN, BASE_NONE, 0, 0x0,
2278               NULL, HFILL
2279             }
2280         },
2281         { &hf_rlc_lte_sequence_analysis_repeated_nack,
2282             { "Repeated NACK",
2283               "rlc-lte.sequence-analysis.repeated-nack", FT_UINT16, BASE_DEC, 0, 0x0,
2284               NULL, HFILL
2285             }
2286         },
2287
2288         { &hf_rlc_lte_header_only,
2289             { "RLC PDU Header only",
2290               "rlc-lte.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
2291               NULL, HFILL
2292             }
2293         },
2294     };
2295
2296     static gint *ett[] =
2297     {
2298         &ett_rlc_lte,
2299         &ett_rlc_lte_context,
2300         &ett_rlc_lte_um_header,
2301         &ett_rlc_lte_am_header,
2302         &ett_rlc_lte_extension_part,
2303         &ett_rlc_lte_sequence_analysis
2304     };
2305
2306     static enum_val_t sequence_analysis_vals[] = {
2307         {"no-analysis", "No-Analysis",     FALSE},
2308         {"mac-only",    "Only-MAC-frames", SEQUENCE_ANALYSIS_MAC_ONLY},
2309         {"rlc-only",    "Only-RLC-frames", SEQUENCE_ANALYSIS_RLC_ONLY},
2310         {NULL, NULL, -1}
2311     };
2312     
2313     module_t *rlc_lte_module;
2314
2315     /* Register protocol. */
2316     proto_rlc_lte = proto_register_protocol("RLC-LTE", "RLC-LTE", "rlc-lte");
2317     proto_register_field_array(proto_rlc_lte, hf, array_length(hf));
2318     proto_register_subtree_array(ett, array_length(ett));
2319
2320     /* Allow other dissectors to find this one by name. */
2321     register_dissector("rlc-lte", dissect_rlc_lte, proto_rlc_lte);
2322
2323     /* Register the tap name */
2324     rlc_lte_tap = register_tap("rlc-lte");
2325
2326     /* Preferences */
2327     rlc_lte_module = prefs_register_protocol(proto_rlc_lte, NULL);
2328
2329     prefs_register_enum_preference(rlc_lte_module, "do_sequence_analysis_am",
2330         "Do sequence analysis for AM channels",
2331         "Attempt to keep track of PDUs for AM channels, and point out problems",
2332         &global_rlc_lte_am_sequence_analysis, sequence_analysis_vals, FALSE);
2333
2334     prefs_register_enum_preference(rlc_lte_module, "do_sequence_analysis",
2335         "Do sequence analysis for UM channels",
2336         "Attempt to keep track of PDUs for UM channels, and point out problems",
2337         &global_rlc_lte_um_sequence_analysis, sequence_analysis_vals, FALSE);
2338
2339     prefs_register_bool_preference(rlc_lte_module, "call_pdcp_for_srb",
2340         "Call PDCP dissector for SRB PDUs",
2341         "Call PDCP dissector for signalling PDUs.  Note that without reassembly, it can"
2342         "only be called for complete PDus (i.e. not segmented over RLC)",
2343         &global_rlc_lte_call_pdcp);
2344
2345     prefs_register_bool_preference(rlc_lte_module, "call_rrc_for_ccch",
2346         "Call RRC dissector for CCCH PDUs",
2347         "Call RRC dissector for CCCH PDUs",
2348         &global_rlc_lte_call_rrc);
2349
2350     prefs_register_bool_preference(rlc_lte_module, "heuristic_rlc_lte_over_udp",
2351         "Try Heuristic LTE-RLC over UDP framing",
2352         "When enabled, use heuristic dissector to find RLC-LTE frames sent with "
2353         "UDP framing",
2354         &global_rlc_lte_heur);
2355
2356     prefs_register_bool_preference(rlc_lte_module, "header_only_mode",
2357         "May see RLC headers only",
2358         "When enabled, if data is not present, don't report as an error, but instead "
2359         "add expert info to indicate that headers were ommitted",
2360         &global_rlc_lte_headers_expected);
2361
2362     register_init_routine(&rlc_lte_init_protocol);
2363 }
2364
2365 void
2366 proto_reg_handoff_rlc_lte(void)
2367 {
2368     static dissector_handle_t rlc_lte_handle;
2369     if (!rlc_lte_handle) {
2370         rlc_lte_handle = find_dissector("rlc-lte");
2371
2372         /* Add as a heuristic UDP dissector */
2373         heur_dissector_add("udp", dissect_rlc_lte_heur, proto_rlc_lte);
2374     }
2375 }