From Vincent Helfre:
[obnox/wireshark/wip.git] / epan / dissectors / packet-gsm_a_rr.c
index d91c8f2c72d68eb7d2fa96cdbdceb75be7fbfcf0..fdaa359f7fcb0ae81110134d6c1893fbe0810458 100644 (file)
@@ -5,7 +5,7 @@
  * In association with Telos Technology Inc.
  *
  * Added Dissection of Radio Resource Management Information Elements
- * and othere enhancements and fixes.
+ * and other enhancements and fixes.
  * Copyright 2005 - 2006, Anders Broman [AT] ericsson.com
  *
  * Title               3GPP                    Other
@@ -48,7 +48,6 @@
 # include "config.h"
 #endif
 
-#include <stdio.h>
 #include <stdlib.h>
 
 #include <string.h>
@@ -301,9 +300,9 @@ const value_string gsm_rr_elem_strings[] = {
     { 0x00, "Extended Measurement Results" },                                  /* [3] 10.5.2.45 Extended Measurement Results */
     { 0x00, "Extended Measurement Frequency List" },                           /* [3] 10.5.2.46 Extended Measurement Frequency List */
     { 0x00, "Suspension Cause" },                                              /* [3] 10.5.2.47                                                                */
-/* [3] 10.5.2.48 APDU ID
- * [3] 10.5.2.49 APDU Flags
- * [3] 10.5.2.50 APDU Data */
+    { 0x00, "APDU ID" },                                                       /* [3] 10.5.2.48 APDU ID */
+    { 0x00, "APDU Flags" },                                                    /* [3] 10.5.2.49 APDU Flags */
   { 0x00, "APDU Data" },                                                     /* [3] 10.5.2.50 APDU Data */
     { 0x00, "Handover to UTRAN Command" },                                     /* [3] 10.5.2.51 Handover To UTRAN Command */
 /* [3] 10.5.2.52 Handover To cdma2000 Command
  * [3] 10.5.2.53 (void)
@@ -331,7 +330,7 @@ const value_string gsm_rr_elem_strings[] = {
 const value_string gsm_rr_rest_octets_elem_strings[] = {
     /* RR Rest Octets information elements */
     { 0, "UTRAN FDD Description" },
-    { 0, "UTRAN TDD Description" }, 
+    { 0, "UTRAN TDD Description" },
     { 0, "3G Measurement Parameters Description" },
     { 0, "3G Additional Measurement Parameters Description" },
     { 0, "Measurement Parameters Description" },
@@ -347,6 +346,16 @@ const value_string gsm_rr_rest_octets_elem_strings[] = {
     { 0, "TDD Cell Information Field" },
     { 0, "GPRS 3G Measurement Parameters Description" },
     { 0, "3G Additional Measurement Parameters Description 2" },
+    { 0, "Priority and E-UTRAN Parameters Description" },
+    { 0, "Serving Cell Priority Parameters Description" },
+    { 0, "3G Priority Parameters Description" },
+    { 0, "UTRAN Priority Parameters" },
+    { 0, "E-UTRAN Parameters Description" },
+    { 0, "E-UTRAN Neighbour Cells" },
+    { 0, "E-UTRAN Not Allowed Cells" },
+    { 0, "E-UTRAN PCID to TA mapping" },
+    { 0, "3G CSG Description" },
+    { 0, "E-UTRAN CSG Description" },
     { 0, "Optional Selection Parameters" },
     { 0, "GPRS Indicator" },
     { 0, "SI4 Rest Octets_O" },
@@ -461,6 +470,7 @@ static int hf_gsm_a_rr_sync_ind_nci = -1;
 static int hf_gsm_a_rr_sync_ind_rot = -1;
 static int hf_gsm_a_rr_sync_ind_si = -1;
 static int hf_gsm_a_rr_format_id = -1;
+static int hf_gsm_a_rr_format_id2 = -1;
 static int hf_gsm_a_rr_channel_mode = -1;
 static int hf_gsm_a_rr_channel_mode2 = -1;
 static int hf_gsm_a_rr_sc = -1;
@@ -497,6 +507,9 @@ static int hf_gsm_a_rr_chnl_needed_ch2 = -1;
 static int hf_gsm_a_rr_chnl_needed_ch3 = -1;
 static int hf_gsm_a_rr_chnl_needed_ch4 = -1;
 static int hf_gsm_a_rr_suspension_cause = -1;
+static int hf_gsm_a_rr_apdu_id = -1;
+static int hf_gsm_a_rr_apdu_flags = -1;
+static int hf_gsm_a_rr_apdu_data = -1;
 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b8 = -1;
 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b7 = -1;
 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b6 = -1;
@@ -682,6 +695,54 @@ static int hf_gsm_a_rr_mean_bep_gmsk = -1;
 static int hf_gsm_a_rr_mean_cv_bep = -1;
 static int hf_gsm_a_rr_nbr_rcvd_blocks = -1;
 static int hf_gsm_a_rr_reporting_quantity = -1;
+/* Additions in Rel-8 */
+static int hf_gsm_a_rr_3g_priority_param_desc_utran_start = -1;
+static int hf_gsm_a_rr_3g_priority_param_desc_utran_stop = -1;
+static int hf_gsm_a_rr_3g_priority_param_desc_default_utran_prio = -1;
+static int hf_gsm_a_rr_3g_priority_param_desc_default_threshold_utran = -1;
+static int hf_gsm_a_rr_3g_priority_param_desc_default_utran_qrxlevmin = -1;
+static int hf_gsm_a_rr_utran_frequency_index = -1;
+static int hf_gsm_a_rr_utran_priority = -1;
+static int hf_gsm_a_rr_thresh_utran_high = -1;
+static int hf_gsm_a_rr_thresh_utran_low = -1;
+static int hf_gsm_a_rr_utran_qrxlevmin = -1;
+static int hf_gsm_a_rr_eutran_ccn_active = -1;
+static int hf_gsm_a_rr_eutran_start = -1;
+static int hf_gsm_a_rr_eutran_stop = -1;
+static int hf_gsm_a_rr_qsearch_c_eutran_initial = -1;
+static int hf_gsm_a_rr_eutran_rep_quant = -1;
+static int hf_gsm_a_rr_eutran_multirat_reporting = -1;
+static int hf_gsm_a_rr_eutran_fdd_reporting_threshold = -1;
+static int hf_gsm_a_rr_eutran_fdd_reporting_threshold_2 = -1;
+static int hf_gsm_a_rr_eutran_tdd_reporting_threshold = -1;
+static int hf_gsm_a_rr_eutran_tdd_reporting_threshold_2 = -1;
+static int hf_gsm_a_rr_eutran_fdd_measurement_report_offset = -1;
+static int hf_gsm_a_rr_eutran_tdd_measurement_report_offset = -1;
+static int hf_gsm_a_rr_reporting_granularity = -1;
+static int hf_gsm_a_rr_qsearch_p_eutran = -1;
+static int hf_gsm_a_rr_serving_cell_priority_param_geran_priority = -1;
+static int hf_gsm_a_rr_serving_cell_priority_param_thresh_prio_search = -1;
+static int hf_gsm_a_rr_serving_cell_priority_param_thresh_gsm_low = -1;
+static int hf_gsm_a_rr_serving_cell_priority_param_h_prio = -1;
+static int hf_gsm_a_rr_serving_cell_priority_param_t_reselection = -1;
+static int hf_gsm_a_rr_eutran_earfcn = -1;
+static int hf_gsm_a_rr_eutran_measurement_bandwidth = -1;
+static int hf_gsm_a_rr_eutran_priority = -1;
+static int hf_gsm_a_rr_thresh_eutran_high = -1;
+static int hf_gsm_a_rr_thresh_eutran_low = -1;
+static int hf_gsm_a_rr_eutran_qrxlevmin = -1;
+static int hf_gsm_a_rr_eutran_pcid = -1;
+static int hf_gsm_a_rr_eutran_pcid_bitmap_group = -1;
+static int hf_gsm_a_rr_eutran_pcid_pattern_length = -1;
+static int hf_gsm_a_rr_eutran_pcid_pattern = -1;
+static int hf_gsm_a_rr_eutran_pcid_pattern_sense = -1;
+static int hf_gsm_a_rr_eutran_frequency_index = -1;
+static int hf_gsm_a_rr_psc = -1;
+static int hf_gsm_a_rr_utran_psc_pattern_length = -1;
+static int hf_gsm_a_rr_utran_psc_pattern_sense = -1;
+static int hf_gsm_a_rr_utran_csg_fdd_uarfcn = -1;
+static int hf_gsm_a_rr_utran_csg_tdd_uarfcn = -1;
+static int hf_gsm_a_rr_csg_earfcn = -1;
 
 /* Initialize the subtree pointers */
 static gint ett_ccch_msg = -1;
@@ -691,7 +752,7 @@ static gint ett_sacch_msg = -1;
 static char a_bigbuf[1024];
 
 static dissector_handle_t data_handle;
-
+static dissector_handle_t rrlp_dissector;
 
 
 #define        NUM_GSM_RR_ELEM (sizeof(gsm_rr_elem_strings)/sizeof(value_string))
@@ -717,6 +778,16 @@ typedef enum
     DE_RR_REST_OCTETS_TDD_CELL_INFORMATION_FIELD,
     DE_RR_REST_OCTETS_GPRS_3G_MEAS_PARAM_DESC,
     DE_RR_REST_OCTETS_3G_ADD_MEAS_PARAM_DESC2,
+    DE_RR_REST_OCTETS_PRIORITY_AND_EUTRAN_PARAM_DESC,
+    DE_RR_REST_OCTETS_SERVING_CELL_PRIORITY_PARAM_DESC,
+    DE_RR_REST_OCTETS_3G_PRIORITY_PARAM_DESC,
+    DE_RR_REST_OCTETS_UTRAN_PRIO_PARAM,
+    DE_RR_REST_OCTETS_EUTRAN_PARAM_DESC,
+    DE_RR_REST_OCTETS_EUTRAN_NEIGHBOUR_CELLS,
+    DE_RR_REST_OCTETS_EUTRAN_NOT_ALLOWED_CELLS,
+    DE_RR_REST_OCTETS_EUTRAN_PCID_TO_TA_MAPPING,
+    DE_RR_REST_OCTETS_3G_CSG_DESC,
+    DE_RR_REST_OCTETS_EUTRAN_CSG_DESC,
     DE_RR_REST_OCTETS_OPTIONAL_SEL_PARAM,
     DE_RR_REST_OCTETS_GPRS_INDICATOR,
     DE_RR_REST_OCTETS_SI4_REST_OCTETS_O,
@@ -794,35 +865,35 @@ static void display_channel_list(guint8 *list, tvbuff_t *tvb, proto_tree *tree,
     return;
 }
 
-static gint greatest_power_of_2_lesser_or_equal_to(gint index)
+static gint greatest_power_of_2_lesser_or_equal_to(gint idx)
 {
     gint j = 1;
     do {
         j<<=1;
-    } while (j<=index);
+    } while (j<=idx);
     j >>= 1;
     return j;
 }
 
 static gint f_k(gint k, gint *w, gint range)
 {
-    gint index, n, j;
+    gint idx, n, j;
 
-    index = k;
+    idx = k;
     range -= 1;
-    range = range/greatest_power_of_2_lesser_or_equal_to(index);
-    n = w[index]-1;
+    range = range/greatest_power_of_2_lesser_or_equal_to(idx);
+    n = w[idx]-1;
 
-    while (index>1) {
-        j = greatest_power_of_2_lesser_or_equal_to(index);
+    while (idx>1) {
+        j = greatest_power_of_2_lesser_or_equal_to(idx);
         range = 2*range+1;
-        if ((2*index) < 3*j){ /* left child */
-            index -= j/2;
-            n = (n+w[index]-1+((range-1)/2)+1)%range;
+        if ((2*idx) < 3*j){ /* left child */
+            idx -= j/2;
+            n = (n+w[idx]-1+((range-1)/2)+1)%range;
         }
         else { /* right child */
-            index -= j;
-            n = (n+w[index]-1+1)%range;
+            idx -= j;
+            n = (n+w[idx]-1+1)%range;
         }
     }
 
@@ -879,7 +950,7 @@ static void dissect_channel_list_n_range(tvbuff_t *tvb, proto_tree *tree, guint3
     for (i=1; i<=imax; i++) {
         wi = octet & ~(0xff<<bits);     /* mask "bits" low bits to start wi from existing octet */
         wbits = bits;
-        if (wsize>wbits) {              /* need to extract more bits from the next octet */
+        while (wsize>wbits) {       /* need to extract more bits from the next octet */
             octet = tvb_get_guint8(tvb, curr_offset++);
             wi = (wi << 8) + octet;
             bits = 8;
@@ -917,21 +988,16 @@ static void dissect_channel_list_n_range(tvbuff_t *tvb, proto_tree *tree, guint3
 }
 
 static guint16
-dissect_arfcn_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+dissect_arfcn_list_core(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_, guint8 format)
 {
-    guint32    curr_offset;
-    guint8  oct,bit,byte;
+    guint32 curr_offset,byte;
+    guint8  oct,bit;
     guint16 arfcn;
     proto_item *item;
 
     curr_offset = offset;
 
-    oct = tvb_get_guint8(tvb, curr_offset);
-
-    /* FORMAT-ID, Format Identifier (part of octet 3)*/
-    proto_tree_add_item(tree, hf_gsm_a_rr_format_id, tvb, curr_offset, 1, FALSE);
-
-    if ((oct & 0xc0) == 0x00)
+    if ((format & 0xc0) == 0x00)
     {
         /* bit map 0 */
         item = proto_tree_add_text(tree,tvb, curr_offset, len, "List of ARFCNs =");
@@ -952,34 +1018,34 @@ dissect_arfcn_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
             curr_offset++;
         }
     }
-    else if ((oct & 0xc8) == 0x80)
+    else if ((format & 0xc8) == 0x80)
     {
         /* 1024 range */
         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 1024);
         curr_offset = curr_offset + len;
     }
-    else if ((oct & 0xce) == 0x88)
+    else if ((format & 0xce) == 0x88)
     {
         /* 512 range */
         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 512);
         curr_offset = curr_offset + len;
     }
-    else if ((oct & 0xce) == 0x8a)
+    else if ((format & 0xce) == 0x8a)
     {
         /* 256 range */
         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 256);
         curr_offset = curr_offset + len;
     }
-    else if ((oct & 0xce) == 0x8c)
+    else if ((format & 0xce) == 0x8c)
     {
         /* 128 range */
         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 128);
         curr_offset = curr_offset + len;
     }
-    else if ((oct & 0xce) == 0x8e)
+    else if ((format & 0xce) == 0x8e)
     {
         /* variable bit map */
-        arfcn = ((oct & 0x01) << 9) | (tvb_get_guint8(tvb, curr_offset+1) << 1) | ((tvb_get_guint8(tvb, curr_offset + 2) & 0x80) >> 7);
+        arfcn = ((format & 0x01) << 9) | (tvb_get_guint8(tvb, curr_offset+1) << 1) | ((tvb_get_guint8(tvb, curr_offset + 2) & 0x80) >> 7);
         item = proto_tree_add_text(tree,tvb,curr_offset,len,"List of ARFCNs = %d",arfcn);
         curr_offset = curr_offset + 2;
         bit = 7;
@@ -1002,6 +1068,51 @@ dissect_arfcn_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
     return(curr_offset - offset);
 }
 
+/*
+ * Format ID is in bits:
+ * 128 127 124 123 122 (hf_gsm_a_rr_format_id)
+ */
+static guint16
+dissect_arfcn_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+    guint32    curr_offset;
+    guint8  oct;
+
+    curr_offset = offset;
+
+    oct = tvb_get_guint8(tvb, curr_offset);
+
+    /* FORMAT-ID, Format Identifier (part of octet 3)*/
+    proto_tree_add_item(tree, hf_gsm_a_rr_format_id, tvb, curr_offset, 1, FALSE);
+
+    curr_offset += dissect_arfcn_list_core(tvb, tree, offset, len, add_string, string_len, oct);
+
+    return(curr_offset - offset);
+}
+
+/*
+ * Format ID is in bits:
+ * 128 124 123 122 (hf_gsm_a_rr_format_id2)
+ */
+static guint16
+dissect_arfcn_list2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+    guint32    curr_offset;
+    guint8  oct;
+
+    curr_offset = offset;
+
+    /* Turn bit 127 off, in order to reuse the ARFCN dissection code */
+    oct = tvb_get_guint8(tvb, curr_offset) & 0xbf;
+
+    /* FORMAT-ID, Format Identifier (part of octet 3)*/
+    proto_tree_add_item(tree, hf_gsm_a_rr_format_id2, tvb, curr_offset, 1, FALSE);
+
+    curr_offset += dissect_arfcn_list_core(tvb, tree, offset, len, add_string, string_len, oct);
+
+    return(curr_offset - offset);
+}
+
 guint16
 de_rr_cell_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
@@ -1019,7 +1130,6 @@ de_rr_ba_list_pref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
 
     curr_offset = offset;
     proto_tree_add_item(tree, hf_gsm_a_rr_ba_list_pref_length, tvb, curr_offset, 1, FALSE);
-    curr_offset += 1;
     bit_offset = curr_offset << 3;
     value = tvb_get_bits8(tvb,bit_offset,1);
     bit_offset += 1;
@@ -1042,7 +1152,7 @@ de_rr_ba_list_pref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
         bit_offset += 1;
     }
 
-    curr_offset += len - 1;
+    curr_offset += len;
     return (curr_offset - offset);
 }
 
