Eliminate proto_tree_add_text from GSM dissectors.
authorMichael Mann <mmann78@netscape.net>
Wed, 12 Aug 2015 13:01:45 +0000 (09:01 -0400)
committerAnders Broman <a.broman58@gmail.com>
Sat, 15 Aug 2015 06:49:38 +0000 (06:49 +0000)
Change-Id: I36a3d15a4fa86847a83d1dbea40111d36d7cfd61
Reviewed-on: https://code.wireshark.org/review/10036
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
epan/dissectors/packet-gsm_a_rr.c
epan/dissectors/packet-gsm_cbch.c
epan/dissectors/packet-gsm_rlcmac.c

index 6684ecffff2e0c14c933a23f1e03fc36d822c711..3b1a0af4d67ce7dfdf9a620c381090d40a087fa9 100644 (file)
@@ -785,6 +785,28 @@ static int hf_gsm_a_rr_spare = -1;
 static int hf_gsm_a_rr_single_channel_arfcn = -1;
 static int hf_gsm_a_rr_rtd_index = -1;
 static int hf_gsm_a_rr_ti_flag = -1;
+static int hf_gsm_a_rr_arfcn_list = -1;
+static int hf_gsm_a_rr_da_list = -1;
+static int hf_gsm_a_rr_ua_list = -1;
+static int hf_gsm_a_rr_field_bit_long = -1;
+static int hf_gsm_a_rr_ma_bitmap = -1;
+static int hf_gsm_a_rr_inc_arfcn_bitmap = -1;
+static int hf_gsm_a_rr_ccn_supported = -1;
+static int hf_gsm_a_rr_pbcch_use_bcch = -1;
+static int hf_gsm_a_rr_ia_rest_oct_reserved = -1;
+static int hf_gsm_a_rr_tch_facch_sacchm = -1;
+static int hf_gsm_a_rr_tch_facch_sacchf = -1;
+static int hf_gsm_a_rr_tch_facch_sacchm_bi = -1;
+static int hf_gsm_a_rr_tch_acch = -1;
+static int hf_gsm_a_rr_sdcch4_sdcchc4_cbch = -1;
+static int hf_gsm_a_rr_sdcch8_sdcchc8_cbch = -1;
+static int hf_gsm_a_rr_tch_facchf_sacchm_bi = -1;
+static int hf_gsm_a_rr_tch_facchf_sacchm_uni = -1;
+static int hf_gsm_a_rr_tchf_acchs = -1;
+static int hf_gsm_a_rr_unknown_channel_info = -1;
+static int hf_gsm_a_rr_subchannel = -1;
+static int hf_gsm_a_rr_w_elements = -1;
+
 
 /* gsm_rr_csn_flag() fields */
 static int hf_gsm_a_rr_fdd_repeat_freq = -1;
@@ -1097,8 +1119,6 @@ static expert_field ei_gsm_a_rr_data_not_dissected = EI_INIT;
 static expert_field ei_gsm_a_rr_unknown_version = EI_INIT;
 static expert_field ei_gsm_a_rr_extraneous_data = EI_INIT;
 
-static char a_bigbuf[1024];
-
 static dissector_handle_t data_handle;
 static dissector_handle_t rrlp_dissector;
 
