Show number of extensions in header root.
[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    - add intermediate results to segments leading to final reassembly
49    - use multiple active rlc_channel_reassembly_info's per channel
50    - sequence analysis gets confused when we change cells and skip back
51      to SN 0. Maybe add cell-id to context and add to channel/result key?
52 */
53
54 /********************************/
55 /* Preference settings          */
56
57 #define SEQUENCE_ANALYSIS_MAC_ONLY 1
58 #define SEQUENCE_ANALYSIS_RLC_ONLY 2
59
60 /* By default don't try to analyse the sequence of messages for AM/UM channels */
61 static gint global_rlc_lte_am_sequence_analysis = FALSE;
62 static gint global_rlc_lte_um_sequence_analysis = FALSE;
63
64 /* By default don't call PDCP/RRC dissectors for SDU data */
65 static gboolean global_rlc_lte_call_pdcp_for_srb = FALSE;
66
67 enum pdcp_for_drb { PDCP_drb_off, PDCP_drb_SN_7, PDCP_drb_SN_12, PDCP_drb_SN_signalled};
68 static enum_val_t pdcp_drb_col_vals[] = {
69     {"pdcp-drb-off",           "Off",                 PDCP_drb_off},
70     {"pdcp-drb-sn-7",          "7-bit SN",            PDCP_drb_SN_7},
71     {"pdcp-drb-sn-12",         "12-bit SN",           PDCP_drb_SN_12},
72     {"pdcp-drb-sn-signalling", "Use signalled value", PDCP_drb_SN_signalled},
73     {NULL, NULL, -1}
74 };
75 static gint global_rlc_lte_call_pdcp_for_drb = (gint)PDCP_drb_off;
76 static gint signalled_pdcp_sn_bits = 12;
77
78 static gboolean global_rlc_lte_call_rrc = FALSE;
79
80 /* Preference to expect RLC headers without payloads */
81 static gboolean global_rlc_lte_headers_expected = FALSE;
82
83 /* Heuristic dissection */
84 static gboolean global_rlc_lte_heur = FALSE;
85
86 /* Re-assembly of segments */
87 static gboolean global_rlc_lte_reassembly = FALSE;
88
89 /**************************************************/
90 /* Initialize the protocol and registered fields. */
91 int proto_rlc_lte = -1;
92
93 extern int proto_mac_lte;
94 extern int proto_pdcp_lte;
95
96 static int rlc_lte_tap = -1;
97
98 /* Decoding context */
99 static int hf_rlc_lte_context = -1;
100 static int hf_rlc_lte_context_mode = -1;
101 static int hf_rlc_lte_context_direction = -1;
102 static int hf_rlc_lte_context_priority = -1;
103 static int hf_rlc_lte_context_ueid = -1;
104 static int hf_rlc_lte_context_channel_type = -1;
105 static int hf_rlc_lte_context_channel_id = -1;
106 static int hf_rlc_lte_context_pdu_length = -1;
107 static int hf_rlc_lte_context_um_sn_length = -1;
108
109 /* Transparent mode fields */
110 static int hf_rlc_lte_tm = -1;
111 static int hf_rlc_lte_tm_data = -1;
112
113 /* Unacknowledged mode fields */
114 static int hf_rlc_lte_um = -1;
115 static int hf_rlc_lte_um_header = -1;
116 static int hf_rlc_lte_um_fi = -1;
117 static int hf_rlc_lte_um_fixed_e = -1;
118 static int hf_rlc_lte_um_sn = -1;
119 static int hf_rlc_lte_um_fixed_reserved = -1;
120 static int hf_rlc_lte_um_data = -1;
121 static int hf_rlc_lte_extension_part = -1;
122
123 /* Extended header (common to UM and AM) */
124 static int hf_rlc_lte_extension_e = -1;
125 static int hf_rlc_lte_extension_li = -1;
126 static int hf_rlc_lte_extension_padding = -1;
127
128
129 /* Acknowledged mode fields */
130 static int hf_rlc_lte_am = -1;
131 static int hf_rlc_lte_am_header = -1;
132 static int hf_rlc_lte_am_data_control = -1;
133 static int hf_rlc_lte_am_rf = -1;
134 static int hf_rlc_lte_am_p = -1;
135 static int hf_rlc_lte_am_fi = -1;
136 static int hf_rlc_lte_am_fixed_e = -1;
137 static int hf_rlc_lte_am_fixed_sn = -1;
138 static int hf_rlc_lte_am_segment_lsf = -1;
139 static int hf_rlc_lte_am_segment_so = -1;
140 static int hf_rlc_lte_am_data = -1;
141
142 /* Control fields */
143 static int hf_rlc_lte_am_cpt = -1;
144 static int hf_rlc_lte_am_ack_sn = -1;
145 static int hf_rlc_lte_am_e1 = -1;
146 static int hf_rlc_lte_am_e2 = -1;
147 static int hf_rlc_lte_am_nack_sn = -1;
148 static int hf_rlc_lte_am_nacks = -1;
149 static int hf_rlc_lte_am_so_start = -1;
150 static int hf_rlc_lte_am_so_end = -1;
151
152 static int hf_rlc_lte_predefined_pdu = -1;
153 static int hf_rlc_lte_header_only = -1;
154
155 /* Sequence Analysis */
156 static int hf_rlc_lte_sequence_analysis = -1;
157 static int hf_rlc_lte_sequence_analysis_ok = -1;
158 static int hf_rlc_lte_sequence_analysis_previous_frame = -1;
159 static int hf_rlc_lte_sequence_analysis_next_frame = -1;
160 static int hf_rlc_lte_sequence_analysis_expected_sn = -1;
161 static int hf_rlc_lte_sequence_analysis_framing_info_correct = -1;
162
163 static int hf_rlc_lte_sequence_analysis_mac_retx = -1;
164 static int hf_rlc_lte_sequence_analysis_retx = -1;
165 static int hf_rlc_lte_sequence_analysis_repeated = -1;
166 static int hf_rlc_lte_sequence_analysis_skipped = -1;
167
168 static int hf_rlc_lte_sequence_analysis_repeated_nack = -1;
169 static int hf_rlc_lte_sequence_analysis_repeated_nack_original_frame = -1;
170
171 static int hf_rlc_lte_sequence_analysis_ack_out_of_range = -1;
172 static int hf_rlc_lte_sequence_analysis_ack_out_of_range_opposite_frame = -1;
173
174 /* Reassembly */
175 static int hf_rlc_lte_reassembly_source = -1;
176 static int hf_rlc_lte_reassembly_source_number_of_segments = -1;
177 static int hf_rlc_lte_reassembly_source_total_length = -1;
178 static int hf_rlc_lte_reassembly_source_segment = -1;
179 static int hf_rlc_lte_reassembly_source_segment_sn = -1;
180 static int hf_rlc_lte_reassembly_source_segment_framenum = -1;
181 static int hf_rlc_lte_reassembly_source_segment_length = -1;
182
183 /* Subtrees. */
184 static int ett_rlc_lte = -1;
185 static int ett_rlc_lte_context = -1;
186 static int ett_rlc_lte_um_header = -1;
187 static int ett_rlc_lte_am_header = -1;
188 static int ett_rlc_lte_extension_part = -1;
189 static int ett_rlc_lte_sequence_analysis = -1;
190 static int ett_rlc_lte_reassembly_source = -1;
191 static int ett_rlc_lte_reassembly_source_segment = -1;
192
193 /* Value-strings */
194 static const value_string direction_vals[] =
195 {
196     { DIRECTION_UPLINK,      "Uplink"},
197     { DIRECTION_DOWNLINK,    "Downlink"},
198     { 0, NULL }
199 };
200
201 static const value_string rlc_mode_short_vals[] =
202 {
203     { RLC_TM_MODE,      "TM"},
204     { RLC_UM_MODE,      "UM"},
205     { RLC_AM_MODE,      "AM"},
206     { RLC_PREDEF,       "PREDEFINED"},  /* For data testing */
207     { 0, NULL }
208 };
209
210 static const value_string rlc_mode_vals[] =
211 {
212     { RLC_TM_MODE,      "Transparent Mode"},
213     { RLC_UM_MODE,      "Unacknowledged Mode"},
214     { RLC_AM_MODE,      "Acknowledged Mode"},
215     { 0, NULL }
216 };
217
218 static const value_string rlc_channel_type_vals[] =
219 {
220     { CHANNEL_TYPE_CCCH,         "CCCH"},
221     { CHANNEL_TYPE_BCCH_BCH,     "BCCH_BCH"},
222     { CHANNEL_TYPE_PCCH,         "PCCH"},
223     { CHANNEL_TYPE_SRB,          "SRB"},
224     { CHANNEL_TYPE_DRB,          "DRB"},
225     { CHANNEL_TYPE_BCCH_DL_SCH,  "BCCH_DL_SCH"},
226     { 0, NULL }
227 };
228
229 static const value_string framing_info_vals[] =
230 {
231     { 0,      "First byte begins a RLC SDU and last byte ends a RLC SDU"},
232     { 1,      "First byte begins a RLC SDU and last byte does not end a RLC SDU"},
233     { 2,      "First byte does not begin a RLC SDU and last byte ends a RLC SDU"},
234     { 3,      "First byte does not begin a RLC SDU and last byte does not end a RLC SDU"},
235     { 0, NULL }
236 };
237
238 static const value_string fixed_extension_vals[] =
239 {
240     { 0,      "Data field follows from the octet following the fixed part of the header"},
241     { 1,      "A set of E field and LI field follows from the octet following the fixed part of the header"},
242     { 0, NULL }
243 };
244
245 static const value_string extension_extension_vals[] =
246 {
247     { 0,      "Data field follows from the octet following the LI field following this E field"},
248     { 1,      "A set of E field and LI field follows from the bit following the LI field following this E field"},
249     { 0, NULL }
250 };
251
252 static const value_string data_or_control_vals[] =
253 {
254     { 0,      "Control PDU"},
255     { 1,      "Data PDU"},
256     { 0, NULL }
257 };
258
259 static const value_string resegmentation_flag_vals[] =
260 {
261     { 0,      "AMD PDU"},
262     { 1,      "AMD PDU segment"},
263     { 0, NULL }
264 };
265
266 static const value_string polling_bit_vals[] =
267 {
268     { 0,      "Status report not requested"},
269     { 1,      "Status report is requested"},
270     { 0, NULL }
271 };
272
273 static const value_string lsf_vals[] =
274 {
275     { 0,      "Last byte of the AMD PDU segment does not correspond to the last byte of an AMD PDU"},
276     { 1,      "Last byte of the AMD PDU segment corresponds to the last byte of an AMD PDU"},
277     { 0, NULL }
278 };
279
280 static const value_string control_pdu_type_vals[] =
281 {
282     { 0,      "STATUS PDU"},
283     { 0, NULL }
284 };
285
286 static const value_string am_e1_vals[] =
287 {
288     { 0,      "A set of NACK_SN, E1 and E2 does not follow"},
289     { 1,      "A set of NACK_SN, E1 and E2 follows"},
290     { 0, NULL }
291 };
292
293 static const value_string am_e2_vals[] =
294 {
295     { 0,      "A set of SOstart and SOend does not follow for this NACK_SN"},
296     { 1,      "A set of SOstart and SOend follows for this NACK_SN"},
297     { 0, NULL }
298 };
299
300 static const value_string header_only_vals[] =
301 {
302     { 0,      "RLC PDU Headers and body present"},
303     { 1,      "RLC PDU Headers only"},
304     { 0, NULL }
305 };
306
307
308
309 /**********************************************************************************/
310 /* These are for keeping track of UM/AM extension headers, and the lengths found  */
311 /* in them                                                                        */
312 static guint8  s_number_of_extensions = 0;
313 #define MAX_RLC_SDUS 64
314 static guint16 s_lengths[MAX_RLC_SDUS];
315
316
317 /*********************************************************************/
318 /* UM/AM sequence analysis                                           */
319
320 /* Types for RLC channel hash table                                   */
321 /* This table is maintained during initial dissection of RLC          */
322 /* frames, mapping from channel_hash_key -> sequence_analysis_report  */
323
324 /* Channel key */
325 typedef struct
326 {
327     unsigned  ueId : 16;
328     unsigned  channelType : 3;
329     unsigned  channelId : 5;
330     unsigned  direction : 1;
331 } channel_hash_key;
332
333
334 /******************************************************************/
335 /* State maintained for AM/UM reassembly                          */
336
337 typedef struct rlc_segment {
338     guint32 frameNum;
339     guint16 SN;
340     guint8 *data;
341     guint16 length;
342 } rlc_segment;
343
344 typedef struct rlc_channel_reassembly_info
345 {
346     guint16 number_of_segments;
347     #define RLC_MAX_SEGMENTS 100
348     rlc_segment segments[RLC_MAX_SEGMENTS];
349 } rlc_channel_reassembly_info;
350
351
352
353
354 /*******************************************************************/
355 /* Conversation-type status for sequence analysis on channel       */
356 typedef struct
357 {
358     guint8   rlcMode;
359
360     /* For UM, we always expect the SN to keep advancing, and these fields
361        keep track of this.
362        For AM, these correspond to new data */
363     guint16  previousSequenceNumber;
364     guint32  previousFrameNum;
365     gboolean previousSegmentIncomplete;
366
367     /* Accumulate info about current segmented SDU */
368     struct rlc_channel_reassembly_info *reassembly_info;
369 } channel_sequence_analysis_status;
370
371 /* The sequence analysis channel hash table */
372 static GHashTable *sequence_analysis_channel_hash = NULL;
373
374
375 /* Types for sequence analysis frame report hash table                  */
376 /* This is a table from framenum -> state_report_in_frame               */
377 /* This is necessary because the per-packet info is already being used  */
378 /* for context information before the dissector is called               */
379
380 /* Info to attach to frame when first read, recording what to show about sequence */
381 typedef enum { 
382     SN_OK, SN_Repeated, SN_MAC_Retx, SN_Retx, SN_Missing, ACK_Out_of_Window, SN_Error
383 } sequence_analysis_state;
384
385
386 typedef struct
387 {
388     gboolean  sequenceExpectedCorrect;
389     guint16   sequenceExpected;
390     guint32   previousFrameNum;
391     gboolean  previousSegmentIncomplete;
392     guint32   nextFrameNum;
393
394     guint16   firstSN;
395     guint16   lastSN;
396
397     /* AM/UM */
398     sequence_analysis_state state;
399 } sequence_analysis_report;
400
401
402 /* The sequence analysis frame report hash table instance itself   */
403 static GHashTable *sequence_analysis_report_hash = NULL;
404
405
406 static gpointer get_report_hash_key(guint16 SN, guint32 frameNumber,
407                                     rlc_lte_info *p_rlc_lte_info,
408                                     gboolean do_persist);
409
410
411
412
413 /* The reassembly result hash table */
414 static GHashTable *reassembly_report_hash = NULL;
415
416
417 /* Create a new struct for reassembly */
418 static void reassembly_reset(channel_sequence_analysis_status *status)
419 {
420     status->reassembly_info = se_alloc0(sizeof(rlc_channel_reassembly_info));
421 }
422
423 /* Hide previous one */
424 static void reassembly_destroy(channel_sequence_analysis_status *status)
425 {
426     /* Just "leak" it. There seems to be no way to free this memory... */
427     status->reassembly_info = NULL;
428 }
429
430 /* Add a new segment to the accumulating segmented SDU */
431 static void reassembly_add_segment(channel_sequence_analysis_status *status,
432                                    guint16 SN, guint32 frame,
433                                    tvbuff_t *tvb, gint offset, gint length)
434 {
435     int segment_number =  status->reassembly_info->number_of_segments;
436     guint8 *segment_data;
437
438     /* Give up if reach segment limit */
439     if (segment_number >= (RLC_MAX_SEGMENTS-1)) {
440         reassembly_destroy(status);
441         return;
442     }
443
444     segment_data = se_alloc(length);
445     /* TODO: is there a better way to do this? */
446     memcpy(segment_data, tvb_get_ptr(tvb, offset, length), length);
447
448     /* Add new segment */
449     status->reassembly_info->segments[segment_number].frameNum = frame;
450     status->reassembly_info->segments[segment_number].SN = SN;
451     status->reassembly_info->segments[segment_number].data = segment_data;
452     status->reassembly_info->segments[segment_number].length = length;
453
454     status->reassembly_info->number_of_segments++;
455 }
456
457
458 /* Record the current & complete segmented SDU by mapping from this frame number to
459    struct with segment info. */
460 static void reassembly_record(channel_sequence_analysis_status *status, packet_info *pinfo,
461                               guint16 SN, rlc_lte_info *p_rlc_lte_info)
462 {
463     /* Just store existing info in hash table */
464     g_hash_table_insert(reassembly_report_hash,
465                         get_report_hash_key(SN, pinfo->fd->num, p_rlc_lte_info, TRUE),
466                         status->reassembly_info);
467 }
468
469 /* Create and return a tvb based upon contents of reassembly info */
470 static tvbuff_t* reassembly_get_reassembled_tvb(rlc_channel_reassembly_info *reassembly_info,
471                                                 tvbuff_t *parent_tvb, packet_info *pinfo)
472 {
473     gint n;
474     guint   combined_length = 0;
475     guint8 *combined_data;
476     guint combined_offset = 0;
477     tvbuff_t *reassembled_tvb;
478
479     /* Allocate buffer big enough to hold re-assembled data */
480     for (n=0; n < reassembly_info->number_of_segments; n++) {
481         combined_length += reassembly_info->segments[n].length;
482     }
483     combined_data = ep_alloc(combined_length);
484
485     /* Copy data into contiguous buffer */
486     for (n=0; n < reassembly_info->number_of_segments; n++) {
487         guint8 *data = reassembly_info->segments[n].data;
488         int length = reassembly_info->segments[n].length;
489         memcpy(combined_data+combined_offset, data, length);
490         combined_offset += length;
491     }
492
493     /* Create and return tvb with this data */
494     reassembled_tvb = tvb_new_child_real_data(parent_tvb, combined_data, combined_offset, combined_offset);
495     add_new_data_source(pinfo, reassembled_tvb, "Reassembled SDU");
496     return reassembled_tvb;
497 }
498
499 /* Show where the segments came from for a reassembled SDU */
500 static void reassembly_show_source(rlc_channel_reassembly_info *reassembly_info,
501                                    proto_tree *tree, tvbuff_t *tvb, gint offset)
502 {
503     int n;
504     proto_item *source_ti, *ti;
505     proto_tree *source_tree;
506     proto_item *segment_ti;
507     proto_tree *segment_tree;
508     guint      total_length=0;
509
510     /* Create root of source info */
511     source_ti = proto_tree_add_item(tree,
512                                     hf_rlc_lte_reassembly_source,
513                                     tvb, 0, 0, ENC_ASCII|ENC_NA);
514     source_tree = proto_item_add_subtree(source_ti, ett_rlc_lte_reassembly_source);
515     PROTO_ITEM_SET_GENERATED(source_ti);
516
517     for (n=0; n < reassembly_info->number_of_segments; n++) {
518         total_length += reassembly_info->segments[n].length;
519     }
520     proto_item_append_text(source_ti, " %u segments, %u bytes", reassembly_info->number_of_segments,
521                            total_length);
522
523     /* Number of segments */
524     ti = proto_tree_add_uint(source_tree,
525                              hf_rlc_lte_reassembly_source_number_of_segments,
526                              tvb, 0, 0, reassembly_info->number_of_segments);
527     PROTO_ITEM_SET_GENERATED(ti);
528
529     /* Total length */
530     ti = proto_tree_add_uint(source_tree,
531                              hf_rlc_lte_reassembly_source_total_length,
532                              tvb, 0, 0, total_length);
533     PROTO_ITEM_SET_GENERATED(ti);
534
535     /* Now add info about each segment in turn */
536     for (n=0; n < reassembly_info->number_of_segments; n++) {
537
538         /* Add next segment as a subtree */
539         rlc_segment *segment = &(reassembly_info->segments[n]);
540         proto_item_append_text(source_ti, " (SN=%u frame=%u len=%u)",
541                                segment->SN, segment->frameNum, segment->length);
542
543         /* N.B. assume last segment from passed-in tvb! */
544         segment_ti = proto_tree_add_item(source_tree,
545                                          hf_rlc_lte_reassembly_source_segment,
546                                          tvb,
547                                          (n == reassembly_info->number_of_segments-1) ? offset : 0,
548                                          (n == reassembly_info->number_of_segments-1) ? segment->length : 0,
549                                          ENC_NA);
550         segment_tree = proto_item_add_subtree(segment_ti, ett_rlc_lte_reassembly_source_segment);
551         proto_item_append_text(segment_ti, " (SN=%u frame=%u length=%u)",
552                                segment->SN, segment->frameNum, segment->length);
553         PROTO_ITEM_SET_GENERATED(segment_ti);
554
555         /* Add details to segment tree */
556         ti = proto_tree_add_uint(segment_tree, hf_rlc_lte_reassembly_source_segment_sn,
557                                  tvb, 0, 0, segment->SN);
558         PROTO_ITEM_SET_GENERATED(ti);
559         ti = proto_tree_add_uint(segment_tree, hf_rlc_lte_reassembly_source_segment_framenum,
560                                  tvb, 0, 0, segment->frameNum);
561         PROTO_ITEM_SET_GENERATED(ti);
562         ti = proto_tree_add_uint(segment_tree, hf_rlc_lte_reassembly_source_segment_length,
563                                  tvb, 0, 0, segment->length);
564         PROTO_ITEM_SET_GENERATED(ti);
565     }
566 }
567
568
569
570
571 /******************************************************************/
572 /* Conversation-type status for repeated NACK checking on channel */
573 typedef struct
574 {
575     guint16         noOfNACKs;
576     guint16         NACKs[MAX_NACKs];
577     guint32         frameNum;
578 } channel_repeated_nack_status;
579
580 static GHashTable *repeated_nack_channel_hash = NULL;
581
582 typedef struct {
583     guint16         noOfNACKsRepeated;
584     guint16         repeatedNACKs[MAX_NACKs];
585     guint32         previousFrameNum;
586 } channel_repeated_nack_report;
587
588 static GHashTable *repeated_nack_report_hash = NULL;
589
590
591
592 /********************************************************/
593 /* Forward declarations & functions                     */
594 static void dissect_rlc_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
595
596
597 /* Write the given formatted text to:
598    - the info column
599    - the top-level RLC PDU item
600    - another subtree item (if supplied) */
601 static void write_pdu_label_and_info(proto_item *pdu_ti, proto_item *sub_ti,
602                                      packet_info *pinfo, const char *format, ...)
603 {
604     #define MAX_INFO_BUFFER 256
605     static char info_buffer[MAX_INFO_BUFFER];
606
607     va_list ap;
608
609     va_start(ap, format);
610     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
611     va_end(ap);
612
613     /* Add to indicated places */
614     col_append_str(pinfo->cinfo, COL_INFO, info_buffer);
615     proto_item_append_text(pdu_ti, "%s", info_buffer);
616     if (sub_ti != NULL) {
617         proto_item_append_text(sub_ti, "%s", info_buffer);
618     }
619 }
620
621
622
623 /* Dissect extension headers (common to both UM and AM) */
624 static int dissect_rlc_lte_extension_header(tvbuff_t *tvb, packet_info *pinfo _U_,
625                                             proto_tree *tree,
626                                             int offset)
627 {
628     guint8  isOdd;
629     guint64 extension = 1;
630     guint64 length;
631
632     /* Reset this count */
633     s_number_of_extensions = 0;
634
635     while (extension && (s_number_of_extensions < MAX_RLC_SDUS)) {
636         proto_tree *extension_part_tree;
637         proto_item *extension_part_ti;
638
639         isOdd = (s_number_of_extensions % 2);
640
641         /* Extension part subtree */
642         extension_part_ti = proto_tree_add_string_format(tree,
643                                                          hf_rlc_lte_extension_part,
644                                                          tvb, offset, 2,
645                                                          "",
646                                                          "Extension Part");
647         extension_part_tree = proto_item_add_subtree(extension_part_ti,
648                                                      ett_rlc_lte_extension_part);
649
650         /* Read next extension */
651         proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_e, tvb,
652                                     (offset*8) + ((isOdd) ? 4 : 0),
653                                     1,
654                                     &extension, ENC_BIG_ENDIAN);
655
656         /* Read length field */
657         proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_li, tvb,
658                                     (offset*8) + ((isOdd) ? 5 : 1),
659                                     11,
660                                     &length, ENC_BIG_ENDIAN);
661
662         proto_item_append_text(extension_part_tree, " (length=%u)", (guint16)length);
663
664         /* Move on to byte of next extension */
665         if (isOdd) {
666             offset += 2;
667         } else {
668             offset++;
669         }
670
671         s_lengths[s_number_of_extensions++] = (guint16)length;
672     }
673
674     /* May need to skip padding after last extension part */
675     isOdd = (s_number_of_extensions % 2);
676     if (isOdd) {
677         proto_tree_add_item(tree, hf_rlc_lte_extension_padding,
678                             tvb, offset++, 1, ENC_BIG_ENDIAN);
679     }
680
681     return offset;
682 }
683
684
685 /* Show in the info column how many bytes are in the UM/AM PDU, and indicate
686    whether or not the beginning and end are included in this packet */
687 static void show_PDU_in_info(packet_info *pinfo,
688                              proto_item *top_ti,
689                              gint32 length,
690                              gboolean first_includes_start,
691                              gboolean last_includes_end)
692 {
693     /* Reflect this PDU in the info column */
694     if (length > 0) {
695         write_pdu_label_and_info(top_ti, NULL, pinfo,
696                                  "  %s%u-byte%s%s",
697                                  (first_includes_start) ? "[" : "..",
698                                  length,
699                                  (length > 1) ? "s" : "",
700                                  (last_includes_end) ? "]" : "..");
701     }
702     else {
703         write_pdu_label_and_info(top_ti, NULL, pinfo,
704                                  "  %sunknown-bytes%s",
705                                  (first_includes_start) ? "[" : "..",
706                                  (last_includes_end) ? "]" : "..");
707     }
708 }
709
710
711 /* Show an SDU.  If configured, pass to PDCP dissector */
712 static void show_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, gint offset, gint length,
713                              rlc_lte_info *rlc_info, gboolean whole_pdu, rlc_channel_reassembly_info *reassembly_info,
714                              sequence_analysis_state state)
715 {
716     /* Add raw data (according to mode) */
717     proto_item *data_ti = proto_tree_add_item(tree,
718                                               (rlc_info->rlcMode == RLC_AM_MODE) ?
719                                                     hf_rlc_lte_am_data :
720                                                     hf_rlc_lte_um_data,
721                                               tvb, offset, length, ENC_NA);
722
723     /* Send whole PDU to PDCP */
724     if ((whole_pdu || (reassembly_info != NULL)) &&
725         (((global_rlc_lte_call_pdcp_for_srb) && (rlc_info->channelType == CHANNEL_TYPE_SRB)) ||
726          ((global_rlc_lte_call_pdcp_for_drb != PDCP_drb_off) && (rlc_info->channelType == CHANNEL_TYPE_DRB)))) {
727
728         /* TODO: made static to avoid compiler warning... */
729         static tvbuff_t *pdcp_tvb = NULL;
730         volatile dissector_handle_t protocol_handle;
731         struct pdcp_lte_info *p_pdcp_lte_info;
732
733         /* Get tvb for passing to LTE PDCP dissector */
734         if (reassembly_info == NULL) {
735             pdcp_tvb = tvb_new_subset(tvb, offset, length, length);
736         }
737         else {
738             /* Get combined tvb. */
739             pdcp_tvb = reassembly_get_reassembled_tvb(reassembly_info, tvb, pinfo);
740             reassembly_show_source(reassembly_info, tree, tvb, offset);
741         }
742
743         /* Reuse or allocate struct */
744         p_pdcp_lte_info = p_get_proto_data(pinfo->fd, proto_pdcp_lte);
745         if (p_pdcp_lte_info == NULL) {
746             p_pdcp_lte_info = se_alloc0(sizeof(struct pdcp_lte_info));
747             /* Store info in packet */
748             p_add_proto_data(pinfo->fd, proto_pdcp_lte, p_pdcp_lte_info);
749         }
750
751         p_pdcp_lte_info->ueid = rlc_info->ueid;
752         p_pdcp_lte_info->channelType = Channel_DCCH;
753         p_pdcp_lte_info->channelId = rlc_info->channelId;
754         p_pdcp_lte_info->direction = rlc_info->direction;
755         p_pdcp_lte_info->is_retx = (state != SN_OK);
756
757         /* Set plane and sequnce number length */
758         p_pdcp_lte_info->no_header_pdu = FALSE;
759         if (rlc_info->channelType == CHANNEL_TYPE_SRB) {
760             p_pdcp_lte_info->plane = SIGNALING_PLANE;
761             p_pdcp_lte_info->seqnum_length = 5;
762         }
763         else {
764             p_pdcp_lte_info->plane = USER_PLANE;
765             switch (global_rlc_lte_call_pdcp_for_drb) {
766                 case PDCP_drb_SN_7:
767                     p_pdcp_lte_info->seqnum_length = 7;
768                     break;
769                 case PDCP_drb_SN_12:
770                     p_pdcp_lte_info->seqnum_length = 12;
771                     break;
772                 case PDCP_drb_SN_signalled:
773                     /* Use whatever was signalled (e.g. in RRC) */
774                     p_pdcp_lte_info->seqnum_length = signalled_pdcp_sn_bits;
775                     break;
776
777                 default:
778                     DISSECTOR_ASSERT(FALSE);
779                     break;
780             }
781         }
782
783         p_pdcp_lte_info->rohc_compression = FALSE;
784
785
786         /* Get dissector handle */
787         protocol_handle = find_dissector("pdcp-lte");
788
789         TRY {
790             call_dissector_only(protocol_handle, pdcp_tvb, pinfo, tree);
791         }
792         CATCH_ALL {
793         }
794         ENDTRY
795
796         PROTO_ITEM_SET_HIDDEN(data_ti);
797     }
798 }
799
800 /* Hash table functions for RLC channels */
801
802 /* Equal keys */
803 static gint rlc_channel_equal(gconstpointer v, gconstpointer v2)
804 {
805     const channel_hash_key* val1 = v;
806     const channel_hash_key* val2 = v2;
807
808     /* All fields must match */
809     /* N.B. Currently fits into one word, so could return (*v == *v2)
810        if we're sure they're initialised to 0... */
811     return ((val1->ueId        == val2->ueId) &&
812             (val1->channelType == val2->channelType) &&
813             (val1->channelId   == val2->channelId) &&
814             (val1->direction   == val2->direction));
815 }
816
817 /* Compute a hash value for a given key. */
818 static guint rlc_channel_hash_func(gconstpointer v)
819 {
820     const channel_hash_key* val1 = v;
821
822     /* TODO: check/reduce multipliers */
823     return ((val1->ueId * 1024) + (val1->channelType*64) + (val1->channelId*2) + val1->direction);
824 }
825
826
827 /*************************************************************************/
828 /* Result hash                                                           */
829
830 typedef struct {
831     guint32            frameNumber;
832     unsigned           SN :             10;
833     unsigned           channelType :    2;
834     unsigned           channelId:       5;
835     unsigned           direction:       1;
836 } rlc_result_hash_key;
837
838 static gint rlc_result_hash_equal(gconstpointer v, gconstpointer v2)
839 {
840     const rlc_result_hash_key* val1 = (rlc_result_hash_key *)v;
841     const rlc_result_hash_key* val2 = (rlc_result_hash_key *)v2;
842
843     /* All fields must match */
844     return (memcmp(val1, val2, sizeof(rlc_result_hash_key)) == 0);
845 }
846
847 /* Compute a hash value for a given key. */
848 static guint rlc_result_hash_func(gconstpointer v)
849 {
850     const rlc_result_hash_key* val1 = (rlc_result_hash_key *)v;
851
852     /* TODO: check collision-rate / execution-time of these multipliers?  */
853     return val1->frameNumber + (val1->SN<<13) +
854                                (val1->channelType<<5) +
855                                (val1->channelId<<18) +
856                                (val1->direction<<9);
857 }
858
859 /* Convenience function to get a pointer for the hash_func to work with */
860 static gpointer get_report_hash_key(guint16 SN, guint32 frameNumber,
861                                     rlc_lte_info *p_rlc_lte_info,
862                                     gboolean do_persist)
863 {
864     static rlc_result_hash_key key;
865     rlc_result_hash_key *p_key;
866
867     /* Only allocate a struct when will be adding entry */
868     if (do_persist) {
869         p_key = se_new0(rlc_result_hash_key);
870     }
871     else {
872         memset(&key, 0, sizeof(rlc_result_hash_key));
873         p_key = &key;
874     }
875
876     /* Fill in details, and return pointer */
877     p_key->frameNumber = frameNumber;
878     p_key->SN = SN;
879     p_key->channelType = p_rlc_lte_info->channelType;
880     p_key->channelId = p_rlc_lte_info->channelId;
881     p_key->direction = p_rlc_lte_info->direction;
882
883     return p_key;
884 }
885
886
887
888
889 /* Add to the tree values associated with sequence analysis for this frame */
890 static void addChannelSequenceInfo(sequence_analysis_report *p,
891                                    gboolean isControlFrame,
892                                    rlc_lte_info *p_rlc_lte_info,
893                                    guint16   sequenceNumber,
894                                    gboolean  newSegmentStarted,
895                                    rlc_lte_tap_info *tap_info,
896                                    packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb)
897 {
898     proto_tree *seqnum_tree;
899     proto_item *seqnum_ti;
900     proto_item *ti;
901
902     /* Create subtree */
903     seqnum_ti = proto_tree_add_string_format(tree,
904                                              hf_rlc_lte_sequence_analysis,
905                                              tvb, 0, 0,
906                                              "", "Sequence Analysis");
907     seqnum_tree = proto_item_add_subtree(seqnum_ti,
908                                          ett_rlc_lte_sequence_analysis);
909     PROTO_ITEM_SET_GENERATED(seqnum_ti);
910
911     if (p->previousFrameNum != 0) {
912         ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_previous_frame,
913                                  tvb, 0, 0, p->previousFrameNum);
914         PROTO_ITEM_SET_GENERATED(ti);
915     }
916
917     switch (p_rlc_lte_info->rlcMode) {
918         case RLC_AM_MODE:
919
920             /********************************************/
921             /* AM                                       */
922             /********************************************/
923
924             switch (p->state) {
925                 case SN_OK:
926                     if (isControlFrame) {
927                         return;
928                     }
929
930                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
931                                                 tvb, 0, 0, TRUE);
932                     PROTO_ITEM_SET_GENERATED(ti);
933                     proto_item_append_text(seqnum_ti, " - OK");
934
935                     /* Link to next SN in channel (if known) */
936                     if (p->nextFrameNum != 0) {
937                         proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_next_frame,
938                                             tvb, 0, 0, p->nextFrameNum);
939                     }
940                     break;
941
942                 case SN_MAC_Retx:
943                     if (isControlFrame) {
944                         return;
945                     }
946
947                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
948                                                 tvb, 0, 0, FALSE);
949                     PROTO_ITEM_SET_GENERATED(ti);
950                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_mac_retx,
951                                                 tvb, 0, 0, TRUE);
952                     PROTO_ITEM_SET_GENERATED(ti);
953                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
954                                            "AM Frame retransmitted for %s on UE %u - due to MAC retx!",
955                                            val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
956                                            p_rlc_lte_info->ueid);
957                     proto_item_append_text(seqnum_ti, " - MAC retx of SN %u", p->firstSN);
958                     break;
959
960                 case SN_Retx:
961                     if (isControlFrame) {
962                         return;
963                     }
964
965                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
966                                                 tvb, 0, 0, FALSE);
967                     PROTO_ITEM_SET_GENERATED(ti);
968                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_retx,
969                                                 tvb, 0, 0, TRUE);
970                     PROTO_ITEM_SET_GENERATED(ti);
971                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
972                                            "AM Frame retransmitted for %s on UE %u - most likely in response to NACK",
973                                            val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
974                                            p_rlc_lte_info->ueid);
975                     proto_item_append_text(seqnum_ti, " - SN %u retransmitted", p->firstSN);
976                     break;
977
978                 case SN_Repeated:
979                     if (isControlFrame) {
980                         return;
981                     }
982
983                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
984                                                 tvb, 0, 0, FALSE);
985                     PROTO_ITEM_SET_GENERATED(ti);
986                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_repeated,
987                                                 tvb, 0, 0, TRUE);
988                     PROTO_ITEM_SET_GENERATED(ti);
989                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
990                                            "AM SN Repeated for %s for UE %u - probably because didn't receive Status PDU?",
991                                            val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
992                                            p_rlc_lte_info->ueid);
993                     proto_item_append_text(seqnum_ti, "- SN %u Repeated", p->firstSN);
994                     break;
995
996                 case SN_Missing:
997                     if (isControlFrame) {
998                         return;
999                     }
1000
1001                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
1002                                                 tvb, 0, 0, FALSE);
1003                     PROTO_ITEM_SET_GENERATED(ti);
1004                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_skipped,
1005                                                 tvb, 0, 0, TRUE);
1006                     PROTO_ITEM_SET_GENERATED(ti);
1007                     if (p->lastSN != p->firstSN) {
1008                         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1009                                                "AM SNs (%u to %u) missing for %s on UE %u",
1010                                                p->firstSN, p->lastSN,
1011                                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1012                                                p_rlc_lte_info->ueid);
1013                         proto_item_append_text(seqnum_ti, " - SNs missing (%u to %u)",
1014                                                p->firstSN, p->lastSN);
1015                         tap_info->missingSNs = ((1024 + p->lastSN - p->firstSN) % 1024) + 1;
1016                     }
1017                     else {
1018                         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1019                                                "AM SN (%u) missing for %s on UE %u",
1020                                                p->firstSN,
1021                                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1022                                                p_rlc_lte_info->ueid);
1023                         proto_item_append_text(seqnum_ti, " - SN missing (%u)", p->firstSN);
1024                         tap_info->missingSNs = 1;
1025                     }
1026                     break;
1027
1028                 case ACK_Out_of_Window:
1029                     if (!isControlFrame) {
1030                         return;
1031                     }
1032
1033
1034                     /* Not OK */
1035                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
1036                                                 tvb, 0, 0, FALSE);
1037                     /* Out of range */
1038                     PROTO_ITEM_SET_GENERATED(ti);
1039                     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ack_out_of_range,
1040                                                 tvb, 0, 0, TRUE);
1041                     PROTO_ITEM_SET_GENERATED(ti);
1042
1043                     /* Link back to last seen SN in other direction */
1044                     ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_ack_out_of_range_opposite_frame,
1045                                              tvb, 0, 0, p->previousFrameNum);
1046                     PROTO_ITEM_SET_GENERATED(ti);
1047
1048                     /* Expert error */
1049                     expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_ERROR,
1050                                            "AM ACK for SN %u - but last received SN in other direction is %u for UE %u",
1051                                            p->firstSN, p->sequenceExpected,
1052                                            p_rlc_lte_info->ueid);
1053                     proto_item_append_text(seqnum_ti, "- ACK SN %u Outside Rx Window - last received SN is %u",
1054                                            p->firstSN, p->sequenceExpected);
1055
1056                     break;
1057
1058                 default:
1059                     return;
1060             }
1061             break;
1062
1063         case RLC_UM_MODE:
1064
1065             /********************************************/
1066             /* UM                                       */
1067             /********************************************/
1068
1069             /* Previous channel frame */
1070             if (p->previousFrameNum != 0) {
1071                 ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_previous_frame,
1072                                          tvb, 0, 0, p->previousFrameNum);
1073                 PROTO_ITEM_SET_GENERATED(ti);
1074             }
1075
1076             /* Expected sequence number */
1077             ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_expected_sn,
1078                                     tvb, 0, 0, p->sequenceExpected);
1079             PROTO_ITEM_SET_GENERATED(ti);
1080
1081             if (!p->sequenceExpectedCorrect) {
1082                 /* Work out SN wrap (in case needed below) */
1083                 guint16 snLimit;
1084                 if (p_rlc_lte_info->UMSequenceNumberLength == 5) {
1085                     snLimit = 32;
1086                 }
1087                 else {
1088                     snLimit = 1024;
1089                 }
1090
1091                 switch (p->state) {
1092                     case SN_Missing:
1093                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
1094                                                     tvb, 0, 0, FALSE);
1095                         PROTO_ITEM_SET_GENERATED(ti);
1096                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_skipped,
1097                                                     tvb, 0, 0, TRUE);
1098                         PROTO_ITEM_SET_GENERATED(ti);
1099                         if (p->lastSN != p->firstSN) {
1100                             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1101                                                    "UM SNs (%u to %u) missing for %s on UE %u",
1102                                                    p->firstSN, p->lastSN,
1103                                                    val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1104                                                    p_rlc_lte_info->ueid);
1105                             proto_item_append_text(seqnum_ti, " - SNs missing (%u to %u)",
1106                                                    p->firstSN, p->lastSN);
1107                             tap_info->missingSNs = ((snLimit + p->lastSN - p->firstSN) % snLimit) + 1;
1108                         }
1109                         else {
1110                             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1111                                                    "UM SN (%u) missing for %s on UE %u",
1112                                                    p->firstSN,
1113                                                    val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1114                                                    p_rlc_lte_info->ueid);
1115                             proto_item_append_text(seqnum_ti, " - SN missing (%u)",
1116                                                    p->firstSN);
1117                             tap_info->missingSNs = 1;
1118                         }
1119                         break;
1120
1121                     case SN_Repeated:
1122                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
1123                                                     tvb, 0, 0, FALSE);
1124                         PROTO_ITEM_SET_GENERATED(ti);
1125                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_repeated,
1126                                                     tvb, 0, 0, TRUE);
1127                         PROTO_ITEM_SET_GENERATED(ti);
1128                         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1129                                                "UM SN (%u) repeated for %s for UE %u",
1130                                                p->firstSN,
1131                                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1132                                                p_rlc_lte_info->ueid);
1133                         proto_item_append_text(seqnum_ti, "- SN %u Repeated",
1134                                                p->firstSN);
1135                         break;
1136
1137                     case SN_MAC_Retx:
1138                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
1139                                                     tvb, 0, 0, FALSE);
1140                         PROTO_ITEM_SET_GENERATED(ti);
1141                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_mac_retx,
1142                                                     tvb, 0, 0, TRUE);
1143                         PROTO_ITEM_SET_GENERATED(ti);
1144                         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1145                                                "UM Frame retransmitted for %s on UE %u - due to MAC retx!",
1146                                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1147                                                p_rlc_lte_info->ueid);
1148                         break;
1149
1150                     case SN_OK:
1151                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
1152                                                     tvb, 0, 0, TRUE);
1153                         PROTO_ITEM_SET_GENERATED(ti);
1154                         proto_item_append_text(seqnum_ti, " - OK");
1155
1156                         /* Link to next SN in channel (if known) */
1157                         if (p->nextFrameNum != 0) {
1158                             proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_next_frame,
1159                                                 tvb, 0, 0, p->nextFrameNum);
1160                         }
1161                         break;
1162
1163                     default:
1164                         /* Incorrect sequence number */
1165                         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1166                                                "Wrong Sequence Number for %s on UE %u - got %u, expected %u",
1167                                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1168                                                p_rlc_lte_info->ueid, sequenceNumber, p->sequenceExpected);
1169                         break;
1170                 }
1171
1172             }
1173             else {
1174                 /* Correct sequence number, so check frame indication bits consistent */
1175                 if (p->previousSegmentIncomplete) {
1176                     /* Previous segment was incomplete, so this PDU should continue it */
1177                     if (newSegmentStarted) {
1178                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
1179                                                      tvb, 0, 0, FALSE);
1180                         if (!p->sequenceExpectedCorrect) {
1181                             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1182                                                    "Last segment of previous PDU was not continued for UE %u",
1183                                                    p_rlc_lte_info->ueid);
1184                         }
1185                     }
1186                     else {
1187                        ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
1188                                                    tvb, 0, 0, TRUE);
1189                     }
1190                 }
1191                 else {
1192                     /* Previous segment was complete, so this PDU should start a new one */
1193                     if (!newSegmentStarted) {
1194                         ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
1195                                                     tvb, 0, 0, FALSE);
1196                         if (!p->sequenceExpectedCorrect) {
1197                             expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
1198                                                    "Last segment of previous PDU was complete, but new segment was not started");
1199                         }
1200                     }
1201                     else {
1202                        ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct,
1203                                                    tvb, 0, 0, TRUE);
1204                     }
1205
1206                 }
1207                 PROTO_ITEM_SET_GENERATED(ti);
1208             }
1209     }
1210 }
1211
1212 /* Update the channel status and set report for this frame */
1213 static sequence_analysis_state checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb,
1214                                                         rlc_lte_info *p_rlc_lte_info,
1215                                                         gboolean isControlFrame,
1216                                                         guint8 number_of_segments,
1217                                                         guint16 firstSegmentOffset,
1218                                                         guint16 firstSegmentLength,
1219                                                         guint16 lastSegmentOffset,
1220                                                         guint16 sequenceNumber,
1221                                                         gboolean first_includes_start, gboolean last_includes_end,
1222                                                         gboolean is_resegmented _U_,
1223                                                         rlc_lte_tap_info *tap_info,
1224                                                         proto_tree *tree)
1225 {
1226     channel_hash_key   channel_key;
1227     channel_hash_key   *p_channel_key;
1228     channel_sequence_analysis_status     *p_channel_status;
1229     sequence_analysis_report *p_report_in_frame = NULL;
1230     gboolean               createdChannel = FALSE;
1231     guint16                expectedSequenceNumber = 0;
1232     guint16                snLimit = 0;
1233
1234     /* If find stat_report_in_frame already, use that and get out */
1235     if (pinfo->fd->flags.visited) {
1236         p_report_in_frame = (sequence_analysis_report*)g_hash_table_lookup(sequence_analysis_report_hash,
1237                                                                            get_report_hash_key(sequenceNumber,
1238                                                                                                pinfo->fd->num,
1239                                                                                                p_rlc_lte_info,
1240                                                                                                FALSE));
1241         if (p_report_in_frame != NULL) {
1242             addChannelSequenceInfo(p_report_in_frame, isControlFrame, p_rlc_lte_info,
1243                                    sequenceNumber, first_includes_start,
1244                                    tap_info, pinfo, tree, tvb);
1245             return p_report_in_frame->state;
1246         }
1247
1248         /* Don't just give up here... */
1249     }
1250
1251
1252     /**************************************************/
1253     /* Create or find an entry for this channel state */
1254     channel_key.ueId = p_rlc_lte_info->ueid;
1255     channel_key.channelType = p_rlc_lte_info->channelType;
1256     channel_key.channelId = p_rlc_lte_info->channelId;
1257     channel_key.direction = p_rlc_lte_info->direction;
1258
1259     /* Do the table lookup */
1260     p_channel_status = (channel_sequence_analysis_status*)g_hash_table_lookup(sequence_analysis_channel_hash, &channel_key);
1261
1262     /* Create table entry if necessary */
1263     if (p_channel_status == NULL) {
1264         createdChannel = TRUE;
1265
1266         /* Allocate a new value and duplicate key contents */
1267         p_channel_status = se_alloc0(sizeof(channel_sequence_analysis_status));
1268         p_channel_key = se_memdup(&channel_key, sizeof(channel_hash_key));
1269
1270         /* Set mode */
1271         p_channel_status->rlcMode = p_rlc_lte_info->rlcMode;
1272
1273         /* Add entry */
1274         g_hash_table_insert(sequence_analysis_channel_hash, p_channel_key, p_channel_status);
1275     }
1276
1277     /* Create space for frame state_report */
1278     p_report_in_frame = se_alloc(sizeof(sequence_analysis_report));
1279
1280
1281     /* Deal with according to channel mode */
1282     switch (p_channel_status->rlcMode) {
1283         case RLC_UM_MODE:
1284
1285             if (p_rlc_lte_info->UMSequenceNumberLength == 5) {
1286                 snLimit = 32;
1287             }
1288             else {
1289                 snLimit = 1024;
1290             }
1291
1292             /* Work out expected sequence number */
1293             if (!createdChannel) {
1294                 expectedSequenceNumber = (p_channel_status->previousSequenceNumber + 1) % snLimit;
1295             }
1296             else {
1297                 /* Whatever we got is fine.. */
1298                 expectedSequenceNumber = sequenceNumber;
1299             }
1300
1301             /* Set report for this frame */
1302             /* For UM, sequence number is always expectedSequence number */
1303             p_report_in_frame->sequenceExpectedCorrect = (sequenceNumber == expectedSequenceNumber);
1304
1305             /* For wrong sequence number... */
1306             if (!p_report_in_frame->sequenceExpectedCorrect) {
1307
1308                 reassembly_destroy(p_channel_status);
1309
1310                 /* Don't get confused by MAC (HARQ) retx */
1311                 if (is_mac_lte_frame_retx(pinfo, p_rlc_lte_info->direction)) {
1312                     p_report_in_frame->state = SN_MAC_Retx;
1313                     p_report_in_frame->firstSN = sequenceNumber;
1314                 }
1315
1316                 /* Frames are not missing if we get an earlier sequence number again */
1317                 /* TODO: taking time into account would give better idea of whether missing or repeated... */
1318                 else if (((snLimit + sequenceNumber - expectedSequenceNumber) % snLimit) < 10) {
1319                     p_report_in_frame->state = SN_Missing;
1320                     tap_info->missingSNs = (snLimit + sequenceNumber - expectedSequenceNumber) % snLimit;
1321                     p_report_in_frame->firstSN = expectedSequenceNumber;
1322                     p_report_in_frame->lastSN = (snLimit + sequenceNumber - 1) % snLimit;
1323
1324                     p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1325                     p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1326                     p_report_in_frame->previousSegmentIncomplete = p_channel_status->previousSegmentIncomplete;
1327
1328                     /* Update channel status to remember *this* frame */
1329                     p_channel_status->previousFrameNum = pinfo->fd->num;
1330                     p_channel_status->previousSequenceNumber = sequenceNumber;
1331                     p_channel_status->previousSegmentIncomplete = !last_includes_end;
1332                 }
1333                 else {
1334                     /* An SN has been repeated */
1335                     p_report_in_frame->state = SN_Repeated;
1336                     p_report_in_frame->firstSN = sequenceNumber;
1337
1338                     p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1339                     p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1340                 }
1341             }
1342             else {
1343                 /* SN was OK */
1344                 p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1345                 p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1346                 p_report_in_frame->previousSegmentIncomplete = p_channel_status->previousSegmentIncomplete;
1347
1348                 /* Update channel status to remember *this* frame */
1349                 p_channel_status->previousFrameNum = pinfo->fd->num;
1350                 p_channel_status->previousSequenceNumber = sequenceNumber;
1351                 p_channel_status->previousSegmentIncomplete = !last_includes_end;
1352
1353                 if (p_channel_status->reassembly_info) {
1354
1355                     /* Add next segment to reassembly info */
1356                     reassembly_add_segment(p_channel_status, sequenceNumber, pinfo->fd->num,
1357                                            tvb, firstSegmentOffset, firstSegmentLength);
1358
1359                     /* The end of existing reassembly? */
1360                     if (!first_includes_start &&
1361                         ((number_of_segments > 1) || last_includes_end)) {
1362
1363                         reassembly_record(p_channel_status, pinfo, sequenceNumber, p_rlc_lte_info);
1364                         reassembly_destroy(p_channel_status);
1365                     }
1366                 }
1367
1368                 /* The start of a new reassembly? */
1369                 if (!last_includes_end &&
1370                     ((number_of_segments > 1) || first_includes_start)) {
1371
1372                     guint16 lastSegmentLength = tvb_length(tvb)-lastSegmentOffset;
1373
1374                     if (global_rlc_lte_reassembly) {
1375                         reassembly_reset(p_channel_status);
1376                         reassembly_add_segment(p_channel_status, sequenceNumber,
1377                                                pinfo->fd->num,
1378                                                tvb, lastSegmentOffset, lastSegmentLength);
1379                     }
1380                 }
1381
1382                 if (p_report_in_frame->previousFrameNum != 0) {
1383                     /* Get report for previous frame */
1384                     sequence_analysis_report *p_previous_report;
1385                     guint16 snLimit;
1386                     if (p_rlc_lte_info->UMSequenceNumberLength == 5) {
1387                         snLimit = 32;
1388                     }
1389                     else {
1390                         snLimit = 1024;
1391                     }
1392
1393                     p_previous_report = (sequence_analysis_report*)g_hash_table_lookup(sequence_analysis_report_hash,
1394                                                                                        get_report_hash_key((sequenceNumber+snLimit-1) % snLimit,
1395                                                                                                            p_report_in_frame->previousFrameNum,
1396                                                                                                            p_rlc_lte_info,
1397                                                                                                            FALSE));
1398                     /* It really shouldn't be NULL... */
1399                     if (p_previous_report != NULL) {
1400                         /* Point it forward to this one */
1401                         p_previous_report->nextFrameNum = pinfo->fd->num;
1402                     }
1403                 }
1404             }
1405
1406             break;
1407
1408         case RLC_AM_MODE:
1409
1410             /* Work out expected sequence number */
1411             if (!createdChannel) {
1412                 expectedSequenceNumber = (p_channel_status->previousSequenceNumber + 1) % 1024;
1413             }
1414             else {
1415                 /* Whatever we got is fine.. */
1416                 expectedSequenceNumber = sequenceNumber;
1417             }
1418
1419             /* For AM, may be:
1420                - expected Sequence number OR
1421                - previous frame repeated
1422                - old SN being sent (in response to NACK)
1423                - new SN, but with frames missed out
1424                Assume window whose front is at expectedSequenceNumber */
1425
1426             /* First of all, check to see whether frame is judged to be MAC Retx */
1427             if (is_mac_lte_frame_retx(pinfo, p_rlc_lte_info->direction)) {
1428                 /* Just report that this is a MAC Retx */
1429                 p_report_in_frame->state = SN_MAC_Retx;
1430                 p_report_in_frame->firstSN = sequenceNumber;
1431
1432                 /* No channel state to update */
1433                 break;
1434             }
1435
1436             if (sequenceNumber != expectedSequenceNumber) {
1437                 /* Don't trash reassembly info if this looks like a close  retx... */
1438                 if (((1024 + sequenceNumber - expectedSequenceNumber) % 1024) < 50) {
1439                     reassembly_destroy(p_channel_status);
1440                 }
1441             }
1442
1443             /* Expected? */
1444             if (sequenceNumber == expectedSequenceNumber) {
1445                 /* Set report for this frame */
1446                 p_report_in_frame->sequenceExpectedCorrect = TRUE;
1447                 p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1448                 p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1449                 p_report_in_frame->previousSegmentIncomplete = p_channel_status->previousSegmentIncomplete;
1450                 p_report_in_frame->state = SN_OK;
1451
1452                 /* Update channel status */
1453                 p_channel_status->previousSequenceNumber = sequenceNumber;
1454                 p_channel_status->previousFrameNum = pinfo->fd->num;
1455                 p_channel_status->previousSegmentIncomplete = !last_includes_end;
1456
1457
1458                 if (p_channel_status->reassembly_info) {
1459
1460                     /* Add next segment to reassembly info */
1461                     reassembly_add_segment(p_channel_status, sequenceNumber, pinfo->fd->num,
1462                                            tvb, firstSegmentOffset, firstSegmentLength);
1463
1464                     /* The end of existing reassembly? */
1465                     if (!first_includes_start &&
1466                         ((number_of_segments > 1) || last_includes_end)) {
1467
1468                         reassembly_record(p_channel_status, pinfo,
1469                                           sequenceNumber, p_rlc_lte_info);
1470                         reassembly_destroy(p_channel_status);
1471                     }
1472                 }
1473
1474                 /* The start of a new reassembly? */
1475                 if (!last_includes_end &&
1476                     ((number_of_segments > 1) || first_includes_start)) {
1477
1478                     guint16 lastSegmentLength = tvb_length(tvb)-lastSegmentOffset;
1479                     if (global_rlc_lte_reassembly) {
1480                         reassembly_reset(p_channel_status);
1481                         reassembly_add_segment(p_channel_status, sequenceNumber,
1482                                                pinfo->fd->num,
1483                                                tvb, lastSegmentOffset, lastSegmentLength);
1484                     }
1485                 }
1486
1487                 if (p_report_in_frame->previousFrameNum != 0) {
1488                     /* Get report for previous frame */
1489                     sequence_analysis_report *p_previous_report;
1490                     p_previous_report = (sequence_analysis_report*)g_hash_table_lookup(sequence_analysis_report_hash,
1491                                                                                        get_report_hash_key((sequenceNumber+1023) % 1024,
1492                                                                                                            p_report_in_frame->previousFrameNum,
1493                                                                                                            p_rlc_lte_info,
1494                                                                                                            FALSE));
1495                     /* It really shouldn't be NULL... */
1496                     if (p_previous_report != NULL) {
1497                         /* Point it forward to this one */
1498                         p_previous_report->nextFrameNum = pinfo->fd->num;
1499                     }
1500                 }
1501
1502             }
1503
1504             /* Previous subframe repeated? */
1505             else if (((sequenceNumber+1) % 1024) == expectedSequenceNumber) {
1506                 p_report_in_frame->state = SN_Repeated;
1507
1508                 /* Set report for this frame */
1509                 p_report_in_frame->sequenceExpectedCorrect = FALSE;
1510                 p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1511                 p_report_in_frame->firstSN = sequenceNumber;
1512                 p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1513                 p_report_in_frame->previousSegmentIncomplete = p_channel_status->previousSegmentIncomplete;
1514
1515
1516                 /* Really should be nothing to update... */
1517                 p_channel_status->previousSequenceNumber = sequenceNumber;
1518                 p_channel_status->previousFrameNum = pinfo->fd->num;
1519                 p_channel_status->previousSegmentIncomplete = !last_includes_end;
1520             }
1521
1522             else {
1523                 /* Need to work out if new (with skips, or likely a retx (due to NACK)) */
1524                 int delta  = (1024 + expectedSequenceNumber - sequenceNumber) % 1024;
1525
1526                 /* Rx window is 512, so check to see if this is a retx */
1527                 if (delta < 512) {
1528                     /* Probably a retx due to receiving NACK */
1529                     p_report_in_frame->state = SN_Retx;
1530
1531                     p_report_in_frame->firstSN = sequenceNumber;
1532                     /* Don't update anything in channel state */
1533                 }
1534
1535                 else {
1536                     /* Ahead of expected SN. Assume frames have been missed */
1537                     p_report_in_frame->state = SN_Missing;
1538
1539                     p_report_in_frame->firstSN = expectedSequenceNumber;
1540                     p_report_in_frame->lastSN = (1024 + sequenceNumber-1) % 1024;
1541
1542                     /* Update channel state - forget about missed SNs */
1543                     p_report_in_frame->sequenceExpected = expectedSequenceNumber;
1544                     p_channel_status->previousSequenceNumber = sequenceNumber;
1545                     p_channel_status->previousFrameNum = pinfo->fd->num;
1546                     p_channel_status->previousSegmentIncomplete = !last_includes_end;
1547                 }
1548             }
1549             break;
1550
1551         default:
1552             /* Shouldn't get here! */
1553             return SN_Error;
1554     }
1555
1556     /* Associate with this frame number */
1557     g_hash_table_insert(sequence_analysis_report_hash,
1558                         get_report_hash_key(sequenceNumber, pinfo->fd->num, p_rlc_lte_info, TRUE),
1559                         p_report_in_frame);
1560
1561     /* Add state report for this frame into tree */
1562     addChannelSequenceInfo(p_report_in_frame, isControlFrame, p_rlc_lte_info, sequenceNumber,
1563                            first_includes_start, tap_info, pinfo, tree, tvb);
1564
1565     return p_report_in_frame->state;
1566 }
1567
1568
1569 /* Add to the tree values associated with sequence analysis for this frame */
1570 static void addChannelRepeatedNACKInfo(channel_repeated_nack_report *p,
1571                                        rlc_lte_info *p_rlc_lte_info,
1572                                        packet_info *pinfo, proto_tree *tree,
1573                                        tvbuff_t *tvb)
1574 {
1575     proto_tree *seqnum_tree;
1576     proto_item *seqnum_ti;
1577     proto_item *ti;
1578     gint       n;
1579
1580     /* Create subtree */
1581     seqnum_ti = proto_tree_add_string_format(tree,
1582                                              hf_rlc_lte_sequence_analysis,
1583                                              tvb, 0, 0,
1584                                              "", "Sequence Analysis");
1585     seqnum_tree = proto_item_add_subtree(seqnum_ti,
1586                                          ett_rlc_lte_sequence_analysis);
1587     PROTO_ITEM_SET_GENERATED(seqnum_ti);
1588
1589     /* OK = FALSE */
1590     ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok,
1591                                 tvb, 0, 0, FALSE);
1592     PROTO_ITEM_SET_GENERATED(ti);
1593
1594     /* Add each repeated NACK as item & expert info */
1595     for (n=0; n < p->noOfNACKsRepeated; n++) {
1596
1597         ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_repeated_nack,
1598                                  tvb, 0, 0, p->repeatedNACKs[n]);
1599         PROTO_ITEM_SET_GENERATED(ti);
1600
1601         expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_ERROR,
1602                                "Same SN  (%u) NACKd for %s on UE %u in successive Status PDUs",
1603                                p->repeatedNACKs[n],
1604                                val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
1605                                p_rlc_lte_info->ueid);
1606     }
1607
1608     /* Link back to previous status report */
1609     ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_repeated_nack_original_frame,
1610                              tvb, 0, 0, p->previousFrameNum);
1611     PROTO_ITEM_SET_GENERATED(ti);
1612
1613     /* Append count to sequence analysis root */
1614     proto_item_append_text(seqnum_ti, " - %u SNs repeated from previous Status PDU",
1615                            p->noOfNACKsRepeated);
1616 }
1617
1618
1619 /* Update the channel repeated NACK status and set report for this frame */
1620 static void checkChannelRepeatedNACKInfo(packet_info *pinfo,
1621                                          rlc_lte_info *p_rlc_lte_info,
1622                                          rlc_lte_tap_info *tap_info,
1623                                          proto_tree *tree,
1624                                          tvbuff_t *tvb)
1625 {
1626     channel_hash_key   channel_key;
1627     channel_hash_key   *p_channel_key;
1628     channel_repeated_nack_status     *p_channel_status;
1629     channel_repeated_nack_report  *p_report_in_frame = NULL;
1630
1631     guint16         noOfNACKsRepeated = 0;
1632     guint16         repeatedNACKs[MAX_NACKs];
1633     gint            n, i, j;
1634
1635     /* If find state_report_in_frame already, use that and get out */
1636     if (pinfo->fd->flags.visited) {
1637         p_report_in_frame = (channel_repeated_nack_report*)g_hash_table_lookup(repeated_nack_report_hash,
1638                                                                                get_report_hash_key(0, pinfo->fd->num,
1639                                                                                                    p_rlc_lte_info, FALSE));
1640         if (p_report_in_frame != NULL) {
1641             addChannelRepeatedNACKInfo(p_report_in_frame, p_rlc_lte_info,
1642                                        pinfo, tree, tvb);
1643             return;
1644         }
1645         else {
1646             /* Give up - we must have tried already... */
1647             return;
1648         }
1649     }
1650
1651
1652     /**************************************************/
1653     /* Create or find an entry for this channel state */
1654     channel_key.ueId = p_rlc_lte_info->ueid;
1655     channel_key.channelType = p_rlc_lte_info->channelType;
1656     channel_key.channelId = p_rlc_lte_info->channelId;
1657     channel_key.direction = p_rlc_lte_info->direction;
1658     memset(repeatedNACKs, 0, sizeof(repeatedNACKs));
1659
1660     /* Do the table lookup */
1661     p_channel_status = (channel_repeated_nack_status*)g_hash_table_lookup(repeated_nack_channel_hash, &channel_key);
1662
1663     /* Create table entry if necessary */
1664     if (p_channel_status == NULL) {
1665
1666         /* Allocate a new key and value */
1667         p_channel_key = se_alloc(sizeof(channel_hash_key));
1668         p_channel_status = se_alloc0(sizeof(channel_repeated_nack_status));
1669
1670         /* Copy key contents */
1671         memcpy(p_channel_key, &channel_key, sizeof(channel_hash_key));
1672
1673         /* Add entry to table */
1674         g_hash_table_insert(repeated_nack_channel_hash, p_channel_key, p_channel_status);
1675     }
1676
1677     /* Compare NACKs in channel status with NACKs in tap_info.
1678        Note any that are repeated */
1679     for (i=0; i < p_channel_status->noOfNACKs; i++) {
1680         for (j=0; j < MIN(tap_info->noOfNACKs, MAX_NACKs); j++) {
1681             if (tap_info->NACKs[j] == p_channel_status->NACKs[i]) {
1682                 /* Don't add the same repeated NACK twice! */
1683                 if ((noOfNACKsRepeated == 0) ||
1684                     (repeatedNACKs[noOfNACKsRepeated-1] != p_channel_status->NACKs[i])) {
1685
1686                     repeatedNACKs[noOfNACKsRepeated++] = p_channel_status->NACKs[i];
1687                 }
1688             }
1689         }
1690     }
1691
1692     /* Copy NACKs from tap_info into channel status for next time! */
1693     p_channel_status->noOfNACKs = 0;
1694     for (n=0; n < MIN(tap_info->noOfNACKs, MAX_NACKs); n++) {
1695         p_channel_status->NACKs[p_channel_status->noOfNACKs++] = tap_info->NACKs[n];
1696     }
1697
1698     if (noOfNACKsRepeated >= 1) {
1699         /* Create space for frame state_report */
1700         p_report_in_frame = se_alloc(sizeof(channel_repeated_nack_report));
1701
1702         /* Copy in found duplicates */
1703         for (n=0; n < MIN(tap_info->noOfNACKs, MAX_NACKs); n++) {
1704             p_report_in_frame->repeatedNACKs[n] = repeatedNACKs[n];
1705         }
1706         p_report_in_frame->noOfNACKsRepeated = noOfNACKsRepeated;
1707
1708         p_report_in_frame->previousFrameNum = p_channel_status->frameNum;
1709
1710         /* Associate with this frame number */
1711         g_hash_table_insert(repeated_nack_report_hash,
1712                             get_report_hash_key(0, pinfo->fd->num,
1713                                                 p_rlc_lte_info, TRUE),
1714                             p_report_in_frame);
1715
1716         /* Add state report for this frame into tree */
1717         addChannelRepeatedNACKInfo(p_report_in_frame, p_rlc_lte_info,
1718                                    pinfo, tree, tvb);
1719     }
1720
1721     /* Save frame number for next comparison */
1722     p_channel_status->frameNum = pinfo->fd->num;
1723 }
1724
1725 /* Check that the ACK is consistent with data the expected sequence number
1726    in the other direction */
1727 static void checkChannelACKWindow(guint16 ack_sn,
1728                                   packet_info *pinfo,
1729                                   rlc_lte_info *p_rlc_lte_info,
1730                                   rlc_lte_tap_info *tap_info,
1731                                   proto_tree *tree,
1732                                   tvbuff_t *tvb)
1733 {
1734     channel_hash_key   channel_key;
1735     channel_sequence_analysis_status  *p_channel_status;
1736     sequence_analysis_report  *p_report_in_frame = NULL;
1737
1738     /* If find stat_report_in_frame already, use that and get out */
1739     if (pinfo->fd->flags.visited) {
1740         p_report_in_frame = (sequence_analysis_report*)g_hash_table_lookup(sequence_analysis_report_hash,
1741                                                                            get_report_hash_key(0, pinfo->fd->num,
1742                                                                                                p_rlc_lte_info,
1743                                                                                                FALSE));
1744         if (p_report_in_frame != NULL) {
1745             /* Add any info to tree */
1746             addChannelSequenceInfo(p_report_in_frame, TRUE, p_rlc_lte_info,
1747                                    0, FALSE,
1748                                    tap_info, pinfo, tree, tvb);
1749             return;
1750         }
1751         else {
1752             /* Give up - we must have tried already... */
1753             return;
1754         }
1755     }
1756
1757     /*******************************************************************/
1758     /* Find an entry for this channel state (in the opposite direction */
1759     channel_key.ueId = p_rlc_lte_info->ueid;
1760     channel_key.channelType = p_rlc_lte_info->channelType;
1761     channel_key.channelId = p_rlc_lte_info->channelId;
1762     channel_key.direction =
1763         (p_rlc_lte_info->direction == DIRECTION_UPLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK;
1764
1765     /* Do the table lookup */
1766     p_channel_status = (channel_sequence_analysis_status*)g_hash_table_lookup(sequence_analysis_channel_hash, &channel_key);
1767
1768     /* Create table entry if necessary */
1769     if (p_channel_status == NULL) {
1770         return;
1771     }
1772
1773     /* Is it in the rx window? This test will catch if its ahead, but we don't
1774        really know what the back of the tx window is... */
1775     if (((1024 + p_channel_status->previousSequenceNumber+1 - ack_sn) % 1024) > 512) {
1776
1777         /* Set result */
1778         p_report_in_frame = se_alloc(sizeof(sequence_analysis_report));
1779         p_report_in_frame->state = ACK_Out_of_Window;
1780         p_report_in_frame->previousFrameNum = p_channel_status->previousFrameNum;
1781         p_report_in_frame->sequenceExpected = p_channel_status->previousSequenceNumber;
1782         p_report_in_frame->firstSN = ack_sn;
1783
1784         /* Associate with this frame number */
1785         g_hash_table_insert(sequence_analysis_report_hash,
1786                             get_report_hash_key(0, pinfo->fd->num,
1787                                                 p_rlc_lte_info, TRUE),
1788                             p_report_in_frame);
1789
1790         /* Add state report for this frame into tree */
1791         addChannelSequenceInfo(p_report_in_frame, TRUE, p_rlc_lte_info, 0,
1792                                FALSE, tap_info, pinfo, tree, tvb);
1793     }
1794 }
1795
1796
1797
1798
1799 /***************************************************/
1800 /* Transparent mode PDU. Call RRC if configured to */
1801 static void dissect_rlc_lte_tm(tvbuff_t *tvb, packet_info *pinfo,
1802                                proto_tree *tree,
1803                                int offset,
1804                                rlc_lte_info *p_rlc_lte_info,
1805                                proto_item *top_ti)
1806 {
1807     proto_item *raw_tm_ti;
1808     proto_item *tm_ti;
1809
1810     /* Create hidden TM root */
1811     tm_ti = proto_tree_add_string_format(tree, hf_rlc_lte_tm,
1812                                          tvb, offset, 0, "", "TM");
1813     PROTO_ITEM_SET_HIDDEN(tm_ti);
1814
1815     /* Remaining bytes are all data */
1816     raw_tm_ti = proto_tree_add_item(tree, hf_rlc_lte_tm_data, tvb, offset, -1, ENC_NA);
1817     if (!global_rlc_lte_call_rrc) {
1818         write_pdu_label_and_info(top_ti, NULL, pinfo,
1819                                  "   [%u-bytes]", tvb_length_remaining(tvb, offset));
1820     }
1821
1822     if (global_rlc_lte_call_rrc) {
1823         tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset));
1824         volatile dissector_handle_t protocol_handle = 0;
1825
1826         switch (p_rlc_lte_info->channelType) {
1827             case CHANNEL_TYPE_CCCH:
1828                 if (p_rlc_lte_info->direction == DIRECTION_UPLINK) {
1829                     protocol_handle = find_dissector("lte_rrc.ul_ccch");
1830                 }
1831                 else {
1832                     protocol_handle = find_dissector("lte_rrc.dl_ccch");
1833                 }
1834                 break;
1835
1836             case CHANNEL_TYPE_BCCH_BCH:
1837                 protocol_handle = find_dissector("lte_rrc.bcch_bch");
1838                 break;
1839             case CHANNEL_TYPE_BCCH_DL_SCH:
1840                 protocol_handle = find_dissector("lte_rrc.bcch_dl_sch");
1841                 break;
1842             case CHANNEL_TYPE_PCCH:
1843                 protocol_handle = find_dissector("lte-rrc.pcch");
1844                 break;
1845
1846             case CHANNEL_TYPE_SRB:
1847             case CHANNEL_TYPE_DRB:
1848
1849             default:
1850                 /* Shouldn't happen, just return... */
1851                 return;
1852         }
1853
1854         /* Hide raw view of bytes */
1855         PROTO_ITEM_SET_HIDDEN(raw_tm_ti);
1856
1857         /* Call it (catch exceptions) */
1858         TRY {
1859             call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
1860         }
1861         CATCH_ALL {
1862         }
1863         ENDTRY
1864     }
1865 }
1866
1867
1868
1869 /***************************************************/
1870 /* Unacknowledged mode PDU                         */
1871 static void dissect_rlc_lte_um(tvbuff_t *tvb, packet_info *pinfo,
1872                                proto_tree *tree,
1873                                int offset,
1874                                rlc_lte_info *p_rlc_lte_info,
1875                                proto_item *top_ti,
1876                                rlc_lte_tap_info *tap_info)
1877 {
1878     guint64 framing_info;
1879     gboolean first_includes_start;
1880     gboolean last_includes_end;
1881     guint64 fixed_extension;
1882     guint64 sn;
1883     gint    start_offset = offset;
1884     proto_item *um_ti;
1885     proto_tree *um_header_tree;
1886     proto_item *um_header_ti;
1887     gboolean is_truncated;
1888     proto_item *truncated_ti;
1889     rlc_channel_reassembly_info *reassembly_info = NULL;
1890     sequence_analysis_state seq_anal_state = SN_OK;
1891
1892     /* Hidden UM root */
1893     um_ti = proto_tree_add_string_format(tree, hf_rlc_lte_um,
1894                                          tvb, offset, 0, "", "UM");
1895     PROTO_ITEM_SET_HIDDEN(um_ti);
1896
1897     /* Add UM header subtree */
1898     um_header_ti = proto_tree_add_string_format(tree, hf_rlc_lte_um_header,
1899                                                 tvb, offset, 0,
1900                                                 "", "UM header");
1901     um_header_tree = proto_item_add_subtree(um_header_ti,
1902                                             ett_rlc_lte_um_header);
1903
1904
1905     /*******************************/
1906     /* Fixed UM header             */
1907     if (p_rlc_lte_info->UMSequenceNumberLength == UM_SN_LENGTH_5_BITS) {
1908         /* Framing info (2 bits) */
1909         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fi,
1910                                     tvb, offset*8, 2,
1911                                     &framing_info, ENC_BIG_ENDIAN);
1912
1913         /* Extension (1 bit) */
1914         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fixed_e, tvb,
1915                                     (offset*8) + 2, 1,
1916                                     &fixed_extension, ENC_BIG_ENDIAN);
1917
1918         /* Sequence Number (5 bit) */
1919         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_sn, tvb,
1920                                     (offset*8) + 3, 5,
1921                                     &sn, ENC_BIG_ENDIAN);
1922         offset++;
1923     }
1924     else if (p_rlc_lte_info->UMSequenceNumberLength == UM_SN_LENGTH_10_BITS) {
1925         guint8 reserved;
1926         proto_item *ti;
1927
1928         /* Check 3 Reserved bits */
1929         reserved = (tvb_get_guint8(tvb, offset) & 0xe0) >> 5;
1930         ti = proto_tree_add_item(um_header_tree, hf_rlc_lte_um_fixed_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1931         if (reserved != 0) {
1932             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1933                       "RLC UM Fixed header Reserved bits not zero (found 0x%x)", reserved);
1934         }
1935
1936         /* Framing info (2 bits) */
1937         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fi,
1938                                     tvb, (offset*8)+3, 2,
1939                                     &framing_info, ENC_BIG_ENDIAN);
1940
1941         /* Extension (1 bit) */
1942         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_fixed_e, tvb,
1943                                     (offset*8) + 5, 1,
1944                                     &fixed_extension, ENC_BIG_ENDIAN);
1945
1946         /* Sequence Number (10 bits) */
1947         proto_tree_add_bits_ret_val(um_header_tree, hf_rlc_lte_um_sn, tvb,
1948                                     (offset*8) + 6, 10,
1949                                     &sn, ENC_BIG_ENDIAN);
1950         offset += 2;
1951     }
1952     else {
1953         /* Invalid length of sequence number */
1954         proto_item *ti;
1955         ti = proto_tree_add_text(um_header_tree, tvb, 0, 0, "Invalid sequence number length (%u bits)",
1956                                  p_rlc_lte_info->UMSequenceNumberLength);
1957         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1958                                "Invalid sequence number length (%u bits)",
1959                                p_rlc_lte_info->UMSequenceNumberLength);
1960         return;
1961     }
1962
1963     tap_info->sequenceNumber = (guint16)sn;
1964
1965     /* Show SN in info column */
1966     write_pdu_label_and_info(top_ti, um_header_ti, pinfo, "  SN=%-4u", (guint16)sn);
1967
1968     proto_item_set_len(um_header_ti, offset-start_offset);
1969
1970
1971     /*************************************/
1972     /* UM header extension               */
1973     if (fixed_extension) {
1974         offset = dissect_rlc_lte_extension_header(tvb, pinfo, tree, offset);
1975     }
1976
1977     /* Extract these 2 flags from framing_info */
1978     first_includes_start = ((guint8)framing_info & 0x02) == 0;
1979     last_includes_end =    ((guint8)framing_info & 0x01) == 0;
1980
1981     if (global_rlc_lte_headers_expected) {
1982         /* There might not be any data, if only headers (plus control data) were logged */
1983         is_truncated = (tvb_length_remaining(tvb, offset) == 0);
1984         truncated_ti = proto_tree_add_uint(tree, hf_rlc_lte_header_only, tvb, 0, 0,
1985                                            is_truncated);
1986         if (is_truncated) {
1987             int n;
1988             PROTO_ITEM_SET_GENERATED(truncated_ti);
1989             expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
1990                                    "RLC PDU SDUs have been omitted");
1991
1992             /* Show in the info column how long the data would be */
1993             for (n=0; n < s_number_of_extensions; n++) {
1994                 show_PDU_in_info(pinfo, top_ti, s_lengths[n],
1995                                  (n==0) ? first_includes_start : TRUE,
1996                                  TRUE);
1997                 offset += s_lengths[n];
1998             }
1999             /* Last one */
2000             show_PDU_in_info(pinfo, top_ti, p_rlc_lte_info->pduLength - offset,
2001                              (s_number_of_extensions == 0) ? first_includes_start : TRUE,
2002                              last_includes_end);
2003             return;
2004         }
2005         else {
2006             PROTO_ITEM_SET_HIDDEN(truncated_ti);
2007         }
2008     }
2009
2010     /* Show number of extensions in header root */
2011     if (s_number_of_extensions > 0) {
2012         proto_item_append_text(um_header_ti, " (%u extensions)", s_number_of_extensions);
2013     }
2014
2015     /* Call sequence analysis function now */
2016     if (((global_rlc_lte_um_sequence_analysis == SEQUENCE_ANALYSIS_MAC_ONLY) &&
2017          (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL)) ||
2018         ((global_rlc_lte_um_sequence_analysis == SEQUENCE_ANALYSIS_RLC_ONLY) &&
2019          (p_get_proto_data(pinfo->fd, proto_mac_lte) == NULL))) {
2020
2021         guint16 lastSegmentOffset = offset;
2022         if (s_number_of_extensions >= 1) {
2023             int n;
2024             lastSegmentOffset = offset;
2025             for (n=0; n < s_number_of_extensions; n++) {
2026                 lastSegmentOffset += s_lengths[n];
2027             }
2028         }
2029
2030         seq_anal_state = checkChannelSequenceInfo(pinfo, tvb, p_rlc_lte_info,
2031                                                   FALSE,
2032                                                   s_number_of_extensions+1,
2033                                                   offset, s_lengths[0],
2034                                                   lastSegmentOffset,
2035                                                   (guint16)sn, first_includes_start, last_includes_end,
2036                                                   FALSE, /* UM doesn't re-segment */
2037                                                   tap_info, um_header_tree);
2038     }
2039
2040
2041     /*************************************/
2042     /* Data                              */
2043
2044     reassembly_info = (rlc_channel_reassembly_info *)g_hash_table_lookup(reassembly_report_hash,
2045                                                                          get_report_hash_key((guint16)sn, pinfo->fd->num,
2046                                                                                              p_rlc_lte_info, FALSE));
2047
2048     if (s_number_of_extensions > 0) {
2049         /* Show each data segment separately */
2050         int n;
2051         for (n=0; n < s_number_of_extensions; n++) {
2052             show_PDU_in_tree(pinfo, tree, tvb, offset, s_lengths[n], p_rlc_lte_info,
2053                              (n==0) ? first_includes_start : TRUE,
2054                              (n==0) ? reassembly_info : NULL,
2055                              seq_anal_state);
2056             show_PDU_in_info(pinfo, top_ti, s_lengths[n],
2057                              (n==0) ? first_includes_start : TRUE,
2058                              TRUE);
2059             tvb_ensure_bytes_exist(tvb, offset, s_lengths[n]);
2060             offset += s_lengths[n];
2061         }
2062     }
2063
2064     /* Final data element */
2065     show_PDU_in_tree(pinfo, tree, tvb, offset, -1, p_rlc_lte_info,
2066                      ((s_number_of_extensions == 0) ? first_includes_start : TRUE) && last_includes_end,
2067                      (s_number_of_extensions == 0) ? reassembly_info : NULL,
2068                      seq_anal_state);
2069     show_PDU_in_info(pinfo, top_ti, (guint16)tvb_length_remaining(tvb, offset),
2070                      (s_number_of_extensions == 0) ? first_includes_start : TRUE,
2071                      last_includes_end);
2072 }
2073
2074
2075
2076 /* Dissect an AM STATUS PDU */
2077 static void dissect_rlc_lte_am_status_pdu(tvbuff_t *tvb,
2078                                           packet_info *pinfo,
2079                                           proto_tree *tree,
2080                                           proto_item *status_ti,
2081                                           int offset,
2082                                           proto_item *top_ti,
2083                                           rlc_lte_info *p_rlc_lte_info,
2084                                           rlc_lte_tap_info *tap_info)
2085 {
2086     guint8     cpt;
2087     guint64    ack_sn, nack_sn;
2088     guint16    nack_count = 0;
2089     guint64    e1 = 0, e2 = 0;
2090     guint64    so_start, so_end;
2091     int        bit_offset = offset * 8;
2092     proto_item *ti;
2093
2094     /****************************************************************/
2095     /* Part of RLC control PDU header                               */
2096
2097     /* Control PDU Type (CPT) */
2098     cpt = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
2099     ti = proto_tree_add_item(tree, hf_rlc_lte_am_cpt, tvb, offset, 1, ENC_BIG_ENDIAN);
2100     if (cpt != 0) {
2101         /* Protest and stop - only know about STATUS PDUs */
2102         expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
2103                                "RLC Control frame type %u not handled", cpt);
2104         return;
2105     }
2106
2107     /* The Status PDU itself starts 4 bits into the byte */
2108     bit_offset += 4;
2109
2110     /* ACK SN */
2111     proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_ack_sn, tvb,
2112                                 bit_offset, 10, &ack_sn, ENC_BIG_ENDIAN);
2113     bit_offset += 10;
2114     write_pdu_label_and_info(top_ti, status_ti, pinfo, "  ACK_SN=%-4u", (guint16)ack_sn);
2115
2116     tap_info->ACKNo = (guint16)ack_sn;
2117
2118     /* E1 */
2119     proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e1, tvb,
2120                                 bit_offset, 1, &e1, ENC_BIG_ENDIAN);
2121
2122     /* Skip another bit to byte-align the next bit... */
2123     bit_offset++;
2124
2125     /* Optional, extra fields */
2126     do {
2127         if (e1) {
2128             proto_item *nack_ti;
2129
2130             /****************************/
2131             /* Read NACK_SN, E1, E2     */
2132
2133             /* NACK_SN */
2134             nack_ti = proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_nack_sn, tvb,
2135                                                   bit_offset, 10, &nack_sn, ENC_BIG_ENDIAN);
2136             bit_offset += 10;
2137             write_pdu_label_and_info(top_ti, NULL, pinfo, "  NACK_SN=%-4u", (guint16)nack_sn);
2138
2139             /* We shouldn't NACK the ACK_SN! */
2140             if (nack_sn == ack_sn) {
2141                 expert_add_info_format(pinfo, nack_ti, PI_MALFORMED, PI_ERROR,
2142                                        "Status PDU shouldn't ACK and NACK the same sequence number (%" G_GINT64_MODIFIER "u)",
2143                                        ack_sn);
2144             }
2145
2146             /* Copy into struct, but don't exceed buffer */
2147             if (nack_count < MAX_NACKs) {
2148                 tap_info->NACKs[nack_count++] = (guint16)nack_sn;
2149             }
2150             else {
2151                 /* Let it get bigger than the array for accurate stats... */
2152                 nack_count++;
2153             }
2154
2155             /* E1 */
2156             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e1, tvb,
2157                                         bit_offset, 1, &e1, ENC_BIG_ENDIAN);
2158             bit_offset++;
2159
2160             /* E2 */
2161             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_e2, tvb,
2162                                         bit_offset, 1, &e2, ENC_BIG_ENDIAN);
2163
2164             /* Report as expert info */
2165             if (e2) {
2166                 expert_add_info_format(pinfo, nack_ti, PI_SEQUENCE, PI_WARN,
2167                                        "Status PDU reports NACK (partial) on %s for UE %u",
2168                                        val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
2169                                        p_rlc_lte_info->ueid);
2170             }
2171             else {
2172                 expert_add_info_format(pinfo, nack_ti, PI_SEQUENCE, PI_WARN,
2173                                        "Status PDU reports NACK on %s for UE %u",
2174                                        val_to_str_const(p_rlc_lte_info->direction, direction_vals, "Unknown"),
2175                                        p_rlc_lte_info->ueid);
2176             }
2177
2178             bit_offset++;
2179         }
2180
2181         if (e2) {
2182             /* Read SOstart, SOend */
2183             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_so_start, tvb,
2184                                         bit_offset, 15, &so_start, ENC_BIG_ENDIAN);
2185             bit_offset += 15;
2186
2187             proto_tree_add_bits_ret_val(tree, hf_rlc_lte_am_so_end, tvb,
2188                                         bit_offset, 15, &so_end, ENC_BIG_ENDIAN);
2189             bit_offset += 15;
2190
2191
2192             if ((guint16)so_end == 0x7fff) {
2193                 write_pdu_label_and_info(top_ti, NULL, pinfo,
2194                                          "  (SOstart=%u SOend=<END-OF_PDU>)",
2195                                          (guint16)so_start);
2196             }
2197             else {
2198                 write_pdu_label_and_info(top_ti, NULL, pinfo,
2199                                          "  (SOstart=%u SOend=%u)",
2200                                          (guint16)so_start, (guint16)so_end);
2201             }
2202
2203             /* Reset this flag here */
2204             e2 = 0;
2205         }
2206     } while (e1 || e2);
2207
2208     if (nack_count > 0) {
2209         proto_item *count_ti = proto_tree_add_uint(tree, hf_rlc_lte_am_nacks, tvb, 0, 1, nack_count);
2210         PROTO_ITEM_SET_GENERATED(count_ti);
2211         proto_item_append_text(status_ti, "  (%u NACKs)", nack_count);
2212         tap_info->noOfNACKs = nack_count;
2213     }
2214
2215     /* Check that we've reached the end of the PDU. If not, show malformed */
2216     offset = (bit_offset+7) / 8;
2217     if (tvb_length_remaining(tvb, offset) > 0) {
2218         expert_add_info_format(pinfo, status_ti, PI_MALFORMED, PI_ERROR,
2219                                "%cL %u bytes remaining after Status PDU complete",
2220                                (p_rlc_lte_info->direction == DIRECTION_UPLINK) ? 'U' : 'D',
2221                                tvb_length_remaining(tvb, offset));
2222     }
2223
2224     /* Set selected length of control tree */
2225     proto_item_set_len(status_ti, offset);
2226
2227     /* Repeated NACK analysis & check ACK-SN is in range */
2228     if (((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_MAC_ONLY) &&
2229          (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL)) ||
2230         ((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_RLC_ONLY) &&
2231          (p_get_proto_data(pinfo->fd, proto_mac_lte) == NULL))) {
2232
2233         if (!is_mac_lte_frame_retx(pinfo, p_rlc_lte_info->direction)) {
2234             checkChannelRepeatedNACKInfo(pinfo, p_rlc_lte_info, tap_info, tree, tvb);
2235             checkChannelACKWindow((guint16)ack_sn, pinfo, p_rlc_lte_info, tap_info, tree, tvb);
2236         }
2237      }
2238 }
2239
2240
2241 /***************************************************/
2242 /* Acknowledged mode PDU                           */
2243 static void dissect_rlc_lte_am(tvbuff_t *tvb, packet_info *pinfo,
2244                                proto_tree *tree,
2245                                int offset,
2246                                rlc_lte_info *p_rlc_lte_info,
2247                                proto_item *top_ti,
2248                                rlc_lte_tap_info *tap_info)
2249 {
2250     guint8 is_data;
2251     guint8 is_resegmented;
2252     guint8 polling;
2253     guint8 fixed_extension;
2254     guint8 framing_info;
2255     gboolean first_includes_start;
2256     gboolean last_includes_end;
2257     proto_item *am_ti;
2258     proto_tree *am_header_tree;
2259     proto_item *am_header_ti;
2260     gint   start_offset = offset;
2261     guint16    sn;
2262     gboolean is_truncated;
2263     proto_item *truncated_ti;
2264     rlc_channel_reassembly_info *reassembly_info = NULL;
2265     sequence_analysis_state seq_anal_state = SN_OK;
2266
2267     /* Hidden AM root */
2268     am_ti = proto_tree_add_string_format(tree, hf_rlc_lte_am,
2269                                          tvb, offset, 0, "", "AM");
2270     PROTO_ITEM_SET_HIDDEN(am_ti);
2271
2272     /* Add AM header subtree */
2273     am_header_ti = proto_tree_add_string_format(tree, hf_rlc_lte_am_header,
2274                                                 tvb, offset, 0,
2275                                                 "", "AM Header ");
2276     am_header_tree = proto_item_add_subtree(am_header_ti,
2277                                             ett_rlc_lte_am_header);
2278
2279     /* First bit is Data/Control flag           */
2280     is_data = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
2281     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_data_control, tvb, offset, 1, ENC_BIG_ENDIAN);
2282     tap_info->isControlPDU = !is_data;
2283
2284     if (!is_data) {
2285         /**********************/
2286         /* Status PDU         */
2287         write_pdu_label_and_info(top_ti, NULL, pinfo, " [CONTROL]");
2288
2289         /* Control PDUs are a completely separate format  */
2290         dissect_rlc_lte_am_status_pdu(tvb, pinfo, am_header_tree, am_header_ti,
2291                                       offset, top_ti,
2292                                       p_rlc_lte_info, tap_info);
2293         return;
2294     }
2295
2296     /******************************/
2297     /* Data PDU fixed header      */
2298
2299     /* Re-segmentation Flag (RF) field */
2300     is_resegmented = (tvb_get_guint8(tvb, offset) & 0x40) >> 6;
2301     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_rf, tvb, offset, 1, ENC_BIG_ENDIAN);
2302     tap_info->isResegmented = is_resegmented;
2303
2304     write_pdu_label_and_info(top_ti, NULL, pinfo,
2305                              (is_resegmented) ? " [DATA-SEGMENT]" : " [DATA]");
2306
2307     /* Polling bit */
2308     polling = (tvb_get_guint8(tvb, offset) & 0x20) >> 5;
2309     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_p, tvb, offset, 1, ENC_BIG_ENDIAN);
2310
2311     write_pdu_label_and_info(top_ti, NULL, pinfo, (polling) ? " (P) " : "     ");
2312     if (polling) {
2313         proto_item_append_text(am_header_ti, " (P) ");
2314     }
2315
2316     /* Framing Info */
2317     framing_info = (tvb_get_guint8(tvb, offset) & 0x18) >> 3;
2318     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_fi, tvb, offset, 1, ENC_BIG_ENDIAN);
2319
2320     /* Extension bit */
2321     fixed_extension = (tvb_get_guint8(tvb, offset) & 0x04) >> 2;
2322     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_fixed_e, tvb, offset, 1, ENC_BIG_ENDIAN);
2323
2324     /* Sequence Number */
2325     sn = tvb_get_ntohs(tvb, offset) & 0x03ff;
2326     proto_tree_add_item(am_header_tree, hf_rlc_lte_am_fixed_sn, tvb, offset, 2, ENC_BIG_ENDIAN);
2327     offset += 2;
2328     tap_info->sequenceNumber = sn;
2329
2330     write_pdu_label_and_info(top_ti, am_header_ti, pinfo, "sn=%-4u", sn);
2331
2332     /***************************************/
2333     /* Dissect extra segment header fields */
2334     if (is_resegmented) {
2335         guint16 segmentOffset;
2336
2337         /* Last Segment Field (LSF) */
2338         proto_tree_add_item(am_header_tree, hf_rlc_lte_am_segment_lsf, tvb, offset, 1, ENC_BIG_ENDIAN);
2339
2340         /* SO */
2341         segmentOffset = tvb_get_ntohs(tvb, offset) & 0x7fff;
2342         proto_tree_add_item(am_header_tree, hf_rlc_lte_am_segment_so, tvb, offset, 2, ENC_BIG_ENDIAN);
2343         write_pdu_label_and_info(top_ti, am_header_ti, pinfo, " SO=%u ", segmentOffset);
2344         offset += 2;
2345     }
2346
2347     /*************************************/
2348     /* AM header extension               */
2349     if (fixed_extension) {
2350         offset = dissect_rlc_lte_extension_header(tvb, pinfo, tree, offset);
2351     }
2352
2353     /* Header is now complete */
2354     proto_item_set_len(am_header_ti, offset-start_offset);
2355
2356     /* Show number of extensions in header root */
2357     if (s_number_of_extensions > 0) {
2358         proto_item_append_text(am_header_ti, " (%u extensions)", s_number_of_extensions);
2359     }
2360
2361     /* Extract these 2 flags from framing_info */
2362     first_includes_start = (framing_info & 0x02) == 0;
2363     last_includes_end =    (framing_info & 0x01) == 0;
2364
2365     /* There might not be any data, if only headers (plus control data) were logged */
2366     if (global_rlc_lte_headers_expected) {
2367         is_truncated = (tvb_length_remaining(tvb, offset) == 0);
2368         truncated_ti = proto_tree_add_uint(tree, hf_rlc_lte_header_only, tvb, 0, 0,
2369                                            is_truncated);
2370         if (is_truncated) {
2371             int n;
2372             PROTO_ITEM_SET_GENERATED(truncated_ti);
2373             expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
2374                                    "RLC PDU SDUs have been omitted");
2375             /* Show in the info column how long the data would be */
2376             for (n=0; n < s_number_of_extensions; n++) {
2377                 show_PDU_in_info(pinfo, top_ti, s_lengths[n],
2378                                  (n==0) ? first_includes_start : TRUE,
2379                                  TRUE);
2380                 offset += s_lengths[n];
2381             }
2382             /* Last one */
2383             show_PDU_in_info(pinfo, top_ti, p_rlc_lte_info->pduLength - offset,
2384                              (s_number_of_extensions == 0) ? first_includes_start : TRUE,
2385                              last_includes_end);
2386
2387             /* Just return now */
2388             return;
2389         }
2390         else {
2391             PROTO_ITEM_SET_HIDDEN(truncated_ti);
2392         }
2393     }
2394
2395     /* Call sequence analysis function now */
2396     if (((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_MAC_ONLY) &&
2397          (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL)) ||
2398         ((global_rlc_lte_am_sequence_analysis == SEQUENCE_ANALYSIS_RLC_ONLY) &&
2399          (p_get_proto_data(pinfo->fd, proto_mac_lte) == NULL))) {
2400
2401         guint16 firstSegmentLength;
2402         guint16 lastSegmentOffset = offset;
2403         if (s_number_of_extensions >= 1) {
2404             int n;
2405             for (n=0; n < s_number_of_extensions; n++) {
2406                 lastSegmentOffset += s_lengths[n];
2407             }
2408
2409             firstSegmentLength = s_lengths[0];
2410         }
2411         else {
2412             firstSegmentLength = tvb_length_remaining(tvb, offset);
2413         }
2414
2415         seq_anal_state = checkChannelSequenceInfo(pinfo, tvb, p_rlc_lte_info, FALSE,
2416                                                   s_number_of_extensions+1,
2417                                                   offset, firstSegmentLength,
2418                                                   lastSegmentOffset,
2419                                                   (guint16)sn,
2420                                                   first_includes_start, last_includes_end,
2421                                                   is_resegmented, tap_info, tree);
2422     }
2423
2424
2425     /*************************************/
2426     /* Data                              */
2427
2428     reassembly_info = (rlc_channel_reassembly_info *)g_hash_table_lookup(reassembly_report_hash,
2429                                                                          get_report_hash_key((guint16)sn, pinfo->fd->num,
2430                                                                                              p_rlc_lte_info, FALSE));
2431
2432     if (s_number_of_extensions > 0) {
2433         /* Show each data segment separately */
2434         int n;
2435         for (n=0; n < s_number_of_extensions; n++) {
2436             show_PDU_in_tree(pinfo, tree, tvb, offset, s_lengths[n], p_rlc_lte_info,
2437                              (n==0) ? first_includes_start : TRUE,
2438                              (n==0) ? reassembly_info : NULL,
2439                              seq_anal_state);
2440             show_PDU_in_info(pinfo, top_ti, s_lengths[n],
2441                              (n==0) ? first_includes_start : TRUE,
2442                              TRUE);
2443             tvb_ensure_bytes_exist(tvb, offset, s_lengths[n]);
2444             offset += s_lengths[n];
2445         }
2446     }
2447
2448     /* Final data element */
2449     if (tvb_length_remaining(tvb, offset) > 0) {
2450         show_PDU_in_tree(pinfo, tree, tvb, offset, -1, p_rlc_lte_info,
2451                          ((s_number_of_extensions == 0) ? first_includes_start : TRUE) && last_includes_end,
2452                          (s_number_of_extensions == 0) ? reassembly_info : NULL,
2453                          seq_anal_state);
2454         show_PDU_in_info(pinfo, top_ti, (guint16)tvb_length_remaining(tvb, offset),
2455                          (s_number_of_extensions == 0) ? first_includes_start : TRUE,
2456                          last_includes_end);
2457     }
2458     else {
2459         /* Report that expected data was missing (unless we know it might happen) */
2460         if (!global_rlc_lte_headers_expected) {
2461             if (s_number_of_extensions > 0) {
2462                 expert_add_info_format(pinfo, am_header_ti, PI_MALFORMED, PI_ERROR,
2463                                       "AM data PDU doesn't contain any data beyond extensions");
2464             }
2465             else {
2466                 expert_add_info_format(pinfo, am_header_ti, PI_MALFORMED, PI_ERROR,
2467                                       "AM data PDU doesn't contain any data");
2468             }
2469         }
2470     }
2471 }
2472
2473
2474 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
2475 static gboolean dissect_rlc_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
2476                                      proto_tree *tree)
2477 {
2478     gint                 offset = 0;
2479     struct rlc_lte_info  *p_rlc_lte_info;
2480     tvbuff_t             *rlc_tvb;
2481     guint8               tag = 0;
2482     gboolean             infoAlreadySet = FALSE;
2483     gboolean             umSeqNumLengthTagPresent = FALSE;
2484
2485     /* This is a heuristic dissector, which means we get all the UDP
2486      * traffic not sent to a known dissector and not claimed by
2487      * a heuristic dissector called before us!
2488      */
2489
2490     if (!global_rlc_lte_heur) {
2491         return FALSE;
2492     }
2493
2494     /* Do this again on re-dissection to re-discover offset of actual PDU */
2495
2496     /* Needs to be at least as long as:
2497        - the signature string
2498        - fixed header bytes
2499        - tag for data
2500        - at least one byte of RLC PDU payload */
2501     if ((size_t)tvb_length_remaining(tvb, offset) < (strlen(RLC_LTE_START_STRING)+1+2)) {
2502         return FALSE;
2503     }
2504
2505     /* OK, compare with signature string */
2506     if (tvb_strneql(tvb, offset, RLC_LTE_START_STRING, (gint)strlen(RLC_LTE_START_STRING)) != 0) {
2507         return FALSE;
2508     }
2509     offset += (gint)strlen(RLC_LTE_START_STRING);
2510
2511
2512     /* If redissecting, use previous info struct (if available) */
2513     p_rlc_lte_info = p_get_proto_data(pinfo->fd, proto_rlc_lte);
2514     if (p_rlc_lte_info == NULL) {
2515         /* Allocate new info struct for this frame */
2516         p_rlc_lte_info = se_alloc0(sizeof(struct rlc_lte_info));
2517         infoAlreadySet = FALSE;
2518     }
2519     else {
2520         infoAlreadySet = TRUE;
2521     }
2522
2523
2524     /* Read fixed fields */
2525     p_rlc_lte_info->rlcMode = tvb_get_guint8(tvb, offset++);
2526
2527     /* Read optional fields */
2528     while (tag != RLC_LTE_PAYLOAD_TAG) {
2529         /* Process next tag */
2530         tag = tvb_get_guint8(tvb, offset++);
2531         switch (tag) {
2532             case RLC_LTE_UM_SN_LENGTH_TAG:
2533                 p_rlc_lte_info->UMSequenceNumberLength = tvb_get_guint8(tvb, offset);
2534                 offset++;
2535                 umSeqNumLengthTagPresent = TRUE;
2536                 break;
2537             case RLC_LTE_DIRECTION_TAG:
2538                 p_rlc_lte_info->direction = tvb_get_guint8(tvb, offset);
2539                 offset++;
2540                 break;
2541             case RLC_LTE_PRIORITY_TAG:
2542                 p_rlc_lte_info->priority = tvb_get_guint8(tvb, offset);
2543                 offset++;
2544                 break;
2545             case RLC_LTE_UEID_TAG:
2546                 p_rlc_lte_info->ueid = tvb_get_ntohs(tvb, offset);
2547                 offset += 2;
2548                 break;
2549             case RLC_LTE_CHANNEL_TYPE_TAG:
2550                 p_rlc_lte_info->channelType = tvb_get_ntohs(tvb, offset);
2551                 offset += 2;
2552                 break;
2553             case RLC_LTE_CHANNEL_ID_TAG:
2554                 p_rlc_lte_info->channelId = tvb_get_ntohs(tvb, offset);
2555                 offset += 2;
2556                 break;
2557
2558             case RLC_LTE_PAYLOAD_TAG:
2559                 /* Have reached data, so set payload length and get out of loop */
2560                 p_rlc_lte_info->pduLength= tvb_length_remaining(tvb, offset);
2561                 continue;
2562
2563             default:
2564                 /* It must be a recognised tag */
2565                 return FALSE;
2566         }
2567     }
2568
2569     if ((p_rlc_lte_info->rlcMode == RLC_UM_MODE) && (umSeqNumLengthTagPresent == FALSE)) {
2570         /* Conditional field is not present */
2571         return FALSE;
2572     }
2573
2574     if (!infoAlreadySet) {
2575         /* Store info in packet */
2576         p_add_proto_data(pinfo->fd, proto_rlc_lte, p_rlc_lte_info);
2577     }
2578
2579     /**************************************/
2580     /* OK, now dissect as RLC LTE         */
2581
2582     /* Create tvb that starts at actual RLC PDU */
2583     rlc_tvb = tvb_new_subset(tvb, offset, -1, tvb_reported_length(tvb)-offset);
2584     dissect_rlc_lte(rlc_tvb, pinfo, tree);
2585     return TRUE;
2586 }
2587
2588
2589
2590 /*****************************/
2591 /* Main dissection function. */
2592 /*****************************/
2593
2594 static void dissect_rlc_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2595 {
2596     proto_tree             *rlc_lte_tree;
2597     proto_tree             *context_tree;
2598     proto_item             *top_ti;
2599     proto_item             *context_ti;
2600     proto_item             *ti;
2601     proto_item             *mode_ti;
2602     gint                   offset = 0;
2603     struct rlc_lte_info    *p_rlc_lte_info = NULL;
2604
2605     /* Allocate and Zero tap struct */
2606     rlc_lte_tap_info *tap_info = ep_alloc0(sizeof(rlc_lte_tap_info));
2607
2608     /* Set protocol name */
2609     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC-LTE");
2610
2611     /* Create protocol tree. */
2612     top_ti = proto_tree_add_item(tree, proto_rlc_lte, tvb, offset, -1, ENC_NA);
2613     rlc_lte_tree = proto_item_add_subtree(top_ti, ett_rlc_lte);
2614
2615
2616     /* Look for packet info! */
2617     p_rlc_lte_info = p_get_proto_data(pinfo->fd, proto_rlc_lte);
2618
2619     /* Can't dissect anything without it... */
2620     if (p_rlc_lte_info == NULL) {
2621         ti = proto_tree_add_text(rlc_lte_tree, tvb, offset, -1,
2622                                  "Can't dissect LTE RLC frame because no per-frame info was attached!");
2623         PROTO_ITEM_SET_GENERATED(ti);
2624         return;
2625     }
2626
2627     /*****************************************/
2628     /* Show context information              */
2629
2630     /* Create context root */
2631     context_ti = proto_tree_add_string_format(rlc_lte_tree, hf_rlc_lte_context,
2632                                               tvb, offset, 0, "", "Context");
2633     context_tree = proto_item_add_subtree(context_ti, ett_rlc_lte_context);
2634     PROTO_ITEM_SET_GENERATED(context_ti);
2635
2636     ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_direction,
2637                              tvb, 0, 0, p_rlc_lte_info->direction);
2638     PROTO_ITEM_SET_GENERATED(ti);
2639
2640     mode_ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_mode,
2641                                   tvb, 0, 0, p_rlc_lte_info->rlcMode);
2642     PROTO_ITEM_SET_GENERATED(mode_ti);
2643
2644     if (p_rlc_lte_info->ueid != 0) {
2645         ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_ueid,
2646                                  tvb, 0, 0, p_rlc_lte_info->ueid);
2647         PROTO_ITEM_SET_GENERATED(ti);
2648     }
2649
2650     if ((p_rlc_lte_info->priority >= 1) && (p_rlc_lte_info->priority <=16)) {
2651         ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_priority,
2652                                  tvb, 0, 0, p_rlc_lte_info->priority);
2653         PROTO_ITEM_SET_GENERATED(ti);
2654     }
2655
2656     ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_channel_type,
2657                              tvb, 0, 0, p_rlc_lte_info->channelType);
2658     PROTO_ITEM_SET_GENERATED(ti);
2659
2660     if ((p_rlc_lte_info->channelType == CHANNEL_TYPE_SRB) ||
2661         (p_rlc_lte_info->channelType == CHANNEL_TYPE_DRB)) {
2662         ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_channel_id,
2663                                  tvb, 0, 0, p_rlc_lte_info->channelId);
2664         PROTO_ITEM_SET_GENERATED(ti);
2665     }
2666
2667     ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_pdu_length,
2668                              tvb, 0, 0, p_rlc_lte_info->pduLength);
2669     PROTO_ITEM_SET_GENERATED(ti);
2670
2671     if (p_rlc_lte_info->rlcMode == RLC_UM_MODE) {
2672         ti = proto_tree_add_uint(context_tree, hf_rlc_lte_context_um_sn_length,
2673                                  tvb, 0, 0, p_rlc_lte_info->UMSequenceNumberLength);
2674         PROTO_ITEM_SET_GENERATED(ti);
2675     }
2676
2677     /* Append highlights to top-level item */
2678     if (p_rlc_lte_info->ueid != 0) {
2679         proto_item_append_text(top_ti, "   UEId=%u", p_rlc_lte_info->ueid);
2680     }
2681
2682     if (p_rlc_lte_info->channelId == 0) {
2683         proto_item_append_text(top_ti, " (%s) ",
2684                                val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"));
2685     }
2686     else {
2687         proto_item_append_text(top_ti, " (%s:%u) ",
2688                                val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"),
2689                                p_rlc_lte_info->channelId);
2690     }
2691
2692     /* Append context highlights to info column */
2693     write_pdu_label_and_info(top_ti, NULL, pinfo,
2694                              "[%s] [%s] ",
2695                              (p_rlc_lte_info->direction == 0) ? "UL" : "DL",
2696                              val_to_str_const(p_rlc_lte_info->rlcMode, rlc_mode_short_vals, "Unknown"));
2697     if (p_rlc_lte_info->ueid != 0) {
2698         col_append_fstr(pinfo->cinfo, COL_INFO, "UEId=%u ", p_rlc_lte_info->ueid);
2699     }
2700     if (p_rlc_lte_info->channelId == 0) {
2701         write_pdu_label_and_info(top_ti, NULL, pinfo, "%s",
2702                                  val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"));
2703     }
2704     else {
2705         write_pdu_label_and_info(top_ti, NULL, pinfo, "%s:%-2u",
2706                                  val_to_str_const(p_rlc_lte_info->channelType, rlc_channel_type_vals, "Unknown"),
2707                                  p_rlc_lte_info->channelId);
2708     }
2709
2710     /* Set context-info parts of tap struct */
2711     tap_info->rlcMode = p_rlc_lte_info->rlcMode;
2712     tap_info->direction = p_rlc_lte_info->direction;
2713     tap_info->priority = p_rlc_lte_info->priority;
2714     tap_info->ueid = p_rlc_lte_info->ueid;
2715     tap_info->channelType = p_rlc_lte_info->channelType;
2716     tap_info->channelId = p_rlc_lte_info->channelId;
2717     tap_info->pduLength = p_rlc_lte_info->pduLength;
2718     tap_info->UMSequenceNumberLength = p_rlc_lte_info->UMSequenceNumberLength;
2719     tap_info->loggedInMACFrame = (p_get_proto_data(pinfo->fd, proto_mac_lte) != NULL);
2720
2721     tap_info->time = pinfo->fd->abs_ts;
2722
2723     /* Reset this count */
2724     s_number_of_extensions = 0;
2725
2726     /* Dissect the RLC PDU itself. Format depends upon mode... */
2727     switch (p_rlc_lte_info->rlcMode) {
2728
2729         case RLC_TM_MODE:
2730             dissect_rlc_lte_tm(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti);
2731             break;
2732
2733         case RLC_UM_MODE:
2734             dissect_rlc_lte_um(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti,
2735                                tap_info);
2736             break;
2737
2738         case RLC_AM_MODE:
2739             dissect_rlc_lte_am(tvb, pinfo, rlc_lte_tree, offset, p_rlc_lte_info, top_ti,
2740                                tap_info);
2741             break;
2742
2743         case RLC_PREDEF:
2744             /* Predefined data (i.e. not containing a valid RLC header */
2745             proto_tree_add_item(rlc_lte_tree, hf_rlc_lte_predefined_pdu, tvb, offset, -1, ENC_NA);
2746             write_pdu_label_and_info(top_ti, NULL, pinfo, "   [%u-bytes]",
2747                                      tvb_length_remaining(tvb, offset));
2748             break;
2749
2750         default:
2751             /* Error - unrecognised mode */
2752             expert_add_info_format(pinfo, mode_ti, PI_MALFORMED, PI_ERROR,
2753                                    "Unrecognised RLC Mode set (%u)", p_rlc_lte_info->rlcMode);
2754             break;
2755     }
2756
2757     /* Queue tap info */
2758     tap_queue_packet(rlc_lte_tap, pinfo, tap_info);
2759 }
2760
2761
2762
2763 /* Initializes the hash tables each time a new
2764  * file is loaded or re-loaded in wireshark */
2765 static void
2766 rlc_lte_init_protocol(void)
2767 {
2768     /* Destroy any existing hashes. */
2769     if (sequence_analysis_channel_hash) {
2770         g_hash_table_destroy(sequence_analysis_channel_hash);
2771     }
2772     if (sequence_analysis_report_hash) {
2773         g_hash_table_destroy(sequence_analysis_report_hash);
2774     }
2775     if (repeated_nack_channel_hash) {
2776         g_hash_table_destroy(repeated_nack_channel_hash);
2777     }
2778     if (repeated_nack_report_hash) {
2779         g_hash_table_destroy(repeated_nack_report_hash);
2780     }
2781     if (reassembly_report_hash) {
2782         g_hash_table_destroy(reassembly_report_hash);
2783     }
2784
2785     /* Now create them over */
2786     sequence_analysis_channel_hash = g_hash_table_new(rlc_channel_hash_func, rlc_channel_equal);
2787     sequence_analysis_report_hash = g_hash_table_new(rlc_result_hash_func, rlc_result_hash_equal);
2788
2789     repeated_nack_channel_hash = g_hash_table_new(rlc_channel_hash_func, rlc_channel_equal);
2790     repeated_nack_report_hash = g_hash_table_new(rlc_result_hash_func, rlc_result_hash_equal);
2791     reassembly_report_hash = g_hash_table_new(rlc_result_hash_func, rlc_result_hash_equal);
2792 }
2793
2794
2795 /* Configure number of PDCP SN bits to use for DRB channels.
2796    TODO: currently assume all UEs/Channels will use the same length... */
2797 void set_rlc_lte_drb_pdcp_seqnum_length(guint16 ueid _U_, guint8 drbid _U_,
2798                                         guint8 userplane_seqnum_length)
2799 {
2800     signalled_pdcp_sn_bits = userplane_seqnum_length;
2801 }
2802
2803
2804 void proto_register_rlc_lte(void)
2805 {
2806     static hf_register_info hf[] =
2807     {
2808         /**********************************/
2809         /* Items for decoding context     */
2810         { &hf_rlc_lte_context,
2811             { "Context",
2812               "rlc-lte.context", FT_STRING, BASE_NONE, NULL, 0x0,
2813               NULL, HFILL
2814             }
2815         },
2816         { &hf_rlc_lte_context_mode,
2817             { "RLC Mode",
2818               "rlc-lte.mode", FT_UINT8, BASE_DEC, VALS(rlc_mode_vals), 0x0,
2819               NULL, HFILL
2820             }
2821         },
2822         { &hf_rlc_lte_context_direction,
2823             { "Direction",
2824               "rlc-lte.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
2825               "Direction of message", HFILL
2826             }
2827         },
2828         { &hf_rlc_lte_context_priority,
2829             { "Priority",
2830               "rlc-lte.priority", FT_UINT8, BASE_DEC, 0, 0x0,
2831               NULL, HFILL
2832             }
2833         },
2834         { &hf_rlc_lte_context_ueid,
2835             { "UEId",
2836               "rlc-lte.ueid", FT_UINT16, BASE_DEC, 0, 0x0,
2837               "User Equipment Identifier associated with message", HFILL
2838             }
2839         },
2840         { &hf_rlc_lte_context_channel_type,
2841             { "Channel Type",
2842               "rlc-lte.channel-type", FT_UINT16, BASE_DEC, VALS(rlc_channel_type_vals), 0x0,
2843               "Channel Type associated with message", HFILL
2844             }
2845         },
2846         { &hf_rlc_lte_context_channel_id,
2847             { "Channel ID",
2848               "rlc-lte.channel-id", FT_UINT16, BASE_DEC, 0, 0x0,
2849               "Channel ID associated with message", HFILL
2850             }
2851         },
2852         { &hf_rlc_lte_context_pdu_length,
2853             { "PDU Length",
2854               "rlc-lte.pdu-length", FT_UINT16, BASE_DEC, 0, 0x0,
2855               "Length of PDU (in bytes)", HFILL
2856             }
2857         },
2858         { &hf_rlc_lte_context_um_sn_length,
2859             { "UM Sequence number length",
2860               "rlc-lte.um-seqnum-length", FT_UINT8, BASE_DEC, 0, 0x0,
2861               "Length of UM sequence number in bits", HFILL
2862             }
2863         },
2864
2865         /* Transparent mode fields */
2866         { &hf_rlc_lte_tm,
2867             { "TM",
2868               "rlc-lte.tm", FT_STRING, BASE_NONE, NULL, 0x0,
2869               "Transparent Mode", HFILL
2870             }
2871         },
2872         { &hf_rlc_lte_tm_data,
2873             { "TM Data",
2874               "rlc-lte.tm.data", FT_BYTES, BASE_NONE, 0, 0x0,
2875               "Transparent Mode Data", HFILL
2876             }
2877         },
2878
2879         /* Unacknowledged mode fields */
2880         { &hf_rlc_lte_um,
2881             { "UM",
2882               "rlc-lte.um", FT_STRING, BASE_NONE, NULL, 0x0,
2883               "Unackowledged Mode", HFILL
2884             }
2885         },
2886         { &hf_rlc_lte_um_header,
2887             { "UM Header",
2888               "rlc-lte.um.header", FT_STRING, BASE_NONE, NULL, 0x0,
2889               "Unackowledged Mode Header", HFILL
2890             }
2891         },
2892         { &hf_rlc_lte_um_fi,
2893             { "Framing Info",
2894               "rlc-lte.um.fi", FT_UINT8, BASE_HEX, VALS(framing_info_vals), 0x0,
2895               NULL, HFILL
2896             }
2897         },
2898         { &hf_rlc_lte_um_fixed_e,
2899             { "Extension",
2900               "rlc-lte.um.fixed.e", FT_UINT8, BASE_HEX, VALS(fixed_extension_vals), 0x0,
2901               "Extension in fixed part of UM header", HFILL
2902             }
2903         },
2904         { &hf_rlc_lte_um_sn,
2905             { "Sequence number",
2906               "rlc-lte.um.sn", FT_UINT8, BASE_DEC, 0, 0x0,
2907               "Unacknowledged Mode Sequence Number", HFILL
2908             }
2909         },
2910         { &hf_rlc_lte_um_fixed_reserved,
2911             { "Reserved",
2912               "rlc-lte.um.reserved", FT_UINT8, BASE_DEC, 0, 0xe0,
2913               "Unacknowledged Mode Fixed header reserved bits", HFILL
2914             }
2915         },
2916         { &hf_rlc_lte_um_data,
2917             { "UM Data",
2918               "rlc-lte.um.data", FT_BYTES, BASE_NONE, 0, 0x0,
2919               "Unacknowledged Mode Data", HFILL
2920             }
2921         },
2922         { &hf_rlc_lte_extension_part,
2923             { "Extension Part",
2924               "rlc-lte.extension-part", FT_STRING, BASE_NONE, 0, 0x0,
2925               NULL, HFILL
2926             }
2927         },
2928         { &hf_rlc_lte_extension_e,
2929             { "Extension",
2930               "rlc-lte.extension.e", FT_UINT8, BASE_HEX, VALS(extension_extension_vals), 0x0,
2931               "Extension in extended part of the header", HFILL
2932             }
2933         },
2934         { &hf_rlc_lte_extension_li,
2935             { "Length Indicator",
2936               "rlc-lte.extension.li", FT_UINT16, BASE_DEC, 0, 0x0,
2937               NULL, HFILL
2938             }
2939         },
2940         { &hf_rlc_lte_extension_padding,
2941             { "Padding",
2942               "rlc-lte.extension.padding", FT_UINT8, BASE_HEX, 0, 0x0f,
2943               "Extension header padding", HFILL
2944             }
2945         },
2946
2947         { &hf_rlc_lte_am,
2948             { "AM",
2949               "rlc-lte.am", FT_STRING, BASE_NONE, NULL, 0x0,
2950               "Ackowledged Mode", HFILL
2951             }
2952         },
2953         { &hf_rlc_lte_am_header,
2954             { "AM Header",
2955               "rlc-lte.am.header", FT_STRING, BASE_NONE, NULL, 0x0,
2956               "Ackowledged Mode Header", HFILL
2957             }
2958         },
2959         { &hf_rlc_lte_am_data_control,
2960             { "Frame type",
2961               "rlc-lte.am.frame-type", FT_UINT8, BASE_HEX, VALS(data_or_control_vals), 0x80,
2962               "AM Frame Type (Control or Data)", HFILL
2963             }
2964         },
2965         { &hf_rlc_lte_am_rf,
2966             { "Re-segmentation Flag",
2967               "rlc-lte.am.rf", FT_UINT8, BASE_HEX, VALS(resegmentation_flag_vals), 0x40,
2968               "AM Re-segmentation Flag", HFILL
2969             }
2970         },
2971         { &hf_rlc_lte_am_p,
2972             { "Polling Bit",
2973               "rlc-lte.am.p", FT_UINT8, BASE_HEX, VALS(polling_bit_vals), 0x20,
2974               NULL, HFILL
2975             }
2976         },
2977         { &hf_rlc_lte_am_fi,
2978             { "Framing Info",
2979               "rlc-lte.am.fi", FT_UINT8, BASE_HEX, VALS(framing_info_vals), 0x18,
2980               "AM Framing Info", HFILL
2981             }
2982         },
2983         { &hf_rlc_lte_am_fixed_e,
2984             { "Extension",
2985               "rlc-lte.am.fixed.e", FT_UINT8, BASE_HEX, VALS(fixed_extension_vals), 0x04,
2986               "Fixed Extension Bit", HFILL
2987             }
2988         },
2989         { &hf_rlc_lte_am_fixed_sn,
2990             { "Sequence Number",
2991               "rlc-lte.am.fixed.sn", FT_UINT16, BASE_DEC, 0, 0x03ff,
2992               "AM Fixed Sequence Number", HFILL
2993             }
2994         },
2995         { &hf_rlc_lte_am_segment_lsf,
2996             { "Last Segment Flag",
2997               "rlc-lte.am.segment.lsf", FT_UINT8, BASE_HEX, VALS(lsf_vals), 0x80,
2998               NULL, HFILL
2999             }
3000         },
3001         { &hf_rlc_lte_am_segment_so,
3002             { "Segment Offset",
3003               "rlc-lte.am.segment.offset", FT_UINT16, BASE_DEC, 0, 0x7fff,
3004               NULL, HFILL
3005             }
3006         },
3007         { &hf_rlc_lte_am_data,
3008             { "AM Data",
3009               "rlc-lte.am.data", FT_BYTES, BASE_NONE, 0, 0x0,
3010               "Acknowledged Mode Data", HFILL
3011             }
3012         },
3013
3014         { &hf_rlc_lte_am_cpt,
3015             { "Control PDU Type",
3016               "rlc-lte.am.cpt", FT_UINT8, BASE_HEX, VALS(control_pdu_type_vals), 0x70,
3017               "AM Control PDU Type", HFILL
3018             }
3019         },
3020         { &hf_rlc_lte_am_ack_sn,
3021             { "ACK Sequence Number",
3022               "rlc-lte.am.ack-sn", FT_UINT16, BASE_DEC, 0, 0x0,
3023               "Sequence Number we expect to receive next", HFILL
3024             }
3025         },
3026         { &hf_rlc_lte_am_e1,
3027             { "Extension bit 1",
3028               "rlc-lte.am.e1", FT_UINT8, BASE_HEX, VALS(am_e1_vals), 0x0,
3029               NULL, HFILL
3030             }
3031         },
3032         { &hf_rlc_lte_am_e2,
3033             { "Extension bit 2",
3034               "rlc-lte.am.e2", FT_UINT8, BASE_HEX, VALS(am_e2_vals), 0x0,
3035               NULL, HFILL
3036             }
3037         },
3038         { &hf_rlc_lte_am_nacks,
3039             { "Number of NACKs",
3040               "rlc-lte.am.nacks", FT_UINT16, BASE_DEC, 0, 0x0,
3041               "Number of NACKs in this status PDU", HFILL
3042             }
3043         },
3044         { &hf_rlc_lte_am_nack_sn,
3045             { "NACK Sequence Number",
3046               "rlc-lte.am.nack-sn", FT_UINT16, BASE_DEC, 0, 0x0,
3047               "Negative Acknowledgement Sequence Number", HFILL
3048             }
3049         },
3050         { &hf_rlc_lte_am_so_start,
3051             { "SO Start",
3052               "rlc-lte.am.so-start", FT_UINT16, BASE_DEC, 0, 0x0,
3053               "Segment Offset Start byte index", HFILL
3054             }
3055         },
3056         { &hf_rlc_lte_am_so_end,
3057             { "SO End",
3058               "rlc-lte.am.so-end", FT_UINT16, BASE_DEC, 0, 0x0,
3059               "Segment Offset End byte index", HFILL
3060             }
3061         },
3062
3063         { &hf_rlc_lte_predefined_pdu,
3064             { "Predefined data",
3065               "rlc-lte.predefined-data", FT_BYTES, BASE_NONE, 0, 0x0,
3066               "Predefined test data", HFILL
3067             }
3068         },
3069
3070         { &hf_rlc_lte_sequence_analysis,
3071             { "Sequence Analysis",
3072               "rlc-lte.sequence-analysis", FT_STRING, BASE_NONE, 0, 0x0,
3073               NULL, HFILL
3074             }
3075         },
3076         { &hf_rlc_lte_sequence_analysis_ok,
3077             { "OK",
3078               "rlc-lte.sequence-analysis.ok", FT_BOOLEAN, BASE_NONE, 0, 0x0,
3079               NULL, HFILL
3080             }
3081         },
3082         { &hf_rlc_lte_sequence_analysis_previous_frame,
3083             { "Previous frame for channel",
3084               "rlc-lte.sequence-analysis.previous-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
3085               NULL, HFILL
3086             }
3087         },
3088         { &hf_rlc_lte_sequence_analysis_next_frame,
3089             { "Next frame for channel",
3090               "rlc-lte.sequence-analysis.next-frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
3091               NULL, HFILL
3092             }
3093         },
3094         { &hf_rlc_lte_sequence_analysis_expected_sn,
3095             { "Expected SN",
3096               "rlc-lte.sequence-analysis.expected-sn", FT_UINT16, BASE_DEC, 0, 0x0,
3097               NULL, HFILL
3098             }
3099         },
3100         { &hf_rlc_lte_sequence_analysis_framing_info_correct,
3101             { "Frame info continued correctly",
3102               "rlc-lte.sequence-analysis.framing-info-correct", FT_BOOLEAN, BASE_NONE, 0, 0x0,
3103               NULL, HFILL
3104             }
3105         },
3106         { &hf_rlc_lte_sequence_analysis_mac_retx,
3107             { "Frame retransmitted by MAC",
3108               "rlc-lte.sequence-analysis.mac-retx", FT_BOOLEAN, BASE_NONE, 0, 0x0,
3109               NULL, HFILL
3110             }
3111         },
3112         { &hf_rlc_lte_sequence_analysis_retx,
3113             { "Retransmitted frame",
3114               "rlc-lte.sequence-analysis.retx", FT_BOOLEAN, BASE_NONE, 0, 0x0,
3115               NULL, HFILL
3116             }
3117         },
3118         { &hf_rlc_lte_sequence_analysis_skipped,
3119             { "Skipped frames",
3120               "rlc-lte.sequence-analysis.skipped-frames", FT_BOOLEAN, BASE_NONE, 0, 0x0,
3121               NULL, HFILL
3122             }
3123         },
3124         { &hf_rlc_lte_sequence_analysis_repeated,
3125             { "Repeated frame",
3126               "rlc-lte.sequence-analysis.repeated-frame", FT_BOOLEAN, BASE_NONE, 0, 0x0,
3127               NULL, HFILL
3128             }
3129         },
3130         { &hf_rlc_lte_sequence_analysis_repeated_nack,
3131             { "Repeated NACK",
3132               "rlc-lte.sequence-analysis.repeated-nack", FT_UINT16, BASE_DEC, 0, 0x0,
3133               NULL, HFILL
3134             }
3135         },
3136         { &hf_rlc_lte_sequence_analysis_repeated_nack_original_frame,
3137             { "Frame with previous status PDU",
3138               "rlc-lte.sequence-analysis.repeated-nack.original-frame",  FT_FRAMENUM, BASE_NONE, 0, 0x0,
3139               NULL, HFILL
3140             }
3141         },
3142
3143         { &hf_rlc_lte_sequence_analysis_ack_out_of_range,
3144             { "Out of range ACK",
3145               "rlc-lte.sequence-analysis.ack-out-of-range", FT_BOOLEAN, BASE_NONE, 0, 0x0,
3146               NULL, HFILL
3147             }
3148         },
3149         { &hf_rlc_lte_sequence_analysis_ack_out_of_range_opposite_frame,
3150             { "Frame with most recent SN",
3151               "rlc-lte.sequence-analysis.ack-out-of-range.last-sn-frame",  FT_FRAMENUM, BASE_NONE, 0, 0x0,
3152               NULL, HFILL
3153             }
3154         },
3155
3156         { &hf_rlc_lte_reassembly_source,
3157             { "Reassembly Source",
3158               "rlc-lte.reassembly-info", FT_STRING, BASE_NONE, 0, 0x0,
3159               NULL, HFILL
3160             }
3161         },
3162         { &hf_rlc_lte_reassembly_source_number_of_segments,
3163             { "Number of segments",
3164               "rlc-lte.reassembly-info.number-of-segments", FT_UINT16, BASE_DEC, 0, 0x0,
3165               NULL, HFILL
3166             }
3167         },
3168         { &hf_rlc_lte_reassembly_source_total_length,
3169             { "Total length",
3170               "rlc-lte.reassembly-info.total-length", FT_UINT16, BASE_DEC, 0, 0x0,
3171               NULL, HFILL
3172             }
3173         },
3174         { &hf_rlc_lte_reassembly_source_segment,
3175             { "Segment",
3176               "rlc-lte.reassembly-info.segment", FT_NONE, BASE_NONE, 0, 0x0,
3177               NULL, HFILL
3178             }
3179         },
3180         { &hf_rlc_lte_reassembly_source_segment_sn,
3181             { "SN",
3182               "rlc-lte.reassembly-info.segment.sn", FT_UINT16, BASE_DEC, 0, 0x0,
3183               NULL, HFILL
3184             }
3185         },
3186         { &hf_rlc_lte_reassembly_source_segment_framenum,
3187             { "Frame",
3188               "rlc-lte.reassembly-info.segment.frame", FT_FRAMENUM, BASE_NONE, 0, 0x0,
3189               NULL, HFILL
3190             }
3191         },
3192         { &hf_rlc_lte_reassembly_source_segment_length,
3193             { "Length",
3194               "rlc-lte.reassembly-info.segment.length", FT_UINT32, BASE_DEC, 0, 0x0,
3195               NULL, HFILL
3196             }
3197         },
3198
3199         { &hf_rlc_lte_header_only,
3200             { "RLC PDU Header only",
3201               "rlc-lte.header-only", FT_UINT8, BASE_DEC, VALS(header_only_vals), 0x0,
3202               NULL, HFILL
3203             }
3204         },
3205     };
3206
3207     static gint *ett[] =
3208     {
3209         &ett_rlc_lte,
3210         &ett_rlc_lte_context,
3211         &ett_rlc_lte_um_header,
3212         &ett_rlc_lte_am_header,
3213         &ett_rlc_lte_extension_part,
3214         &ett_rlc_lte_sequence_analysis,
3215         &ett_rlc_lte_reassembly_source,
3216         &ett_rlc_lte_reassembly_source_segment
3217     };
3218
3219     static enum_val_t sequence_analysis_vals[] = {
3220         {"no-analysis", "No-Analysis",     FALSE},
3221         {"mac-only",    "Only-MAC-frames", SEQUENCE_ANALYSIS_MAC_ONLY},
3222         {"rlc-only",    "Only-RLC-frames", SEQUENCE_ANALYSIS_RLC_ONLY},
3223         {NULL, NULL, -1}
3224     };
3225
3226     module_t *rlc_lte_module;
3227
3228     /* Register protocol. */
3229     proto_rlc_lte = proto_register_protocol("RLC-LTE", "RLC-LTE", "rlc-lte");
3230     proto_register_field_array(proto_rlc_lte, hf, array_length(hf));
3231     proto_register_subtree_array(ett, array_length(ett));
3232
3233     /* Allow other dissectors to find this one by name. */
3234     register_dissector("rlc-lte", dissect_rlc_lte, proto_rlc_lte);
3235
3236     /* Register the tap name */
3237     rlc_lte_tap = register_tap("rlc-lte");
3238
3239     /* Preferences */
3240     rlc_lte_module = prefs_register_protocol(proto_rlc_lte, NULL);
3241
3242     prefs_register_enum_preference(rlc_lte_module, "do_sequence_analysis_am",
3243         "Do sequence analysis for AM channels",
3244         "Attempt to keep track of PDUs for AM channels, and point out problems",
3245         &global_rlc_lte_am_sequence_analysis, sequence_analysis_vals, FALSE);
3246
3247     prefs_register_enum_preference(rlc_lte_module, "do_sequence_analysis",
3248         "Do sequence analysis for UM channels",
3249         "Attempt to keep track of PDUs for UM channels, and point out problems",
3250         &global_rlc_lte_um_sequence_analysis, sequence_analysis_vals, FALSE);
3251
3252     prefs_register_bool_preference(rlc_lte_module, "call_pdcp_for_srb",
3253         "Call PDCP dissector for SRB PDUs",
3254         "Call PDCP dissector for signalling PDUs.  Note that without reassembly, it can"
3255         "only be called for complete PDus (i.e. not segmented over RLC)",
3256         &global_rlc_lte_call_pdcp_for_srb);
3257
3258     prefs_register_enum_preference(rlc_lte_module, "call_pdcp_for_drb",
3259         "Call PDCP dissector for DRB PDUs",
3260         "Call PDCP dissector for user-plane PDUs.  Note that without reassembly, it can"
3261         "only be called for complete PDUs (i.e. not segmented over RLC)",
3262         &global_rlc_lte_call_pdcp_for_drb, pdcp_drb_col_vals, FALSE);
3263
3264
3265     prefs_register_bool_preference(rlc_lte_module, "call_rrc_for_ccch",
3266         "Call RRC dissector for CCCH PDUs",
3267         "Call RRC dissector for CCCH PDUs",
3268         &global_rlc_lte_call_rrc);
3269
3270     prefs_register_bool_preference(rlc_lte_module, "heuristic_rlc_lte_over_udp",
3271         "Try Heuristic LTE-RLC over UDP framing",
3272         "When enabled, use heuristic dissector to find RLC-LTE frames sent with "
3273         "UDP framing",
3274         &global_rlc_lte_heur);
3275
3276     prefs_register_bool_preference(rlc_lte_module, "header_only_mode",
3277         "May see RLC headers only",
3278         "When enabled, if data is not present, don't report as an error, but instead "
3279         "add expert info to indicate that headers were omitted",
3280         &global_rlc_lte_headers_expected);
3281
3282     prefs_register_bool_preference(rlc_lte_module, "reassembly",
3283         "Attempt SDU reassembly",
3284         "When enabled, attempts to re-assemble upper-layer SDUs that are split over "
3285         "more than one RLC PDU.  Note: does not currently support out-of-order or "
3286         "re-segmentation. N.B. sequence analysis must also be turned on in order "
3287         "for reassembly to work",
3288         &global_rlc_lte_reassembly);
3289
3290
3291     register_init_routine(&rlc_lte_init_protocol);
3292 }
3293
3294 void
3295 proto_reg_handoff_rlc_lte(void)
3296 {
3297     /* Add as a heuristic UDP dissector */
3298     heur_dissector_add("udp", dissect_rlc_lte_heur, proto_rlc_lte);
3299 }