@@ -1058,7 +1168,6 @@ de_rr_utran_freq_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len
 
     curr_offset = offset;
     proto_tree_add_item(tree, hf_gsm_a_rr_utran_freq_list_length, tvb, curr_offset, 1, FALSE);
-    curr_offset += 1;
     bit_offset = curr_offset << 3;
     value = tvb_get_bits8(tvb,bit_offset,1);
     bit_offset += 1;
@@ -1079,7 +1188,7 @@ de_rr_utran_freq_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len
         bit_offset += 1;
     }
 
-    curr_offset += len - 1;
+    curr_offset += len;
     return (curr_offset - offset);
 }
 
@@ -1133,7 +1242,7 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
         break;
     case 1: /* UTRAN FDD Description */
         bit_offset_sav = bit_offset;
-        item = proto_tree_add_text(tree, tvb, bit_offset>>3, -1, "%s", 
+        item = proto_tree_add_text(tree, tvb, bit_offset>>3, -1, "%s",
                                    gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_FDD_DESC].strptr);
         subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_UTRAN_FDD_DESC]);
         value = tvb_get_bits8(tvb,bit_offset,1);
@@ -1175,10 +1284,10 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
                     nwi = 1;
                     jwi = 0;
                     i = 1;
-   
+
                     while (idx > 0)
                     {
-                        w[i] = tvb_get_bits16(tvb, bit_offset, wsize, FALSE);
+                        w[i] = tvb_get_bits(tvb, bit_offset, wsize, FALSE);
                         bit_offset += wsize;
                         idx -= wsize;
                         if (w[i] == 0)
@@ -1199,13 +1308,13 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
                         bit_offset += idx;
                     }
                     iused = i-1;
-   
+
                     for (i=1; i <= iused; i++)
                     {
                         xdd_cell_info = f_k(i, w, 1024);
-                        proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0, 
+                        proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0,
                                             "Scrambling Code: %d", xdd_cell_info & 0x01FF);
-                        proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0, 
+                        proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0,
                                             "Diversity: %d", (xdd_cell_info >> 9) & 0x01);
                     }
                 }
@@ -1245,7 +1354,7 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
                 proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "Nr of TDD Cells : %d", idx);
                 bit_offset += 5;
                 idx = convert_n_to_q[idx];
-                item2 = proto_tree_add_text(subtree,tvb, bit_offset>>3, (idx>>3)+1, "%s", 
+                item2 = proto_tree_add_text(subtree,tvb, bit_offset>>3, (idx>>3)+1, "%s",
                                             gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_TDD_DESC].strptr);
                 subtree2 = proto_item_add_subtree(item2, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_TDD_CELL_INFORMATION_FIELD]);
                 proto_tree_add_text(subtree2,tvb, bit_offset>>3, (idx>>3)+1, "Field is %d bits long", idx);
@@ -1261,10 +1370,10 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
                     nwi = 1;
                     jwi = 0;
                     i = 1;
-   
+
                     while (idx > 0)
                     {
-                        w[i] = tvb_get_bits16(tvb, bit_offset, wsize, FALSE);
+                        w[i] = tvb_get_bits(tvb, bit_offset, wsize, FALSE);
                         bit_offset += wsize;
                         idx -= wsize;
                         if (w[i] == 0)
@@ -1285,7 +1394,7 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
                         bit_offset += idx;
                     }
                     iused = i-1;
-                                               
+
                     for (i=1; i <= iused; i++)
                     {
                         xdd_cell_info = f_k(i, w, 512);
@@ -1516,13 +1625,12 @@ de_rr_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gch
         else if ((oct8 & 0xc0) == 0x40)
         {
             str = "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8), Subchannel";
-            subchannel = ((oct8 % 0x38)>>3);
+            subchannel = ((oct8 & 0x38)>>3);
         } else {
-            str = "";
-            subchannel = 0;
-            DISSECTOR_ASSERT_NOT_REACHED();
+            str = "Unknown channel information";
+            subchannel = oct8;
         }
-       
+
         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s %d",a_bigbuf,str,subchannel);
     }
@@ -1531,12 +1639,12 @@ de_rr_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gch
     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
 
     curr_offset +=1;
-       
+
     /* Octet 3 */
     oct8 = tvb_get_guint8(tvb, curr_offset);
     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
-       
+
 
     if ((oct8 & 0x10) == 0x10)
     {
@@ -1562,7 +1670,7 @@ de_rr_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gch
         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
     }
-       
+
     curr_offset = curr_offset + 2;
 
     return(curr_offset - offset);
@@ -1634,9 +1742,8 @@ de_rr_ch_dsc2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gc
             str = "TCH/F + FACCH/F and SACCH/M + unidirectional channels at timeslot";
             subchannel = ((oct8 % 0x38)>>3);
         } else {
-            str = "";
-            subchannel = 0;
-            DISSECTOR_ASSERT_NOT_REACHED();
+            str = "Unknown channel information";
+            subchannel = oct8;
         }
         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s %d",a_bigbuf,str,subchannel);
@@ -1646,7 +1753,7 @@ de_rr_ch_dsc2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gc
     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
 
     curr_offset +=1;
-       
+
     /* Octet 3 */
     oct8 = tvb_get_guint8(tvb, curr_offset);
     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
@@ -1676,7 +1783,7 @@ de_rr_ch_dsc2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gc
         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
     }