@@ -1308,7 +1328,7 @@ static void display_channel_list(guint8 *list, tvbuff_t *tvb, proto_tree *tree,
     int         arfcn;
     proto_item *ti = NULL;
 
-    ti = proto_tree_add_text(tree, tvb, offset, len, "List of ARFCNs =");
+    ti = proto_tree_add_bytes_format(tree, hf_gsm_a_rr_arfcn_list, tvb, offset, len, NULL, "List of ARFCNs =");
     for (arfcn=0; arfcn<ARFCN_MAX; arfcn++) {
         if (list[arfcn])
             proto_item_append_text(ti, " %d", arfcn);
@@ -1452,9 +1472,8 @@ static void dissect_channel_list_n_range(tvbuff_t *tvb, proto_tree *tree, packet
     /* extract the variable size w[] elements */
     for (i=1; i<=imax; i++) {
         w[i] = (gint) tvb_get_bits(tvb, bit_offset, wsize, FALSE);
-        proto_tree_add_text(subtree, tvb, bit_offset>>3, ((bit_offset+wsize-1)>>3) - (bit_offset>>3) + 1 , "%s %s(%d): %d",
+        proto_tree_add_bytes_format(subtree, hf_gsm_a_rr_w_elements, tvb, bit_offset>>3, ((bit_offset+wsize-1)>>3) - (bit_offset>>3) + 1 , NULL, "%s W(%d): %d",
                             decode_bits_in_field(bit_offset, wsize, w[i]),
-                            "W",
                             i,
                             w[i]);
         bit_offset += wsize;
@@ -1497,7 +1516,7 @@ dissect_arfcn_list_core(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
     if ((format & 0xc0) == 0x00)
     {
         /* bit map 0 */
-        item = proto_tree_add_text(tree,tvb, curr_offset, len, "List of ARFCNs =");
+        item = proto_tree_add_bytes_format(tree, hf_gsm_a_rr_arfcn_list, tvb, curr_offset, len, NULL, "List of ARFCNs =");
         bit = 4;
         arfcn = 125;
         for (byte = 0; byte <= len-1; byte++)
@@ -1543,7 +1562,7 @@ dissect_arfcn_list_core(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
     {
         /* variable bit map */
         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);
+        item = proto_tree_add_bytes_format(tree, hf_gsm_a_rr_arfcn_list, tvb, curr_offset, len, NULL, "List of ARFCNs = %d",arfcn);
         curr_offset = curr_offset + 2;
         bit = 7;
         for (byte = 0; byte <= len-3; byte++)
@@ -1750,7 +1769,7 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
                 subtree2 = proto_tree_add_subtree(subtree,tvb, bit_offset>>3, (idx>>3)+1,
                                             ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_FDD_CELL_INFORMATION_FIELD], NULL,
                                             gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_FDD_DESC].strptr);
-                proto_tree_add_text(subtree2,tvb, bit_offset>>3, (idx>>3)+1, "Field is %d bits long", idx);
+                proto_tree_add_bytes_format(subtree2, hf_gsm_a_rr_field_bit_long, tvb, bit_offset>>3, (idx>>3)+1, NULL, "Field is %d bits long", idx);
                 if (xdd_indic0)
                 {
                     proto_tree_add_uint(subtree2, hf_gsm_a_rr_scrambling_code, tvb, bit_offset>>3, 0, 0);
@@ -1821,7 +1840,7 @@ de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
                 subtree2 = proto_tree_add_subtree(subtree,tvb, bit_offset>>3, (idx>>3)+1,
                                             ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_TDD_CELL_INFORMATION_FIELD], NULL,
                                             gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_TDD_DESC].strptr);
-                proto_tree_add_text(subtree2,tvb, bit_offset>>3, (idx>>3)+1, "Field is %d bits long", idx);
+                proto_tree_add_bytes_format(subtree2, hf_gsm_a_rr_field_bit_long, tvb, bit_offset>>3, (idx>>3)+1, NULL, "Field is %d bits long", idx);
                 if (xdd_indic0)
                 {
                     proto_tree_add_uint(subtree2, hf_gsm_a_rr_cell_parameter, tvb, bit_offset>>3, 0, 0);
@@ -2053,7 +2072,7 @@ de_rr_ch_dsc(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo _U_, guint32
     guint32      curr_offset;
     guint8       oct8,subchannel;
     guint16      arfcn, hsn, maio;
-    const gchar *str;
+    int hf_subchannel;
 
     curr_offset = offset;
 
@@ -2062,33 +2081,31 @@ de_rr_ch_dsc(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo _U_, guint32
 
     if ((oct8 & 0xf8) == 0x08)
     {
-        str = "TCH/F + ACCHs";
-        other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
-        proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
+        proto_tree_add_item(subtree, hf_gsm_a_rr_tchf_acchs, tvb, curr_offset, 1, ENC_NA);
     }
     else
     {
         if ((oct8 & 0xf0) == 0x10)
         {
-            str = "TCH/H + ACCHs, Subchannel";
+            hf_subchannel = hf_gsm_a_rr_tch_acch;
             subchannel = ((oct8 & 0x08)>>3);
         }
         else if ((oct8 & 0xe0) == 0x20)
         {
-            str = "SDCCH/4 + SACCH/C4 or CBCH (SDCCH/4), Subchannel";
+            hf_subchannel = hf_gsm_a_rr_sdcch4_sdcchc4_cbch;
             subchannel = ((oct8 & 0x18)>>3);
         }
         else if ((oct8 & 0xc0) == 0x40)
         {
-            str = "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8), Subchannel";
+            hf_subchannel = hf_gsm_a_rr_sdcch8_sdcchc8_cbch;
             subchannel = ((oct8 & 0x38)>>3);
         } else {
-            str = "Unknown channel information";
+            hf_subchannel = hf_gsm_a_rr_unknown_channel_info;
             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);
+        proto_tree_add_item(subtree, hf_subchannel, tvb, curr_offset, 1, ENC_NA);
+        proto_tree_add_uint(subtree, hf_gsm_a_rr_subchannel, tvb, curr_offset, 1, subchannel);
     }
 
     proto_tree_add_item(subtree, hf_gsm_a_rr_timeslot, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
@@ -2131,60 +2148,57 @@ de_rr_ch_dsc2(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo _U_, guint3
     guint32      curr_offset;
     guint8       oct8,subchannel;
     guint16      arfcn, hsn, maio;
-    const gchar *str;
+    int hf_subchannel;
 
     curr_offset = offset;
 
     /* Octet 2 */
     oct8 = tvb_get_guint8(tvb, curr_offset);
 
-    other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
     if ((oct8 & 0xf8) == 0x0)
     {
-        str = "TCH/F + FACCH/F and SACCH/M";
-        proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
+        proto_tree_add_item(subtree, hf_gsm_a_rr_tch_facch_sacchm, tvb, curr_offset, 1, ENC_NA);
     }
     else if ((oct8 & 0xf8) == 0x08)
     {
-        str = "TCH/F + FACCH/F and SACCH/F";
-        proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
+        proto_tree_add_item(subtree, hf_gsm_a_rr_tch_facch_sacchf, tvb, curr_offset, 1, ENC_NA);
     }
     else if ((oct8 & 0xf8) == 0xf0)
     {
-        str = "TCH/F + FACCH/F and SACCH/M + bi- and unidirectional channels";
-        proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
+        proto_tree_add_item(subtree, hf_gsm_a_rr_tch_facch_sacchm_bi, tvb, curr_offset, 1, ENC_NA);
     }
     else
     {
         if ((oct8 & 0xf0) == 0x10)
         {
-            str = "TCH/H + ACCHs, Subchannel";
+            hf_subchannel = hf_gsm_a_rr_tch_acch;
             subchannel = ((oct8 & 0x08)>>3);
         }
         else if ((oct8 & 0xe0) == 0x20)
         {
-            str = "SDCCH/4 + SACCH/C4 or CBCH (SDCCH/4), Subchannel";
+            hf_subchannel = hf_gsm_a_rr_sdcch4_sdcchc4_cbch;
             subchannel = ((oct8 & 0x18)>>3);
         }
         else if ((oct8 & 0xc0) == 0x40)
         {
-            str = "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8), Subchannel";
+            hf_subchannel = hf_gsm_a_rr_sdcch8_sdcchc8_cbch;
             subchannel = ((oct8 % 0x38)>>3);
         }
         else if ((oct8 & 0xc0) == 0x80)
         {
-            str = "TCH/F + FACCH/F and SACCH/M + bidirectional channels at timeslot";
+            hf_subchannel = hf_gsm_a_rr_tch_facchf_sacchm_bi;
             subchannel = ((oct8 % 0x38)>>3);
         }
         else if ((oct8 & 0xe0) == 0xc0)
         {
-            str = "TCH/F + FACCH/F and SACCH/M + unidirectional channels at timeslot";
+            hf_subchannel = hf_gsm_a_rr_tch_facchf_sacchm_uni;
             subchannel = ((oct8 % 0x38)>>3);
         } else {
-            str = "Unknown channel information";
+            hf_subchannel = hf_gsm_a_rr_unknown_channel_info;
             subchannel = oct8;
         }
-        proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s %d",a_bigbuf,str,subchannel);
+        proto_tree_add_item(subtree, hf_subchannel, tvb, curr_offset, 1, ENC_NA);
+        proto_tree_add_uint(subtree, hf_gsm_a_rr_subchannel, tvb, curr_offset, 1, subchannel);
     }
 
     proto_tree_add_item(subtree, hf_gsm_a_rr_timeslot, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
@@ -3743,7 +3757,7 @@ de_rr_ia_rest_oct(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo _U_, gu
             }
             else
             {
-                proto_tree_add_text(subtree, tvb, bit_offset>>3, 1, "reserved for future use (however the value 7C for the first octet shall not be used)");
+                proto_tree_add_item(subtree, hf_gsm_a_rr_ia_rest_oct_reserved, tvb, bit_offset>>3, 1, ENC_NA);
             }
         }
     }
@@ -3762,7 +3776,7 @@ de_rr_ia_rest_oct(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo _U_, gu
                 proto_tree_add_uint(subtree, hf_gsm_a_rr_maio, tvb, bit_offset>>3, 1, tvb_get_bits8(tvb,bit_offset,6));
                 bit_offset += 6;
                 length = (gint)ma_length;
-                item = proto_tree_add_text(subtree,tvb, bit_offset>>3, (length>>3)-1, "MA Bitmap: ");
+                item = proto_tree_add_bytes_format(subtree, hf_gsm_a_rr_ma_bitmap, tvb, bit_offset>>3, (length>>3)-1, NULL, "MA Bitmap: ");
                 length = (length-1)*8;
                 while (length)
                 {
@@ -3965,7 +3979,8 @@ de_rr_mob_all(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 o
 
     curr_offset = offset;
 
-    item = proto_tree_add_text(tree, tvb, curr_offset, len, "Bitmap of increasing ARFCNs included in the Mobile Allocation: ");
+    item = proto_tree_add_bytes_format(tree, hf_gsm_a_rr_inc_arfcn_bitmap, tvb, curr_offset, len, NULL,
+                                        "Bitmap of increasing ARFCNs included in the Mobile Allocation: ");
     for(i=len; i>0; i--)
     {
         value = tvb_get_guint8(tvb,curr_offset+i-1);
@@ -4197,9 +4212,9 @@ de_rr_mult_all(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32
 
     curr_offset = offset;
 
-    item = proto_tree_add_text(tree,tvb, curr_offset, 1 ,"List of DA:");
-
     oct = tvb_get_guint8(tvb, curr_offset);
+    item = proto_tree_add_uint_format(tree, hf_gsm_a_rr_da_list, tvb, curr_offset, 1, oct, "List of DA:");
+
     curr_offset++;
     for( i=0;i<7;i++ )
     {
@@ -4211,8 +4226,8 @@ de_rr_mult_all(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32
 
     if( oct & 0x80 )  /* octet 3a present */
     {
-        item = proto_tree_add_text(tree,tvb, curr_offset, 1 ,"List of UA:");
         oct = tvb_get_guint8(tvb, curr_offset);
+        item = proto_tree_add_uint_format(tree, hf_gsm_a_rr_ua_list, tvb, curr_offset, 1, oct, "List of UA:");
         curr_offset++;
         for( i=0;i<7;i++ )
         {
@@ -4332,7 +4347,8 @@ de_rr_p1_rest_oct(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo _U_, gu
                 }
             }
         }
-        proto_tree_add_text(subtree,tvb, bit_offset_sav>>3, (bit_offset-bit_offset_sav)>>3,"Group Call Information: Data(Not decoded)");
+        proto_tree_add_expert_format(subtree, pinfo, &ei_gsm_a_rr_data_not_dissected, tvb, bit_offset_sav>>3, (bit_offset-bit_offset_sav)>>3,
+                    "Group Call Information: Data(Not decoded)");
     }
     gsm_rr_csn_HL_flag(tvb, subtree, bit_len, bit_offset++, hf_gsm_a_rr_packet_page_indication_1);
     gsm_rr_csn_HL_flag(tvb, subtree, bit_len, bit_offset++, hf_gsm_a_rr_packet_page_indication_2);
@@ -5308,7 +5324,7 @@ de_rr_si2quater_meas_info_utran_fdd_desc(tvbuff_t *tvb, proto_tree *tree, gint b
         idx = convert_n_to_p[idx];
         subtree2 = proto_tree_add_subtree(subtree,tvb, curr_bit_offset>>3, (idx>>3)+1, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_FDD_CELL_INFORMATION_FIELD], &item2,
                                             gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_FDD_DESC].strptr);
-        proto_tree_add_text(subtree2,tvb, curr_bit_offset>>3, (idx>>3)+1, "Field is %d bits long", idx);
+        proto_tree_add_bytes_format(subtree2, hf_gsm_a_rr_field_bit_long, tvb, curr_bit_offset>>3, (idx>>3)+1, NULL, "Field is %d bits long", idx);
         if (xdd_indic0)
         {
             proto_tree_add_uint(subtree2, hf_gsm_a_rr_scrambling_code, tvb, curr_bit_offset>>3, 0, 0);
@@ -5387,7 +5403,7 @@ de_rr_si2quater_meas_info_utran_tdd_desc(tvbuff_t *tvb, proto_tree *tree, gint b
         idx = convert_n_to_q[idx];
         subtree2 = proto_tree_add_subtree(subtree,tvb, curr_bit_offset>>3, (idx>>3)+1, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_TDD_CELL_INFORMATION_FIELD], &item,
                                         gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_TDD_DESC].strptr);
-        proto_tree_add_text(subtree2,tvb, curr_bit_offset>>3, (idx>>3)+1, "Field is %d bits long", idx);
+        proto_tree_add_bytes_format(subtree2, hf_gsm_a_rr_field_bit_long, tvb, curr_bit_offset>>3, (idx>>3)+1, NULL, "Field is %d bits long", idx);
         if (xdd_indic0)
         {
             proto_tree_add_uint(subtree2, hf_gsm_a_rr_cell_parameter, tvb, curr_bit_offset>>3, 0, 0);
@@ -6822,7 +6838,7 @@ de_rr_si2quater_rest_oct(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo
             proto_tree_add_uint(subtree3, hf_gsm_a_rr_number_cells, tvb, bit_offset>>3, 1, value);
             bit_offset += 7;
             idx -= 7;
-            item2 = proto_tree_add_text(subtree3,tvb, bit_offset>>3, (value>>3)+1, "CCN Supported: ");
+            item2 = proto_tree_add_bytes_format(subtree3, hf_gsm_a_rr_ccn_supported, tvb, bit_offset>>3, (value>>3)+1, NULL, "CCN Supported: ");
             while (value)
             {
                 proto_item_append_text(item2,"%d",tvb_get_bits8(tvb,bit_offset,1));
@@ -7612,7 +7628,7 @@ de_rr_rest_oct_gprs_mobile_allocation(tvbuff_t *tvb, proto_tree *tree, gint bit_
         proto_tree_add_bits_ret_val(subtree, hf_gsm_a_rr_ma_length, tvb, curr_bit_offset, 6, &ma_length, ENC_BIG_ENDIAN);
         curr_bit_offset += 6;
         value = (gint)ma_length + 1;
-        item = proto_tree_add_text(subtree,tvb, curr_bit_offset>>3, (value>>3)+1, "MA Bitmap: ");
+        item = proto_tree_add_bytes_format(subtree, hf_gsm_a_rr_ma_bitmap, tvb, curr_bit_offset>>3, (value>>3)+1, NULL, "MA Bitmap: ");
         while (value)
         {
             proto_item_append_text(item,"%d",tvb_get_bits8(tvb,curr_bit_offset,1));
@@ -7944,7 +7960,7 @@ de_rr_si13_rest_oct(tvbuff_t *tvb, proto_tree *subtree, packet_info *pinfo _U_,
                     bit_offset += 10;
                 }
                 else
-                    proto_tree_add_text(subtree2, tvb, bit_offset>>3, 1, "PBCCH shall use the BCCH carrier");
+                    proto_tree_add_item(subtree2, hf_gsm_a_rr_pbcch_use_bcch, tvb, bit_offset>>3, 1, ENC_NA);
             }
             proto_item_set_len(item2, (bit_offset>>3) - (bit_offset_sav>>3)+1);
         }
@@ -12973,6 +12989,27 @@ proto_register_gsm_a_rr(void)
             { &hf_gsm_a_rr_single_channel_arfcn, { "Single channel ARFCN", "gsm_a.rr.single_channel_arfcn", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
             { &hf_gsm_a_rr_rtd_index, { "RTD index", "gsm_a.rr.rtd_index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
             { &hf_gsm_a_rr_ti_flag, { "TI flag", "gsm_a.rr.ti_flag", FT_BOOLEAN, 8, TFS(&tfs_allocated_by_receiver_sender), 0x80, NULL, HFILL }},
+            { &hf_gsm_a_rr_arfcn_list, { "List of ARFCNs", "gsm_a.rr.arfcn_list", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_da_list, { "List of DA", "gsm_a.rr.da_list", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_ua_list, { "List of UA", "gsm_a.rr.ua_list", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_ma_bitmap, { "MA Bitmap", "gsm_a.rr.ma_bitmap", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_inc_arfcn_bitmap, { "Bitmap of increasing ARFCNs included in the Mobile Allocation", "gsm_a.rr.inc_arfcn_bitmap", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_ccn_supported, { "CCN Supported", "gsm_a.rr.ccn_supported", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_pbcch_use_bcch, { "PBCCH shall use the BCCH carrier", "gsm_a.rr.pbcch_use_bcch", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_ia_rest_oct_reserved, { "Reserved for future use (however the value 7C for the first octet shall not be used)", "gsm_a.rr.ia_rest_oct_reserved", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_tch_facch_sacchm, { "TCH/F + FACCH/F and SACCH/M", "gsm_a.rr.tch_facch_sacchm", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_tch_facch_sacchf, { "TCH/F + FACCH/F and SACCH/F", "gsm_a.rr.tch_facch_sacchf", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_tch_facch_sacchm_bi, { "TCH/F + FACCH/F and SACCH/M + bi- and unidirectional channels", "gsm_a.rr.tch_facch_sacchm_bi", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_tch_acch, { "TCH/H + ACCHs", "gsm_a.rr.tch_acch", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_sdcch4_sdcchc4_cbch, { "SDCCH/4 + SACCH/C4 or CBCH (SDCCH/4)", "gsm_a.rr.sdcch4_sdcchc4_cbch", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_sdcch8_sdcchc8_cbch, { "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8)", "gsm_a.rr.sdcch8_sdcchc8_cbch", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_tch_facchf_sacchm_bi, { "TCH/F + FACCH/F and SACCH/M + bidirectional channels at timeslot", "gsm_a.rr.tch_facchf_sacchm_bi", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_tch_facchf_sacchm_uni, { "TCH/F + FACCH/F and SACCH/M + unidirectional channels at timeslot", "gsm_a.rr.tch_facchf_sacchm_uni", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_unknown_channel_info, { "Unknown channel information", "gsm_a.rr.unknown_channel_info", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_tchf_acchs, { "TCH/F + ACCHs", "gsm_a.rr.tchf_acchs", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL }},
+            { &hf_gsm_a_rr_subchannel, { "Subchannel", "gsm_a.rr.tch_facch_sacchm", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_w_elements, { "W elements", "gsm_a.rr.w_elements", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+            { &hf_gsm_a_rr_field_bit_long, { "Field is X bits long", "gsm_a.rr.field_bit_long", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
 
             /* gsm_rr_csn_flag() fields */
             { &hf_gsm_a_rr_fdd_repeat_freq, { "Repeating FDD Frequency", "gsm_a.rr.fdd_repeat_freq", FT_BOOLEAN, BASE_NONE, TFS(&tfs_present_not_present), 0x00, NULL, HFILL }},
index e84e23cc7813383525c10ac71d445e20ad5bab64..82a0c1d853f46011e7062cf8799ebed2b9961483 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <epan/packet.h>
 #include <epan/reassemble.h>
+#include <epan/expert.h>
 
 void proto_register_gsm_cbch(void);
 void proto_reg_handoff_gsm_cbch(void);
@@ -69,6 +70,8 @@ static int hf_gsm_cbch_sched_spare = -1;
 static int hf_gsm_cbch_sched_end_slot = -1;
 static int hf_gsm_cbch_slot = -1;
 /* static int hf_gsm_cbch_sched_msg_id = -1; */
+static int hf_gsm_cbch_padding = -1;
+static int hf_gsm_cbch_block = -1;
 
 /* These fields are used when reassembling cbch fragments
  */
@@ -90,6 +93,11 @@ static gint ett_schedule_new_msg = -1;
 static gint ett_cbch_fragment = -1;
 static gint ett_cbch_fragments = -1;
 
+static expert_field ei_gsm_cbch_sched_end_slot = EI_INIT;
+static expert_field ei_gsm_cbch_seq_num_null = EI_INIT;
+static expert_field ei_gsm_cbch_seq_num_reserved = EI_INIT;
+static expert_field ei_gsm_cbch_lpd = EI_INIT;
+
 static dissector_handle_t data_handle;
 static dissector_handle_t cbs_handle;
 
@@ -129,6 +137,15 @@ cbch_defragment_cleanup(void)
     reassembly_table_destroy(&cbch_block_reassembly_table);
 }
 
+static const range_string gsm_cbch_sched_begin_slot_rvals[] = {
+    { 0,     0,     "Out of range (ignoring message)" },
+    { 1,     1,     "(apparently) Scheduled Scheduling Message" },
+    { 2,     48,    "(apparently) Unscheduled Scheduling Message" },
+    { 49,    0xFF,  "Out of range (ignoring message)" },
+
+    { 0x00, 0x00,  NULL },
+};
+
 static void
 dissect_schedule_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree)
 {
@@ -153,27 +170,19 @@ dissect_schedule_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree
     octet1 = tvb_get_guint8(tvb, offset);
     if (0 == (octet1 & 0xC0))
     {
+        proto_item* slot_item;
         sched_begin = octet1 & 0x3F;
         proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_begin_slot, tvb, offset++, 1, ENC_BIG_ENDIAN);
-        if (1 == sched_begin)
+        if ((sched_begin < 1) || (sched_begin > 48))
         {
-            proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "(apparently) Scheduled Scheduling Message");
-        }
-        else if ((2 <= sched_begin) && (48 >= sched_begin))
-        {
-            proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "(apparently) Unscheduled Scheduling Message");
-        }
-        else
-        {
-            proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "Begin Slot Number out of range: ignoring message");
             valid_message = FALSE;
         }
         proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_spare, tvb, offset, 1, ENC_BIG_ENDIAN);
         sched_end = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_end_slot, tvb, offset++, 1, ENC_BIG_ENDIAN);
+        slot_item = proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_end_slot, tvb, offset++, 1, ENC_BIG_ENDIAN);
         if (sched_end < sched_begin)
         {
-            proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "End Slot Number less than Begin Slot Number: ignoring message");
+            expert_add_info(pinfo, slot_item, &ei_gsm_cbch_sched_end_slot);
             valid_message = FALSE;
         }
 
@@ -355,7 +364,7 @@ dissect_schedule_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree
                 }
             }
             proto_item_set_end(item, tvb, offset);
-            proto_tree_add_text(sched_tree, tvb, offset, -1, "Padding");
+            proto_tree_add_item(sched_tree, hf_gsm_cbch_padding, tvb, offset, -1, ENC_NA);
         }
     }
 }
@@ -366,7 +375,7 @@ dissect_cbch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     fragment_head *frag_data = NULL;
     guint8         octet, lb, lpd, seq_num;
     guint32        offset;
-    proto_item    *cbch_item;
+    proto_item    *cbch_item, *lpd_item, *seq_item;
     proto_tree    *cbch_tree;
     tvbuff_t      *reass_tvb = NULL, *msg_tvb = NULL;
 
@@ -383,12 +392,12 @@ dissect_cbch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
     cbch_tree = proto_item_add_subtree(cbch_item, ett_cbch_msg);
 
-    proto_tree_add_text(cbch_tree, tvb, offset, 1, "CBCH Block");
+    proto_tree_add_uint(cbch_tree, hf_gsm_cbch_block, tvb, offset, 1, octet);
 
     proto_tree_add_uint(cbch_tree, hf_gsm_cbch_spare_bit, tvb, offset, 1, octet);
-    proto_tree_add_uint(cbch_tree, hf_gsm_cbch_lpd,       tvb, offset, 1, octet);
+    lpd_item = proto_tree_add_uint(cbch_tree, hf_gsm_cbch_lpd,       tvb, offset, 1, octet);
     proto_tree_add_uint(cbch_tree, hf_gsm_cbch_lb,        tvb, offset, 1, octet);
-    proto_tree_add_uint(cbch_tree, hf_gsm_cbch_seq_num,   tvb, offset, 1, octet);
+    seq_item = proto_tree_add_uint(cbch_tree, hf_gsm_cbch_seq_num,   tvb, offset, 1, octet);
     seq_num =  octet & 0x0F;
     lpd     = (octet & 0x60) >> 5;
     lb      = (octet & 0x10) >> 4;
@@ -429,12 +438,12 @@ dissect_cbch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
             break;
 
         case 0x0F:
-            proto_tree_add_text(cbch_tree, tvb, offset, 1, "NULL message");
+            expert_add_info(pinfo, seq_item, &ei_gsm_cbch_seq_num_null);
             call_dissector(data_handle, tvb, pinfo, cbch_tree);
             break;
 
         default:
-            proto_tree_add_text(cbch_tree, tvb, offset, 1, "reserved Sequence Number");
+            expert_add_info(pinfo, seq_item, &ei_gsm_cbch_seq_num_reserved);
             call_dissector(data_handle, tvb, pinfo, cbch_tree);
             break;
         }
@@ -461,7 +470,7 @@ dissect_cbch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     }
     else
     {
-        proto_tree_add_text(cbch_tree, tvb, offset, 1, "invalid Link Protocol Discriminator");
+        expert_add_info(pinfo, lpd_item, &ei_gsm_cbch_lpd);
         call_dissector(data_handle, tvb, pinfo, cbch_tree);
     }
 }
@@ -500,7 +509,7 @@ proto_register_gsm_cbch(void)
             },
             { &hf_gsm_cbch_sched_begin_slot,
               { "GSM CBCH Schedule Begin slot", "gsm_cbch.schedule_begin",
-                FT_UINT8, BASE_DEC, NULL, 0x3F,
+              FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_cbch_sched_begin_slot_rvals), 0x3F,
                 NULL, HFILL}
             },
             { &hf_gsm_cbch_sched_spare,
@@ -518,6 +527,17 @@ proto_register_gsm_cbch(void)
                 FT_UINT8, BASE_DEC, NULL, 0x0,
                 NULL, HFILL}
             },
+            { &hf_gsm_cbch_padding,
+              { "Padding",   "gsm_cbch.padding",
+                FT_BYTES, BASE_NONE, NULL, 0x0,
+                NULL, HFILL}
+            },
+            { &hf_gsm_cbch_block,
+              { "CBCH Block",   "gsm_cbch.block",
+                FT_UINT8, BASE_HEX, NULL, 0x0,
+                NULL, HFILL}
+            },
+
 #if 0
             { &hf_gsm_cbch_sched_msg_id,
               { "GSM CBCH Schedule Message ID", "gsm_cbch.sched_msg_id",
@@ -608,9 +628,20 @@ proto_register_gsm_cbch(void)
         &ett_cbch_fragments,
     };
 
+    expert_module_t* expert_cbch;
+
+    static ei_register_info ei[] = {
+        { &ei_gsm_cbch_sched_end_slot, { "gsm_cbch.sched_end.bad_range", PI_PROTOCOL, PI_WARN, "End Slot Number less than Begin Slot Number: ignoring message", EXPFILL }},
+        { &ei_gsm_cbch_seq_num_null, { "gsm_cbch.block_type.seq_num.null", PI_PROTOCOL, PI_NOTE, "NULL message", EXPFILL }},
+        { &ei_gsm_cbch_seq_num_reserved, { "gsm_cbch.block_type.seq_num.reserved", PI_PROTOCOL, PI_NOTE, "Reserved Sequence Number", EXPFILL }},
+        { &ei_gsm_cbch_lpd, { "gsm_cbch.block_type.lpd.invalid", PI_PROTOCOL, PI_WARN, "Invalid Link Protocol Discriminator", EXPFILL }},
+    };
+
     /* Register the protocol name and description */
     proto_cbch = proto_register_protocol("GSM Cell Broadcast Channel", "GSM CBCH", "gsm_cbch");
     proto_register_field_array(proto_cbch, hf_smscb, array_length(hf_smscb));
+    expert_cbch = expert_register_protocol(proto_cbch);
+    expert_register_field_array(expert_cbch, ei, array_length(ei));
 
     /* subdissector code */
     register_dissector("gsm_cbch", dissect_cbch, proto_cbch);
index 1ae3e7fc993581d9320fe263c8293383b396ddc8..323f14e78a2db4ba0b0b82dadad96c2d9e4801af 100644 (file)
@@ -988,6 +988,7 @@ static expert_field ei_gsm_rlcmac_gprs_fanr_header_dissection_not_supported = EI
 static expert_field ei_gsm_rlcmac_coding_scheme_unknown = EI_INIT;
 static expert_field ei_gsm_rlcmac_egprs_header_type_not_handled = EI_INIT;
 static expert_field ei_gsm_rlcmac_unexpected_header_extension = EI_INIT;
+static expert_field ei_gsm_rlcmac_unknown_pacch_access_burst = EI_INIT;
 
 static dissector_handle_t data_handle;
 
@@ -6961,7 +6962,6 @@ static guint8 dissect_gprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, prot
   tvbuff_t*   data_tvb     = NULL;
   gboolean    more         = TRUE, first_li = TRUE;
   proto_tree *subtree      = NULL;
-  proto_item *ti           = NULL;
 
   /* decode the LIs and any associated LLC Frames */
   for(i = 0; (i < li_count) && more; i++)
@@ -6974,7 +6974,7 @@ static guint8 dissect_gprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, prot
     switch (li)
     {
       case 0:
-        proto_tree_add_text(tree, tvb, li_array[i].offset, 1,
+        proto_tree_add_subtree_format(tree, tvb, li_array[i].offset, 1, ett_data_segments, NULL,
                             "LI[%d]=%d indicates: The previous segment of LLC Frame precisely filled the previous RLC Block",
                             i, li);
         break;
@@ -6982,27 +6982,25 @@ static guint8 dissect_gprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, prot
       case 63:
         if (first_li)
         {
-          ti = proto_tree_add_text(tree, tvb, octet_offset, li,
+          subtree = proto_tree_add_subtree_format(tree, tvb, octet_offset, li, ett_data_segments, NULL,
                                    "data segment: LI[%d]=%d indicates: The RLC data block contains only filler bits",
                                    i, li);
         }
         else
         {
-          ti = proto_tree_add_text(tree, tvb, octet_offset, li,
+          subtree = proto_tree_add_subtree_format(tree, tvb, octet_offset, li, ett_data_segments, NULL,
                                    "data segment: LI[%d]=%d indicates: The remainder of the RLC data block contains filler bits",
                                    i, li);
         }
-        subtree = proto_item_add_subtree(ti, ett_data_segments);
         data_tvb = tvb_new_subset_length(tvb, octet_offset, octet_length - octet_offset);
         call_dissector(data_handle, data_tvb, pinfo, subtree);
         octet_offset = octet_length;
         break;
 
       default:
-        ti = proto_tree_add_text(tree, tvb, octet_offset, li,
+        subtree = proto_tree_add_subtree_format(tree, tvb, octet_offset, li, ett_data_segments, NULL,
                                  "data segment: LI[%d]=%d indicates: (Last segment of) LLC frame (%d octets)",
                                  i, li, li);
-        subtree = proto_item_add_subtree(ti, ett_data_segments);
         data_tvb = tvb_new_subset_length(tvb, octet_offset, li);
         call_dissector(data_handle, data_tvb, pinfo, subtree);
         octet_offset += li;
@@ -7015,14 +7013,13 @@ static guint8 dissect_gprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, prot
     /* if there is space left in the RLC Block, then it is a segment of LLC Frame without LI*/
     if (more)
     {
-      ti = proto_tree_add_text(tree, tvb, octet_offset, octet_length - octet_offset,
+      subtree = proto_tree_add_subtree_format(tree, tvb, octet_offset, octet_length - octet_offset, ett_data_segments, NULL,
                                "data segment: LI not present: \n The Upper Layer PDU in the current RLC data block either fills the current RLC data block precisely \nor continues in the following in-sequence RLC data block");
     }
     else
     {
-      ti = proto_tree_add_text(tree, tvb, octet_offset, octet_length - octet_offset, "Padding Octets");
+      subtree = proto_tree_add_subtree(tree, tvb, octet_offset, octet_length - octet_offset, ett_data_segments, NULL, "Padding Octets");
     }
-    subtree = proto_item_add_subtree(ti, ett_data_segments);
     data_tvb = tvb_new_subset_length(tvb, octet_offset, octet_length - octet_offset);
     call_dissector(data_handle, data_tvb, pinfo, subtree);
     octet_offset = octet_length;
@@ -7037,7 +7034,6 @@ static guint16 dissect_egprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, pr
   tvbuff_t   *data_tvb     = NULL;
   gboolean    first_li     = TRUE;
   proto_tree *subtree      = NULL;
-  proto_item *ti           = NULL;
 
   /* decode the LIs and any associated LLC Frames */
   for(i = 0; i < li_count; i++)
@@ -7052,20 +7048,20 @@ static guint16 dissect_egprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, pr
         {
           if (li_array[i].li & 1)
           {
-            proto_tree_add_text(tree, tvb, li_array[i].offset, 1,
+            proto_tree_add_subtree_format(tree, tvb, li_array[i].offset, 1, ett_data_segments, NULL,
                                 "LI[%d]=%d indicates: The previous RLC data block contains a Upper Layer PDU, or a part of it, \nthat fills precisely the previous data block and for which there is no length indicator in that RLC data block. \nThe current RLC data block contains a Upper Layer PDU that either fills the current RLC data block precisely or \ncontinues in the next RLC data block.",
                                 i, li);
           }
           else
           {
-            proto_tree_add_text(tree, tvb, li_array[i].offset, 1,
+            proto_tree_add_subtree_format(tree, tvb, li_array[i].offset, 1, ett_data_segments, NULL,
                                 "LI[%d]=%d indicates: The last Upper Layer PDU of the previous in sequence RLC data block ends \nat the boundary of that RLC data block and it has no LI in the header of that RLC data block. \nThus the current RLC data block contains the first segment of all included Upper Layer PDUs.",
                                 i, li);
           }
         }
         else
         {
-          proto_tree_add_text(tree, tvb, li_array[i].offset, 1,
+          proto_tree_add_subtree_format(tree, tvb, li_array[i].offset, 1, ett_data_segments, NULL,
                               "LI[%d]=%d indicates: Unexpected occurrence of LI=0.",
                               i, li);
         }
@@ -7076,20 +7072,20 @@ static guint16 dissect_egprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, pr
         {
           if (li_array[i].li & 1)
           {
-            proto_tree_add_text(tree, tvb, li_array[i].offset, 1,
+            proto_tree_add_subtree_format(tree, tvb, li_array[i].offset, 1, ett_data_segments, NULL,
                                 "LI[%d]=%d indicates: The current RLC data block contains the first segment of an Upper Layer PDU \nthat either fills the current RLC data block precisely or continues in the next RLC data block.",
                                 i, li);
           }
           else
           {
-            proto_tree_add_text(tree, tvb, li_array[i].offset, 1,
+            proto_tree_add_subtree_format(tree, tvb, li_array[i].offset, 1, ett_data_segments, NULL,
                                 "LI[%d]=%d indicates: The current RLC data block contains the first segment of all included Upper Layer PDUs.",
                                 i, li);
           }
         }
         else
         {
-          proto_tree_add_text(tree, tvb, li_array[i].offset, 1,
+          proto_tree_add_subtree_format(tree, tvb, li_array[i].offset, 1, ett_data_segments, NULL,
                               "LI[%d]=%d indicates: Unexpected occurrence of LI=126.",
                               i, li);
         }
@@ -7098,27 +7094,25 @@ static guint16 dissect_egprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, pr
       case 127:
         if (first_li)
         {
-          ti = proto_tree_add_text(tree, tvb, octet_offset, octet_length - octet_offset,
+          subtree = proto_tree_add_subtree_format(tree, tvb, octet_offset, octet_length - octet_offset, ett_data_segments, NULL,
                                    "data segment: LI[%d]=%d indicates: The RLC data block contains only filler bits",
                                    i, li);
         }
         else
         {
-          ti = proto_tree_add_text(tree, tvb, octet_offset, octet_length - octet_offset,
+          subtree = proto_tree_add_subtree_format(tree, tvb, octet_offset, octet_length - octet_offset, ett_data_segments, NULL,
                                    "data segment: LI[%d]=%d indicates: The remainder of the RLC data block contains filler bits",
                                    i, li);
         }
-        subtree = proto_item_add_subtree(ti, ett_data_segments);
         data_tvb = tvb_new_subset_length(tvb, octet_offset, octet_length - octet_offset);
         call_dissector(data_handle, data_tvb, pinfo, subtree);
         octet_offset = octet_length;
         break;
 
       default:
-        ti = proto_tree_add_text(tree, tvb, octet_offset, li,
+        subtree = proto_tree_add_subtree_format(tree, tvb, octet_offset, li, ett_data_segments, NULL,
                                  "data segment: LI[%d]=%d indicates: (Last segment of) LLC frame (%d octets)",
                                  i, li, li);
-        subtree = proto_item_add_subtree(ti, ett_data_segments);
         data_tvb = tvb_new_subset_length(tvb, octet_offset, li);
         call_dissector(data_handle, data_tvb, pinfo, subtree);
         octet_offset += li;
@@ -7129,9 +7123,8 @@ static guint16 dissect_egprs_data_segments(tvbuff_t *tvb, packet_info *pinfo, pr
   /* if there is space left in the RLC Block, then it is a segment of LLC Frame without LI*/
   if (octet_offset < octet_length)
   {
-    ti = proto_tree_add_text(tree, tvb, octet_offset, octet_length - octet_offset,
+    subtree = proto_tree_add_subtree(tree, tvb, octet_offset, octet_length - octet_offset, ett_data_segments, NULL,
                              "data segment: LI not present: \n The Upper Layer PDU in the current RLC data block either fills the current RLC data block precisely \nor continues in the following in-sequence RLC data block");
-    subtree = proto_item_add_subtree(ti, ett_data_segments);
     data_tvb = tvb_new_subset_length(tvb, octet_offset, octet_length - octet_offset);
     call_dissector(data_handle, data_tvb, pinfo, subtree);
     octet_offset = octet_length;
@@ -7615,8 +7608,7 @@ dissect_ul_pacch_access_burst(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
   }
   else
   {
-    proto_tree_add_text(tree, tvb, 0, -1,
-                        "Unknown PACCH access burst");
+    proto_tree_add_expert(tree, pinfo, &ei_gsm_rlcmac_unknown_pacch_access_burst, tvb, 0, -1);
     call_dissector(data_handle, tvb, pinfo, tree);
   }
 }
@@ -12367,6 +12359,7 @@ proto_register_gsm_rlcmac(void)
       { &ei_gsm_rlcmac_gprs_fanr_header_dissection_not_supported, { "gsm_rlcmac.gprs_fanr_header_dissection_not_supported", PI_UNDECODED, PI_WARN, "GPRS FANR Header dissection not supported (yet)", EXPFILL }},
       { &ei_gsm_rlcmac_egprs_header_type_not_handled, { "gsm_rlcmac.egprs_header_type_not_handled", PI_UNDECODED, PI_WARN, "EGPRS Header Type not handled (yet)", EXPFILL }},
       { &ei_gsm_rlcmac_coding_scheme_unknown, { "gsm_rlcmac.coding_scheme.unknown", PI_PROTOCOL, PI_WARN, "GSM RLCMAC unknown coding scheme", EXPFILL }},
+      { &ei_gsm_rlcmac_unknown_pacch_access_burst, { "gsm_rlcmac.unknown_pacch_access_burst", PI_PROTOCOL, PI_WARN, "Unknown PACCH access burst", EXPFILL }},
   };
 
   expert_module_t* expert_gsm_rlcmac;