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