-       
+
     curr_offset = curr_offset + 2;
 
     return(curr_offset - offset);
@@ -1730,7 +1837,7 @@ de_rr_ch_dsc3(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gc
         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
     }
-       
+
     curr_offset = curr_offset + 2;
 
     return(curr_offset - offset);
@@ -1814,14 +1921,14 @@ de_rr_utran_cm(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar
 {
     guint32 curr_offset;
     tvbuff_t *rrc_irat_ho_info_tvb;
-    static packet_info p_info;
 
     curr_offset = offset;
     if (len)
     {
         rrc_irat_ho_info_tvb = tvb_new_subset(tvb, curr_offset, len, len);
-        if (rrc_irat_ho_info_handle)
-            call_dissector(rrc_irat_ho_info_handle, rrc_irat_ho_info_tvb, &p_info, tree);
+        if (rrc_irat_ho_info_handle && gsm_a_dtap_pinfo)
+                       /* gsm_a_dtap_pinfo MUST be set by any dissector calling de_rr_utran_cm */
+            call_dissector(rrc_irat_ho_info_handle, rrc_irat_ho_info_tvb, gsm_a_dtap_pinfo, tree);
     }
 
     curr_offset += len;
@@ -2065,7 +2172,7 @@ de_rr_ctrl_ch_desc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U
 /* [3] 10.5.2.11a DTM Information Details
  */
 /*
- * [3]  10.5.2.11b     Dynamic ARFCN Mapping   
+ * [3]  10.5.2.11b     Dynamic ARFCN Mapping
  */
 static const value_string gsm_a_rr_gsm_band_vals[] = {
     {  0, "GSM 750"},
@@ -2151,7 +2258,7 @@ de_rr_freq_ch_seq(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_
  */
 /*
  * [3] 10.5.2.13 Frequency List
- * 
+ *
  * Bit Bit Bit Bit Bit format notation
  * 8 7  4 3 2
  * 0 0  X X X bit map 0
@@ -2161,7 +2268,7 @@ de_rr_freq_ch_seq(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_
  * 1 0  1 1 0 128 range
  * 1 0  1 1 1 variable bit map
  */
-/* The mask 0xce (1100 1110) will produce the result 0110 0111*/ 
+/* The mask 0xce (1100 1110) will produce the result 0110 0111*/
 static const value_string gsm_a_rr_freq_list_format_id_vals[] = {
     { 0x00, "bit map 0"},
     { 0x02, "bit map 0"},
@@ -2181,6 +2288,7 @@ static const value_string gsm_a_rr_freq_list_format_id_vals[] = {
     { 0x47, "variable bit map"},
     { 0x00, NULL }
 };
+
 static guint16
 de_rr_freq_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
@@ -2364,7 +2472,7 @@ de_rr_rest_oct_gprs_power_control_parameters(tvbuff_t *tvb, proto_tree *tree, gi
     proto_tree *subtree;
     proto_item *item;
     gint curr_bit_offset;
-       
+
     curr_bit_offset = bit_offset;
 
     item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_GPRS_POWER_CONTROL_PARAMS].strptr);
@@ -2394,7 +2502,7 @@ de_rr_gprs_broadcast_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint
     bit_offset = curr_offset << 3;
 
     bit_offset += de_rr_rest_oct_gprs_cell_options(tvb, tree, bit_offset);
-    bit_offset += de_rr_rest_oct_gprs_power_control_parameters(tvb, tree, bit_offset);  
+    bit_offset += de_rr_rest_oct_gprs_power_control_parameters(tvb, tree, bit_offset);
     curr_offset += len;
 
     return (curr_offset - offset);
@@ -2547,77 +2655,10 @@ static const true_false_string gsm_a_rr_dtx_vals  = {
     "DTX was not used"
 };
 
-static const value_string gsm_a_rr_rxlev_vals [] = {
-    { 0, "< -110 dBm"},
-    { 1, "-110 <= x < -109 dBm"},
-    { 2, "-109 <= x < -108 dBm"},
-    { 3, "-108 <= x < -107 dBm"},
-    { 4, "-107 <= x < -106 dBm"},
-    { 5, "-106 <= x < -105 dBm"},
-    { 6, "-105 <= x < -104 dBm"},
-    { 7, "-104 <= x < -103 dBm"},
-    { 8, "-103 <= x < -102 dBm"},
-    { 9, "-102 <= x < -101 dBm"},
-    {10, "-101 <= x < -100 dBm"},
-    {11, "-100 <= x < -99 dBm"},
-    {12, "-99 <= x < -98 dBm"},
-    {13, "-98 <= x < -97 dBm"},
-    {14, "-97 <= x < -96 dBm"},
-    {15, "-96 <= x < -95 dBm"},
-    {16, "-95 <= x < -94 dBm"},
-    {17, "-94 <= x < -93 dBm"},
-    {18, "-93 <= x < -92 dBm"},
-    {19, "-92 <= x < -91 dBm"},
-    {20, "-91 <= x < -90 dBm"},
-    {21, "-90 <= x < -89 dBm"},
-    {22, "-89 <= x < -88 dBm"},
-    {23, "-88 <= x < -87 dBm"},
-    {24, "-87 <= x < -86 dBm"},
-    {25, "-86 <= x < -85 dBm"},
-    {26, "-85 <= x < -84 dBm"},
-    {27, "-84 <= x < -83 dBm"},
-    {28, "-83 <= x < -82 dBm"},
-    {29, "-82 <= x < -81 dBm"},
-    {30, "-81 <= x < -80 dBm"},
-    {31, "-80 <= x < -79 dBm"},
-    {32, "-79 <= x < -78 dBm"},
-    {33, "-78 <= x < -77 dBm"},
-    {34, "-77 <= x < -76 dBm"},
-    {35, "-76 <= x < -75 dBm"},
-    {36, "-75 <= x < -74 dBm"},
-    {37, "-74 <= x < -73 dBm"},
-    {38, "-73 <= x < -72 dBm"},
-    {39, "-72 <= x < -71 dBm"},
-    {40, "-71 <= x < -70 dBm"},
-    {41, "-70 <= x < -69 dBm"},
-    {42, "-69 <= x < -68 dBm"},
-    {43, "-68 <= x < -67 dBm"},
-    {44, "-67 <= x < -66 dBm"},
-    {45, "-66 <= x < -65 dBm"},
-    {46, "-65 <= x < -64 dBm"},
-    {47, "-64 <= x < -63 dBm"},
-    {48, "-63 <= x < -62 dBm"},
-    {49, "-62 <= x < -61 dBm"},
-    {50, "-61 <= x < -60 dBm"},
-    {51, "-60 <= x < -59 dBm"},
-    {52, "-59 <= x < -58 dBm"},
-    {53, "-58 <= x < -57 dBm"},
-    {54, "-57 <= x < -56 dBm"},
-    {55, "-56 <= x < -55 dBm"},
-    {56, "-55 <= x < -54 dBm"},
-    {57, "-54 <= x < -53 dBm"},
-    {58, "-53 <= x < -52 dBm"},
-    {59, "-52 <= x < -51 dBm"},
-    {60, "-51 <= x < -50 dBm"},
-    {61, "-50 <= x < -49 dBm"},
-    {62, "-49 <= x < -48 dBm"},
-    {63, ">= -48 dBm"},
-    { 0, NULL}
-};
 
 static const true_false_string gsm_a_rr_mv_vals  = {
-    "The measurement results are valid",
-    "The measurement results are not valid"
+    "The measurement results are not valid",
+    "The measurement results are valid"
 };
 
 static const value_string gsm_a_rr_rxqual_vals [] = {
@@ -2671,10 +2712,10 @@ de_rr_meas_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, g
     curr_offset++;
 
     /* 3rd octet */
-    /* 3G-BA-USED */ 
+    /* 3G-BA-USED */
     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_3g_ba_used, tvb, curr_offset<<3, 1, FALSE);
     /* MEAS-VALID */
-    proto_tree_add_item(subtree, hf_gsm_a_rr_meas_valid, tvb, curr_offset, 1, FALSE);  
+    proto_tree_add_item(subtree, hf_gsm_a_rr_meas_valid, tvb, curr_offset, 1, FALSE);
     /* RXLEV-SUB-SERVING-CELL */
     proto_tree_add_item(subtree, hf_gsm_a_rr_rxlev_sub_serv_cell, tvb, curr_offset, 1, FALSE);
 
@@ -2992,7 +3033,7 @@ de_rr_neigh_cell_desc2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint le
     proto_tree_add_bits_item(tree, hf_gsm_a_rr_multiband_reporting, tvb, (curr_offset<<3)+1, 2, FALSE);
     proto_tree_add_bits_item(tree, hf_gsm_a_rr_ba_ind, tvb, (curr_offset<<3)+3, 1, FALSE);
 
-    return dissect_arfcn_list(tvb, tree, offset, 16, add_string, string_len);
+    return dissect_arfcn_list2(tvb, tree, offset, 16, add_string, string_len);
 }
 
 /*
@@ -3260,12 +3301,12 @@ de_rr_packet_ch_desc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len
     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
 
     curr_offset +=1;
-       
+
     /* Octet 3 */
     oct8 = tvb_get_guint8(tvb, curr_offset);
     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
-       
+
     if ((oct8 & 0x10) == 0x10)
     {
         /* Hopping sequence */
@@ -4071,7 +4112,7 @@ de_rr_si2quater_meas_info_utran_fdd_desc(tvbuff_t *tvb, proto_tree *tree, gint b
     gint xdd_cell_info, wsize, nwi, jwi, w[64], i, iused, xdd_indic0;
     guint8 value;
 
-    curr_bit_offset = bit_offset; 
+    curr_bit_offset = bit_offset;
 
     item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_FDD_DESC].strptr);
     subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_UTRAN_FDD_DESC]);
@@ -4113,7 +4154,7 @@ de_rr_si2quater_meas_info_utran_fdd_desc(tvbuff_t *tvb, proto_tree *tree, gint b
 
             while (idx > 0)
             {
-                w[i] = tvb_get_bits16(tvb, curr_bit_offset, wsize, FALSE);
+                w[i] = tvb_get_bits(tvb, curr_bit_offset, wsize, FALSE);
                 curr_bit_offset += wsize;
                 idx -= wsize;
                 if (w[i] == 0)
@@ -4159,7 +4200,7 @@ de_rr_si2quater_meas_info_utran_tdd_desc(tvbuff_t *tvb, proto_tree *tree, gint b
     gint xdd_cell_info, wsize, nwi, jwi, w[64], i, iused, xdd_indic0;
     guint8 value;
 
-    curr_bit_offset = bit_offset; 
+    curr_bit_offset = bit_offset;
 
     item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_TDD_DESC].strptr);
     subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_UTRAN_TDD_DESC]);
@@ -4202,7 +4243,7 @@ de_rr_si2quater_meas_info_utran_tdd_desc(tvbuff_t *tvb, proto_tree *tree, gint b
 
             while (idx > 0)
             {
-                w[i] = tvb_get_bits16(tvb, curr_bit_offset, wsize, FALSE);
+                w[i] = tvb_get_bits(tvb, curr_bit_offset, wsize, FALSE);
                 curr_bit_offset += wsize;
                 idx -= wsize;
                 if (w[i] == 0)
@@ -4362,7 +4403,7 @@ de_rr_bsic_desc(tvbuff_t *tvb, proto_tree *tree, gint bit_offset, rr_rest_octets
     {
         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_frequency_scrolling, tvb, curr_bit_offset, 1, FALSE);
         curr_bit_offset += 1;
-        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bsic, tvb, bit_offset, 6, FALSE);
+        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bsic, tvb, curr_bit_offset, 6, FALSE);
         curr_bit_offset += 6;
         idx -= 1;
     }
@@ -4505,6 +4546,797 @@ de_rr_3g_add_meas_param_desc2(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
     return(curr_bit_offset - bit_offset);
 }
 
+/* Additions in Rel-8 */
+static const true_false_string priority_utran_start = {
+  "This is the first instance of the message",
+  "This is not the first instance of the message"
+};
+
+static const true_false_string priority_utran_stop = {
+  "This is the last instance of the message",
+  "This is not the last instance of the message"
+};
+
+static const true_false_string eutran_ccn_active = {
+  "CCN towards E-UTRAN cells is enabled in the cell",
+  "The broadcast E-UTRAN_CCN_ACTIVE parameter shall apply if applicable. Otherwise, CCN towards E-UTRAN cells is disabled in the cell"
+};
+
+static const value_string gsm_a_rr_pcid_psc_pattern_length[] = {
+  { 0, "1"},
+  { 1, "2"},
+  { 2, "3"},
+  { 3, "4"},
+  { 4, "5"},
+  { 5, "6"},
+  { 6, "7"},
+  { 7, "8"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_eutran_measurement_bandwidth[] = {
+  { 0, "NRB = 6"},
+  { 1, "NRB = 15"},
+  { 2, "NRB = 25"},
+  { 3, "NRB = 50"},
+  { 4, "NRB = 75"},
+  { 5, "NRB = 100"},
+  { 6, "Reserved for future use"},
+  { 7, "Reserved for future use"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_serving_cell_thresh_gsm_low[] = {
+  { 0, "0 dB"},
+  { 1, "2 dB"},
+  { 2, "4 dB"},
+  { 3, "6 dB"},
+  { 4, "8 dB"},
+  { 5, "10 dB"},
+  { 6, "12 dB"},
+  { 7, "14 dB"},
+  { 8, "16 dB"},
+  { 9, "18 dB"},
+  {10, "20 dB"},
+  {11, "22 dB"},
+  {12, "24 dB"},
+  {13, "26 dB"},
+  {14, "28 dB"},
+  {15, "Always allowed"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_serving_cell_thresh_priority_search[] = {
+  { 0, "-98 dBm"},
+  { 1, "-95 dBm"},
+  { 2, "-92 dBm"},
+  { 3, "-89 dBm"},
+  { 4, "-86 dBm"},
+  { 5, "-83 dBm"},
+  { 6, "-80 dBm"},
+  { 7, "-77 dBm"},
+  { 8, "-74 dBm"},
+  { 9, "-71 dBm"},
+  {10, "-68 dBm"},
+  {11, "-65 dBm"},
+  {12, "-62 dBm"},
+  {13, "-59 dBm"},
+  {14, "-56 dBm"},
+  {15, "Always search"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_utran_qrxlevmin[] = {
+  { 0, "-119 dBm"},
+  { 1, "-117 dBm"},
+  { 2, "-115 dBm"},
+  { 3, "-113 dBm"},
+  { 4, "-111 dBm"},
+  { 5, "-109 dBm"},
+  { 6, "-107 dBm"},
+  { 7, "-105 dBm"},
+  { 8, "-103 dBm"},
+  { 9, "-101 dBm"},
+  {10, "-99 dBm"},
+  {11, "-97 dBm"},
+  {12, "-95 dBm"},
+  {13, "-93 dBm"},
+  {14, "-91 dBm"},
+  {15, "-89 dBm"},
+  {16, "-87 dBm"},
+  {17, "-85 dBm"},
+  {18, "-83 dBm"},
+  {19, "-81 dBm"},
+  {20, "-79 dBm"},
+  {21, "-77 dBm"},
+  {22, "-75 dBm"},
+  {23, "-73 dBm"},
+  {24, "-71 dBm"},
+  {25, "-69 dBm"},
+  {26, "-67 dBm"},
+  {27, "-65 dBm"},
+  {28, "-63 dBm"},
+  {29, "-61 dBm"},
+  {30, "-59 dBm"},
+  {31, "-57 dBm"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_thresh_utran_eutran_high_low[] = {
+  { 0, "0 dB"},
+  { 1, "2 dB"},
+  { 2, "4 dB"},
+  { 3, "6 dB"},
+  { 4, "8 dB"},
+  { 5, "10 dB"},
+  { 6, "12 dB"},
+  { 7, "14 dB"},
+  { 8, "16 dB"},
+  { 9, "18 dB"},
+  {10, "20 dB"},
+  {11, "22 dB"},
+  {12, "24 dB"},
+  {13, "26 dB"},
+  {14, "28 dB"},
+  {15, "30 dB"},
+  {16, "32 dB"},
+  {17, "34 dB"},
+  {18, "36 dB"},
+  {19, "38 dB"},
+  {20, "40 dB"},
+  {21, "42 dB"},
+  {22, "44 dB"},
+  {23, "46 dB"},
+  {24, "48 dB"},
+  {25, "50 dB"},
+  {26, "52 dB"},
+  {27, "54 dB"},
+  {28, "56 dB"},
+  {29, "58 dB"},
+  {30, "60 dB"},
+  {31, "62 dB"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_eutran_qrxlevmin[] = {
+  { 0, "-140 dBm"},
+  { 1, "-138 dBm"},
+  { 2, "-136 dBm"},
+  { 3, "-134 dBm"},
+  { 4, "-132 dBm"},
+  { 5, "-130 dBm"},
+  { 6, "-128 dBm"},
+  { 7, "-126 dBm"},
+  { 8, "-124 dBm"},
+  { 9, "-122 dBm"},
+  {10, "-120 dBm"},
+  {11, "-118 dBm"},
+  {12, "-116 dBm"},
+  {13, "-114 dBm"},
+  {14, "-112 dBm"},
+  {15, "-110 dBm"},
+  {16, "-108 dBm"},
+  {17, "-106 dBm"},
+  {18, "-104 dBm"},
+  {19, "-102 dBm"},
+  {20, "-100 dBm"},
+  {21, "-98 dBm"},
+  {22, "-96 dBm"},
+  {23, "-94 dBm"},
+  {24, "-92 dBm"},
+  {25, "-90 dBm"},
+  {26, "-88 dBm"},
+  {27, "-86 dBm"},
+  {28, "-84 dBm"},
+  {29, "-82 dBm"},
+  {30, "-80 dBm"},
+  {31, "-78 dBm"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_serving_cell_priority_param_h_prio[] = {
+  { 0, "disabled"},
+  { 1, "5 dB"},
+  { 2, "4 dB"},
+  { 3, "3 dB"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_serving_cell_priority_param_t_reselection[] = {
+  { 0, "5 s"},
+  { 1, "10 s"},
+  { 2, "15 s"},
+  { 3, "20 s"},
+  { 0, NULL }
+};
+
+static const value_string gsm_a_rr_qsearch_c_eutran_initial[] = {
+  { 0, "search if signal is below -98 dBm"},
+  { 1, "search if signal is below -94 dBm"},
+  { 2, "search if signal is below -90 dBm"},
+  { 3, "search if signal is below -86 dBm"},
+  { 4, "search if signal is below -82 dBm"},
+  { 5, "search if signal is below -78 dBm"},
+  { 6, "search if signal is below -74 dBm"},
+  { 7, "always search"},
+  { 8, "search is signal is above -78 dBm"},
+  { 9, "search is signal is above -74 dBm"},
+  {10, "search is signal is above -70 dBm"},
+  {11, "search is signal is above -66 dBm"},
+  {12, "search is signal is above -62 dBm"},
+  {13, "search is signal is above -58 dBm"},
+  {14, "search is signal is above -54 dBm"},
+  {15, "never search"},
+  { 0, NULL }
+};
+
+static const true_false_string gsm_a_rr_pcid_pattern_sense = {
+  "The group of identified cells are the one not belonging to the PCID_BITMAP_GROUP",
+  "The group of identified cells are the one identified by the PCID_BITMAP_GROUP"
+};
+
+static gint
+de_rr_3g_priority_param_desc(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_3G_PRIORITY_PARAM_DESC].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_3G_PRIORITY_PARAM_DESC]);
+
+  proto_tree_add_bits_item(subtree, hf_gsm_a_rr_3g_priority_param_desc_utran_start, tvb, curr_bit_offset, 1, FALSE);
+  curr_bit_offset += 1;
+  proto_tree_add_bits_item(subtree, hf_gsm_a_rr_3g_priority_param_desc_utran_stop, tvb, curr_bit_offset, 1, FALSE);
+  curr_bit_offset += 1;
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  if (value)
+  {
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_3g_priority_param_desc_default_utran_prio, tvb, curr_bit_offset, 3, FALSE);
+    curr_bit_offset += 3;
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_3g_priority_param_desc_default_threshold_utran, tvb, curr_bit_offset, 5, FALSE);
+    curr_bit_offset += 5;
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_3g_priority_param_desc_default_utran_qrxlevmin, tvb, curr_bit_offset, 5, FALSE);
+    curr_bit_offset += 5;
+  }
+  /* Repeated UTRAN Priority Parameters */
+  while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    proto_tree *subtree_rep_utran_prio;
+    proto_item *item_rep_utran_prio;
+    gint rep_utran_prio_bit_offset = curr_bit_offset;
+       
+    item_rep_utran_prio = proto_tree_add_text(subtree, tvb, curr_bit_offset>>3, 1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_PRIO_PARAM].strptr);
+    subtree_rep_utran_prio = proto_item_add_subtree(item_rep_utran_prio, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_UTRAN_PRIO_PARAM]);
+
+    while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+    {
+      proto_tree_add_bits_item(subtree_rep_utran_prio, hf_gsm_a_rr_utran_frequency_index, tvb, curr_bit_offset, 5, FALSE);
+      curr_bit_offset += 5;
+    }
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree_rep_utran_prio, hf_gsm_a_rr_utran_priority, tvb, curr_bit_offset, 3, FALSE);
+      curr_bit_offset += 3;
+    }
+    proto_tree_add_bits_item(subtree_rep_utran_prio, hf_gsm_a_rr_thresh_utran_high, tvb, curr_bit_offset, 5, FALSE);
+    curr_bit_offset += 5;
+    
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree_rep_utran_prio, hf_gsm_a_rr_thresh_utran_low, tvb, curr_bit_offset, 5, FALSE);
+      curr_bit_offset += 5;
+    }
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree_rep_utran_prio, hf_gsm_a_rr_utran_qrxlevmin, tvb, curr_bit_offset, 5, FALSE);
+      curr_bit_offset += 5;
+    }
+       proto_item_set_len(item_rep_utran_prio,((curr_bit_offset-rep_utran_prio_bit_offset)>>3)+1);
+  }
+  
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+
+static gint
+de_rr_eutran_neighbour_cells(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_EUTRAN_NEIGHBOUR_CELLS].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_EUTRAN_NEIGHBOUR_CELLS]);
+  
+  while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_earfcn, tvb, curr_bit_offset, 16, FALSE);
+    curr_bit_offset += 16;
+    
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_measurement_bandwidth, tvb, curr_bit_offset, 3, FALSE);
+      curr_bit_offset += 3;
+    }
+  }
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  if (value)
+  {
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_priority, tvb, curr_bit_offset, 3, FALSE);
+    curr_bit_offset += 3;
+  }
+  proto_tree_add_bits_item(subtree, hf_gsm_a_rr_thresh_eutran_high, tvb, curr_bit_offset, 5, FALSE);
+  curr_bit_offset += 5;
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  if (value)
+  {
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_thresh_eutran_low, tvb, curr_bit_offset, 5, FALSE);
+    curr_bit_offset += 5;
+  }
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  if (value)
+  {
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_qrxlevmin, tvb, curr_bit_offset, 5, FALSE);
+    curr_bit_offset += 5;
+  }
+  
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+
+static gint
+de_rr_eutran_pcid(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  gint curr_bit_offset = bit_offset;
+  guint8 value;
+  proto_item *item;
+
+  while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    proto_tree_add_bits_item(tree, hf_gsm_a_rr_eutran_pcid, tvb, curr_bit_offset, 9, FALSE);
+    curr_bit_offset += 9;
+  }
+  
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  if (value)
+  {
+    gint i;
+    guint8 bitmap = tvb_get_bits8(tvb,curr_bit_offset,6);
+    item = proto_tree_add_bits_item(tree, hf_gsm_a_rr_eutran_pcid_bitmap_group, tvb, curr_bit_offset, 6, FALSE);
+    if (bitmap > 0)
+    {
+      proto_item_append_text(item, ": Cells IDs addressed by the bitmap:");
+    }
+    for (i = 0; i < 6; i++)
+    {
+      if ((1 << i) & bitmap)
+      {
+        if ( i != 0)
+        {
+          proto_item_append_text(item, ",");
+        }
+        proto_item_append_text(item, " %d to %d",i*84, (i+1)*84 - 1);
+      }
+    }
+    curr_bit_offset += 6;
+  }
+  while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    gint pcid_pattern_length;
+    gint pcid_pattern;
+    gint pattern_lower_bound, pattern_upper_bound;
+    gint i;
+
+    pcid_pattern_length = tvb_get_bits8(tvb,curr_bit_offset,3) + 1;
+    proto_tree_add_bits_item(tree, hf_gsm_a_rr_eutran_pcid_pattern_length, tvb, curr_bit_offset, 3, FALSE);
+    curr_bit_offset += 3;
+    pcid_pattern = tvb_get_bits8(tvb,curr_bit_offset, pcid_pattern_length);
+
+    item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, 1, "%s = PCID_Pattern: %d", 
+                               decode_bits_in_field(curr_bit_offset,pcid_pattern_length, pcid_pattern), 
+                               pcid_pattern);
+
+    pattern_lower_bound = pcid_pattern << (9 - pcid_pattern_length);
+    pattern_upper_bound = pattern_lower_bound;
+    for (i = 0; i < (9-pcid_pattern_length); i++)
+    {
+      pattern_upper_bound |= 1 << i;
+    }
+    proto_item_append_text(item, ": Cells IDs addressed by the pattern: %d to %d", pattern_lower_bound, pattern_upper_bound);
+
+    curr_bit_offset += pcid_pattern_length;
+    proto_tree_add_bits_item(tree, hf_gsm_a_rr_eutran_pcid_pattern_sense, tvb, curr_bit_offset, 1, FALSE);
+    curr_bit_offset += 1;
+  }
+
+  return(curr_bit_offset - bit_offset);
+}
+
+static gint
+de_rr_eutran_not_allowed_cells(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_EUTRAN_NOT_ALLOWED_CELLS].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_EUTRAN_NOT_ALLOWED_CELLS]);
+  
+  /* dissect PCID group */
+  curr_bit_offset += de_rr_eutran_pcid(tvb, subtree, curr_bit_offset);
+
+  while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_frequency_index, tvb, curr_bit_offset, 3, FALSE);
+    curr_bit_offset += 3;
+  }
+
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+
+static gint
+de_rr_eutran_pcid_to_ta_mapping(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_EUTRAN_PCID_TO_TA_MAPPING].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_EUTRAN_PCID_TO_TA_MAPPING]);
+  
+  while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    /* dissect PCID group */
+    curr_bit_offset += de_rr_eutran_pcid(tvb, subtree, curr_bit_offset);
+  }
+
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+
+static gint
+de_rr_eutran_param_desc(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_EUTRAN_PARAM_DESC].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_EUTRAN_PARAM_DESC]);
+
+  proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_ccn_active, tvb, curr_bit_offset, 1, FALSE);
+  curr_bit_offset += 1;
+  proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_start, tvb, curr_bit_offset, 1, FALSE);
+  curr_bit_offset += 1;
+  proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_stop, tvb, curr_bit_offset, 1, FALSE);
+  curr_bit_offset += 1;
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  if (value)
+  {
+    /* E-UTRAN Measurement Parameters Description */
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_qsearch_c_eutran_initial, tvb, curr_bit_offset, 4, FALSE);
+    curr_bit_offset += 4;
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_rep_quant, tvb, curr_bit_offset, 1, FALSE);
+    curr_bit_offset += 1;
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_multirat_reporting, tvb, curr_bit_offset, 2, FALSE);
+      curr_bit_offset += 2;
+    }
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (!value)
+    {
+      value = tvb_get_bits8(tvb,curr_bit_offset,1);
+      curr_bit_offset += 1;
+      if (value)
+      {
+        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_fdd_reporting_threshold, tvb, curr_bit_offset, 3, FALSE);
+        curr_bit_offset += 3;
+        value = tvb_get_bits8(tvb,curr_bit_offset,1);
+        curr_bit_offset += 1;
+        if (value)
+        {
+          proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_fdd_reporting_threshold_2, tvb, curr_bit_offset, 6, FALSE);
+          curr_bit_offset += 6;
+        }
+      }
+      value = tvb_get_bits8(tvb,curr_bit_offset,1);
+      curr_bit_offset += 1;
+      if (value)
+      {
+        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_tdd_reporting_threshold, tvb, curr_bit_offset, 3, FALSE);
+        curr_bit_offset += 3;
+        value = tvb_get_bits8(tvb,curr_bit_offset,1);
+        curr_bit_offset += 1;
+        if (value)
+        {
+          proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_tdd_reporting_threshold_2, tvb, curr_bit_offset, 6, FALSE);
+          curr_bit_offset += 6;
+        }
+      }
+    }
+    else
+    {
+      value = tvb_get_bits8(tvb,curr_bit_offset,1);
+      curr_bit_offset += 1;
+      if (value)
+      {
+        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_fdd_measurement_report_offset, tvb, curr_bit_offset, 6, FALSE);
+        curr_bit_offset += 6;
+        value = tvb_get_bits8(tvb,curr_bit_offset,1);
+        curr_bit_offset += 1;
+        if (value)
+        {
+          proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_fdd_reporting_threshold_2, tvb, curr_bit_offset, 6, FALSE);
+          curr_bit_offset += 6;
+        }
+      }
+      value = tvb_get_bits8(tvb,curr_bit_offset,1);
+      curr_bit_offset += 1;
+      if (value)
+      {
+        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_tdd_measurement_report_offset, tvb, curr_bit_offset, 6, FALSE);
+        curr_bit_offset += 6;
+        value = tvb_get_bits8(tvb,curr_bit_offset,1);
+        curr_bit_offset += 1;
+        if (value)
+        {
+          proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_tdd_reporting_threshold_2, tvb, curr_bit_offset, 6, FALSE);
+          curr_bit_offset += 6;
+        }
+      }
+    }
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_reporting_granularity, tvb, curr_bit_offset, 1, FALSE);
+    curr_bit_offset += 1;
+  }
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  if (value)
+  {
+    /* GPRS E-UTRAN Measurement Parameters Description */
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_qsearch_p_eutran, tvb, curr_bit_offset, 4, FALSE);
+    curr_bit_offset += 4;
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_rep_quant, tvb, curr_bit_offset, 1, FALSE);
+    curr_bit_offset += 1;
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_multirat_reporting, tvb, curr_bit_offset, 2, FALSE);
+      curr_bit_offset += 2;
+    }
+    value = tvb_get_bits8(tvb,curr_bit_offset,1);
+    curr_bit_offset += 1;
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_fdd_reporting_threshold, tvb, curr_bit_offset, 3, FALSE);
+      curr_bit_offset += 3;
+      value = tvb_get_bits8(tvb,curr_bit_offset,1);
+      curr_bit_offset += 1;
+      if (value)
+      {
+        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_fdd_reporting_threshold_2, tvb, curr_bit_offset, 6, FALSE);
+        curr_bit_offset += 6;
+      }
+    }
+    if (value)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_tdd_reporting_threshold, tvb, curr_bit_offset, 3, FALSE);
+      curr_bit_offset += 3;
+      value = tvb_get_bits8(tvb,curr_bit_offset,1);
+      curr_bit_offset += 1;
+      if (value)
+      {
+        proto_tree_add_bits_item(subtree, hf_gsm_a_rr_eutran_tdd_reporting_threshold_2, tvb, curr_bit_offset, 6, FALSE);
+        curr_bit_offset += 6;
+      }
+    }
+  }
+
+  /* Repeated E-UTRAN Neighbour Cells */
+  while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    curr_bit_offset += de_rr_eutran_neighbour_cells(tvb, subtree, curr_bit_offset);
+  }
+
+  /* Repeated E-UTRAN Not Allowed Cells */
+  while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    curr_bit_offset += de_rr_eutran_not_allowed_cells(tvb, subtree, curr_bit_offset);
+  }
+
+  /* Repeated E-UTRAN PCID to TA mapping */
+  while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    curr_bit_offset += de_rr_eutran_pcid_to_ta_mapping(tvb, subtree, curr_bit_offset);
+  }
+
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+
+static gint
+de_rr_priority_and_eutran_param_desc(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_PRIORITY_AND_EUTRAN_PARAM_DESC].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_PRIORITY_AND_EUTRAN_PARAM_DESC]);
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+
+  /* Serving Cell Priority Parameters Description */
+  if (value)
+  {
+    proto_tree *subtree_serv;
+    proto_item *item_serv;
+    gint serv_bit_offset = curr_bit_offset;
+         
+    item_serv = proto_tree_add_text(subtree, tvb, curr_bit_offset>>3, ((curr_bit_offset+15)>>3)-(curr_bit_offset>>3) + 1 , "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_SERVING_CELL_PRIORITY_PARAM_DESC].strptr);
+    subtree_serv = proto_item_add_subtree(item_serv, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_SERVING_CELL_PRIORITY_PARAM_DESC]);
+
+    proto_tree_add_bits_item(subtree_serv, hf_gsm_a_rr_serving_cell_priority_param_geran_priority, tvb, curr_bit_offset, 3, FALSE);
+    curr_bit_offset += 3;
+    proto_tree_add_bits_item(subtree_serv, hf_gsm_a_rr_serving_cell_priority_param_thresh_prio_search, tvb, curr_bit_offset, 4, FALSE);
+    curr_bit_offset += 4;
+    proto_tree_add_bits_item(subtree_serv, hf_gsm_a_rr_serving_cell_priority_param_thresh_gsm_low, tvb, curr_bit_offset, 4, FALSE);
+    curr_bit_offset += 4;
+    proto_tree_add_bits_item(subtree_serv, hf_gsm_a_rr_serving_cell_priority_param_h_prio, tvb, curr_bit_offset, 2, FALSE);
+    curr_bit_offset += 2;
+    proto_tree_add_bits_item(subtree_serv, hf_gsm_a_rr_serving_cell_priority_param_t_reselection, tvb, curr_bit_offset, 2, FALSE);
+    curr_bit_offset += 2;
+    proto_item_set_len(item_serv,((curr_bit_offset-serv_bit_offset)>>3)+1);
+  }
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  /* 3G Priority Parameters Description */
+  if (value)
+  {
+    curr_bit_offset += de_rr_3g_priority_param_desc(tvb, subtree, curr_bit_offset);
+  }
+  value = tvb_get_bits8(tvb,curr_bit_offset,1);
+  curr_bit_offset += 1;
+  /* E-UTRAN Parameters Description */
+  if (value)
+  {
+    curr_bit_offset += de_rr_eutran_param_desc(tvb, subtree, curr_bit_offset);
+  }
+  
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+                      
+static gint
+de_rr_3g_csg_desc(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_3G_CSG_DESC].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_3G_CSG_DESC]);
+
+  while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    /* CSG_PSC_SPLIT struct */
+    while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_psc, tvb, curr_bit_offset, 9, FALSE);
+      curr_bit_offset += 9;
+    }
+    while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+    {
+      gint psc_pattern_length;
+      gint psc_pattern;
+      
+      psc_pattern_length = tvb_get_bits8(tvb,curr_bit_offset,3) + 1;
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_utran_psc_pattern_length, tvb, curr_bit_offset, 3, FALSE);
+      curr_bit_offset += 3;
+      psc_pattern = tvb_get_bits8(tvb,curr_bit_offset, psc_pattern_length);
+
+      item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, 1, "%s = PSC_Pattern: %d", 
+                                 decode_bits_in_field(curr_bit_offset,psc_pattern_length, psc_pattern), 
+                                 psc_pattern);
+
+      curr_bit_offset += psc_pattern_length;
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_utran_psc_pattern_sense, tvb, curr_bit_offset, 1, FALSE);
+      curr_bit_offset += 1;
+    }
+    
+    while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_utran_frequency_index, tvb, curr_bit_offset, 5, FALSE);
+      curr_bit_offset += 5;
+    }
+  }
+
+  while((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    /* CSG_FDD_UARFCN */
+    value = tvb_get_bits8(tvb,bit_offset,1);
+    bit_offset += 1;
+    if (!value)
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_utran_csg_fdd_uarfcn, tvb, curr_bit_offset, 14, FALSE);
+      curr_bit_offset += 14;
+    }
+    else
+    {
+      proto_tree_add_bits_item(subtree, hf_gsm_a_rr_utran_csg_tdd_uarfcn, tvb, curr_bit_offset, 14, FALSE);
+      curr_bit_offset += 14;
+    }
+  }
+
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+
+static gint
+de_rr_eutran_csg_desc(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
+{ 
+  proto_tree *subtree;
+  proto_item *item;
+  gint curr_bit_offset;
+  guint8 value;
+  
+  curr_bit_offset = bit_offset;
+  item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_EUTRAN_CSG_DESC].strptr);
+  subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_EUTRAN_CSG_DESC]);
+
+  while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    /* dissect PCID group */
+    curr_bit_offset += de_rr_eutran_pcid(tvb, subtree, curr_bit_offset);
+  }
+
+  while ((value = tvb_get_bits8(tvb,curr_bit_offset++,1)) == 1)
+  {
+    proto_tree_add_bits_item(subtree, hf_gsm_a_rr_csg_earfcn, tvb, curr_bit_offset, 16, FALSE);
+    curr_bit_offset += 16;
+  }
+
+  proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
+  
+  return(curr_bit_offset - bit_offset);
+}
+
 static guint16
 de_rr_si2quater_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
@@ -4801,9 +5633,36 @@ de_rr_si2quater_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint
                                 proto_tree_add_bits_item(subtree, hf_gsm_a_rr_810_reporting_threshold, tvb, bit_offset, 3, FALSE);
                                 bit_offset += 3;
                             }
+                            /* Additions in Rel-8 */
+                            if (((curr_offset + len)<<3) - bit_offset > 0)
+                            {
+                              /* There is still room left in the Rest Octets IE */
+                              if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
+                              { /* Additions in Rel-8 */
+                                bit_offset += 1;
+                                value = tvb_get_bits8(tvb,bit_offset,1);
+                                bit_offset += 1;
+                                if (value)
+                                {
+                                  bit_offset += de_rr_priority_and_eutran_param_desc(tvb, subtree, bit_offset);
+                                }
+                                value = tvb_get_bits8(tvb,bit_offset,1);
+                                bit_offset += 1;
+                                if (value)
+                                {
+                                  bit_offset += de_rr_3g_csg_desc(tvb, subtree, bit_offset);
+                                }
+                                value = tvb_get_bits8(tvb,bit_offset,1);
+                                bit_offset += 1;
+                                if (value)
+                                {
+                                  bit_offset += de_rr_eutran_csg_desc(tvb, subtree, bit_offset);
+                                }
+                              }
+                            }
                         }
                         else
-                            bit_offset += 1;
+                          bit_offset += 1;
                     }
                 }
                 else
@@ -5082,7 +5941,7 @@ de_rr_si3_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_si13alt_position, tvb, bit_offset, 1, FALSE);
         bit_offset += 1;
     }
-   
+
     curr_offset = curr_offset + len;
 
     return curr_offset-offset;
@@ -5894,7 +6753,7 @@ de_rr_si13_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len,
             proto_tree_add_bits_item(subtree, hf_gsm_a_rr_network_control_order, tvb, bit_offset, 2, FALSE);
             bit_offset += 2;
             bit_offset += de_rr_rest_oct_gprs_cell_options(tvb, subtree, bit_offset);
-            bit_offset += de_rr_rest_oct_gprs_power_control_parameters(tvb, subtree, bit_offset);  
+            bit_offset += de_rr_rest_oct_gprs_power_control_parameters(tvb, subtree, bit_offset);
         }
         if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
         { /* Additions in release 99 */
@@ -6193,7 +7052,7 @@ de_rr_ext_meas_freq_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint
    curr_offset = offset;
 
    proto_tree_add_bits_item(tree, hf_gsm_a_rr_seq_code, tvb,(curr_offset<<3)+3, 1, FALSE);
-   
+
    return dissect_arfcn_list(tvb, tree, offset, 16, add_string, string_len);
 }
 
@@ -6226,9 +7085,52 @@ de_rr_sus_cau(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gc
 }
 /*
  * [3] 10.5.2.48 APDU ID
+ */
+static const value_string gsm_a_rr_apdu_id_vals[] = {
+    { 0, "RRLP (GSM 04.31) LCS" },
+    { 0, NULL },
+};
+static guint16
+de_rr_apdu_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
+{
+    proto_tree_add_item(tree, hf_gsm_a_rr_apdu_id, tvb, offset, 1, FALSE);
+
+    return 0;
+}
+
+/*
  * [3] 10.5.2.49 APDU Flags
+ */
+static const value_string gsm_a_rr_apdu_flags_vals[] = {
+    { 1, "Last or only segment" },
+    { 2, "First or only segment" },
+    { 0, NULL },
+};
+static guint16
+de_rr_apdu_flags(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
+{
+    proto_tree_add_item(tree, hf_gsm_a_rr_apdu_flags, tvb, offset, 1, FALSE);
+
+    return 1;
+}
+
+/*
  * [3] 10.5.2.50 APDU Data
  */
+static guint16
+de_rr_apdu_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+    tvbuff_t *sub_tvb;
+
+    sub_tvb = tvb_new_subset(tvb, offset, len, len);
+
+    /* gsm_a_dtap_pinfo MUST be set by any dissector calling de_rr_apdu_data      */
+    /* XXX: test added to match de_rr_ho_to_utran_cmd & etc (and to fix a crash)  */
+    if (rrlp_dissector && gsm_a_dtap_pinfo)
+        call_dissector(rrlp_dissector, sub_tvb, gsm_a_dtap_pinfo, tree);
+
+    return len;
+}
 
 /*
  * [3] 10.5.2.51 Handover To UTRAN Command
@@ -6238,14 +7140,14 @@ de_rr_ho_to_utran_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len
 {
     guint32 curr_offset;
     tvbuff_t *rrc_irat_ho_to_utran_cmd_tvb;
-    static packet_info p_info;
 
     curr_offset = offset;
     if (len)
     {
         rrc_irat_ho_to_utran_cmd_tvb = tvb_new_subset(tvb, curr_offset, len, len);
-        if (rrc_irat_ho_to_utran_cmd_handle)
-            call_dissector(rrc_irat_ho_to_utran_cmd_handle, rrc_irat_ho_to_utran_cmd_tvb, &p_info, tree);
+        if (rrc_irat_ho_to_utran_cmd_handle && gsm_a_dtap_pinfo)
+            /* gsm_a_dtap_pinfo MUST be set by any dissector calling de_rr_ho_to_utran_cmd */
+            call_dissector(rrc_irat_ho_to_utran_cmd_handle, rrc_irat_ho_to_utran_cmd_tvb, gsm_a_dtap_pinfo, tree);
     }
 
     curr_offset += len;
@@ -6468,9 +7370,9 @@ guint16 (*rr_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint
     de_rr_ext_meas_result,                     /* [3] 10.5.2.45 Extended Measurement Results           */
     de_rr_ext_meas_freq_list,                  /* [3] 10.5.2.46 Extended Measurement Frequency List    */
     de_rr_sus_cau,                             /* [3] 10.5.2.47 Suspension Cause                       */
-/* [3] 10.5.2.48 APDU ID
- * [3] 10.5.2.49 APDU Flags
- * [3] 10.5.2.50 APDU Data */
+    de_rr_apdu_id,                             /* [3] 10.5.2.48 APDU ID                                */
+    de_rr_apdu_flags,                          /* [3] 10.5.2.49 APDU Flags                             */
   de_rr_apdu_data,                           /* [3] 10.5.2.50 APDU Data */
     de_rr_ho_to_utran_cmd,                     /* [3] 10.5.2.51 Handover To UTRAN Command              */
 /* [3] 10.5.2.52 Handover To cdma2000 Command
  * [3] 10.5.2.53 (void)
@@ -6785,7 +7687,7 @@ dtap_rr_cip_mode_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
 /*
  * 9.1.10 Ciphering Mode Complete
  */
-static void
+void
 dtap_rr_cip_mode_cpte(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
 {
     guint32    curr_offset;
@@ -7193,7 +8095,7 @@ dtap_rr_ho_fail(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
 }
 
 /*
- * 9.1.18 Immediate assignment
+ * 9.1.18 Immediate assignment See 3GPP TS 44.018
  */
 static void
 dtap_rr_imm_ass(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
@@ -7522,7 +8424,7 @@ dtap_rr_paging_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
     curr_offset++;
     curr_len--;
 
-    if (curr_len <= 0) return;
+    if ((signed)curr_len <= 0) return;
 
     ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MS_CM_2, NULL);
 
@@ -7865,6 +8767,24 @@ dtap_rr_ext_meas_report(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
     ELEM_MAND_V(GSM_A_PDU_TYPE_RR, DE_RR_EXT_MEAS_RESULT);
 }
 
+/*
+ * 9.1.53 Application Information
+ */
+static void
+dtap_rr_app_inf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
+{
+    guint32    curr_offset;
+    guint32    consumed;
+    guint      curr_len;
+
+    curr_offset = offset;
+    curr_len = len;
+
+    ELEM_MAND_V(GSM_A_PDU_TYPE_RR, DE_RR_APDU_ID);
+    ELEM_MAND_V(GSM_A_PDU_TYPE_RR, DE_RR_APDU_FLAGS);
+    ELEM_MAND_LV(GSM_A_PDU_TYPE_RR, DE_RR_APDU_DATA, NULL);
+}
+
 /*
  * [4] 9.1.54 Measurement Information
  */
@@ -7884,7 +8804,7 @@ static const value_string gsm_a_rr_3g_wait_vals[] = {
 static void
 sacch_rr_meas_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_)
 {
-    proto_tree *subtree, *subtree2;
+    proto_tree *subtree = NULL, *subtree2 = NULL;
     proto_item *item, *item2;
     guint32 curr_offset;
     gint bit_offset, bit_offset_sav, bit_offset_sav2;
@@ -8139,6 +9059,33 @@ sacch_rr_meas_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U
                         proto_tree_add_bits_item(tree, hf_gsm_a_rr_810_reporting_threshold, tvb, bit_offset, 3, FALSE);
                         bit_offset += 3;
                     }
+                    /* Additions in Rel-8 */
+                    if (((curr_offset + len)<<3) - bit_offset > 0)
+                    {
+                      /* There is still room left in the Rest Octets IE */
+                      if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
+                      { /* Additions in Rel-8 */
+                        bit_offset += 1;
+                        value = tvb_get_bits8(tvb,bit_offset,1);
+                        bit_offset += 1;
+                        if (value)
+                        {
+                          bit_offset += de_rr_priority_and_eutran_param_desc(tvb, subtree, bit_offset);
+                        }
+                        value = tvb_get_bits8(tvb,bit_offset,1);
+                        bit_offset += 1;
+                        if (value)
+                        {
+                          bit_offset += de_rr_3g_csg_desc(tvb, subtree, bit_offset);
+                        }
+                        value = tvb_get_bits8(tvb,bit_offset,1);
+                        bit_offset += 1;
+                        if (value)
+                        {
+                          bit_offset += de_rr_eutran_csg_desc(tvb, subtree, bit_offset);
+                        }
+                      }
+                    }
                 }
                 else
                     bit_offset += 1;
@@ -8210,7 +9157,6 @@ static const value_string gsm_a_rr_cv_bep_vals[] = {
     {  0, NULL }
 };
 
-
 static void
 sacch_rr_enh_meas_report(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
 {
@@ -8388,19 +9334,21 @@ static void (*dtap_msg_rr_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset
 
     NULL,                      /* UTRAN Classmark Change/Handover To UTRAN Command */  /* spec conflict */
 
-    NULL,                      /* Application Information */
+    dtap_rr_app_inf,           /* Application Information */
 
     NULL,                      /* NONE */
 };
 
-void get_rr_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf_idx, msg_fcn *msg_fcn)
+void get_rr_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf_idx, msg_fcn *msg_fcn_p)
 {
     gint                       idx;
 
     *msg_str = match_strval_idx((guint32) (oct & DTAP_RR_IEI_MASK), gsm_a_dtap_msg_rr_strings, &idx);
-    *ett_tree = ett_gsm_dtap_msg_rr[idx]; // -1 !!
     *hf_idx = hf_gsm_a_dtap_msg_rr_type;
-    *msg_fcn = dtap_msg_rr_fcn[idx];      // -1 !!
+    if (*msg_str != NULL) {
+        *ett_tree = ett_gsm_dtap_msg_rr[idx];
+        *msg_fcn_p  = dtap_msg_rr_fcn[idx];
+    }
 
     return;
 }
@@ -8417,7 +9365,7 @@ dissect_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     static gsm_a_tap_rec_t     *tap_p;
     static guint               tap_current=0;
 
-    void                       (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
+    void                       (*msg_fcn_p)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
     guint8                     oct;
     guint8                     pd;
     guint32                    offset, saved_offset;
@@ -8448,9 +9396,7 @@ dissect_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         return;
     }
 
-    if (check_col(pinfo->cinfo, COL_INFO)){
-        col_append_str(pinfo->cinfo, COL_INFO, "(CCCH) ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, "(CCCH) ");
     /*
      * set tap record pointer
      */
@@ -8488,18 +9434,16 @@ dissect_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     msg_str = NULL;
     ett_tree = -1;
     hf_idx = -1;
-    msg_fcn = NULL;
+    msg_fcn_p = NULL;
     nsd = FALSE;
-    if (check_col(pinfo->cinfo, COL_INFO)){
-        col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ",val_to_str(pd,gsm_a_pd_short_str_vals,"Unknown (%u)"));
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ",val_to_str(pd,gsm_a_pd_short_str_vals,"Unknown (%u)"));
 
     /*
      * octet 1
      */
     switch (pd){
     case 6:
-        get_rr_msg_params(oct, &msg_str, &ett_tree, &hf_idx, &msg_fcn);
+        get_rr_msg_params(oct, &msg_str, &ett_tree, &hf_idx, &msg_fcn_p);
         break;
 
     default:
@@ -8523,9 +9467,7 @@ dissect_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         ccch_tree = proto_item_add_subtree(ccch_item, ett_tree);
     }
 
-    if (check_col(pinfo->cinfo, COL_INFO)){
-        col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
 
     /* back to the begining */
     saved_offset = offset;
@@ -8543,6 +9485,7 @@ dissect_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     ELEM_MAND_V(GSM_A_PDU_TYPE_RR, DE_RR_L2_PSEUDO_LEN);
     tree = saved_tree;
     offset = saved_offset;
+    len = curr_len;
 
     oct_1_item =
        proto_tree_add_text(ccch_tree,
@@ -8609,17 +9552,17 @@ dissect_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     if (msg_str == NULL)
         return;
 
-    if ((len - offset) <= 0)
+    if (offset >= len)
         return;
 
     /*
      * decode elements
      */
-    if (msg_fcn == NULL){
+    if (msg_fcn_p == NULL){
         proto_tree_add_text(ccch_tree, tvb, offset, len - offset,
                             "Message Elements");
     }else{
-        (*msg_fcn)(tvb, ccch_tree, offset, len - offset);
+        (*msg_fcn_p)(tvb, ccch_tree, offset, len - offset);
     }
 }
 
@@ -8651,14 +9594,16 @@ static void (*sacch_msg_rr_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offse
     NULL,                      /* NONE */
 };
 
-void get_rr_short_pd_msg_params(guint8 mess_type, const gchar **msg_str, int *ett_tree, int *hf_idx, msg_fcn *msg_fcn)
+void get_rr_short_pd_msg_params(guint8 mess_type, const gchar **msg_str, int *ett_tree, int *hf_idx, msg_fcn *msg_fcn_p)
 {
     gint                       idx;
 
     *msg_str = match_strval_idx((guint32) mess_type, gsm_a_sacch_msg_rr_strings, &idx);
-    *ett_tree = ett_gsm_sacch_msg_rr[idx]; // -1 !!
     *hf_idx = hf_gsm_a_sacch_msg_rr_type;
-    *msg_fcn = sacch_msg_rr_fcn[idx];      // -1 !!
+    if (*msg_str != NULL) {
+        *ett_tree = ett_gsm_sacch_msg_rr[idx];
+        *msg_fcn_p = sacch_msg_rr_fcn[idx];
+    }
 }
 
 const value_string short_protocol_discriminator_vals[] = {
@@ -8673,7 +9618,7 @@ dissect_sacch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     static gsm_a_tap_rec_t     *tap_p;
     static guint               tap_current=0;
 
-    void                       (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
+    void                       (*msg_fcn_p)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len);
     guint8                     oct, short_pd, mess_type;
     guint32                    offset;
     guint32                    len;
@@ -8685,8 +9630,7 @@ dissect_sacch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
     len = tvb_length(tvb);
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-        col_append_str(pinfo->cinfo, COL_INFO, "(SACCH) ");
+    col_append_str(pinfo->cinfo, COL_INFO, "(SACCH) ");
 
     /*
      * set tap record pointer
@@ -8705,21 +9649,19 @@ dissect_sacch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     msg_str = NULL;
     ett_tree = -1;
     hf_idx = -1;
-    msg_fcn = NULL;
+    msg_fcn_p = NULL;
 
     short_pd = (oct & 0x80) >> 7;
     mess_type = (oct & 0x7c) >> 2;
 
     if (short_pd == 0)
     {
-        if (check_col(pinfo->cinfo, COL_INFO))
-            col_append_fstr(pinfo->cinfo, COL_INFO, "(RR) ");
-        get_rr_short_pd_msg_params(mess_type, &msg_str, &ett_tree, &hf_idx, &msg_fcn);
+        col_append_fstr(pinfo->cinfo, COL_INFO, "(RR) ");
+        get_rr_short_pd_msg_params(mess_type, &msg_str, &ett_tree, &hf_idx, &msg_fcn_p);
     }
     else
     {
-        if (check_col(pinfo->cinfo, COL_INFO))
-            col_append_fstr(pinfo->cinfo, COL_INFO, "(Unknown) ");
+        col_append_fstr(pinfo->cinfo, COL_INFO, "(Unknown) ");
     }
 
     /*
@@ -8736,9 +9678,7 @@ dissect_sacch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
         sacch_tree = proto_item_add_subtree(sacch_item, ett_tree);
 
-       if (check_col(pinfo->cinfo, COL_INFO)){
-            col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
     }
 
     if (short_pd == 0)
@@ -8773,11 +9713,11 @@ dissect_sacch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     /*
      * decode elements
      */
-    if (msg_fcn == NULL){
+    if (msg_fcn_p == NULL){
         proto_tree_add_text(sacch_tree, tvb, offset, len - offset,
                             "Message Elements");
     }else{
-        (*msg_fcn)(tvb, sacch_tree, offset, len - offset);
+        (*msg_fcn_p)(tvb, sacch_tree, offset, len - offset);
     }
 }
 
@@ -8843,7 +9783,7 @@ proto_register_gsm_a_rr(void)
                "ARFCN indicating a single frequency to be used by the mobile station in cell selection and reselection (BA Freq)", HFILL }
             },
             { &hf_gsm_a_rr_utran_freq_list_length,
-              { "Length of BA List Pref","gsm_a.rr.ba_list_pref_length",
+              { "Length of UTRAN freq list","gsm_a.rr.utran_freq_length",
                FT_UINT8, BASE_DEC,  NULL, 0xff,
                NULL, HFILL }
             },
@@ -8972,6 +9912,11 @@ proto_register_gsm_a_rr(void)
                FT_UINT8,BASE_HEX,  VALS(gsm_a_rr_freq_list_format_id_vals), 0xce,
                NULL, HFILL }
             },
+            { &hf_gsm_a_rr_format_id2,
+              { "Format Identifier","gsm_a.rr_format_id",
+               FT_UINT8,BASE_HEX,  VALS(gsm_a_rr_freq_list_format_id_vals), 0x8e,
+               NULL, HFILL }
+            },
             { &hf_gsm_a_rr_channel_mode,
               { "Channel Mode","gsm_a.rr.channel_mode",
                FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_channel_mode_vals), 0x0,
@@ -9153,6 +10098,21 @@ proto_register_gsm_a_rr(void)
                FT_UINT8,BASE_DEC,  VALS(gsm_a_rr_suspension_cause_vals), 0x0,
                NULL, HFILL }
             },
+            { &hf_gsm_a_rr_apdu_id,
+              { "APDU ID","gsm_a.rr.apdu_id",
+               FT_UINT8,BASE_HEX,  VALS(gsm_a_rr_apdu_id_vals), 0x0f,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_apdu_flags,
+              { "APDU Flags","gsm_a.rr.apdu_flags",
+               FT_UINT8,BASE_HEX,  VALS(gsm_a_rr_apdu_flags_vals), 0xf0,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_apdu_data,
+              { "APDU Data","gsm_a.rr.apdu_data",
+               FT_BYTES,BASE_NONE,  NULL, 0x00,
+               NULL, HFILL }
+            },
             { &hf_gsm_a_rr_set_of_amr_codec_modes_v1_b8,
               { "12,2 kbit/s codec rate", "gsm_a.rr.set_of_amr_codec_modes_v1b8",
                FT_BOOLEAN,8,  TFS(&gsm_a_rr_set_of_amr_codec_modes), 0x80,
@@ -9850,12 +10810,12 @@ proto_register_gsm_a_rr(void)
             },
             { &hf_gsm_a_rr_psi1_repeat_period,
               { "PSI1 Repeat Period", "gsm_a.rr.psi1_repeat_period",
-               FT_UINT8, BASE_DEC, VALS(&gsm_a_rr_psi1_repeat_period_vals), 0x0,
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_psi1_repeat_period_vals), 0x0,
                NULL, HFILL }
             },
             { &hf_gsm_a_rr_pbcch_pb,
               { "Pb", "gsm_a.rr.pbcch_pb",
-               FT_UINT8, BASE_DEC, VALS(&gsm_a_rr_pbcch_pb_vals), 0x0,
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_pbcch_pb_vals), 0x0,
                "Power reduction on PBCCH/PCCCH (Pb)", HFILL }
             },
             { &hf_gsm_a_rr_pbcch_tsc,
@@ -10077,6 +11037,241 @@ proto_register_gsm_a_rr(void)
               { "Reporting Quantity", "gsm_a.rr.reporting_quantity",
                FT_UINT8, BASE_DEC, NULL, 0x00,
                NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_3g_priority_param_desc_utran_start,
+              { "UTRAN Start", "gsm_a.rr.3g_priority.utran_start",
+               FT_BOOLEAN, BASE_DEC, TFS(&priority_utran_start), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_3g_priority_param_desc_utran_stop,
+              { "UTRAN Stop", "gsm_a.rr.3g_priority.utran_stop",
+               FT_BOOLEAN, BASE_DEC, TFS(&priority_utran_stop), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_3g_priority_param_desc_default_utran_prio,
+              { "DEFAULT_UTRAN_PRIORITY", "gsm_a.rr.3g_priority.default_utran_prio",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_3g_priority_param_desc_default_threshold_utran,
+              { "DEFAULT_THRESH_UTRAN", "gsm_a.rr.3g_priority.default_threshold_utran",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_3g_priority_param_desc_default_utran_qrxlevmin,
+              { "DEFAULT_UTRAN_QRXLEVMIN", "gsm_a.rr.3g_priority.default_utran_qrxlevmin",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_utran_qrxlevmin), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_utran_frequency_index,
+              { "UTRAN Frequency Index", "gsm_a.rr.3g_priority.utran_frequency_index",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_utran_priority,
+              { "UTRAN_PRIORITY", "gsm_a.rr.3g_priority.utran_priority",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_thresh_utran_high,
+              { "THRESH_UTRAN_high", "gsm_a.rr.3g_priority.thres_utran_high",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_thresh_utran_eutran_high_low), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_thresh_utran_low,
+              { "THRESH_UTRAN_low", "gsm_a.rr.3g_priority.thres_utran_low",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_thresh_utran_eutran_high_low), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_utran_qrxlevmin,
+              { "UTRAN_QRXLEVMIN", "gsm_a.rr.3g_priority.utran_qrxlevmin",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_ccn_active,
+              { "E-UTRAN_CCN_ACTIVE", "gsm_a.rr.3g_priority.eutran_ccn_active",
+               FT_BOOLEAN, BASE_DEC, TFS(&eutran_ccn_active), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_start,
+              { "E-UTRAN Start", "gsm_a.rr.3g_priority.eutran_start",
+               FT_BOOLEAN, BASE_DEC, TFS(&priority_utran_start), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_stop,
+              { "E-UTRAN Stop", "gsm_a.rr.3g_priority.utran_stop",
+               FT_BOOLEAN, BASE_DEC, TFS(&priority_utran_stop), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_qsearch_c_eutran_initial,
+              { "Qsearch_C_E-UTRAN_Initial", "gsm_a.rr.qsearch_c_eutran_initial",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_qsearch_c_eutran_initial), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_rep_quant,
+              { "E-UTRAN_REP_QUANT", "gsm_a.rr.eutran_rep_quant",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_multirat_reporting,
+              { "E-UTRAN_MULTIRAT_REPORTING", "gsm_a.rr.eutran_multirat_reporting",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_fdd_reporting_threshold,
+              { "E-UTRAN_FDD_REPORTING_THRESHOLD", "gsm_a.rr.eutran_fdd_reporting_threshold",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_fdd_reporting_threshold_2,
+              { "E-UTRAN_FDD_REPORTING_THRESHOLD_2", "gsm_a.rr.eutran_fdd_reporting_threshold_2",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_tdd_reporting_threshold,
+              { "E-UTRAN_TDD_REPORTING_THRESHOLD", "gsm_a.rr.eutran_tdd_reporting_threshold",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_tdd_reporting_threshold_2,
+              { "E-UTRAN_TDD_REPORTING_THRESHOLD_2", "gsm_a.rr.eutran_tdd_reporting_threshold_2",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_fdd_measurement_report_offset,
+              { "E-UTRAN_FDD_MEASUREMENT_REPORT_OFFSET", "gsm_a.rr.eutran_fdd_measurement_report_offset",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_tdd_measurement_report_offset,
+              { "E-UTRAN_TDD_MEASUREMENT_REPORT_OFFSET", "gsm_a.rr.eutran_tdd_measurement_report_offset",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_reporting_granularity,
+              { "REPORTING_GRANULARITY", "gsm_a.rr.reporting_granularity",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_qsearch_p_eutran,
+              { "Qsearch_P_E-UTRAN", "gsm_a.rr.qsearch_p_eutran",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_serving_cell_priority_param_geran_priority,
+              { "GERAN_PRIORITY", "gsm_a.rr.serving_cell_priority_param_geran_priority",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_serving_cell_priority_param_thresh_prio_search,
+              { "THRESH_Priority_Search", "gsm_a.rr.serving_cell_priority_param_thresh_prio_search",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_serving_cell_thresh_priority_search), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_serving_cell_priority_param_thresh_gsm_low,
+              { "THRESH_GSM_low", "gsm_a.rr.serving_cell_priority_param_thresh_gsm_low",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_serving_cell_thresh_gsm_low), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_serving_cell_priority_param_h_prio,
+              { "H_PRIO", "gsm_a.rr.serving_cell_priority_param_h_prio",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_serving_cell_priority_param_h_prio), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_serving_cell_priority_param_t_reselection,
+              { "T_Reselection", "gsm_a.rr.serving_cell_priority_param_t_reselection",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_serving_cell_priority_param_t_reselection), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_earfcn,
+              { "EARFCN", "gsm_a.rr.earfcn",
+               FT_UINT16, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_measurement_bandwidth,
+              { "Measurement Bandwidth", "gsm_a.rr.eutran_measurement_bandwidth",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_eutran_measurement_bandwidth), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_priority,
+              { "E-UTRAN_PRIORITY", "gsm_a.rr.eutran_priority",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_thresh_eutran_high,
+              { "THRESH_EUTRAN_high", "gsm_a.rr.thresh_eutran_high",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_thresh_utran_eutran_high_low), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_thresh_eutran_low,
+              { "THRESH_EUTRAN_low", "gsm_a.rr.thresh_eutran_low",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_thresh_utran_eutran_high_low), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_qrxlevmin,
+              { "E-UTRAN_QRXLEVMIN", "gsm_a.rr.eutran_qrxlevmin",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_eutran_qrxlevmin), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_pcid,
+              { "PCID", "gsm_a.rr.pcid",
+               FT_UINT16, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_pcid_bitmap_group,
+              { "PCID_BITMAP_GROUP", "gsm_a.rr.pcid_bitmap_group",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_pcid_pattern_length,
+              { "PCID_Pattern_length", "gsm_a.rr.pcid_pattern_length",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_pcid_psc_pattern_length), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_pcid_pattern,
+              { "PCID_Pattern", "gsm_a.rr.pcid_pattern",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_pcid_pattern_sense,
+              { "PCID_pattern_sense", "gsm_a.rr.pcid_pattern_sense",
+               FT_BOOLEAN, BASE_DEC, TFS(&gsm_a_rr_pcid_pattern_sense), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_eutran_frequency_index,
+              { "E-UTRAN_FREQUENCY_INDEX", "gsm_a.rr.eutran_frequency_index",
+               FT_UINT8, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_psc,
+              { "PSC", "gsm_a.rr.psc",
+               FT_UINT16, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_utran_psc_pattern_length,
+              { "PSC_Pattern_length", "gsm_a.rr.psc_pattern_length",
+               FT_UINT8, BASE_DEC, VALS(gsm_a_rr_pcid_psc_pattern_length), 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_utran_psc_pattern_sense,
+              { "PSC_pattern_sense", "gsm_a.rr.psc_pattern_sense",
+               FT_BOOLEAN, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_utran_csg_fdd_uarfcn,
+              { "CSG FDD UARFCN", "gsm_a.rr.utran_csg_fdd_uarfcn",
+               FT_UINT16, BASE_DEC,  NULL, 0x0000,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_utran_csg_tdd_uarfcn,
+              { "CSG TDD UARFCN", "gsm_a.rr.utran_csg_tdd_uarfcn",
+               FT_UINT16, BASE_DEC,  NULL, 0x0000,
+               NULL, HFILL }
+            },
+            { &hf_gsm_a_rr_csg_earfcn,
+              { "CSG_EARFCN", "gsm_a.rr.csg_earfcn",
+               FT_UINT16, BASE_DEC, NULL, 0x00,
+               NULL, HFILL }
             }
        };
 
@@ -10089,13 +11284,13 @@ proto_register_gsm_a_rr(void)
             }
        };
 
-       /* Setup protocol subtree array */
+    /* Setup protocol subtree array */
 #define        NUM_INDIVIDUAL_ELEMS    3
-    static gint *ett[NUM_INDIVIDUAL_ELEMS +
-                     NUM_GSM_DTAP_MSG_RR +
-                     NUM_GSM_RR_ELEM +
-                     NUM_GSM_RR_REST_OCTETS_ELEM +
-                     NUM_GSM_SACCH_MSG_RR];
+    gint *ett[NUM_INDIVIDUAL_ELEMS +
+              NUM_GSM_DTAP_MSG_RR +
+              NUM_GSM_RR_ELEM +
+              NUM_GSM_RR_REST_OCTETS_ELEM +
+              NUM_GSM_SACCH_MSG_RR];
 
     ett[0] = &ett_ccch_msg;
     ett[1] = &ett_ccch_oct_1;
@@ -10152,6 +11347,8 @@ proto_register_gsm_a_rr(void)
 void
 proto_reg_handoff_gsm_a_rr(void)
 {
+    data_handle = find_dissector("data");
     rrc_irat_ho_info_handle = find_dissector("rrc.irat.irat_ho_info");
     rrc_irat_ho_to_utran_cmd_handle = find_dissector("rrc.irat.ho_to_utran_cmd");
+    rrlp_dissector = find_dissector("rrlp");
 }