checkAPIs.pl: support for new-style dissectors in check_hf_entries
[metze/wireshark/wip.git] / epan / dissectors / packet-gsm_a_gm.c
index 94442e91419f16de819673d2e15fc3987778607f..179dd0880c2036b4714d71d43f800484ec6a8198 100644 (file)
  *   Mobile radio interface Layer 3 specification;
  *   Core network protocols;
  *   Stage 3
- *   (3GPP TS 24.008 version 11.5.0 Release 11)
+ *   (3GPP TS 24.008 version 11.7.0 Release 11)
  *
- * $Id$
+ *   Reference [12]
+ *   Mobile radio interface Layer 3 specification;
+ *   Core network protocols;
+ *   Stage 3
+ *   (3GPP TS 24.008 version 12.10.0 Release 12)
+ *
+ *   Reference [13]
+ *   Mobile radio interface Layer 3 specification;
+ *   Core network protocols;
+ *   Stage 3
+ *   (3GPP TS 24.008 version 13.8.0 Release 13)
+ *
+ *   Reference [14]
+ *   Mobile radio interface Layer 3 specification;
+ *   Core network protocols;
+ *   Stage 3
+ *   (3GPP TS 24.008 version 14.6.0 Release 14)
+ *
+ *   Reference [15]
+ *   Mobile radio interface Layer 3 specification;
+ *   Core network protocols;
+ *   Stage 3
+ *   (3GPP TS 24.008 version 15.2.0 Release 15)
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #include "config.h"
 
-#include <string.h>
 
 #include <epan/packet.h>
 #include <epan/expert.h>
-#include <epan/prefs.h>
-#include <epan/tap.h>
-#include <epan/asn1.h>
-
-#include "packet-bssap.h"
-#include "packet-sccp.h"
+#include <epan/ipproto.h>
 #include "packet-ber.h"
-#include "packet-q931.h"
 #include "packet-gsm_a_common.h"
 #include "packet-e212.h"
 #include "packet-ppp.h"
-#include "ipproto.h"
+#include "packet-e164.h"
+
+void proto_register_gsm_a_gm(void);
+void proto_reg_handoff_gsm_a_gm(void);
 
 /* PROTOTYPES/FORWARDS */
 
@@ -108,13 +114,15 @@ const value_string gsm_a_dtap_msg_gmm_strings[] = {
        { 0x12, "Authentication and Ciphering Req" },
        { 0x13, "Authentication and Ciphering Resp" },
        { 0x14, "Authentication and Ciphering Rej" },
-       { 0x1c, "Authentication and Ciphering Failure" },
        { 0x15, "Identity Request" },
        { 0x16, "Identity Response" },
+       { 0x1c, "Authentication and Ciphering Failure" },
        { 0x20, "GMM Status" },
        { 0x21, "GMM Information" },
        { 0, NULL }
 };
+static value_string_ext gsm_a_dtap_msg_gmm_strings_ext = VALUE_STRING_EXT_INIT(gsm_a_dtap_msg_gmm_strings);
+
 
 const value_string gsm_a_dtap_msg_sm_strings[] = {
        { 0x41, "Activate PDP Context Request" },
@@ -148,75 +156,89 @@ const value_string gsm_a_dtap_msg_sm_strings[] = {
        { 0x5d, "Notification" },
        { 0, NULL }
 };
+static value_string_ext gsm_a_dtap_msg_sm_strings_ext = VALUE_STRING_EXT_INIT(gsm_a_dtap_msg_sm_strings);
+
 
 static const value_string gsm_gm_elem_strings[] = {
        /* GPRS Mobility Management Information Elements 10.5.5 */
-       { DE_ADD_UPD_TYPE,      "Additional Update Type" },
-       { DE_ATTACH_RES,        "Attach Result" },
-       { DE_ATTACH_TYPE,       "Attach Type" },
-       { DE_CIPH_ALG,  "Cipher Algorithm" },
-       { DE_TMSI_STAT, "TMSI Status" },
-       { DE_DETACH_TYPE,       "Detach Type" },
-       { DE_DRX_PARAM, "DRX Parameter" },
-       { DE_FORCE_TO_STAND,    "Force to Standby" },
-       { DE_FORCE_TO_STAND_H, "Force to Standby" },
-       { DE_P_TMSI_SIG,        "P-TMSI Signature" },
-       { DE_P_TMSI_SIG_2,      "P-TMSI Signature 2" },
-       { DE_ID_TYPE_2, "Identity Type 2" },
-       { DE_IMEISV_REQ,        "IMEISV Request" },
-       { DE_REC_N_PDU_NUM_LIST,        "Receive N-PDU Numbers List" },
-       { DE_MS_NET_CAP,        "MS Network Capability" },
-       { DE_MS_RAD_ACC_CAP,    "MS Radio Access Capability" },
-       { DE_GMM_CAUSE, "GMM Cause" },
-       { DE_RAI,       "Routing Area Identification" },
-       { DE_RAI_2,     "Routing Area Identification 2" },
-       { DE_UPD_RES,   "Update Result" },
-       { DE_UPD_TYPE, "Update Type" },
-       { DE_AC_REF_NUM,        "A&C Reference Number" },
-       { DE_AC_REF_NUM_H, "A&C Reference Number" },
-       { DE_SRVC_TYPE, "Service Type" },
-       { DE_CELL_NOT,  "Cell Notification" },
-       { DE_PS_LCS_CAP, "PS LCS Capability" },
-       { DE_NET_FEAT_SUP,      "Network Feature Support" },
-       { DE_ADD_NET_FEAT_SUP,  "Additional Network Feature Support" },
-       { DE_RAT_INFO_CONTAINER, "Inter RAT information container" },
-       { DE_REQ_MS_INFO, "Requested MS information" },
-       { DE_UE_NETWORK_CAP, "UE network capability" },
-       { DE_EUTRAN_IRAT_INFO_CONTAINER, "E-UTRAN inter RAT information container" },
-       { DE_VOICE_DOMAIN_PREF, "Voice domain preference and UE's usage setting" },
-       { DE_PTMSI_TYPE, "P-TMSI type" },
-       { DE_LAI_2, "Location Area Identification 2" },
-       { DE_NET_RES_ID_CONT, "Network resource identifier container" },
+       { DE_ADD_UPD_TYPE,               "Additional Update Type" },
+       { DE_ATTACH_RES,                 "Attach Result" },
+       { DE_ATTACH_TYPE,                "Attach Type" },
+       { DE_CIPH_ALG,                   "Ciphering Algorithm" },
+       { DE_INTEG_ALG,                  "Integrity Algorithm" },
+       { DE_TMSI_STAT,                  "TMSI Status" },
+       { DE_DETACH_TYPE,                "Detach Type" },
+       { DE_DRX_PARAM,                  "DRX Parameter" },
+       { DE_FORCE_TO_STAND,             "Force to Standby" },
+       { DE_FORCE_TO_STAND_H,           "Force to Standby" },
+       { DE_P_TMSI_SIG,                 "P-TMSI Signature" },
+       { DE_P_TMSI_SIG_2,               "P-TMSI Signature 2" },
+       { DE_ID_TYPE_2,                  "Identity Type 2" },
+       { DE_IMEISV_REQ,                 "IMEISV Request" },
+       { DE_REC_N_PDU_NUM_LIST,         "Receive N-PDU Numbers List" },
+       { DE_MS_NET_CAP,                 "MS Network Capability" },
+       { DE_MS_RAD_ACC_CAP,             "MS Radio Access Capability" },
+       { DE_GMM_CAUSE,                  "GMM Cause" },
+       { DE_RAI,                        "Routing Area Identification" },
+       { DE_RAI_2,                      "Routing Area Identification 2" },
+       { DE_UPD_RES,                    "Update Result" },
+       { DE_UPD_TYPE,                   "Update Type" },
+       { DE_AC_REF_NUM,                 "A&C Reference Number" },
+       { DE_AC_REF_NUM_H,               "A&C Reference Number" },
+       { DE_SRVC_TYPE,                  "Service Type" },
+       { DE_CELL_NOT,                   "Cell Notification" },
+       { DE_PS_LCS_CAP,                 "PS LCS Capability" },
+       { DE_NET_FEAT_SUP,               "Network Feature Support" },
+       { DE_ADD_NET_FEAT_SUP,           "Additional Network Feature Support" },
+       { DE_RAT_INFO_CONTAINER,         "Inter RAT Information Container" },
+       { DE_REQ_MS_INFO,                "Requested MS Information" },
+       { DE_UE_NETWORK_CAP,             "UE Network Capability" },
+       { DE_EUTRAN_IRAT_INFO_CONTAINER, "E-UTRAN Inter RAT Information Container" },
+       { DE_VOICE_DOMAIN_PREF,          "Voice Domain Preference and UE's Usage Setting" },
+       { DE_PTMSI_TYPE,                 "P-TMSI Type" },
+       { DE_LAI_2,                      "Location Area Identification 2" },
+       { DE_NET_RES_ID_CONT,            "Network Resource Identifier Container" },
+       { DE_EXT_DRX_PARAMS,             "Extended DRX Parameters" },
+       { DE_MAC,                        "Message Authentication Code" },
+       { DE_UP_INTEG_IND,               "User Plane Integrity Indicator" },
+       { DE_DCN_ID,                     "DCN-ID"},
+       { DE_PLMN_ID_CN_OPERATOR,        "PLMN identity of the CN operator"},
+       { DE_NON_3GPP_NW_PROV_POL,       "Non-3GPP NW provided policies"},
        /* Session Management Information Elements 10.5.6 */
-       { DE_ACC_POINT_NAME,    "Access Point Name" },
-       { DE_NET_SAPI,  "Network Service Access Point Identifier" },
-       { DE_PRO_CONF_OPT,      "Protocol Configuration Options" },
-       { DE_PD_PRO_ADDR,       "Packet Data Protocol Address" },
-       { DE_QOS,       "Quality Of Service" },
-       { DE_SM_CAUSE,  "SM Cause" },
-       { DE_SM_CAUSE_2, "SM Cause 2" },
-       { DE_LINKED_TI, "Linked TI" },
-       { DE_LLC_SAPI,  "LLC Service Access Point Identifier" },
-       { DE_TEAR_DOWN_IND,     "Tear Down Indicator" },
-       { DE_PACKET_FLOW_ID,    "Packet Flow Identifier" },
-       { DE_TRAFFIC_FLOW_TEMPLATE,     "Traffic Flow Template" },
-       { DE_TMGI, "Temporary Mobile Group Identity (TMGI)" },
-       { DE_MBMS_BEARER_CAP, "MBMS bearer capabilities" },
-       { DE_MBMS_PROT_CONF_OPT, "MBMS protocol configuration options" },
-       { DE_ENH_NSAPI, "Enhanced network service access point identifier" },
-       { DE_REQ_TYPE, "Request type" },
-       { DE_SM_NOTIF_IND, "Notification indicator" },
-       { DE_SM_CONNECTIVITY_TYPE, "Connectivity type" },
+       { DE_ACC_POINT_NAME,             "Access Point Name" },
+       { DE_NET_SAPI,                   "Network Service Access Point Identifier" },
+       { DE_PRO_CONF_OPT,               "Protocol Configuration Options" },
+       { DE_EXT_PRO_CONF_OPT,           "Extended Protocol Configuration Options" },
+       { DE_PD_PRO_ADDR,                "Packet Data Protocol Address" },
+       { DE_QOS,                        "Quality Of Service" },
+       { DE_RE_ATTEMPT_IND,             "Re-attempt Indicator" },
+       { DE_EXT_QOS,                    "Extended Quality Of Service" },
+       { DE_SM_CAUSE,                   "SM Cause" },
+       { DE_SM_CAUSE_2,                 "SM Cause 2" },
+       { DE_LINKED_TI,                  "Linked TI" },
+       { DE_LLC_SAPI,                   "LLC Service Access Point Identifier" },
+       { DE_TEAR_DOWN_IND,              "Tear Down Indicator" },
+       { DE_PACKET_FLOW_ID,             "Packet Flow Identifier" },
+       { DE_TRAFFIC_FLOW_TEMPLATE,      "Traffic Flow Template" },
+       { DE_TMGI,                       "Temporary Mobile Group Identity (TMGI)" },
+       { DE_MBMS_BEARER_CAP,            "MBMS bearer capabilities" },
+       { DE_MBMS_PROT_CONF_OPT,         "MBMS protocol configuration options" },
+       { DE_ENH_NSAPI,                  "Enhanced network service access point identifier" },
+       { DE_REQ_TYPE,                   "Request type" },
+       { DE_SM_NOTIF_IND,               "Notification indicator" },
+       { DE_SM_CONNECTIVITY_TYPE,       "Connectivity type" },
+       { DE_SM_WLAN_OFFLOAD_ACCEPT,     "WLAN offload acceptability" },
+       { DE_NBIFOM_CONT,                "NBIFOM container" },
        /* GPRS Common Information Elements 10.5.7 */
-       { DE_PDP_CONTEXT_STAT,  "PDP Context Status" },
-       { DE_RAD_PRIO,  "Radio Priority" },
-       { DE_GPRS_TIMER,        "GPRS Timer" },
-       { DE_GPRS_TIMER_2,      "GPRS Timer 2" },
-       { DE_GPRS_TIMER_3,      "GPRS Timer 3" },
-       { DE_RAD_PRIO_2, "Radio Priority 2"},
-       { DE_MBMS_CTX_STATUS,   "MBMS context status"},
-       { DE_UPLINK_DATA_STATUS,        "Uplink data status"},
-       { DE_DEVICE_PROPERTIES, "Device properties"},
+       { DE_PDP_CONTEXT_STAT,           "PDP Context Status" },
+       { DE_RAD_PRIO,                   "Radio Priority" },
+       { DE_GPRS_TIMER,                 "GPRS Timer" },
+       { DE_GPRS_TIMER_2,               "GPRS Timer 2" },
+       { DE_GPRS_TIMER_3,               "GPRS Timer 3" },
+       { DE_RAD_PRIO_2,                 "Radio Priority 2"},
+       { DE_MBMS_CTX_STATUS,            "MBMS context status"},
+       { DE_UPLINK_DATA_STATUS,         "Uplink data status"},
+       { DE_DEVICE_PROPERTIES,          "Device properties"},
        { 0, NULL }
 };
 value_string_ext gsm_gm_elem_strings_ext = VALUE_STRING_EXT_INIT(gsm_gm_elem_strings);
@@ -239,9 +261,10 @@ static int hf_gsm_a_sm_qos_ber = -1;
 static int hf_gsm_a_sm_qos_sdu_err_rat = -1;
 static int hf_gsm_a_sm_qos_traff_hdl_pri = -1;
 
+static int hf_gsm_a_gmm_split_pg_cycle_code = -1;
 static int hf_gsm_a_gmm_split_on_ccch = -1;
 static int hf_gsm_a_gmm_non_drx_timer = -1;
-static int hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef = -1;
+static int hf_gsm_a_gmm_cn_spec_drx_cycle_len_coef = -1;
 
 static int hf_gsm_a_gmm_ptmsi_sig =-1;
 static int hf_gsm_a_gmm_ptmsi_sig2 =-1;
@@ -265,6 +288,15 @@ static int hf_gsm_a_sm_tft_traffic_class = -1;
 static int hf_gsm_a_sm_tft_traffic_mask = -1;
 static int hf_gsm_a_sm_tft_flow_label_type = -1;
 static int hf_gsm_a_sm_tft_param_id = -1;
+static int hf_gsm_a_sm_tft_packet_filter = -1;
+static int hf_gsm_a_sm_tft_packet_evaluation_precedence = -1;
+static int hf_gsm_a_sm_tft_packet_filter_length = -1;
+static int hf_gsm_a_sm_tft_authorization_token_value = -1;
+static int hf_gsm_a_sm_tft_media_component_number_value = -1;
+static int hf_gsm_a_sm_tft_ip_flow_number = -1;
+static int hf_gsm_a_sm_tft_packet_filter_identifier = -1;
+static int hf_gsm_a_sm_tft_parameter_content = -1;
+static int hf_gsm_a_sm_tft_packet_filter_component_type_id = -1;
 static int hf_gsm_a_gm_acc_tech_type = -1;
 static int hf_gsm_a_gm_acc_cap_struct_len = -1;
 static int hf_gsm_a_gm_sms_value = -1;
@@ -276,19 +308,26 @@ static int hf_gsm_a_gm_add_upd_type = -1;
 static int hf_gsm_a_gm_fop = -1;
 static int hf_gsm_a_gm_res_of_attach = -1;
 static int hf_gsm_a_gm_type_of_ciph_alg = -1;
+static int hf_gsm_a_gm_type_of_integ_alg = -1;
 static int hf_gsm_a_gm_imeisv_req = -1;
+static int hf_gsm_a_gm_nsapi = -1;
 static int hf_gsm_a_gm_ac_ref_nr = -1;
 static int hf_gsm_a_gm_force_to_standby = -1;
 static int hf_gsm_a_gm_serv_type = -1;
-static int hf_gsm_a_gm_ciph_key_seq_num = -1;
 static int hf_gsm_a_gm_for = -1;
 static int hf_gsm_a_gm_type_of_attach = -1;
 static int hf_gsm_a_gm_tmsi_flag = -1;
+static int hf_gsm_a_gm_power_off = -1;
+static int hf_gsm_a_gm_type_of_detach_mo = -1;
+static int hf_gsm_a_gm_type_of_detach_mt = -1;
 static int hf_gsm_a_gm_update_type = -1;
+static int hf_gsm_a_gm_gprs_timer = -1;
 static int hf_gsm_a_gm_gprs_timer_unit = -1;
 static int hf_gsm_a_gm_gprs_timer_value = -1;
+static int hf_gsm_a_gm_gprs_timer2 = -1;
 static int hf_gsm_a_gm_gprs_timer2_unit = -1;
 static int hf_gsm_a_gm_gprs_timer2_value = -1;
+static int hf_gsm_a_gm_gprs_timer3 = -1;
 static int hf_gsm_a_gm_gprs_timer3_unit = -1;
 static int hf_gsm_a_gm_gprs_timer3_value = -1;
 static int hf_gsm_a_gm_nsapi_5_ul_stat = -1;
@@ -308,16 +347,22 @@ static int hf_gsm_a_gm_pco_pid = -1;
 static int hf_gsm_a_gm_pco_app_spec_info = -1;
 static int hf_gsm_a_gm_type_of_identity = -1;
 int hf_gsm_a_gm_rac = -1;
+static int hf_gsm_a_gm_mta_e = -1;
+static int hf_gsm_a_gm_mta_r = -1;
 static int hf_gsm_a_gm_apc = -1;
 static int hf_gsm_a_gm_otd_a = -1;
 static int hf_gsm_a_gm_otd_b = -1;
 static int hf_gsm_a_gm_gps_a = -1;
 static int hf_gsm_a_gm_gps_b = -1;
 static int hf_gsm_a_gm_gps_c = -1;
+static int hf_gsm_a_gm_motd = -1;
+static int hf_gsm_a_gm_mta_a = -1;
 static int hf_gsm_a_gm_lcs_molr = -1;
 static int hf_gsm_a_gm_mbms = -1;
 static int hf_gsm_a_gm_ims_vops = -1;
 static int hf_gsm_a_gm_emc_bs = -1;
+static int hf_gsm_a_gm_epco = -1;
+static int hf_gsm_a_gm_restrict_ec = -1;
 static int hf_gsm_a_gm_gprs_sms = -1;
 static int hf_gsm_a_gm_req_ms_info_irat = -1;
 static int hf_gsm_a_gm_req_ms_info_irat2 = -1;
@@ -325,6 +370,12 @@ static int hf_gsm_a_gm_ue_usage_setting = -1;
 static int hf_gsm_a_gm_voice_domain_pref_for_eutran = -1;
 static int hf_gsm_a_gm_ptmsi_type = -1;
 static int hf_gsm_a_gm_nri_cont = -1;
+static int hf_gsm_a_gm_paging_time_window = -1;
+static int hf_gsm_a_gm_edrx_value = -1;
+static int hf_gsm_a_gm_mac = -1;
+static int hf_gsm_a_gm_up_integ_ind = -1;
+static int hf_gsm_a_gm_dcn_id = -1;
+static int hf_gsm_a_gm_n3en_ind = -1;
 static int hf_gsm_a_sm_pdp_type_org = -1;
 static int hf_gsm_a_sm_qos_mean_thr = -1;
 static int hf_gsm_a_sm_qos_peak_thr = -1;
@@ -344,6 +395,9 @@ static int hf_gsm_a_sm_qos_max_bitrate_upl_ext2 = -1;
 static int hf_gsm_a_sm_qos_max_bitrate_downl_ext2 = -1;
 static int hf_gsm_a_sm_qos_guar_bitrate_upl_ext2 = -1;
 static int hf_gsm_a_sm_qos_guar_bitrate_downl_ext2 = -1;
+static int hf_gsm_a_sm_qos_maximum_sdu_size = -1;
+static int hf_gsm_a_sm_eplmnc = -1;
+static int hf_gsm_a_sm_ratc = -1;
 static int hf_gsm_a_sm_cause = -1;
 static int hf_gsm_a_sm_cause_2 = -1;
 static int hf_gsm_a_sm_llc_sapi = -1;
@@ -354,6 +408,9 @@ static int hf_gsm_a_sm_enh_nsapi = -1;
 static int hf_gsm_a_sm_req_type = -1;
 static int hf_gsm_a_sm_notif_ind = -1;
 static int hf_gsm_a_sm_connectivity_type = -1;
+static int hf_gsm_a_sm_wlan_utran_offload_accept = -1;
+static int hf_gsm_a_sm_wlan_eutran_offload_accept = -1;
+static int hf_gsm_a_sm_nbifom_cont = -1;
 static int hf_gsm_a_gm_rac_ctrled_early_cm_sending = -1;
 static int hf_gsm_a_gm_rac_pseudo_sync = -1;
 static int hf_gsm_a_gm_rac_vgcs = -1;
@@ -413,6 +470,20 @@ static int hf_gsm_a_gm_rac_fast_down_freq_switch_cap = -1;
 static int hf_gsm_a_gm_rac_tighter_cap = -1;
 static int hf_gsm_a_gm_rac_fanr_cap = -1;
 static int hf_gsm_a_gm_rac_ipa_cap = -1;
+static int hf_gsm_a_gm_rac_geran_nw_sharing_support = -1;
+static int hf_gsm_a_gm_rac_eutra_wb_rsrq_support = -1;
+static int hf_gsm_a_gm_rac_utra_mfbi_support = -1;
+static int hf_gsm_a_gm_rac_eutra_mfbi_support = -1;
+static int hf_gsm_a_gm_rac_dlmc_non_contig_intra_band_recep = -1;
+static int hf_gsm_a_gm_rac_dlmc_inter_band_recep = -1;
+static int hf_gsm_a_gm_rac_dlmc_max_bandwidth = -1;
+static int hf_gsm_a_gm_rac_dlmc_max_nb_dl_ts = -1;
+static int hf_gsm_a_gm_rac_dlmc_max_nb_dl_carriers = -1;
+static int hf_gsm_a_gm_rac_ext_tsc_set_cap_support = -1;
+static int hf_gsm_a_gm_rac_ext_earfcn_value_range = -1;
+static int hf_gsm_a_gm_rac_ec_pch_mon_support = -1;
+static int hf_gsm_a_gm_rac_ms_sync_accuracy = -1;
+static int hf_gsm_a_gm_rac_ext_ec_ul_cov_enh_support = -1;
 static int hf_gsm_a_sm_ti_flag = -1;
 static int hf_gsm_a_sm_ext = -1;
 
@@ -440,21 +511,57 @@ static int hf_gsm_a_gmm_net_cap_srvcc_to_geran = -1;
 static int hf_gsm_a_gmm_net_cap_epc = -1;
 static int hf_gsm_a_gmm_net_cap_nf = -1;
 static int hf_gsm_a_gmm_net_geran_net_sharing = -1;
+static int hf_gsm_a_gmm_net_cap_up_int_prot = -1;
+static int hf_gsm_a_gmm_net_cap_up_gia4 = -1;
+static int hf_gsm_a_gmm_net_cap_up_gia5 = -1;
+static int hf_gsm_a_gmm_net_cap_up_gia6 = -1;
+static int hf_gsm_a_gmm_net_cap_up_gia7 = -1;
+static int hf_gsm_a_gmm_net_cap_epco_ie_ind = -1;
+static int hf_gsm_a_gmm_net_cap_restrict_use_enh_cov = -1;
+static int hf_gsm_a_gmm_net_cap_dc_eutra_nr_cap = -1;
+
+/* Generated from convert_proto_tree_add_text.pl */
+static int hf_gsm_a_gm_presence = -1;
+static int hf_gsm_a_gm_8psk_power_class = -1;
+static int hf_gsm_a_gm_rf_power_capability = -1;
+static int hf_gsm_a_gm_a5_bits = -1;
+static int hf_gsm_a_gm_8psk_power_capability = -1;
+static int hf_gsm_a_gm_extended_dtm_gprs_multi_slot_class = -1;
+static int hf_gsm_a_gm_extended_dtm_egprs_multi_slot_class = -1;
+static int hf_gsm_a_gm_high_multislot_capability = -1;
+static int hf_gsm_a_gm_gmsk_multislot_power_profile = -1;
+static int hf_gsm_a_gm_8psk_multislot_power_profile = -1;
+static int hf_gsm_a_gm_update_result = -1;
+static int hf_gsm_a_gm_radio_priority_pdp = -1;
+static int hf_gsm_a_gm_radio_priority_tom8 = -1;
+static int hf_gsm_a_gm_configuration_protocol = -1;
+static int hf_gsm_a_gm_sm_pco_length = -1;
+static int hf_gsm_a_gm_sm_pco_pcscf_ipv6 = -1;
+static int hf_gsm_a_gm_sm_pco_dns_ipv6 = -1;
+static int hf_gsm_a_gm_sm_pco_dsmipv6_home_agent_ipv6 = -1;
+static int hf_gsm_a_gm_sm_pco_dsmipv6_home_network_ipv6 = -1;
+static int hf_gsm_a_gm_sm_pco_reject_code = -1;
+static int hf_gsm_a_gm_sm_pco_dsmipv6_home_network_prefix_length = -1;
+static int hf_gsm_a_gm_sm_pco_dsmipv6_home_agent_ipv4 = -1;
+static int hf_gsm_a_gm_sm_pco_pcscf_ipv4 = -1;
+static int hf_gsm_a_gm_sm_pco_dns_ipv4 = -1;
+static int hf_gsm_a_gm_sm_pco_ipv4_link_mtu_size = -1;
+static int hf_gsm_a_gm_sm_pco_nbifom_mode = -1;
+static int hf_gsm_a_gm_sm_pco_non_ip_link_mtu_size = -1;
+static int hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_aer = -1;
+static int hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_ul_time_unit = -1;
+static int hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_max_ul_rate = -1;
+static int hf_gsm_a_gm_sm_pco_3gpp_data_off_ue_status = -1;
+static int hf_gsm_a_gm_sm_pco_sel_bearer_ctrl_mode = -1;
+static int hf_gsm_a_gm_sm_pco_add_apn_rate_ctrl_params_ul_time_unit = -1;
+static int hf_gsm_a_gm_sm_pco_add_apn_rate_ctrl_params_max_ul_rate = -1;
+static int hf_gsm_a_gm_sm_pco_pdu_session_id = -1;
+static int hf_gsm_a_gm_sm_pco_pdu_session_address_lifetime = -1;
+static int hf_gsm_a_sm_pdp_type_number = -1;
+static int hf_gsm_a_sm_pdp_address = -1;
+static int hf_gsm_a_gm_ti_value = -1;
 
 /* Initialize the subtree pointers */
-static gint ett_tc_component = -1;
-static gint ett_tc_invoke_id = -1;
-static gint ett_tc_linked_id = -1;
-static gint ett_tc_opr_code = -1;
-static gint ett_tc_err_code = -1;
-static gint ett_tc_prob_code = -1;
-static gint ett_tc_sequence = -1;
-
-static gint ett_gmm_drx = -1;
-static gint ett_gmm_detach_type = -1;
-static gint ett_gmm_attach_type = -1;
-static gint ett_gmm_context_stat = -1;
-static gint ett_gmm_update_type = -1;
 static gint ett_gmm_radio_cap = -1;
 static gint ett_gmm_network_cap = -1;
 static gint ett_gsm_a_gm_msrac_multislot_capability = -1;
@@ -464,12 +571,20 @@ static gint ett_gmm_gprs_timer = -1;
 static gint ett_sm_tft = -1;
 static gint ett_sm_pco = -1;
 
-static dissector_handle_t data_handle;
+static expert_field ei_gsm_a_gm_extraneous_data = EI_INIT;
+static expert_field ei_gsm_a_gm_not_enough_data = EI_INIT;
+static expert_field ei_gsm_a_gm_undecoded = EI_INIT;
+static expert_field ei_gsm_a_gm_apn_too_long = EI_INIT;
+static expert_field ei_gsm_a_gm_missing_mandatory_element = EI_INIT;
+
 static dissector_handle_t rrc_irat_ho_info_handle;
 static dissector_handle_t lte_rrc_ue_eutra_cap_handle;
+static dissector_handle_t nbifom_handle;
 
 static dissector_table_t gprs_sm_pco_subdissector_table; /* GPRS SM PCO PPP Protocols */
 
+static const unit_name_string units_message_messages = { " message", " messages" };
+
 #define        NUM_GSM_GM_ELEM (sizeof(gsm_gm_elem_strings)/sizeof(value_string))
 gint ett_gsm_gm_elem[NUM_GSM_GM_ELEM];
 
@@ -530,19 +645,8 @@ static const value_string gsm_a_gm_type_of_attach_vals[] = {
 static guint16
 de_gmm_attach_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
-       proto_item *tf;
-       proto_tree *tf_tree;
-
-       proto_tree_add_bits_item(tree, hf_gsm_a_gm_ciph_key_seq_num, tvb, offset << 3, 4, ENC_BIG_ENDIAN);
-
-       tf = proto_tree_add_text(tree,
-               tvb, offset, 1,
-               "Attach Type");
-
-       tf_tree = proto_item_add_subtree(tf, ett_gmm_attach_type);
-
-       proto_tree_add_item(tf_tree, hf_gsm_a_gm_for, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(tf_tree, hf_gsm_a_gm_type_of_attach, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_for, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_type_of_attach, tvb, offset, 1, ENC_BIG_ENDIAN);
 
        /* no length check possible */
        return (1);
@@ -573,6 +677,27 @@ de_gmm_ciph_alg(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32
        return (1);
 }
 
+/*
+ * [13] 10.5.5.3a Integrity protection algorithm
+ */
+const value_string gsm_a_gm_type_of_integ_alg_vals[] = {
+       { 0x00, "GPRS Integrity Algorithm GIA/4" },
+       { 0x01, "GPRS Integrity Algorithm GIA/5" },
+       { 0x02, "GPRS Integrity Algorithm GIA/6" },
+       { 0x03, "GPRS Integrity Algorithm GIA/7" },
+       { 0, NULL }
+};
+
+static guint16
+de_gmm_integ_alg(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
+{
+       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (offset << 3) + 4, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_type_of_integ_alg, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+       /* no length check possible */
+       return (1);
+}
+
 /*
  * [9] 10.5.5.4 TMSI status
  */
@@ -594,52 +719,40 @@ de_gmm_tmsi_stat(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint3
 /*
  * [7] 10.5.5.5
  */
+const true_false_string gsm_a_gm_power_off_value = {
+       "power switched off",
+       "normal detach"
+};
+
+const value_string gsm_a_gm_type_of_detach_mo_vals[] = {
+       { 0x01, "GPRS detach" },
+       { 0x02, "IMSI detach" },
+       { 0x03, "Combined GPRS/IMSI detach" },
+       { 0, NULL }
+};
+
+const value_string gsm_a_gm_type_of_detach_mt_vals[] = {
+       { 0x01, "re-attach required" },
+       { 0x02, "re-attach not required" },
+       { 0x03, "IMSI detach (after VLR failure)" },
+       { 0, NULL }
+};
+
 static guint16
 de_gmm_detach_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
-       guint8       oct;
-       guint32      curr_offset;
-       const gchar *str;
-       const gchar *str_power;
-       proto_item  *tf;
-       proto_tree  *tf_tree;
+       guint32 curr_offset;
 
        curr_offset = offset;
 
-       oct = tvb_get_guint8(tvb, curr_offset);
-
-       switch (oct&7)
-       {
-               case 1:  str = "GPRS detach/re-attach required";                            break;
-               case 2:  str = "IMSI detach/re-attach not required";                        break;
-               case 3:  str = "Combined GPRS/IMSI detach/IMSI detach (after VLR failure)"; break;
-               default: str = "Combined GPRS/IMSI detach/re-attach not required";
-       }
-
-       switch (oct&8)
-       {
-               case 8:  str_power = "power switched off"; break;
-               default: str_power = "normal detach";      break;
+       if (pinfo->p2p_dir == P2P_DIR_RECV) {
+               proto_tree_add_item(tree, hf_gsm_a_gm_power_off, tvb, offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_gsm_a_gm_type_of_detach_mo, tvb, offset, 1, ENC_BIG_ENDIAN);
+       } else {
+               proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (offset << 3) + 4, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_gsm_a_gm_type_of_detach_mt, tvb, offset, 1, ENC_BIG_ENDIAN);
        }
 
-       tf = proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "Detach Type");
-
-       tf_tree = proto_item_add_subtree(tf, ett_gmm_detach_type);
-
-       proto_tree_add_text(tf_tree,
-               tvb, curr_offset, 1,
-               "Type: %s (%u)",
-               str,
-               oct&7);
-
-       proto_tree_add_text(tf_tree,
-               tvb, curr_offset, 1,
-               "Power: %s (%u)",
-               str_power,
-               (oct>>3)&1);
-
        curr_offset++;
 
        /* no length check possible */
@@ -649,8 +762,114 @@ de_gmm_detach_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guin
 
 /*
  * [7] 10.5.5.6
- *
- * SPLIT on CCCH, octet 3 (bit 4)
+ */
+
+/* SPLIT PG CYCLE CODE, octet 2 */
+static const value_string gsm_a_gmm_split_pg_cycle_code_strings[] = {
+       {  0, "704 (equivalent to no DRX)" },
+       {  1, "1" },
+       {  2, "2" },
+       {  3, "3" },
+       {  4, "4" },
+       {  5, "5" },
+       {  6, "6" },
+       {  7, "7" },
+       {  8, "8" },
+       {  9, "9" },
+       { 10, "10" },
+       { 11, "11" },
+       { 12, "12" },
+       { 13, "13" },
+       { 14, "14" },
+       { 15, "15" },
+       { 16, "16" },
+       { 17, "17" },
+       { 18, "18" },
+       { 19, "19" },
+       { 20, "20" },
+       { 21, "21" },
+       { 22, "22" },
+       { 23, "23" },
+       { 24, "24" },
+       { 25, "25" },
+       { 26, "26" },
+       { 27, "27" },
+       { 28, "28" },
+       { 29, "29" },
+       { 30, "30" },
+       { 31, "31" },
+       { 32, "32" },
+       { 33, "33" },
+       { 34, "34" },
+       { 35, "35" },
+       { 36, "36" },
+       { 37, "37" },
+       { 38, "38" },
+       { 39, "39" },
+       { 40, "40" },
+       { 41, "41" },
+       { 42, "42" },
+       { 43, "43" },
+       { 44, "44" },
+       { 45, "45" },
+       { 46, "46" },
+       { 47, "47" },
+       { 48, "48" },
+       { 49, "49" },
+       { 50, "50" },
+       { 51, "51" },
+       { 52, "52" },
+       { 53, "53" },
+       { 54, "54" },
+       { 55, "55" },
+       { 56, "56" },
+       { 57, "57" },
+       { 58, "58" },
+       { 59, "59" },
+       { 60, "60" },
+       { 61, "61" },
+       { 62, "62" },
+       { 63, "63" },
+       { 64, "64" },
+       { 65, "71" },
+       { 66, "72" },
+       { 67, "74" },
+       { 68, "75" },
+       { 69, "77" },
+       { 70, "79" },
+       { 71, "80" },
+       { 72, "83" },
+       { 73, "86" },
+       { 74, "88" },
+       { 75, "90" },
+       { 76, "92" },
+       { 77, "96" },
+       { 78, "101" },
+       { 79, "103" },
+       { 80, "107" },
+       { 81, "112" },
+       { 82, "116" },
+       { 83, "118" },
+       { 84, "128" },
+       { 85, "141" },
+       { 86, "144" },
+       { 87, "150" },
+       { 88, "160" },
+       { 89, "171" },
+       { 90, "176" },
+       { 91, "192" },
+       { 92, "214" },
+       { 93, "224" },
+       { 94, "235" },
+       { 95, "256" },
+       { 96, "288" },
+       { 97, "320" },
+       { 98, "352" },
+       { 0, NULL }
+};
+static value_string_ext gsm_a_gmm_split_pg_cycle_code_strings_ext = VALUE_STRING_EXT_INIT(gsm_a_gmm_split_pg_cycle_code_strings);
+
+/* SPLIT on CCCH, octet 3 (bit 4)
  * 0 Split pg cycle on CCCH is not supported by the mobile station
  * 1 Split pg cycle on CCCH is supported by the mobile station
  */
@@ -691,7 +910,7 @@ static const value_string gsm_a_gmm_non_drx_timer_strings[] = {
  * NOTE: For Iu mode and S1 mode, this field (octet 3 bits 8 to 5) is used, but was spare in earlier
  * versions of this protocol.
  */
-static const range_string gsm_a_gmm_cn_spec_drs_cycle_len_coef_strings[] = {
+static const range_string gsm_a_gmm_cn_spec_drx_cycle_len_coef_strings[] = {
        { 0x00, 0x05, "CN Specific DRX cycle length coefficient / value not specified by the MS" },
        { 0x06, 0x06, "CN Specific DRX cycle length coefficient 6 and T = 32" },
        { 0x07, 0x07, "CN Specific DRX cycle length coefficient 7 and T = 64" },
@@ -703,72 +922,15 @@ static const range_string gsm_a_gmm_cn_spec_drs_cycle_len_coef_strings[] = {
 guint16
 de_gmm_drx_param(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
-       guint8       oct;
-       guint32      curr_offset;
-       const gchar *str;
-       proto_item  *tf;
-       proto_tree  *tf_tree;
+       guint32 curr_offset;
 
        curr_offset = offset;
 
-       tf = proto_tree_add_text(tree,
-               tvb, curr_offset, 2,
-               "DRX Parameter");
-
-       tf_tree = proto_item_add_subtree(tf, ett_gmm_drx);
-
-       oct = tvb_get_guint8(tvb, curr_offset);
-
-       switch (oct)
-       {
-               case 0:  str = "704"; break;
-               case 65: str = "71";  break;
-               case 66: str = "72";  break;
-               case 67: str = "74";  break;
-               case 68: str = "75";  break;
-               case 69: str = "77";  break;
-               case 70: str = "79";  break;
-               case 71: str = "80";  break;
-               case 72: str = "83";  break;
-               case 73: str = "86";  break;
-               case 74: str = "88";  break;
-               case 75: str = "90";  break;
-               case 76: str = "92";  break;
-               case 77: str = "96";  break;
-               case 78: str = "101"; break;
-               case 79: str = "103"; break;
-               case 80: str = "107"; break;
-               case 81: str = "112"; break;
-               case 82: str = "116"; break;
-               case 83: str = "118"; break;
-               case 84: str = "128"; break;
-               case 85: str = "141"; break;
-               case 86: str = "144"; break;
-               case 87: str = "150"; break;
-               case 88: str = "160"; break;
-               case 89: str = "171"; break;
-               case 90: str = "176"; break;
-               case 91: str = "192"; break;
-               case 92: str = "214"; break;
-               case 93: str = "224"; break;
-               case 94: str = "235"; break;
-               case 95: str = "256"; break;
-               case 96: str = "288"; break;
-               case 97: str = "320"; break;
-               case 98: str = "352"; break;
-               default: str = "Reserved, interpreted as 1";
-       }
-
-       proto_tree_add_text(tf_tree,
-               tvb, curr_offset, 1,
-               "Split PG Cycle Code: %s (%u)",
-               str,
-               oct);
-
+       proto_tree_add_item(tree, hf_gsm_a_gmm_split_pg_cycle_code, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
        curr_offset++;
-       proto_tree_add_item(tf_tree, hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(tf_tree, hf_gsm_a_gmm_split_on_ccch, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(tf_tree, hf_gsm_a_gmm_non_drx_timer, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gmm_cn_spec_drx_cycle_len_coef, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gmm_split_on_ccch, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gmm_non_drx_timer, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
 
        curr_offset++;
 
@@ -854,7 +1016,7 @@ de_gmm_ptmsi_sig2(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 o
        proto_item_append_text(curr_item, "%s", add_string ? add_string : "");
        curr_offset += 3;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -927,12 +1089,7 @@ de_gmm_rec_npdu_lst(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
                curr_len -= 2;
                oct <<= 8;
 
-               proto_tree_add_text(tree,
-                       tvb, curr_offset, 2,
-                       "NSAPI %d: 0x%02x (%u)",
-                       oct>>20,
-                       (oct>>12)&0xff,
-                       (oct>>12)&0xff);
+               proto_tree_add_uint_format(tree, hf_gsm_a_gm_nsapi, tvb, curr_offset, 2, (oct>>12)&0xff, "NSAPI %d: 0x%02x (%u)", oct>>20, (oct>>12)&0xff, (oct>>12)&0xff);
                curr_offset +=  2;
 
                if (curr_len > 2)
@@ -941,18 +1098,13 @@ de_gmm_rec_npdu_lst(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
                        curr_len--;
                        oct <<= 12;
 
-                       proto_tree_add_text(tree,
-                               tvb, curr_offset-1, 2,
-                               "NSAPI %d: 0x%02x (%u)",
-                               oct>>20,
-                               (oct>>12)&0xff,
-                               (oct>>12)&0xff);
+                       proto_tree_add_uint_format(tree, hf_gsm_a_gm_nsapi, tvb, curr_offset-1, 2, (oct>>12)&0xff, "NSAPI %d: 0x%02x (%u)", oct>>20, (oct>>12)&0xff, (oct>>12)&0xff);
                        curr_offset++;
                }
 
        } while (curr_len > 1);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -1048,6 +1200,26 @@ static const true_false_string gsm_a_gmm_net_geran_net_vals = {
        "Mobile station does not support GERAN network sharing"
 };
 
+static const true_false_string gsm_a_gmm_net_cap_gia_vals = {
+       "Integrity algorithm available",
+       "Integrity algorithm not available"
+};
+
+static const true_false_string gsm_a_gmm_net_cap_epco_ie_ind_vals = {
+       "Used by a mobile station supporting extended protocol configuration options IE",
+       "Used by a mobile station not supporting extended protocol configuration options IE"
+};
+
+static const true_false_string gsm_a_gmm_net_cap_restrict_use_enh_cov_vals = {
+       "Mobile station supports restriction on use of enhanced coverage",
+       "Mobile station does not support restriction on use of enhanced coverage"
+};
+
+static const true_false_string gsm_a_gmm_net_cap_dc_eutra_nr_cap_vals = {
+       "Mobile station supports dual connectivity of E-UTRA with NR",
+       "Mobile station does not support dual connectivity of E-UTRA with NR"
+};
+
 guint16
 de_gmm_ms_net_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
@@ -1125,7 +1297,34 @@ de_gmm_ms_net_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 o
        proto_tree_add_item(tree, hf_gsm_a_gmm_net_geran_net_sharing, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
 
        curr_offset++;
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       NO_MORE_DATA_CHECK(len);
+
+       /* bit 8: User plane integrity protection support */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_up_int_prot, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       /* bit 7: GIA/4 */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_up_gia4, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       /* bit 6: GIA/5 */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_up_gia5, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       /* bit 5: GIA/6 */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_up_gia6, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       /* bit 4: GIA/7 */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_up_gia7, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       /* bit 3: ePCO IE indicator */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_epco_ie_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       /* bit 2: Restriction on use of enhanced coverage capability */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_restrict_use_enh_cov, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       /* bit 1: Dual connectivity of E-UTRA with NR capability */
+       proto_tree_add_item(tree, hf_gsm_a_gmm_net_cap_dc_eutra_nr_cap, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       curr_offset++;
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -1142,9 +1341,7 @@ de_gmm_ms_net_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 o
                guint32 tmp_oct; \
                if (curr_len == 0) \
                { \
-                       proto_tree_add_text(tf_tree, \
-                               tvb, curr_offset, 1, \
-                               "Not enough data available"); \
+                       proto_tree_add_expert(tf_tree, pinfo, &ei_gsm_a_gm_not_enough_data, tvb, curr_offset, 1); \
                } \
                tmp_oct = tvb_get_guint8(tvb, curr_offset); \
                oct |= tmp_oct<<(32-8-bits_in_oct); \
@@ -1293,7 +1490,7 @@ static const value_string gsm_a_gm_ul_egprs2_vals[] = {
        { 0x00, "The mobile station does not support either EGPRS2-A or EGPRS2-B in the uplink" },
        { 0x01, "The mobile station supports EGPRS2-A in the uplink" },
        { 0x02, "The mobile station supports both EGPRS2-A and EGPRS2-B in the uplink" },
-       { 0x03, "This value is not used in this release/version of the specifications. If received it shall be interpreted as 'The mobile station supports both EGPRS2-A and EGPRS2-B in the uplink'" },
+       { 0x03, "The mobile station supports both EGPRS2-A and EGPRS2-B in the uplink" },
        { 0, NULL }
 };
 
@@ -1301,15 +1498,15 @@ static const value_string gsm_a_gm_dl_egprs2_vals[] = {
        { 0x00, "The mobile station does not support either EGPRS2-A or EGPRS2-B in the downlink" },
        { 0x01, "The mobile station supports EGPRS2-A in the downlink" },
        { 0x02, "The mobile station supports both EGPRS2-A and EGPRS2-B in the downlink" },
-       { 0x03, "This value is not used in this release/version of the specifications. If received it shall be interpreted as 'The mobile station supports both EGPRS2-A and EGPRS2-B in the downlink'" },
+       { 0x03, "The mobile station supports both EGPRS2-A and EGPRS2-B in the downlink" },
        { 0, NULL }
 };
 
 static const value_string gsm_a_gm_geran_to_eutra_support_in_geran_ptm_vals[] = {
        { 0x00, "None" },
-       { 0x01, "E-UTRAN Neighbour Cell measurements and MS autonomous cell reselection to E-UTRAN supported" },
-       { 0x02, "CCN towards E-UTRAN, E-UTRAN Neighbour Cell measurement reporting and Network controlled cell reselection to E-UTRAN supported in addition to capabilities indicated by '01'" },
-       { 0x03, "PS Handover to E-UTRAN supported in addition to capabilities indicated by '01' and '10'" },
+       { 0x01, "E-UTRAN neighbour cell measurements and MS autonomous cell reselection to E-UTRAN supported" },
+       { 0x02, "E-UTRAN neighbour cell meas and report, MS autonomous cell resel, CCN and network controlled cell reselection to E-UTRAN" },
+       { 0x03, "E-UTRAN neighbour cell meas and report, MS autonomous cell resel, CCN, network controlled cell reselection and PS Handover to E-UTRAN" },
        { 0, NULL }
 };
 
@@ -1333,13 +1530,117 @@ static const value_string gsm_a_gm_alt_efta_multi_slot_class_vals[] = {
        { 0, NULL }
 };
 
+static const value_string gsm_a_gm_dlmc_non_contig_intra_band_recep_vals[] = {
+       { 0x00, "Not supported" },
+       { 0x01, "Supported in band E-GSM or GSM850" },
+       { 0x02, "Supported in band DCS1800 or PCS1900" },
+       { 0x03, "Supported in band E-GSM, or GSM850, or DCS1800 or PCS1900" },
+       { 0, NULL }
+};
+
+static const true_false_string gsm_a_gm_dlmc_inter_band_recep_val = {
+       "Supported in band combination (E-GSM, DCS1800), or band combination (GSM850, PCS1900)",
+       "Not supported"
+};
+
+static const value_string gsm_a_gm_dlmc_max_bandwidth_vals[] = {
+       { 0x00, "5 MHz" },
+       { 0x01, "10 MHz" },
+       { 0x02, "15 MHz" },
+       { 0x03, "20 MHz" },
+       { 0, NULL }
+};
+
+static void
+gsm_a_gm_dlmc_max_nb_dl_ts_fmt(gchar *s, guint32 v)
+{
+       if (v < 0x3E)
+               g_snprintf(s, ITEM_LABEL_LENGTH, "%u TS supported (%u)",
+                          2*v + 6, v);
+       else
+               g_snprintf(s, ITEM_LABEL_LENGTH, "Reserved (%u)", v);
+}
+
+static const value_string gsm_a_gm_dlmc_max_nb_dl_carriers_vals[] = {
+       { 0x00, "2 carriers supported" },
+       { 0x01, "4 carriers supported" },
+       { 0x02, "6 carriers supported" },
+       { 0x03, "8 carriers supported" },
+       { 0x04, "10 carriers supported" },
+       { 0x05, "12 carriers supported" },
+       { 0x06, "14 carriers supported" },
+       { 0x07, "16 carriers supported" },
+       { 0, NULL }
+};
+
+static const value_string gsm_a_gm_8psk_power_class_vals[] = {
+       {0x00, "8PSK modulation not supported for uplink" },
+       {0x01, "Power class E1"},
+       {0x02, "Power class E2"},
+       {0x03, "Power class E3"},
+       {0, NULL},
+};
+
+
+static const value_string gsm_a_gm_8psk_power_cap_vals[] = {
+       {0x00, "Reserved" },
+       {0x01, "Power class E1"},
+       {0x02, "Power class E2"},
+       {0x03, "Power class E3"},
+       {0, NULL},
+};
+
+static const value_string gsm_a_gm_extended_dtm_gprs_multi_slot_class_vals[] = {
+       {0x00,  "Unused. If received, it shall be interpreted as Multislot class 5 supported" },
+       {0x01,  "Unused. If received, it shall be interpreted as Multislot class 5 supported"},
+       {0x02,  "Unused. If received, it shall be interpreted as Multislot class 5 supported"},
+       {0x03,  "Unused. If received, it shall be interpreted as Multislot class 5 supported"},
+       {0x10,  "Multislot class 5 supported"},
+       {0x11,  "Multislot class 6 supported"},
+       {0x12,  "Unused. If received, it shall be interpreted as Multislot class 5 supported"},
+       {0x13,  "Unused. If received, it shall be interpreted as Multislot class 5 supported"},
+       {0x20,  "Multislot class 9 supported"},
+       {0x21,  "Multislot class 10 supported"},
+       {0x22,  "Unused. If received, it shall be interpreted as Multislot class 9 supported"},
+       {0x23,  "Unused. If received, it shall be interpreted as Multislot class 9 supported"},
+       {0x30,  "Multislot class 11 supported"},
+       {0x31,  "Unused. If received, it shall be interpreted as Multislot class 11 supported"},
+       {0x32,  "Unused. If received, it shall be interpreted as Multislot class 11 supported"},
+       {0x33,  "Unused. If received, it shall be interpreted as Multislot class 11 supported"},
+       {0, NULL}
+};
+
+static const value_string gsm_a_gm_gmsk_multislot_power_profile_vals[] = {
+       {0x00,  "GMSK_MULTISLOT_POWER_PROFILE 0" },
+       {0x01,  "GMSK_MULTISLOT_POWER_PROFILE 1"},
+       {0x02,  "GMSK_MULTISLOT_POWER_PROFILE 2"},
+       {0x03,  "GMSK_MULTISLOT_POWER_PROFILE 3"},
+       {0, NULL}
+};
+
+static const value_string gsm_a_gm_8psk_multislot_power_profile_vals[] = {
+       {0x00,  "8-PSK_MULTISLOT_POWER_PROFILE 0" },
+       {0x01,  "8-PSK_MULTISLOT_POWER_PROFILE 1"},
+       {0x02,  "8-PSK_MULTISLOT_POWER_PROFILE 2"},
+       {0x03,  "8-PSK_MULTISLOT_POWER_PROFILE 3"},
+       {0, NULL}
+};
+
+static const value_string gsm_a_gm_ec_pch_mon_support_vals[] = {
+       {0x00, "PCH supported"},
+       {0x01, "EC-PCH supported"},
+       {0x02, "PCH and EC-PCH supported"},
+       {0x03, "Reserved"},
+       {0, NULL}
+};
+
 guint16
 de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
        guint32      curr_offset;
        guint        curr_len;
        int          bit_offset;
-       proto_item  *tf = NULL, *mc_item = NULL;
+       proto_item  *tf = NULL, *mc_item = NULL, *ti;
        proto_tree  *tf_tree = NULL, *mc_tree = NULL;
        guint32      oct;
        guchar       bits_in_oct;
@@ -1394,11 +1695,9 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                }
 
                indx++;
-               tf = proto_tree_add_text(tree,
+               tf_tree = proto_tree_add_subtree_format(tree,
                                tvb, curr_offset, 1,
-                               "MS RA capability %d", indx);
-
-               tf_tree = proto_item_add_subtree(tf, ett_gmm_radio_cap);
+                               ett_gmm_radio_cap, &tf, "MS RA capability %d", indx);
 
                /*
                 * Access Technology
@@ -1456,9 +1755,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                                        default:   str = "This should not happen";
                                }
 
-                               proto_tree_add_text(tf_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "Presence: %s (%u)", str, oct>>(32-bits_needed));
+                               proto_tree_add_uint_format_value(tf_tree, hf_gsm_a_gm_presence, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed), "%s (%u)", str, oct>>(32-bits_needed));
                                bit_offset++;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1492,7 +1789,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
                                acc_type = oct>>(32-bits_needed);
 
-                               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_cap_struct_len, tvb, bit_offset, 7, ENC_BIG_ENDIAN);
+                               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_tech_type, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
                                bit_offset += 4;
 
                                curr_bits_length  -= bits_needed;
@@ -1553,9 +1850,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                                        str = "Not specified??";
 
                                /* decode_bits_in_field(gint bit_offset, gint no_of_bits, guint64 value)*/
-                               proto_tree_add_text(tf_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "%s RF Power Capability, GMSK Power Class: %s (%u)", decode_bits_in_field(bit_offset, 3, value), str, value);
+                               proto_tree_add_uint_format(tf_tree, hf_gsm_a_gm_rf_power_capability, tvb, curr_offset-1-add_octets, 1+add_octets, value,
+                                                                                               "%s RF Power Capability, GMSK Power Class: %s (%u)", decode_bits_in_field(bit_offset, 3, value), str, value);
                                bit_offset        += 3;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1569,18 +1865,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
                                value = tvb_get_bits8(tvb, bit_offset, 2);
                                /* analyse bits */
-                               switch (value)
-                               {
-                                       case 0x00: str = "8PSK modulation not supported for uplink"; break;
-                                       case 0x01: str = "Power class E1"; break;
-                                       case 0x02: str = "Power class E2"; break;
-                                       case 0x03: str = "Power class E3"; break;
-                                       default:   str = "This should not happen";
-                               }
-
-                               proto_tree_add_text(tf_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "8PSK Power Class: %s (%u)", str, value);
+                               proto_tree_add_uint(tf_tree, hf_gsm_a_gm_8psk_power_class, tvb, curr_offset-1-add_octets, 1+add_octets, value);
                                bit_offset        += 2;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1633,9 +1918,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                else
                        str = "Not specified??";
 
-               proto_tree_add_text(tf_tree,
-                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                       "%s RF Power Capability, GMSK Power Class: %s (%u)", decode_bits_in_field(bit_offset, 3, value), str, value);
+               proto_tree_add_uint_format(tf_tree, hf_gsm_a_gm_rf_power_capability, tvb, curr_offset-1-add_octets, 1+add_octets, value,
+                                               "%s RF Power Capability, GMSK Power Class: %s (%u)", decode_bits_in_field(bit_offset, 3, value), str, value);
 
                bit_offset        += 3;
                curr_bits_length  -= bits_needed;
@@ -1651,10 +1935,9 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                /* analyse bits */
                if ((oct>>(32-bits_needed)) == 0)
                {
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1-add_octets, 1+add_octets,
-                               "A5 Bits: Same values apply for parameters as in the immediately preceding Access capabilities field within this IE (%u)",
-                               oct>>(32-bits_needed));
+                       proto_tree_add_uint_format_value(tf_tree, hf_gsm_a_gm_a5_bits, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed),
+                                               "Same values apply for parameters as in the immediately preceding Access capabilities field within this IE (%u)",
+                                               oct>>(32-bits_needed));
                        bit_offset++;
                        curr_bits_length  -= bits_needed;
                        oct              <<= bits_needed;
@@ -1664,9 +1947,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                {
                        int i;
 
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1-add_octets, 1+add_octets,
-                               "A5 Bits: A5 bits follow (%u)", oct>>(32-bits_needed));
+                       proto_tree_add_uint_format_value(tf_tree, hf_gsm_a_gm_a5_bits, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed), "A5 bits follow (%u)", oct>>(32-bits_needed));
 
                        bit_offset++;
                        curr_bits_length  -= bits_needed;
@@ -1689,9 +1970,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                                        default:   str = "This should not happen";
                                }
 
-                               proto_tree_add_text(tf_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "A5/%d: %s (%u)", i, str, oct>>(32-bits_needed));
+                               proto_tree_add_uint_format(tf_tree, hf_gsm_a_gm_a5_bits, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed), "A5/%d: %s (%u)", i, str, oct>>(32-bits_needed));
                                bit_offset++;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1775,9 +2054,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        /* analyse bits */
                        if ((oct>>(32-bits_needed)) == 0)
                        {
-                               proto_tree_add_text(mc_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "HSCSD multislot class: Bits are not available (%u)", oct>>(32-bits_needed));
+                               proto_tree_add_uint_format_value(mc_tree, hf_gsm_a_gm_rac_hscsd_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF,
+                                                                                                "Bits are not available (%u)", oct>>(32-bits_needed));
                                bit_offset++;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1812,9 +2090,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        /* analyse bits */
                        if ((oct>>(32-bits_needed)) == 0)
                        {
-                               proto_tree_add_text(mc_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "GPRS multislot class: Bits are not available (%u)", oct>>(32-bits_needed));
+                               proto_tree_add_uint_format_value(mc_tree, hf_gsm_a_gm_rac_gprs_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF,
+                                                                                               "Bits are not available (%u)", oct>>(32-bits_needed));
                                bit_offset++;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1861,9 +2138,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        /* analyse bits */
                        if ((oct>>(32-bits_needed)) == 0)
                        {
-                               proto_tree_add_text(mc_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "SMS/SM values: Bits are not available (%u)", oct>>(32-bits_needed));
+                               proto_tree_add_uint_format_value(mc_tree, hf_gsm_a_gm_sms_value, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF,
+                                                                                               "Bits are not available (%u)", oct>>(32-bits_needed));
                                bit_offset++;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1912,9 +2188,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        /* analyse bits */
                        if ((oct>>(32-bits_needed)) == 0)
                        {
-                               proto_tree_add_text(mc_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "ECSD multislot class: Bits are not available (%u)", oct>>(32-bits_needed));
+                               proto_tree_add_uint_format_value(mc_tree, hf_gsm_a_gm_rac_ecsd_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF,
+                                                                                               "Bits are not available (%u)", oct>>(32-bits_needed));
                                bit_offset++;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -1949,9 +2224,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        /* analyse bits */
                        if ((oct>>(32-bits_needed)) == 0)
                        {
-                               proto_tree_add_text(mc_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "EGPRS multislot class: Bits are not available (%u)", oct>>(32-bits_needed));
+                               proto_tree_add_uint_format_value(mc_tree, hf_gsm_a_gm_rac_egprs_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF,
+                                                                                               "Bits are not available (%u)", oct>>(32-bits_needed));
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
                                bits_in_oct       -= bits_needed;
@@ -1998,9 +2272,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        /* analyse bits */
                        if ((oct>>(32-bits_needed)) == 0)
                        {
-                               proto_tree_add_text(mc_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "DTM GPRS Multi Slot Class: Bits are not available (%u)", oct>>(32-bits_needed));
+                               proto_tree_add_uint_format_value(mc_tree, hf_gsm_a_gm_rac_dtm_gprs_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF,
+                                                                                               "Bits are not available (%u)", oct>>(32-bits_needed));
                                bit_offset++;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -2076,6 +2349,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                 */
                bits_needed = 1;
                GET_DATA;
+               value = oct>>(32-bits_needed);
 
                proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_8psk_pow_cap_pres, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
                bit_offset++;
@@ -2084,7 +2358,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                bits_in_oct       -= bits_needed;
 
                /* analyse bits */
-               if ((oct>>(32-bits_needed)) == 1)
+               if (value == 1)
                {
                        /*
                         * 8PSK Power Capability
@@ -2092,19 +2366,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        bits_needed = 2;
                        GET_DATA;
 
-                       /* analyse bits */
-                       switch (oct>>(32-bits_needed))
-                       {
-                               case 0x00: str = "Reserved";       break;
-                               case 0x01: str = "Power class E1"; break;
-                               case 0x02: str = "Power class E2"; break;
-                               case 0x03: str = "Power class E3"; break;
-                               default:   str = "This should not happen";
-                       }
 
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1-add_octets, 1+add_octets,
-                               "8PSK Power Capability: %s (%u)", str, oct>>(32-bits_needed));
+                       proto_tree_add_uint(tf_tree, hf_gsm_a_gm_8psk_power_capability, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed));
                        bit_offset        += 2;
                        curr_bits_length  -= bits_needed;
                        oct              <<= bits_needed;
@@ -2205,9 +2468,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                /* analyse bits */
                if ((oct>>(32-bits_needed)) == 0)
                {
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1-add_octets, 1+add_octets,
-                               "Extended DTM (E)GPRS Multi Slot Class: Bits are not available (%u)", oct>>(32-bits_needed));
+                       proto_tree_add_uint_format_value(tf_tree, hf_gsm_a_gm_extended_dtm_egprs_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF, "Bits are not available (%u)", oct>>(32-bits_needed));
                        curr_bits_length  -= bits_needed;
                        oct              <<= bits_needed;
                        bits_in_oct       -= bits_needed;
@@ -2227,30 +2488,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        GET_DATA;
 
                        /* analyse bits */
-                       switch ((oct>>(32-bits_needed))|(dtm_gprs_mslot<<4))
-                       {
-                               case 0x00: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                               case 0x01: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                               case 0x02: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                               case 0x03: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                               case 0x10: str = "Multislot class 5 supported";  break;
-                               case 0x11: str = "Multislot class 6 supported";  break;
-                               case 0x12: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                               case 0x13: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                               case 0x20: str = "Multislot class 9 supported";  break;
-                               case 0x21: str = "Multislot class 10 supported"; break;
-                               case 0x22: str = "Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
-                               case 0x23: str = "Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
-                               case 0x30: str = "Multislot class 11 supported"; break;
-                               case 0x31: str = "Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
-                               case 0x32: str = "Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
-                               case 0x33: str = "Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
-                               default:   str = "This should not happen";
-                       }
-
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1-add_octets, 1+add_octets,
-                               "Extended DTM GPRS Multi Slot Class: %s (%u)", str, oct>>(32-bits_needed));
+                       proto_tree_add_uint(tf_tree, hf_gsm_a_gm_extended_dtm_gprs_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, (oct>>(32-bits_needed))|(dtm_gprs_mslot<<4));
                        bit_offset        += 2;
                        curr_bits_length  -= bits_needed;
                        oct              <<= bits_needed;
@@ -2265,30 +2503,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                                GET_DATA;
 
                                /* analyse bits */
-                               switch ((oct>>(32-bits_needed))|(dtm_egprs_mslot<<4) )
-                               {
-                                       case 0x00: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                                       case 0x01: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                                       case 0x02: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                                       case 0x03: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                                       case 0x10: str = "Multislot class 5 supported";  break;
-                                       case 0x11: str = "Multislot class 6 supported";  break;
-                                       case 0x12: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                                       case 0x13: str = "Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
-                                       case 0x20: str = "Multislot class 9 supported";  break;
-                                       case 0x21: str = "Multislot class 10 supported"; break;
-                                       case 0x22: str = "Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
-                                       case 0x23: str = "Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
-                                       case 0x30: str = "Multislot class 11 supported"; break;
-                                       case 0x31: str = "Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
-                                       case 0x32: str = "Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
-                                       case 0x33: str = "Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
-                                       default:   str = "This should not happen";
-                               }
-
-                               proto_tree_add_text(tf_tree,
-                                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                       "Extended DTM EGPRS Multi Slot Class: %s (%u)", str, oct>>(32-bits_needed));
+                               proto_tree_add_uint(tf_tree, hf_gsm_a_gm_extended_dtm_egprs_multi_slot_class, tvb, curr_offset-1-add_octets, 1+add_octets, (oct>>(32-bits_needed))|(dtm_egprs_mslot<<4));
                                bit_offset        += 2;
                                curr_bits_length  -= bits_needed;
                                oct              <<= bits_needed;
@@ -2317,9 +2532,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                /* analyse bits */
                if ((oct>>(32-bits_needed)) == 0)
                {
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1-add_octets, 1+add_octets,
-                               "High Multislot Capability: Bits are not available (%u)", oct>>(32-bits_needed));
+                       proto_tree_add_uint_format_value(tf_tree, hf_gsm_a_gm_high_multislot_capability, tvb, curr_offset-1-add_octets, 1+add_octets, 0xFF, "Bits are not available (%u)", oct>>(32-bits_needed));
                        bit_offset++;
                        curr_bits_length  -= bits_needed;
                        oct              <<= bits_needed;
@@ -2339,14 +2552,10 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                        GET_DATA;
 
                        /* analyse bits */
-                       proto_tree_add_text(tf_tree,
-                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                                           "High Multislot Capability: 0x%02x (%u)"
-                                           " - This field effect all other multislot fields."
-                                           " To understand the value please read TS 24.008 5.6.0"
-                                           " Release 5 Chap 10.5.5.12 Page 406",
-                                           oct>>(32-bits_needed),
-                                           oct>>(32-bits_needed));
+                       ti = proto_tree_add_uint(tf_tree, hf_gsm_a_gm_high_multislot_capability, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed));
+                       proto_item_append_text(ti, " - This field effect all other multislot fields."
+                                                                           " To understand the value please read TS 24.008 5.6.0"
+                                                                           " Release 5 Chap 10.5.5.12 Page 406");
                        bit_offset        += 2;
                        curr_bits_length  -= bits_needed;
                        oct              <<= bits_needed;
@@ -2404,18 +2613,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                GET_DATA;
 
                /* analyse bits */
-               switch (oct>>(32-bits_needed) )
-               {
-                       case 0x00: str = "GMSK_MULTISLOT_POWER_PROFILE 0"; break;
-                       case 0x01: str = "GMSK_MULTISLOT_POWER_PROFILE 1"; break;
-                       case 0x02: str = "GMSK_MULTISLOT_POWER_PROFILE 2"; break;
-                       case 0x03: str = "GMSK_MULTISLOT_POWER_PROFILE 3"; break;
-                       default:   str = "This should not happen";
-               }
-
-               proto_tree_add_text(tf_tree,
-                       tvb, curr_offset-1-add_octets, 1+add_octets,
-                       "GMSK Multislot Power Profile: %s (%u)", str, oct>>(32-bits_needed));
+               proto_tree_add_uint(tf_tree, hf_gsm_a_gm_gmsk_multislot_power_profile, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed));
                bit_offset        += 2;
                curr_bits_length  -= bits_needed;
                oct              <<= bits_needed;
@@ -2428,17 +2626,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                GET_DATA;
 
                /* analyse bits */
-               switch (oct>>(32-bits_needed) )
-               {
-                       case 0x00: str = "8-PSK_MULTISLOT_POWER_PROFILE 0"; break;
-                       case 0x01: str = "8-PSK_MULTISLOT_POWER_PROFILE 1"; break;
-                       case 0x02: str = "8-PSK_MULTISLOT_POWER_PROFILE 2"; break;
-                       case 0x03: str = "8-PSK_MULTISLOT_POWER_PROFILE 3"; break;
-                       default:   str = "This should not happen";
-               }
-
-               proto_tree_add_text(tf_tree, tvb, curr_offset-1-add_octets, 1+add_octets,
-                                   "8-PSK Multislot Power Profile: %s (%u)", str, oct>>(32-bits_needed));
+               proto_tree_add_uint(tf_tree, hf_gsm_a_gm_8psk_multislot_power_profile, tvb, curr_offset-1-add_octets, 1+add_octets, oct>>(32-bits_needed));
                bit_offset        += 2;
                curr_bits_length  -= bits_needed;
                oct              <<= bits_needed;
@@ -2910,53 +3098,268 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
                bits_in_oct -= bits_needed;
 
                 /*
-                * we are too long ... so jump over it
+                * GERAN Network Sharing support
                 */
-               while (curr_bits_length > 0)
+               bits_needed = 1;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_geran_nw_sharing_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+                /*
+                * E-UTRA Wideband RSRQ measurements support
+                */
+               bits_needed = 1;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_eutra_wb_rsrq_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+               /*
+                * Release 12
+                */
+
+                /*
+                * UTRA Multiple Frequency Band Indicators support
+                */
+               bits_needed = 1;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_utra_mfbi_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+                /*
+                * E-UTRA Multiple Frequency Band Indicators support
+                */
+               bits_needed = 1;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_eutra_mfbi_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+                /*
+                * DLMC Capability
+                */
+               bits_needed = 1;
+               GET_DATA;
+               if ((oct>>(32-bits_needed)) == 0)
                {
-                       if (curr_bits_length > 8)
-                               bits_needed = 8;
-                       else
-                               bits_needed = curr_bits_length;
-                       GET_DATA;
-                       curr_bits_length  -= bits_needed;
-                       oct              <<= bits_needed;
-                       bits_in_oct       -= bits_needed;
+                       bit_offset += bits_needed;
+                       curr_bits_length -= bits_needed;
+                       oct <<= bits_needed;
+                       bits_in_oct -= bits_needed;
                }
+               else
+               {
+                       bit_offset += bits_needed;
+                       curr_bits_length -= bits_needed;
+                       oct  <<= bits_needed;
+                       bits_in_oct -= bits_needed;
 
+                       bits_needed = 1;
+                       GET_DATA;
+                       if ((oct>>(32-bits_needed)) == 0)
+                       {
+                               bit_offset += bits_needed;
+                               curr_bits_length -= bits_needed;
+                               oct <<= bits_needed;
+                               bits_in_oct -= bits_needed;
+                       }
+                       else
+                       {
+                               bit_offset += bits_needed;
+                               curr_bits_length -= bits_needed;
+                               oct <<= bits_needed;
+                               bits_in_oct -= bits_needed;
 
-       } while (1);
+                               /*
+                                * DLMC - Non-contiguous intra-band reception
+                               */
+                               bits_needed = 2;
+                               GET_DATA;
+                               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_dlmc_non_contig_intra_band_recep, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
+                               bit_offset += bits_needed;
+                               curr_bits_length -= bits_needed;
+                               oct <<= bits_needed;
+                               bits_in_oct -= bits_needed;
 
-       curr_offset += curr_len;
+                               /*
+                                * DLMC - Inter-band reception
+                               */
+                               bits_needed = 1;
+                               GET_DATA;
+                               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_dlmc_inter_band_recep, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+                               bit_offset += bits_needed;
+                               curr_bits_length -= bits_needed;
+                               oct <<= bits_needed;
+                               bits_in_oct -= bits_needed;
+                       }
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+                       /*
+                        * DLMC - Maximum Bandwidth
+                       */
+                       bits_needed = 2;
+                       GET_DATA;
+                       proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_dlmc_max_bandwidth, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
+                       bit_offset += bits_needed;
+                       curr_bits_length -= bits_needed;
+                       oct <<= bits_needed;
+                       bits_in_oct -= bits_needed;
 
-       return (curr_offset - offset);
-}
+                       /*
+                        * DLMC - Maximum Number of Downlink Timeslots
+                       */
+                       bits_needed = 6;
+                       GET_DATA;
+                       proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_dlmc_max_nb_dl_ts, tvb, bit_offset, 6, ENC_BIG_ENDIAN);
+                       bit_offset += bits_needed;
+                       curr_bits_length -= bits_needed;
+                       oct <<= bits_needed;
+                       bits_in_oct -= bits_needed;
 
-/*
- * [9] 10.5.5.14
- */
-static const range_string gmm_cause_vals[] = {
-       { 0x00, 0x01, "Protocol error, unspecified"},
-       { 0x02, 0x02, "IMSI unknown in HLR"},
-       { 0x03, 0x03, "Illegal MS"},
-       { 0x04, 0x04, "IMSI unknown in VLR"}, /* Annex G.1 */
-       { 0x05, 0x05, "IMEI not accepted"}, /* Annex G.1 */
-       { 0x06, 0x06, "Illegal ME"},
-       { 0x07, 0x07, "GPRS services not allowed"},
-       { 0x08, 0x08, "GPRS services and non-GPRS services not allowed"},
-       { 0x09, 0x09, "MS identity cannot be derived by the network"},
-       { 0x0a, 0x0a, "Implicitly detached"},
-       { 0x0b, 0x0b, "PLMN not allowed"},
-       { 0x0c, 0x0c, "Location Area not allowed"},
-       { 0x0d, 0x0d, "Roaming not allowed in this location area"},
-       { 0x0e, 0x0e, "GPRS services not allowed in this PLMN"},
-       { 0x0f, 0x0f, "No Suitable Cells In Location Area"},
-       { 0x10, 0x10, "MSC temporarily not reachable"},
-       { 0x11, 0x11, "Network failure"},
-       { 0x12, 0x13, "Protocol error, unspecified"},
-       { 0x14, 0x14, "MAC failure"},
+                       /*
+                        * DLMC - Maximum Number of Downlink Carriers
+                       */
+                       bits_needed = 3;
+                       GET_DATA;
+                       proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_dlmc_max_nb_dl_carriers, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
+                       bit_offset += bits_needed;
+                       curr_bits_length -= bits_needed;
+                       oct <<= bits_needed;
+                       bits_in_oct -= bits_needed;
+               }
+
+               /*
+                * Extended TSC Set Capability support
+                */
+               bits_needed = 1;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_ext_tsc_set_cap_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+               /*
+                * Extended EARFCN value range
+                */
+               bits_needed = 1;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_ext_earfcn_value_range, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+               /*
+                * Release 13
+                */
+
+               /*
+                * (EC-)PCH monitoring support
+                */
+               bits_needed = 2;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_ec_pch_mon_support, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+               /*
+                * Release 14
+                */
+
+               /*
+                * MS Sync Accuracy
+                */
+               bits_needed = 1;
+               GET_DATA;
+               if ((oct>>(32-bits_needed)) == 0)
+               {
+                       bit_offset += bits_needed;
+                       curr_bits_length -= bits_needed;
+                       oct <<= bits_needed;
+                       bits_in_oct -= bits_needed;
+               }
+               else
+               {
+                       bits_needed = 4;
+                       GET_DATA;
+                       proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_ms_sync_accuracy, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
+                       bit_offset += bits_needed;
+                       curr_bits_length -= bits_needed;
+                       oct <<= bits_needed;
+                       bits_in_oct -= bits_needed;
+               }
+
+               /*
+                * EC uplink coverage enhancement support
+                */
+               bits_needed = 1;
+               GET_DATA;
+               proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_rac_ext_ec_ul_cov_enh_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
+               bit_offset += bits_needed;
+               curr_bits_length -= bits_needed;
+               oct <<= bits_needed;
+               bits_in_oct -= bits_needed;
+
+                /*
+                * we are too long ... so jump over it
+                */
+               while (curr_bits_length > 0)
+               {
+                       if (curr_bits_length > 8)
+                               bits_needed = 8;
+                       else
+                               bits_needed = curr_bits_length;
+                       GET_DATA;
+                       curr_bits_length  -= bits_needed;
+                       oct              <<= bits_needed;
+                       bits_in_oct       -= bits_needed;
+               }
+
+
+       } while (1);
+
+       curr_offset += curr_len;
+
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
+
+       return (curr_offset - offset);
+}
+
+/*
+ * [9] 10.5.5.14
+ */
+static const range_string gmm_cause_vals[] = {
+       { 0x00, 0x01, "Protocol error, unspecified"},
+       { 0x02, 0x02, "IMSI unknown in HLR"},
+       { 0x03, 0x03, "Illegal MS"},
+       { 0x04, 0x04, "IMSI unknown in VLR"}, /* Annex G.1 */
+       { 0x05, 0x05, "IMEI not accepted"}, /* Annex G.1 */
+       { 0x06, 0x06, "Illegal ME"},
+       { 0x07, 0x07, "GPRS services not allowed"},
+       { 0x08, 0x08, "GPRS services and non-GPRS services not allowed"},
+       { 0x09, 0x09, "MS identity cannot be derived by the network"},
+       { 0x0a, 0x0a, "Implicitly detached"},
+       { 0x0b, 0x0b, "PLMN not allowed"},
+       { 0x0c, 0x0c, "Location Area not allowed"},
+       { 0x0d, 0x0d, "Roaming not allowed in this location area"},
+       { 0x0e, 0x0e, "GPRS services not allowed in this PLMN"},
+       { 0x0f, 0x0f, "No Suitable Cells In Location Area"},
+       { 0x10, 0x10, "MSC temporarily not reachable"},
+       { 0x11, 0x11, "Network failure"},
+       { 0x12, 0x13, "Protocol error, unspecified"},
+       { 0x14, 0x14, "MAC failure"},
        { 0x15, 0x15, "Synch failure"},
        { 0x16, 0x16, "Congestion"},
        { 0x17, 0x17, "GSM authentication unacceptable"},
@@ -3016,7 +3419,6 @@ guint16
 de_gmm_rai(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
        proto_tree *subtree;
-       proto_item *item;
        guint32     mcc;
        guint32     mnc;
        guint32     lac;
@@ -3037,13 +3439,12 @@ de_gmm_rai(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset,
        lac = tvb_get_ntohs(tvb, curr_offset+3);
        rac = tvb_get_guint8(tvb, curr_offset+5);
 
-       item = proto_tree_add_text(tree,
-               tvb, curr_offset, 6,
+       subtree = proto_tree_add_subtree_format(tree,
+               tvb, curr_offset, 6, ett_gmm_rai, NULL,
                "Routing area identification: %x-%x-%u-%u",
                mcc, mnc, lac, rac);
 
-       subtree = proto_item_add_subtree(item, ett_gmm_rai);
-       dissect_e212_mcc_mnc(tvb, pinfo, subtree, offset, TRUE);
+       dissect_e212_mcc_mnc(tvb, pinfo, subtree, offset, E212_RAI, TRUE);
 
        proto_tree_add_item(subtree, hf_gsm_a_lac, tvb, curr_offset+3, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree, hf_gsm_a_gm_rac, tvb, curr_offset+5, 1, ENC_BIG_ENDIAN);
@@ -3076,32 +3477,26 @@ de_gmm_rai2(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset,
 /*
  * [7] 10.5.5.17
  */
+static const value_string gsm_a_gm_update_res_vals[] = {
+       {0,  "RA updated" },
+       {1,  "Combined RA/LA updated"},
+       {2,  "Reserved"},
+       {3,  "Reserved"},
+       {4,  "Reserved"},
+       {5,  "Reserved"},
+       {6,  "Reserved"},
+       {7,  "Reserved"},
+       {0, NULL}
+};
+
+
 static guint16
 de_gmm_update_res(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
-       guint8       oct;
-       guint32      curr_offset;
-       const gchar *str;
-
-       curr_offset = offset;
-
-       oct = tvb_get_guint8(tvb, curr_offset);
+       guint32      curr_offset = offset;
 
        /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
-       oct >>= 4;
-
-       switch (oct&7)
-       {
-               case 0:  str = "RA updated";              break;
-               case 1:  str = "combined RA/LA updated";        break;
-               default: str = "reserved";
-       }
-
-       proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "Update Result: %s (%u)",
-               str,
-               oct&7);
+       proto_tree_add_item(tree, hf_gsm_a_gm_update_result, tvb, curr_offset, 1, ENC_NA);
 
        curr_offset++;
 
@@ -3124,19 +3519,8 @@ static const value_string gsm_a_gm_update_type_vals[] = {
 static guint16
 de_gmm_update_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
-        proto_item *tf;
-       proto_tree *tf_tree;
-
-       proto_tree_add_bits_item(tree, hf_gsm_a_gm_ciph_key_seq_num, tvb, offset << 3, 4, ENC_BIG_ENDIAN);
-
-       tf = proto_tree_add_text(tree,
-               tvb, offset, 1,
-               "Update Type");
-
-       tf_tree = proto_item_add_subtree(tf, ett_gmm_update_type);
-
-       proto_tree_add_item(tf_tree, hf_gsm_a_gm_for, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(tf_tree, hf_gsm_a_gm_update_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_for, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_update_type, tvb, offset, 1, ENC_BIG_ENDIAN);
 
        /* no length check possible */
        return (1);
@@ -3189,10 +3573,7 @@ de_gmm_service_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, gui
        proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
        bit_offset  +=  1;
        proto_tree_add_bits_item(tree, hf_gsm_a_gm_serv_type, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
-       bit_offset  +=  3;
-       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
-       bit_offset  +=  1;
-       proto_tree_add_bits_item(tree, hf_gsm_a_gm_ciph_key_seq_num, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
+       /*bit_offset  +=  3;*/
 
        /* no length check possible */
        return (1);
@@ -3206,6 +3587,16 @@ de_gmm_service_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, gui
 /*
  * [9] 10.5.5.22 PS LCS Capability
  */
+static const true_false_string gsm_a_gm_mta_e_vals = {
+       "Multilateration Timing Advance using Extended Access Burst method supported",
+       "Multilateration Timing Advance using Extended Access Burst method not supported"
+};
+
+static const true_false_string gsm_a_gm_mta_r_vals = {
+       "Multilateration Timing Advance using RLC data block method supported",
+       "Multilateration Timing Advance using RLC data block method not supported"
+};
+
 static const true_false_string gsm_a_gm_apc_vals = {
        "Additional Positioning Capabilities which can be retrieved by RRLP are supported",
        "Additional Positioning Capabilities which can be retrieved by RRLP are not supported"
@@ -3236,13 +3627,24 @@ static const true_false_string gsm_a_gm_gps_c_vals = {
        "Conventional GPS not supported"
 };
 
+static const true_false_string gsm_a_gm_motd_vals = {
+       "Multilateration Observed Time Difference supported",
+       "Multilateration Observed Time Difference not supported"
+};
+
+static const true_false_string gsm_a_gm_mta_a_vals = {
+       "Multilateration Timing Advance using Access Burst method supported",
+       "Multilateration Timing Advance using Access Burst method not supported"
+};
+
 static guint16
 de_gmm_ps_lcs_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
        guint32 curr_offset;
 
        curr_offset = offset;
-       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset << 3, 2, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_mta_e, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_mta_r, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_gsm_a_gm_apc, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_gsm_a_gm_otd_a, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_gsm_a_gm_otd_b, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
@@ -3252,7 +3654,13 @@ de_gmm_ps_lcs_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 o
 
        curr_offset++;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       if (len > 2) {
+               proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset << 3, 6, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_gsm_a_gm_motd, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_gsm_a_gm_mta_a, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+       }
+
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -3291,6 +3699,14 @@ de_gmm_net_feat_supp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, gu
 /*
  * [7] 10.5.5.23a Additional network feature support
  */
+static const true_false_string gsm_a_gm_epco_value = {
+       "Extended protocol configuration options IE supported",
+       "Extended protocol configuration options IE not supported"
+};
+static const true_false_string gsm_a_gm_restrict_ec_value = {
+       "Enhanced coverage restricted",
+       "Enhanced coverage not restricted"
+};
 static const true_false_string gsm_a_gm_gprs_sms_value = {
        "SMS via GPRS not supported",
        "SMS via GPRS supported"
@@ -3302,7 +3718,9 @@ de_gmm_add_net_feat_supp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_
 
        curr_offset = offset;
 
-       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset << 3, 7, ENC_BIG_ENDIAN);
+       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset << 3, 5, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_epco, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_restrict_ec, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_gsm_a_gm_gprs_sms, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
        curr_offset++;
 
@@ -3320,11 +3738,11 @@ de_gmm_rat_info_container(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, g
 
 /* The value part of the Inter RAT information container information element is the INTER RAT HANDOVER INFO as
 defined in 3GPP TS 25.331 [23c]. If this field includes padding bits, they are defined in 3GPP TS 25.331 [23c].*/
-       rrc_irat_ho_info_tvb = tvb_new_subset(tvb, curr_offset, len, len);
+       rrc_irat_ho_info_tvb = tvb_new_subset_length(tvb, curr_offset, len);
        if (rrc_irat_ho_info_handle)
                call_dissector(rrc_irat_ho_info_handle, rrc_irat_ho_info_tvb, pinfo, tree);
        else
-               proto_tree_add_text(tree, tvb, curr_offset, len, "INTER RAT HANDOVER INFO - Not decoded");
+               proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_gm_undecoded, tvb, curr_offset, len, "INTER RAT HANDOVER INFO - Not decoded");
 
        return len;
 
@@ -3375,11 +3793,11 @@ de_gmm_eutran_irat_info_container(tvbuff_t *tvb, proto_tree *tree, packet_info *
 
 /* The value part of the E-UTRAN inter RAT information container information element
    is formatted and coded according to the UE-EUTRA-Capability IE defined in 3GPP TS 36.331 [129]*/
-       lte_rrc_ue_eutra_cap_tvb = tvb_new_subset(tvb, curr_offset, len, len);
+       lte_rrc_ue_eutra_cap_tvb = tvb_new_subset_length(tvb, curr_offset, len);
        if (lte_rrc_ue_eutra_cap_handle)
                call_dissector(lte_rrc_ue_eutra_cap_handle, lte_rrc_ue_eutra_cap_tvb, pinfo, tree);
        else
-               proto_tree_add_text(tree, tvb, curr_offset, len, "E-UTRAN Inter RAT information container - Not decoded");
+               proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_gm_undecoded, tvb, curr_offset, len, "E-UTRAN Inter RAT information container - Not decoded");
 
        return len;
 }
@@ -3419,8 +3837,8 @@ de_gmm_voice_domain_pref(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_
 
 /* [10] 10.5.5.29 P-TMSI type */
 static const true_false_string gsm_a_gm_ptmsi_type_value = {
-    "Mapped P-TMSI",
-    "Native P-TMSI"
+       "Mapped P-TMSI",
+       "Native P-TMSI"
 };
 
 static guint16
@@ -3465,6 +3883,119 @@ de_gmm_net_res_id_cont(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
        return len;
 }
 
+/* [13] 10.5.5.32 Extended DRX parameters */
+static const value_string gsm_a_gm_paging_time_window_vals[] = {
+       {0x0,   "Iu: 0 s / WB-S1: 1.28 s / NB-S1: 2.56 s"},
+       {0x1,   "Iu: 1 s / WB-S1: 2.56 s / NB-S1: 5.12 s"},
+       {0x2,   "Iu: 2 s / WB-S1: 3.84 s / NB-S1: 7.68 s"},
+       {0x3,   "Iu: 3 s / WB-S1: 5.12 s / NB-S1: 10.24 s"},
+       {0x4,   "Iu: 4 s / WB-S1: 6.4 s / NB-S1: 12.8 s"},
+       {0x5,   "Iu: 5 s / WB-S1: 7.68 s / NB-S1: 15.36 s"},
+       {0x6,   "Iu: 6 s / WB-S1: 8.96 s / NB-S1: 17.92 s"},
+       {0x7,   "Iu: 7 s / WB-S1: 10.24 s / NB-S1: 20.48 s"},
+       {0x8,   "Iu: 8 s / WB-S1: 11.52 s / NB-S1: 23.04 s"},
+       {0x9,   "Iu: 9 s / WB-S1: 12.8 s / NB-S1: 25.6 s"},
+       {0xa,   "Iu: 10 s / WB-S1: 14.08 s / NB-S1: 28.16 s"},
+       {0xb,   "Iu: 12 s / WB-S1: 15.36 s / NB-S1: 30.72 s"},
+       {0xc,   "Iu: 14 s / WB-S1: 16.64 s / NB-S1: 33.28 s"},
+       {0xd,   "Iu: 16 s / WB-S1: 17.92 s / NB-S1: 35.84 s"},
+       {0xe,   "Iu: 18 s / WB-S1: 19.2 s / NB-S1: 38.4 s"},
+       {0xf,   "Iu: 20 s / WB-S1: 20.48 s / NB-S1: 40.96 s"},
+       {  0,   NULL }
+};
+
+static const value_string gsm_a_gm_edrx_vals[] = {
+       {0x0,   "GERAN: 1.88 s / UTRAN: 10.24 s / E-UTRAN: 5.12 s"},
+       {0x1,   "GERAN: 3.76 s / UTRAN: 20.48 s / E-UTRAN: 10.24 s"},
+       {0x2,   "GERAN: 7.53 s / UTRAN: 40.96 s / E-UTRAN: 20.48 s"},
+       {0x3,   "GERAN: 12.24 s / UTRAN: 81.92 s / E-UTRAN: 40.96 s"},
+       {0x4,   "GERAN: 24.48 s / UTRAN: 163.84 s / E-UTRAN: 61.44 s"},
+       {0x5,   "GERAN: 48.96 s / UTRAN: 327.68 s / E-UTRAN: 81.92 s"},
+       {0x6,   "GERAN: 97.92 s / UTRAN: 655.36 s / E-UTRAN: 102.4 s"},
+       {0x7,   "GERAN: 195.84 s / UTRAN: 1310.72 s / E-UTRAN: 122.88 s"},
+       {0x8,   "GERAN: 391.68 s / UTRAN: 1966.08 s / E-UTRAN: 143.36 s"},
+       {0x9,   "GERAN: 783.36 s / UTRAN: 2621.44 s / E-UTRAN: 163.84 s"},
+       {0xa,   "GERAN: 1566.72 s / UTRAN: 10.24 s / E-UTRAN: 327.68 s"},
+       {0xb,   "GERAN: 3133.44 s / UTRAN: 10.24 s / E-UTRAN: 655.36 s"},
+       {0xc,   "GERAN: 1.88 s / UTRAN: 10.24 s / E-UTRAN: 1310.72 s"},
+       {0xd,   "GERAN: 1.88 s / UTRAN: 10.24 s / E-UTRAN: 2621.44 s"},
+       {0xe,   "GERAN: 1.88 s / UTRAN: 10.24 s / E-UTRAN: 5242.88 s"},
+       {0xf,   "GERAN: 1.88 s / UTRAN: 10.24 s / E-UTRAN: 10485.76 s"},
+       {  0,   NULL }
+};
+
+static guint16
+de_gmm_ext_drx_params(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+       guint32 curr_offset;
+
+       curr_offset = offset;
+
+       proto_tree_add_item(tree, hf_gsm_a_gm_paging_time_window, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_edrx_value, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+       return len;
+}
+
+/* [13] 10.5.5.33 Message authentication code */
+static guint16
+de_gmm_mac(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+       proto_tree_add_item(tree, hf_gsm_a_gm_mac, tvb, offset, 4, ENC_BIG_ENDIAN);
+
+       return len;
+}
+
+/* [13] 10.5.5.34 User Plane integrity indicator */
+const true_false_string gsm_a_gm_up_integ_ind_value = {
+       "MS shall enable integrity protection of user plane data in LLC layer",
+       "MS shall disable integrity protection of user plane data in LLC layer"
+};
+
+static guint16
+de_gmm_up_integ_ind(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
+{
+       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (offset << 3) + 4, 3, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_up_integ_ind, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+       /* no length check possible */
+       return (1);
+}
+
+/* [14] 10.5.5.35 DCN-ID */
+static guint16
+de_gmm_dcn_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
+{
+       proto_tree_add_item(tree, hf_gsm_a_gm_dcn_id, tvb, offset, 2, ENC_BIG_ENDIAN);
+
+       return 2;
+}
+
+/* [14] 10.5.5.36 PLMN identity of the CN operator */
+static guint16
+de_gmm_plmn_id_cn_operator(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
+{
+       dissect_e212_mcc_mnc(tvb, pinfo, tree, offset, E212_NONE, TRUE);
+
+       return 3;
+}
+
+/* [14] 10.5.5.37 Non-3GPP NW provided policies */
+const true_false_string gsm_a_gm_n3en_ind_value = {
+       "Use of non-3GPP emergency numbers permitted",
+       "Use of non-3GPP emergency numbers not permitted"
+};
+
+static guint16
+de_gmm_non_3gpp_nw_prov_pol(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
+{
+       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (offset << 3) + 4, 3, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_gm_n3en_ind, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+       /* no length check possible */
+       return (1);
+}
+
 /*
  * [7] 10.5.7.1
  */
@@ -3474,17 +4005,9 @@ de_gc_context_stat(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
        guint8      oct;
        guint16     pdp_nr;
        guint32     curr_offset;
-       proto_item *tf;
-       proto_tree *tf_tree;
 
        curr_offset = offset;
 
-       tf = proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "PDP Context Status");
-
-       tf_tree = proto_item_add_subtree(tf, ett_gmm_context_stat);
-
        oct = tvb_get_guint8(tvb, curr_offset);
 
        for (pdp_nr=0; pdp_nr<16; pdp_nr++)
@@ -3494,17 +4017,13 @@ de_gc_context_stat(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
                        curr_offset++;
                        oct = tvb_get_guint8(tvb, curr_offset);
                }
-               proto_tree_add_text(tf_tree,
-                       tvb, curr_offset, 1,
-                       "NSAPI %d: %s (%u)", pdp_nr,
-                       pdp_str[oct&1],
-                       oct&1);
+               proto_tree_add_uint_format(tree, hf_gsm_a_gm_nsapi, tvb, curr_offset, 1, oct&1, "NSAPI %d: %s (%u)", pdp_nr, pdp_str[oct&1], oct&1);
                oct>>=1;
        }
 
        curr_offset++;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -3512,31 +4031,24 @@ de_gc_context_stat(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 /*
  * [7] 10.5.7.2
  */
+static const value_string gsm_a_gm_radio_prio_vals[] = {
+       {0,  "priority level 4 (lowest)" },
+       {1,  "priority level 1 (highest)"},
+       {2,  "priority level 2"},
+       {3,  "priority level 3"},
+       {4,  "priority level 4 (lowest)"},
+       {5,  "priority level 4 (lowest)"},
+       {6,  "priority level 4 (lowest)"},
+       {7,  "priority level 4 (lowest)"},
+       {0, NULL}
+};
+
 static guint16
 de_gc_radio_prio(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
-       guint8       oct;
-       guint32      curr_offset;
-       const gchar *str;
-
-       curr_offset = offset;
-
-       oct = tvb_get_guint8(tvb, curr_offset);
-
-       switch (oct&7)
-       {
-               case 1:  str = "priority level 1 (highest)"; break;
-               case 2:  str = "priority level 2"; break;
-               case 3:  str = "priority level 3"; break;
-               case 4:  str = "priority level 4 (lowest)"; break;
-               default: str = "priority level 4 (lowest)";
-       }
+       guint32      curr_offset = offset;
 
-       proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "Radio Priority (PDP or SMS): %s (%u)",
-               str,
-               oct&7);
+       proto_tree_add_item(tree, hf_gsm_a_gm_radio_priority_pdp, tvb, curr_offset, 1, ENC_NA);
 
        curr_offset++;
 
@@ -3560,27 +4072,32 @@ de_gc_timer(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 off
        guint8       oct;
        guint16      val;
        const gchar *str;
-       proto_tree  *subtree;
        proto_item  *item = NULL;
+       proto_tree  *subtree;
 
        oct = tvb_get_guint8(tvb, offset);
        val = oct&0x1f;
 
        switch (oct>>5)
        {
-               case 0:  str = "sec"; val*=2; break;
-               case 1:  str = "min"; break;
-               case 2:  str = "min"; val*=6; break;
-               case 7:  str = "";
-                       item = proto_tree_add_text(tree, tvb, offset, 1,
-                                                  "GPRS Timer: timer is deactivated");
+               case 0:
+                       str = "sec"; val*=2;
+                       break;
+               case 1:
+                       str = "min";
+                       break;
+               case 2:
+                       str = "min"; val*=6;
+                       break;
+               case 7:
+                       str = "";
+                       item = proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_gprs_timer, tvb, offset, 1, val, "timer is deactivated");
                        break;
                default:  str = "min";
        }
 
        if (item == NULL) {
-               item = proto_tree_add_text(tree, tvb, offset, 1,
-                                          "GPRS Timer: %u %s", val, str);
+               item = proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_gprs_timer, tvb, offset, 1, val, "%u %s", val, str);
        }
 
        subtree = proto_item_add_subtree(item, ett_gmm_gprs_timer);
@@ -3612,20 +4129,23 @@ de_gc_timer2(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 of
 
        switch (oct>>5)
        {
-               case 0:  str = "sec"; val*=2; break;
-               case 1:  str = "min"; break;
-               case 2:  str = "min"; val*=6; break;
+               case 0:
+                       str = "sec"; val*=2;
+                       break;
+               case 1:
+                       str = "min";
+                       break;
+               case 2:
+                       str = "min"; val*=6;
+                       break;
                case 7:
-                       item = proto_tree_add_text(tree, tvb, curr_offset, 1,
-                                                  "GPRS Timer: timer is deactivated");
+                       item = proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_gprs_timer2, tvb, curr_offset, 1, val, "timer is deactivated");
                        break;
                default:  str = "min";
        }
 
        if (item == NULL) {
-               item = proto_tree_add_text(tree, tvb, curr_offset, 1,
-                                          "GPRS Timer: %u %s %s",
-                                          val, str, add_string ? add_string : "");
+               item = proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_gprs_timer2, tvb, curr_offset, 1, val, "%u %s %s", val, str, add_string ? add_string : "");
        }
 
        subtree = proto_item_add_subtree(item, ett_gmm_gprs_timer);
@@ -3646,11 +4166,12 @@ static const value_string gsm_a_gm_gprs_timer3_unit_vals[] = {
        { 0x03, "value is incremented in multiples of 2 seconds" },
        { 0x04, "value is incremented in multiples of 30 seconds" },
        { 0x05, "value is incremented in multiples of 1 minute" },
+       { 0x06, "value is incremented in multiples of 320 hours (for T3312/T3412 extended), 1 hour otherwise" },
        { 0x07, "value indicates that the timer is deactivated" },
        { 0, NULL }
 };
 
-static guint16
+guint16
 de_gc_timer3(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
        guint8       oct;
@@ -3675,15 +4196,13 @@ de_gc_timer3(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 of
                case 4:  str = "sec"; val*=30; break;
                case 5:  str = "min"; break;
                case 7:
-                       item = proto_tree_add_text(tree, tvb, curr_offset, 1,
-                                                  "GPRS Timer: timer is deactivated");
+                       item = proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_gprs_timer3, tvb, curr_offset, 1, val, "timer is deactivated");
                        break;
                default:  str = "hr";
        }
 
        if (item == NULL) {
-               item = proto_tree_add_text(tree, tvb, curr_offset, 1,
-                                          "GPRS Timer: %u %s", val, str);
+               item = proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_gprs_timer3, tvb, curr_offset, 1, val, "%u %s", val, str);
        }
 
        subtree = proto_item_add_subtree(item, ett_gmm_gprs_timer);
@@ -3700,31 +4219,10 @@ de_gc_timer3(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 of
 static guint16
 de_gc_radio_prio2(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
 {
-       guint8       oct;
-       guint32      curr_offset;
-       const gchar *str;
-
-       curr_offset = offset;
-
-       oct = tvb_get_guint8(tvb, curr_offset);
+       guint32      curr_offset = offset;
 
        /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
-       oct >>= 4;
-
-       switch (oct&7)
-       {
-               case 1:  str = "priority level 1 (highest)"; break;
-               case 2:  str = "priority level 2"; break;
-               case 3:  str = "priority level 3"; break;
-               case 4:  str = "priority level 4 (lowest)"; break;
-               default: str = "priority level 4 (lowest)";
-       }
-
-       proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "Radio Priority (TOM8): %s (%u)",
-               str,
-               oct&7);
+       proto_tree_add_item(tree, hf_gsm_a_gm_radio_priority_tom8, tvb, curr_offset, 1, ENC_NA);
 
        curr_offset++;
 
@@ -3740,28 +4238,16 @@ de_gc_mbms_context_stat(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
        guint32     curr_offset;
        guint       i;
        guint8      oct, j;
-       proto_item *tf;
-       proto_tree *tf_tree;
 
        curr_offset = offset;
 
-       tf = proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "MBMS Context Status");
-
-       tf_tree = proto_item_add_subtree(tf, ett_gmm_context_stat);
-
        for (i=0; i<len; i++)
        {
                oct = tvb_get_guint8(tvb, curr_offset);
 
                for (j=0; j<8; j++)
                {
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset, 1,
-                               "NSAPI %d: %s (%u)", 128+i*8+j,
-                               pdp_str[oct&1],
-                               oct&1);
+                       proto_tree_add_uint_format(tree, hf_gsm_a_gm_nsapi, tvb, curr_offset, 1, oct&1, "NSAPI %d: %s (%u)", 128+i*8+j, pdp_str[oct&1], oct&1);
                        oct>>=1;
                }
                curr_offset++;
@@ -3846,34 +4332,36 @@ de_gc_device_properties(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
 /*
  * [7] 10.5.6.1
  */
-#define MAX_APN_LENGTH         100
-
 guint16
 de_sm_apn(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
-       guint32 curr_offset;
-       guint   curr_len;
-       guint8  str[MAX_APN_LENGTH+1];
+       guint32     curr_offset;
+       guint       curr_len;
+       guint8     *str;
+       proto_item *pi;
 
        curr_offset = offset;
 
-       /* init buffer and copy it */
-       memset(str, 0, MAX_APN_LENGTH);
-       tvb_memcpy(tvb, str, offset, len<MAX_APN_LENGTH?len:MAX_APN_LENGTH);
+       str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, len, ENC_ASCII|ENC_NA);
 
        curr_len = 0;
-       while ((curr_len < len) && (curr_len < MAX_APN_LENGTH))
+       while (curr_len < len)
        {
                guint step    = str[curr_len];
                str[curr_len] = '.';
                curr_len     += step+1;
        }
 
-       /* High light bytes including the first lenght byte */
-       proto_tree_add_string(tree, hf_gsm_a_gm_apn, tvb, curr_offset, len, str+1);
-       curr_offset +=  len;
+       /* Highlight bytes including the first length byte */
+       if (str[0]) {
+               pi = proto_tree_add_string(tree, hf_gsm_a_gm_apn, tvb, curr_offset, len, str+1);
+               if (len > 100) {
+                       expert_add_info(pinfo, pi, &ei_gsm_a_gm_apn_too_long);
+               }
+       }
+       curr_offset += len;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -3891,10 +4379,7 @@ de_sm_nsapi(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 off
 
        oct = tvb_get_guint8(tvb, curr_offset);
 
-       proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "NSAPI: 0x%02x (%u) %s",
-               oct&0x0f, oct&0x0f, add_string ? add_string : "");
+       proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_nsapi, tvb, curr_offset, 1, oct&0x0f, "0x%02x (%u) %s", oct&0x0f, oct&0x0f, add_string ? add_string : "");
 
        curr_offset++;
 
@@ -3906,7 +4391,7 @@ de_sm_nsapi(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 off
  */
 static const range_string gsm_a_sm_pco_ms2net_prot_vals[] = {
        { 0x0001, 0x0001, "P-CSCF IPv6 Address Request" },
-       { 0x0002, 0x0002, "IM CN Subsystem Signalling Flag" },
+       { 0x0002, 0x0002, "IM CN Subsystem Signaling Flag" },
        { 0x0003, 0x0003, "DNS Server IPv6 Address Request" },
        { 0x0004, 0x0004, "Not Supported" },
        { 0x0005, 0x0005, "MS Support of Network Requested Bearer Control indicator" },
@@ -3922,12 +4407,21 @@ static const range_string gsm_a_sm_pco_ms2net_prot_vals[] = {
        { 0x000f, 0x000f, "IFOM-Support-Request" },
        { 0x0010, 0x0010, "IPv4 Link MTU Request" },
        { 0x0011, 0x0011, "MS support of Local address in TFT indicator" },
+       { 0x0012, 0x0012, "P-CSCF Re-selection support" },
+       { 0x0013, 0x0013, "NBIFOM request indicator" },
+       { 0x0014, 0x0014, "NBIFOM mode" },
+       { 0x0015, 0x0015, "Non-IP Link MTU Request" },
+       { 0x0016, 0x0016, "APN rate control support indicator" },
+       { 0x0017, 0x0017, "3GPP PS data off UE status" },
+       { 0x0018, 0x0018, "Reliable Data Service request indicator" },
+       { 0x0019, 0x0019, "Additional APN rate control for exception data support indicator" },
+       { 0x001a, 0x001a, "PDU session ID" },
        { 0xff00, 0xffff, "Operator Specific Use" },
        { 0, 0, NULL }
 };
 static const range_string gsm_a_sm_pco_net2ms_prot_vals[] = {
        { 0x0001, 0x0001, "P-CSCF IPv6 Address" },
-       { 0x0002, 0x0002, "IM CN Subsystem Signalling Flag" },
+       { 0x0002, 0x0002, "IM CN Subsystem Signaling Flag" },
        { 0x0003, 0x0003, "DNS Server IPv6 Address" },
        { 0x0004, 0x0004, "Policy Control rejection code" },
        { 0x0005, 0x0005, "Selected Bearer Control Mode" },
@@ -3943,6 +4437,19 @@ static const range_string gsm_a_sm_pco_net2ms_prot_vals[] = {
        { 0x000f, 0x000f, "IFOM-Support" },
        { 0x0010, 0x0010, "IPv4 Link MTU" },
        { 0x0011, 0x0011, "Network support of Local address in TFT indicator" },
+       { 0x0012, 0x0012, "Reserved" },
+       { 0x0013, 0x0013, "NBIFOM accepted indicator" },
+       { 0x0014, 0x0014, "NBIFOM mode" },
+       { 0x0015, 0x0015, "Non-IP Link MTU" },
+       { 0x0016, 0x0016, "APN rate control parameters" },
+       { 0x0017, 0x0017, "3GPP PS data off support indication" },
+       { 0x0018, 0x0018, "Reliable Data Service accepted indicator" },
+       { 0x0019, 0x0019, "Additional APN rate control for exception data parameters" },
+       { 0x001a, 0x001a, "Reserved" },
+       { 0x001b, 0x001b, "S-NSSAI" },
+       { 0x001c, 0x001c, "QoS rules" },
+       { 0x001d, 0x001d, "Session-AMBR" },
+       { 0x001e, 0x001e, "PDU session address lifetime" },
        { 0xff00, 0xffff, "Operator Specific Use" },
        { 0, 0, NULL }
 };
@@ -3954,20 +4461,50 @@ static const value_string gsm_a_gm_link_dir_vals[] = {
        { 0, NULL }
 };
 
+static const value_string gsm_a_gm_sel_bearer_ctrl_mode_vals[] = {
+       { 1, "MS only" },
+       { 2, "MS/NW" },
+       { 0, NULL }
+};
+
+static const value_string gsm_a_gm_nbifom_mode_vals[] = {
+       { 0, "UE-initiated" },
+       { 1, "Network-initiated" },
+       { 0, NULL }
+};
+
+const true_false_string gsm_a_gm_apn_rate_ctrl_params_aer_value = {
+       "Additional exception reports at maximum rate reached are allowed",
+       "Additional exception reports at maximum rate reached are not allowed"
+};
+
+static const value_string gsm_a_gm_apn_rate_ctrl_ul_time_unit_vals[] = {
+       { 0, "Unrestricted" },
+       { 1, "Minute" },
+       { 2, "Hour" },
+       { 3, "Day" },
+       { 4, "Week" },
+       { 0, NULL }
+};
+
+static const value_string gsm_a_gm_sm_pco_3gpp_data_off_ue_status_vals[] = {
+       { 1, "Deactivated"},
+       { 2, "Activated"},
+       { 0, NULL}
+};
+
 guint16
 de_sm_pco(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
        proto_item        *generated_item;
        guint32            curr_offset;
-       guint              curr_len;
+       gint               curr_len;
        guchar             oct;
-       struct e_in6_addr  ipv6_addrx;
        int                link_dir;
-       guint32            ipv4_addrx;
        proto_item        *pco_item;
        proto_tree        *pco_tree;
 
-       curr_len    = len;
+       curr_len    = (gint)len; /* length field is only 1 or 2 bytes long */
        curr_offset = offset;
 
        oct = tvb_get_guint8(tvb, curr_offset);
@@ -3987,11 +4524,11 @@ de_sm_pco(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
         * All other values are interpreted as PPP in this version of the protocol.
         * (3GPP TS 24.008 version 9.4.0 Release 9)
         */
-       proto_tree_add_text(tree, tvb, curr_offset, 1, "Configuration Protocol: PPP for use with IP PDP type or IP PDN type (%u)", oct&0x07);
+       proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_configuration_protocol, tvb, curr_offset, 1, oct&0x07, "PPP for use with IP PDP type or IP PDN type (%u)", oct&0x07);
        curr_len--;
        curr_offset++;
 
-       while (curr_len > 0)
+       while (curr_len >= 3) /* 2 bytes protocol/container ID + 1 byte length */
        {
                guchar e_len;
                guint16 prot;
@@ -4004,29 +4541,36 @@ de_sm_pco(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
                 */
 
                prot = tvb_get_ntohs(tvb, curr_offset);
-               pco_item = proto_tree_add_uint_format(tree, hf_gsm_a_gm_pco_pid, tvb, curr_offset, 2, (guint32)prot,
-                               "Protocol or Container ID: %s (0x%04x)",
+               pco_item = proto_tree_add_uint_format_value(tree, hf_gsm_a_gm_pco_pid, tvb, curr_offset, 2, (guint32)prot,
+                               "%s (0x%04x)",
                                link_dir ?
-                                       rval_to_str((guint32)prot, gsm_a_sm_pco_net2ms_prot_vals, val_to_str_ext_const(prot, &ppp_vals_ext, "Unknown")) :
-                                       rval_to_str((guint32)prot, gsm_a_sm_pco_ms2net_prot_vals, val_to_str_ext_const(prot, &ppp_vals_ext, "Unknown")),
+                                       rval_to_str_const((guint32)prot, gsm_a_sm_pco_net2ms_prot_vals, val_to_str_ext_const(prot, &ppp_vals_ext, "Unknown")) :
+                                       rval_to_str_const((guint32)prot, gsm_a_sm_pco_ms2net_prot_vals, val_to_str_ext_const(prot, &ppp_vals_ext, "Unknown")),
                                (guint32)prot);
                pco_tree = proto_item_add_subtree(pco_item, ett_sm_pco);
 
                curr_len    -= 2;
                curr_offset += 2;
                e_len = tvb_get_guint8(tvb, curr_offset);
-               proto_tree_add_text(pco_tree, tvb, curr_offset, 1, "Length: 0x%02x (%u)", e_len, e_len);
+               proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_length, tvb, curr_offset, 1, ENC_NA);
                curr_len    -= 1;
                curr_offset += 1;
 
                switch (prot)
                {
                        case 0x0001:
+                               if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_pcscf_ipv6, tvb, curr_offset, 16, ENC_NA);
+                               }
+                               break;
                        case 0x0003:
+                               if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_dns_ipv6, tvb, curr_offset, 16, ENC_NA);
+                               }
+                               break;
                        case 0x0007:
                                if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
-                                       tvb_get_ipv6(tvb, curr_offset, &ipv6_addrx);
-                                       proto_tree_add_text(pco_tree, tvb, curr_offset, 16, "IPv6: %s", ip6_to_str(&ipv6_addrx));
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_dsmipv6_home_agent_ipv6, tvb, curr_offset, 16, ENC_NA);
                                }
                                break;
                        case 0x0002:
@@ -4035,86 +4579,168 @@ de_sm_pco(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
                        case 0x000B:
                        case 0x000F:
                        case 0x0011:
+                       case 0x0012:
+                       case 0x0013:
+                       case 0x0018:
                                break;
                        case 0x0004:
                                if ((link_dir == P2P_DIR_DL) && (e_len == 1)) {
-                                       oct = tvb_get_guint8(tvb, curr_offset);
-                                       proto_tree_add_text(pco_tree, tvb, curr_offset, 1, "Reject Code: 0x%02x (%u)", oct, oct);
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_reject_code, tvb, curr_offset, 1, ENC_NA);
                                }
                                break;
                        case 0x0005:
                                if ((link_dir == P2P_DIR_DL) && (e_len == 1)) {
-                                       oct = tvb_get_guint8(tvb, curr_offset);
-                                       proto_tree_add_text(pco_tree, tvb, curr_offset, 1, "%s", (oct == 1) ? "MS only" :
-                                                                               ((oct == 2) ? "MS/NW" : "Unknown"));
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_sel_bearer_ctrl_mode, tvb, curr_offset, 1, ENC_NA);
                                }
                                break;
                        case 0x0008:
                                if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
-                                       tvb_get_ipv6(tvb, curr_offset, &ipv6_addrx);
-                                       proto_tree_add_text(pco_tree, tvb, curr_offset, 16,     "IPv6: %s", ip6_to_str(&ipv6_addrx));
-                                       oct = tvb_get_guint8(tvb, curr_offset+16);
-                                       proto_tree_add_text(pco_tree, tvb, curr_offset+16, 1, "Prefix length: %u", oct);
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_dsmipv6_home_network_ipv6, tvb, curr_offset, 16, ENC_NA);
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_dsmipv6_home_network_prefix_length, tvb, curr_offset+16, 1, ENC_NA);
                                }
                                break;
                        case 0x0009:
+                               if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_dsmipv6_home_agent_ipv4, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
+                               }
+                               break;
                        case 0x000C:
+                               if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_pcscf_ipv4, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
+                               }
+                               break;
                        case 0x000D:
                                if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
-                                       ipv4_addrx = tvb_get_ipv4(tvb, curr_offset);
-                                       proto_tree_add_text(pco_tree, tvb, curr_offset, 4,      "IPv4: %s",
-                                                                               ip_to_str((guint8 *)&ipv4_addrx));
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_dns_ipv4, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
+                               }
+                               break;
+                       case 0x000E:
+                               if ((link_dir == P2P_DIR_DL) && (e_len > 0)) {
+                                       dissect_e164_msisdn(tvb, pco_tree, curr_offset, e_len, E164_ENC_BCD);
                                }
                                break;
                        case 0x0010:
                                if ((link_dir == P2P_DIR_DL) && (e_len == 2)) {
-                                       guint16 word = tvb_get_ntohs(tvb, curr_offset);
-                                       proto_tree_add_text(pco_tree, tvb, curr_offset, 2, "IPv4 link MTU size: %u octets", word);
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_ipv4_link_mtu_size, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
+                               }
+                               break;
+                       case 0x0014:
+                               if (e_len == 1) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_nbifom_mode, tvb, curr_offset, 1, ENC_NA);
+                               }
+                               break;
+                       case 0x0015:
+                               if ((link_dir == P2P_DIR_DL) && (e_len == 2)) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_non_ip_link_mtu_size, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
+                               }
+                               break;
+                       case 0x0016:
+                               if (link_dir == P2P_DIR_DL) {
+                                       proto_tree_add_bits_item(pco_tree, hf_gsm_a_spare_bits, tvb, (curr_offset << 3), 4, ENC_BIG_ENDIAN);
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_aer, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_ul_time_unit, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+                                       if (e_len >= 4) {
+                                               proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_max_ul_rate, tvb, curr_offset+1, 3, ENC_BIG_ENDIAN);
+                                       }
+                               }
+                               break;
+                       case 0x0017:
+                               if (link_dir == P2P_DIR_UL && e_len >= 1) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_3gpp_data_off_ue_status, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+                               }
+                               break;
+                       case 0x0019:
+                               if (link_dir == P2P_DIR_DL) {
+                                       proto_tree_add_bits_item(pco_tree, hf_gsm_a_spare_bits, tvb, (curr_offset << 3), 5, ENC_BIG_ENDIAN);
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_add_apn_rate_ctrl_params_ul_time_unit, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+                                       if (e_len >= 3) {
+                                               proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_add_apn_rate_ctrl_params_max_ul_rate, tvb, curr_offset+1, 2, ENC_BIG_ENDIAN);
+                                       }
+                               }
+                               break;
+                       case 0x001a:
+                               if (link_dir == P2P_DIR_UL) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_pdu_session_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+                               }
+                               break;
+                       case 0x001b:
+                               if (link_dir == P2P_DIR_DL && e_len >= 4) {
+                                       de_nas_5gs_cmn_s_nssai(tvb, pco_tree, pinfo, curr_offset, e_len - 3, NULL, 0);
+                                       dissect_e212_mcc_mnc(tvb, pinfo, pco_tree, curr_offset + e_len - 3, E212_NONE, TRUE);
+                               }
+                               break;
+                       case 0x001c:
+                               if (link_dir == P2P_DIR_DL) {
+                                       de_nas_5gs_sm_qos_rules(tvb, pco_tree, pinfo, curr_offset, e_len, NULL, 0);
+                               }
+                               break;
+                       case 0x001d:
+                               if (link_dir == P2P_DIR_DL) {
+                                       /* Network to MS direction */
+                                       de_nas_5gs_sm_session_ambr(tvb, pco_tree, pinfo, curr_offset, e_len, NULL, 0);
+                               }
+                               break;
+                       case 0x001e:
+                               if (link_dir == P2P_DIR_DL && e_len == 2) {
+                                       /* When the container identifier indicates PDU session address lifetime,
+                                        * the length of container identifier contents indicates a length equal to two.
+                                        * The container identifier contents field contains the binary coded representation
+                                        * of how long the network is willing to maintain the PDU session in units of seconds.
+                                        * ...If the length of container identifier contents is different from two octets,
+                                        * then it shall be ignored by the receiver
+                                        */
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_pdu_session_address_lifetime, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
+                               }
+                               break;
+                       case 0x001f:
+                               if (link_dir == P2P_DIR_DL && e_len == 2) {
+                                       proto_tree_add_item(pco_tree, hf_gsm_a_gm_sm_pco_pdu_session_address_lifetime, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
                                }
                                break;
                        default:
                        {
                                if (e_len > 0) {
                                        if (prot >= 0xff00) {
-                                               dissect_e212_mcc_mnc(tvb, pinfo, pco_tree, curr_offset, TRUE);
+                                               dissect_e212_mcc_mnc(tvb, pinfo, pco_tree, curr_offset, E212_NONE, TRUE);
                                                if ((e_len - 3) > 0) {
                                                        proto_tree_add_item(pco_tree, hf_gsm_a_gm_pco_app_spec_info, tvb, curr_offset+3, e_len-3, ENC_NA);
                                                }
                                        } else {
                                                dissector_handle_t handle;
                                                handle = dissector_get_uint_handle (gprs_sm_pco_subdissector_table, prot);
+                                               l3_tvb = tvb_new_subset_length(tvb, curr_offset, e_len);
                                                if (handle != NULL)
                                                {
                                                        /*
                                                         * dissect the embedded message
                                                        */
-                                                       l3_tvb = tvb_new_subset(tvb, curr_offset, e_len, e_len);
                                                        /* In this case we do not want the columns updated */
-                                                       col_set_writable(pinfo->cinfo, FALSE);
+                                                       col_set_writable(pinfo->cinfo, -1, FALSE);
                                                        call_dissector(handle, l3_tvb, pinfo, pco_tree);
-                                                       col_set_writable(pinfo->cinfo, TRUE);
+                                                       col_set_writable(pinfo->cinfo, -1, TRUE);
                                                }
                                                else
                                                {
                                                        /*
                                                        * dissect the embedded DATA message
                                                        */
-                                                       l3_tvb = tvb_new_subset(tvb, curr_offset, e_len, e_len);
-                                                       call_dissector(data_handle, l3_tvb, pinfo, pco_tree);
+                                                       call_data_dissector(l3_tvb, pinfo, pco_tree);
                                                }
                                        }
                                }
                        }
                }
-
                curr_len    -= e_len;
                curr_offset += e_len;
        }
-       curr_offset += curr_len;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       if (curr_len < 0) {
+               proto_tree_add_expert(tree, pinfo, &ei_gsm_a_gm_not_enough_data, tvb, offset, len);
+       } else {
+               EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
+       }
 
-       return (curr_offset - offset);
+       return len;
 }
 
 /*
@@ -4127,7 +4753,7 @@ static const value_string gsm_a_sm_pdp_type_org_vals[] = {
        { 0, NULL }
 };
 
-static guint16
+guint16
 de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
        guint32      curr_offset;
@@ -4150,6 +4776,7 @@ de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offs
                {
                        case 0x00: str = "Reserved, used in earlier version of this protocol"; break;
                        case 0x01: str = "PDP-type PPP"; break;
+                       case 0x02: str = "non IP"; break;
                        default:   str = "reserved";
                }
        }
@@ -4169,23 +4796,17 @@ de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offs
        else
                str = "Not specified";
 
-       proto_tree_add_text(tree,
-               tvb, curr_offset, 1,
-               "PDP type number: %s (%u)", str, pdp_type_num);
+       proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_pdp_type_number, tvb, curr_offset, 1, pdp_type_num, "%s (%u)", str, pdp_type_num);
 
        if ((len == 2) && ((pdp_type_num == 0x21) || (pdp_type_num == 0x57) || (pdp_type_num == 0x8d)))
        {
-               proto_tree_add_text(tree,
-                       tvb, curr_offset, 1,
-                       "Dynamic addressing");
+               proto_tree_add_uint_format(tree, hf_gsm_a_sm_pdp_address, tvb, curr_offset, 1, pdp_type_num, "Dynamic addressing");
                curr_offset += 1;
                return (curr_offset - offset);
        }
        else if (len == 2)
        {
-               proto_tree_add_text(tree,
-                       tvb, curr_offset, 1,
-                       "No PDP address is included");
+               proto_tree_add_uint_format(tree, hf_gsm_a_sm_pdp_address, tvb, curr_offset, 1, 0, "No PDP address is included");
                curr_offset += 1;
                return (curr_offset - offset);
        }
@@ -4211,7 +4832,7 @@ de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offs
                        curr_offset += 4;
        }
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -4455,13 +5076,9 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        }
 
        if ((oct >= 1) && (oct <= 0x96))
-               proto_tree_add_text(tree,
-                       tvb, curr_offset, 1,
-                       "Maximum SDU size: %u octets (%u)", oct*10, oct);
+               proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_maximum_sdu_size, tvb, curr_offset, 1, oct, "%u octets (%u)", oct*10, oct);
        else
-               proto_tree_add_text(tree,
-                       tvb, curr_offset, 1,
-                       "Maximum SDU size: %s (%u)", str, oct);
+               proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_maximum_sdu_size, tvb, curr_offset, 1, oct, "%s (%u)", str, oct);
 
        curr_offset += 1;
 
@@ -4474,7 +5091,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                case 0x00: str = "Subscribed maximum bit rate for uplink/reserved"; break;
                case 0xff: str = "0 kbps"; break;
-               default:   str = ep_strdup_printf("%u kbps", qos_calc_bitrate(oct));
+               default:   str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", qos_calc_bitrate(oct));
        }
 
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_upl, tvb,
@@ -4490,7 +5107,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                case 0x00: str = "Subscribed maximum bit rate for downlink/reserved"; break;
                case 0xff: str = "0 kbps"; break;
-               default:   str = ep_strdup_printf("%u kbps", qos_calc_bitrate(oct));
+               default:   str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", qos_calc_bitrate(oct));
        }
 
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_downl, tvb,
@@ -4521,7 +5138,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
                                temp32 = (tmp_oct - 0x10) * 50 + 200;
                        else
                                temp32 = (tmp_oct - 0x20) * 100 + 1000;
-                       str = ep_strdup_printf("%u ms", temp32);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u ms", temp32);
        }
 
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_trans_delay, tvb,
@@ -4539,7 +5156,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                case 0x00: str = "Subscribed guaranteed bit rate for uplink/reserved"; break;
                case 0xff: str = "0 kbps"; break;
-               default:   str = ep_strdup_printf("%u kbps", qos_calc_bitrate(oct));
+               default:   str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", qos_calc_bitrate(oct));
        }
 
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_guar_bitrate_upl, tvb,
@@ -4555,7 +5172,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                case 0x00: str = "Subscribed guaranteed bit rate for downlink/reserved"; break;
                case 0xff: str = "0 kbps"; break;
-               default:   str = ep_strdup_printf("%u kbps", qos_calc_bitrate(oct));
+               default:   str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", qos_calc_bitrate(oct));
        }
 
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_guar_bitrate_downl, tvb,
@@ -4590,9 +5207,9 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                temp32 = qos_calc_ext_bitrate(oct);
                if (temp32 % 1000 == 0)
-                       str = ep_strdup_printf("%u Mbps", temp32 / 1000);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32 / 1000);
                else
-                       str = ep_strdup_printf("%u kbps", temp32);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_downl_ext, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
@@ -4609,9 +5226,9 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                temp32 = qos_calc_ext_bitrate(oct);
                if (temp32 % 1000 == 0)
-                       str = ep_strdup_printf("%u Mbps", temp32 / 1000);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32 / 1000);
                else
-                       str = ep_strdup_printf("%u kbps", temp32);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_guar_bitrate_downl_ext, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
@@ -4628,9 +5245,9 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                temp32 = qos_calc_ext_bitrate(oct);
                if (temp32 % 1000 == 0)
-                       str = ep_strdup_printf("%u Mbps", temp32 / 1000);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32 / 1000);
                else
-                       str = ep_strdup_printf("%u kbps", temp32);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_upl_ext, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
@@ -4647,9 +5264,9 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        {
                temp32 = qos_calc_ext_bitrate(oct);
                if (temp32 % 1000 == 0)
-                       str = ep_strdup_printf("%u Mbps", temp32 / 1000);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32 / 1000);
                else
-                       str = ep_strdup_printf("%u kbps", temp32);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_guar_bitrate_upl_ext, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
@@ -4665,7 +5282,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        else
        {
                temp32 = qos_calc_ext2_bitrate(oct);
-               str = ep_strdup_printf("%u Mbps", temp32);
+               str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_downl_ext2, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
@@ -4681,7 +5298,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        else
        {
                temp32 = qos_calc_ext2_bitrate(oct);
-               str = ep_strdup_printf("%u Mbps", temp32);
+               str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_guar_bitrate_downl_ext2, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
@@ -4697,7 +5314,7 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        else
        {
                temp32 = qos_calc_ext2_bitrate(oct);
-               str = ep_strdup_printf("%u Mbps", temp32);
+               str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_upl_ext2, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
@@ -4713,18 +5330,63 @@ de_sm_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, g
        else
        {
                temp32 = qos_calc_ext2_bitrate(oct);
-               str = ep_strdup_printf("%u Mbps", temp32);
+               str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_guar_bitrate_upl_ext2, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
 
        curr_offset += 1;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
 
+/*
+ * [12] 10.5.6.5a Re-attempt indicator
+ */
+const true_false_string gsm_a_gm_eplmnc_value = {
+       "MS is not allowed to re-attempt the procedure in an equivalent PLMN",
+       "MS is allowed to re-attempt the procedure in an equivalent PLMN"
+};
+
+const true_false_string gsm_a_gm_ratc_value = {
+       "MS is not allowed to re-attempt the procedure in S1 mode",
+       "MS is allowed to re-attempt the procedure in S1 mode"
+};
+
+static guint16
+de_sm_re_attempt_ind(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+       guint32 curr_offset;
+
+       curr_offset = offset;
+
+       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, offset << 3, 6, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_sm_eplmnc, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_gsm_a_sm_ratc, tvb, offset, 1, ENC_BIG_ENDIAN);
+       curr_offset++;
+
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
+
+       return len;
+}
+
+/*
+ * [15] 10.5.6.5b Extended quality of service
+ */
+static guint16
+de_sm_ext_qos(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+       guint32 curr_offset;
+
+       curr_offset = offset;
+
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
+
+       return len;
+}
+
 /*
  * [9] 10.5.6.6 SM cause
  */
@@ -4759,6 +5421,8 @@ static const value_string gsm_a_sm_cause_vals[] = {
        { 0x33, "PDP type IPv6 only allowed" },
        { 0x34, "Single address bearers only allowed" },
        { 0x38, "Collision with network initiated request" },
+       { 0x39, "PDP type IPv4v6 only allowed" },
+       { 0x3a, "PDP type non IP only allowed" },
        { 0x3c, "Bearer handling not supported" },
        { 0x41, "Maximum number of PDP contexts reached" },
        { 0x42, "Requested APN not supported in current RAT and PLMN combination" },
@@ -4772,6 +5436,7 @@ static const value_string gsm_a_sm_cause_vals[] = {
        { 0x65, "Message not compatible with the protocol state" },
        { 0x6f, "Protocol error, unspecified" },
        { 0x70, "APN restriction value incompatible with active PDP context" },
+       { 0x71, "Multiple accesses to a PDN connection not allowed" },
        { 0, NULL }
 };
 static value_string_ext gsm_a_sm_cause_vals_ext = VALUE_STRING_EXT_INIT(gsm_a_sm_cause_vals);
@@ -4850,24 +5515,20 @@ de_sm_linked_ti(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 off
                curr_offset++;
                oct = tvb_get_guint8(tvb, curr_offset);
 
-               proto_tree_add_text(tree,
-                       tvb, curr_offset, 1,
-                       "TI value: 0x%02x (%u)", oct&0x7f, oct&0x7f);
+               proto_tree_add_uint(tree, hf_gsm_a_gm_ti_value, tvb, curr_offset, 1, oct&0x7f);
 
-               proto_tree_add_item(tree, hf_gsm_a_sm_ext, tvb, offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_gsm_a_sm_ext, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
 
                curr_offset++;
        }
        else
        {
-               proto_tree_add_text(tree,
-                       tvb, curr_offset, 1,
-                       "TI value: 0x%02x (%u)", (oct>>4)&7, (oct>>4)&7);
+               proto_tree_add_uint(tree, hf_gsm_a_gm_ti_value, tvb, curr_offset, 1, (oct>>4)&7);
                curr_offset++;
        }
 
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -4940,7 +5601,7 @@ de_sm_pflow_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offs
        if (add_string)
                g_snprintf(add_string, string_len, " - %s", rval_to_str(value, gsm_a_sm_packet_flow_id_vals, "Unknown"));
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -4950,7 +5611,7 @@ de_sm_pflow_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offs
  */
 /* TFT operation code (octet 3) */
 static const value_string gsm_a_sm_tft_op_code_vals[] = {
-       { 0,            "Spare"},
+       { 0,            "Ignore this IE"},
        { 1,            "Create new TFT"},
        { 2,            "Delete existing TFT"},
        { 3,            "Add packet filters to existing TFT"},
@@ -4981,15 +5642,31 @@ static const value_string gsm_a_sm_tft_param_id_vals[] = {
        { 0,    NULL }
 };
 
+static const value_string packet_filter_component_type_vals[] = {
+       {0x10,  "IPv4 remote address type" },
+       {0x11,  "IPv4 local address type"},
+       {0x20,  "IPv6 remote address type"},
+       {0x21,  "IPv6 remote address/prefix length type"},
+       {0x23,  "IPv6 local address/prefix length type"},
+       {0x30,  "Protocol identifier/Next header type"},
+       {0x40,  "Single local port type"},
+       {0x41,  "Local port range type"},
+       {0x50,  "Single remote port type"},
+       {0x51,  "Remote port range type"},
+       {0x60,  "Security parameter index type"},
+       {0x70,  "Type of service/Traffic class type"},
+       {0x80,  "Flow label type"},
+       {0, NULL}
+};
+
 guint16
 de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
-       guint32       curr_offset;
+       guint32       curr_offset, prev_offset;
        guint         curr_len;
        guint8        op_code;
        guint8        pkt_fil_count;
        guint8        e_bit;
-       const gchar  *str;
        guint8        count;
        guint8        oct;
        gint          pf_length;
@@ -5023,20 +5700,20 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                count = pkt_fil_count;
        while (count < pkt_fil_count)
        {
-               proto_item *tf;
+               proto_item *tf_pf;
                proto_tree *tf_tree;
-               tf = proto_tree_add_text(tree,
-                       tvb, curr_offset, 1,
-                       "Packet filter %d", count);   /* 0-> 7 */
+               prev_offset = curr_offset;
+               tf_pf = proto_tree_add_uint(tree, hf_gsm_a_sm_tft_packet_filter, tvb, curr_offset, 1, count);   /* 0-> 7 */
 
-               tf_tree = proto_item_add_subtree(tf, ett_sm_tft);
+               tf_tree = proto_item_add_subtree(tf_pf, ett_sm_tft);
+
+               if ((curr_offset-offset)<1) {
+                       proto_tree_add_expert(tf_tree, pinfo, &ei_gsm_a_gm_not_enough_data, tvb, curr_offset, 1);
+                       return (len);
+               }
 
                if (op_code == 5)  /* Delete packet filters from existing TFT - just a list of identifiers */
                {
-                       if ((curr_offset-offset)<1) {
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Not enough data");
-                               return (len);
-                       }
                        proto_tree_add_bits_item(tf_tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3), 4, ENC_BIG_ENDIAN);
                        oct = tvb_get_guint8(tvb, curr_offset) & 0x0f;
                        proto_tree_add_uint_format_value(tf_tree, hf_gsm_a_sm_tft_pkt_flt_id, tvb, curr_offset, 1, oct, "%d (%d)", oct+1, oct);
@@ -5046,11 +5723,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                }
                else                            /* create new, Add packet filters or Replace packet filters */
                {
-
-                       if ((curr_offset-offset)<1) {
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Not enough data");
-                               return (len);
-                       }
                        proto_tree_add_bits_item(tf_tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3), 2, ENC_BIG_ENDIAN);
                        proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_pkt_flt_dir, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
                        oct = tvb_get_guint8(tvb, curr_offset) & 0x0f;
@@ -5059,25 +5731,22 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                        curr_len--;
 
                        if ((curr_offset-offset) < 1) {
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Not enough data");
+                               proto_tree_add_expert(tf_tree, pinfo, &ei_gsm_a_gm_not_enough_data, tvb, curr_offset, 1);
                                return (len);
                        }
-                       oct = tvb_get_guint8(tvb, curr_offset);
+                       proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_packet_evaluation_precedence, tvb, curr_offset, 1, ENC_NA);
                        curr_offset++;
                        curr_len--;
 
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1, 1,
-                               "Packet evaluation precedence: 0x%02x (%u)", oct, oct);
-
-                       if ((curr_offset-offset)<1) { proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Not enough data"); return (len);}
+                       if ((curr_offset-offset)<1) {
+                               proto_tree_add_expert(tf_tree, pinfo, &ei_gsm_a_gm_not_enough_data, tvb, curr_offset, 1);
+                               return (len);
+                       }
                        pf_length = tvb_get_guint8(tvb, curr_offset);
+                       proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_packet_filter_length, tvb, curr_offset, 1, ENC_NA);
                        curr_offset++;
                        curr_len--;
 
-                       proto_tree_add_text(tf_tree,
-                               tvb, curr_offset-1, 1,
-                               "Packet filter length: 0x%02x (%u)", pf_length, pf_length);
                        /* New tree for component */
 
                        /* Dissect Packet filter Component */
@@ -5085,23 +5754,23 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                        /* packet filter component type identifier: */
 
                        while (pf_length > 0) {
+                               proto_item *tf;
                                proto_tree *comp_tree;
                                if ((curr_offset-offset) < 1) {
-                                       proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Not enough data");
+                                       proto_tree_add_expert(tf_tree, pinfo, &ei_gsm_a_gm_not_enough_data, tvb, curr_offset, 1);
                                        return (len);
                                }
                                pack_component_type = tvb_get_guint8(tvb, curr_offset);
+                               tf = proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_packet_filter_component_type_id, tvb, curr_offset, 1, ENC_NA);
+                               comp_tree = proto_item_add_subtree(tf, ett_sm_tft);
+
                                curr_offset++;
                                curr_len--;
                                pf_length--;
 
-                               tf = proto_tree_add_text(tf_tree, tvb, curr_offset-1, 1, "Packet filter component type identifier: ");
-                               comp_tree = proto_item_add_subtree(tf, ett_sm_tft);
-
                                switch (pack_component_type) {
 
                                case 0x10:
-                                       str = "IPv4 remote address type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip4_address, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
                                        curr_offset += 4;
                                        curr_len    -= 4;
@@ -5112,7 +5781,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x11:
-                                       str = "IPv4 local address type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip4_address, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
                                        curr_offset += 4;
                                        curr_len    -= 4;
@@ -5123,7 +5791,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x20:
-                                       str = "IPv6 remote address type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip6_address, tvb, curr_offset, 16, ENC_NA);
                                        curr_offset += 16;
                                        curr_len    -= 16;
@@ -5134,29 +5801,26 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x21:
-                                       str = "IPv6 remote address/prefix length type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip6_address, tvb, curr_offset, 16, ENC_NA);
                                        curr_offset += 16;
                                        curr_len    -= 16;
-                                       proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip6_prefix_length, tvb, curr_offset, 1, ENC_NA);
+                                       proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip6_prefix_length, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
                                        curr_offset += 1;
                                        curr_len    -= 1;
                                        pf_length   -= 17;
                                        break;
 
                                case 0x23:
-                                       str = "IPv6 local address/prefix length type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip6_address, tvb, curr_offset, 16, ENC_NA);
                                        curr_offset += 16;
                                        curr_len    -= 16;
-                                       proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip6_prefix_length, tvb, curr_offset, 1, ENC_NA);
+                                       proto_tree_add_item(comp_tree, hf_gsm_a_sm_ip6_prefix_length, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
                                        curr_offset += 1;
                                        curr_len    -= 1;
                                        pf_length   -= 17;
                                        break;
 
                                case 0x30:
-                                       str = "Protocol identifier/Next header type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_protocol_header, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
                                        curr_offset += 1;
                                        curr_len    -= 1;
@@ -5164,7 +5828,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x40:
-                                       str = "Single local port type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_port, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
                                        curr_offset += 2;
                                        curr_len    -= 2;
@@ -5172,7 +5835,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x41:
-                                       str = "Local port range type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_port_low, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
                                        curr_offset += 2;
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_port_high, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
@@ -5182,7 +5844,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x50:
-                                       str = "Single remote port type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_port, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
                                        curr_offset += 2;
                                        curr_len    -= 2;
@@ -5190,7 +5851,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x51:
-                                       str = "Remote port range type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_port_low, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
                                        curr_offset += 2;
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_port_high, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
@@ -5200,7 +5860,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x60:
-                                       str = "Security parameter index type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_security, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
                                        curr_offset += 4;
                                        curr_len    -= 4;
@@ -5209,7 +5868,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
 
 
                                case 0x70:
-                                       str = "Type of service/Traffic class type";
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_traffic_class, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
                                        curr_offset++;
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_traffic_mask, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
@@ -5219,7 +5877,6 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                case 0x80:
-                                       str = "Flow label type";
                                        proto_tree_add_bits_item(comp_tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3), 4, ENC_BIG_ENDIAN);
                                        proto_tree_add_item(comp_tree, hf_gsm_a_sm_tft_flow_label_type, tvb, curr_offset, 3, ENC_BIG_ENDIAN);
                                        curr_offset += 3;
@@ -5228,15 +5885,14 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                                        break;
 
                                default:
-                                       str = "not specified";
                                        curr_offset += pf_length;
                                        curr_len    -= pf_length;
                                        pf_length    = 0;
                                }
-                               proto_item_append_text(tf, "%s (%u)", str, pack_component_type);
                        }
                        count++;
                }
+               proto_item_set_len(tf_pf, curr_offset - prev_offset);
        }
 
        /* The parameters list contains a variable number of parameters that might need to be
@@ -5246,39 +5902,32 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
        if ((e_bit == 1) && curr_len) {
                count = 0;
                while (curr_len) {
-                       proto_item *tf;
                        proto_tree *tf_tree;
                        pf_length = tvb_get_guint8(tvb, curr_offset+1);
-                       tf        = proto_tree_add_text(tree, tvb, curr_offset, pf_length+2, "Parameter %d", count);
-                       tf_tree   = proto_item_add_subtree(tf, ett_sm_tft);
+                       tf_tree   = proto_tree_add_subtree_format(tree, tvb, curr_offset, pf_length+2, ett_sm_tft, NULL, "Parameter %d", count);
                        param     = tvb_get_guint8(tvb, curr_offset);
                        proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_param_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
                        curr_offset += 2;
                        curr_len    -= 2;
                        switch (param) {
                        case 0x01:
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, pf_length, "Authorization token value: 0x%s",
-                                                   tvb_bytes_to_str(tvb, curr_offset, pf_length));
+                               proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_authorization_token_value, tvb, curr_offset, pf_length, ENC_NA);
                                break;
 
                        case 0x02:
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, 2, "Media Component number value: 0x%x",
-                                                   tvb_get_bits16(tvb, curr_offset<<3, 16, ENC_BIG_ENDIAN));
-                               proto_tree_add_text(tf_tree, tvb, curr_offset+2, 2, "IP flow number: 0x%x",
-                                                   tvb_get_bits16(tvb, (curr_offset+2)<<3, 16, ENC_BIG_ENDIAN));
+                               proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_media_component_number_value, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
+                               proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_ip_flow_number, tvb, curr_offset+2, 2, ENC_BIG_ENDIAN);
                                break;
 
                        case 0x03:
                                for (i=0; i<pf_length; i++) {
                                        oct = tvb_get_guint8(tvb, curr_offset+i) & 0x0f;
-                                       proto_tree_add_text(tf_tree, tvb, curr_offset+i, 1, "Packet filter identifier %d: %d (%d)",
-                                                           i, oct+1, oct);
+                                       proto_tree_add_uint_format(tf_tree, hf_gsm_a_sm_tft_packet_filter_identifier, tvb, curr_offset+i, 1, oct+1, "Packet filter identifier %d: %d (%d)", i, oct+1, oct);
                                }
                                break;
 
                        default:
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, pf_length, "Parameter content: 0x%s",
-                                                   tvb_bytes_to_str(tvb, curr_offset, pf_length));
+                               proto_tree_add_item(tf_tree, hf_gsm_a_sm_tft_parameter_content, tvb, curr_offset, pf_length, ENC_NA);
                                break;
                        }
                        curr_offset += pf_length;
@@ -5287,7 +5936,7 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
                }
        }
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (len);
 }
@@ -5306,9 +5955,9 @@ de_sm_tmgi(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset,
        curr_offset += 3;
 
        NO_MORE_DATA_CHECK(len);
-       curr_offset = dissect_e212_mcc_mnc(tvb, pinfo, tree, curr_offset, TRUE);
+       curr_offset = dissect_e212_mcc_mnc(tvb, pinfo, tree, curr_offset, E212_NONE, TRUE);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -5331,7 +5980,7 @@ de_sm_mbms_bearer_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint
        {
                case 0x00: str = "Subscribed maximum bit rate for downlink/reserved"; break;
                case 0xff: str = "0 kbps"; break;
-               default:   str = ep_strdup_printf("%u kbps", qos_calc_bitrate(oct));
+               default:   str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", qos_calc_bitrate(oct));
        }
 
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_downl, tvb,
@@ -5348,16 +5997,16 @@ de_sm_mbms_bearer_cap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint
        {
                temp32 = qos_calc_ext_bitrate(oct);
                if (temp32 % 1000 == 0)
-                       str = ep_strdup_printf("%u Mbps", temp32 / 1000);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u Mbps", temp32 / 1000);
                else
-                       str = ep_strdup_printf("%u kbps", temp32);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "%u kbps", temp32);
        }
        proto_tree_add_uint_format_value(tree, hf_gsm_a_sm_qos_max_bitrate_downl_ext, tvb,
                curr_offset, 1, oct, "%s (%u)", str, oct);
 
        curr_offset += 1;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -5374,7 +6023,7 @@ de_sm_mbms_prot_conf_opt(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gu
        proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3), 8, ENC_BIG_ENDIAN);
        curr_offset++;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo);
+       EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_gm_extraneous_data);
 
        return (curr_offset - offset);
 }
@@ -5393,7 +6042,7 @@ de_sm_enh_nsapi(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32
        if(oct < 0x80)
                str = "Reserved";
        else if (oct < 0xff)
-                       str = ep_strdup_printf("NSAPI %u for Multimedia Broadcast/Multicast Service (MBMS) Multicast mode", oct);
+                       str = wmem_strdup_printf(wmem_packet_scope(), "NSAPI %u for Multimedia Broadcast/Multicast Service (MBMS) Multicast mode", oct);
                else
                        str = "Reserved for use by lower layers in the p2p radio bearer allocation message for MBMS Broadcast mode";
 
@@ -5413,6 +6062,7 @@ static const value_string gsm_a_sm_req_type_vals[] = {
        { 0x02, "Handover" },
        { 0x03, "Unused. If received, the network shall interpret this as \"Initial request\"." },
        { 0x04, "Emergency" },
+       { 0x06, "Handover of emergency bearer services" },
        { 0, NULL }
 };
 
@@ -5460,22 +6110,58 @@ static const range_string gsm_a_sm_connectivity_type_vals[] = {
 static guint16
 de_sm_connectivity_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
 {
-       guint32 curr_offset;
+       proto_tree_add_item(tree, hf_gsm_a_sm_connectivity_type, tvb, offset, 1, ENC_BIG_ENDIAN);
 
-       curr_offset = offset;
+       return (len);
+}
 
-       proto_tree_add_item(tree, hf_gsm_a_sm_connectivity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+/*
+ * [12] 10.5.6.20 WLAN offload acceptability
+ */
+static const true_false_string gsm_a_sm_wlan_utran_offload_accept_value = {
+       "Offloading the traffic of the PDN connection via a WLAN when in Iu mode is acceptable",
+       "Offloading the traffic of the PDN connection via a WLAN when in Iu mode is not acceptable"
+};
+
+static const true_false_string gsm_a_sm_wlan_eutran_offload_accept_value = {
+       "Offloading the traffic of the PDN connection via a WLAN when in S1 mode is acceptable",
+       "Offloading the traffic of the PDN connection via a WLAN when in S1 mode is not acceptable"
+};
+
+static guint16
+de_sm_wlan_offload_accept(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+       proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (offset<<3)+4, 2, ENC_BIG_ENDIAN);
+       proto_tree_add_bits_item(tree, hf_gsm_a_sm_wlan_utran_offload_accept, tvb, (offset<<3)+6, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_bits_item(tree, hf_gsm_a_sm_wlan_eutran_offload_accept, tvb, (offset<<3)+7, 1, ENC_BIG_ENDIAN);
 
        return (len);
 }
 
+/*
+ * [13] 10.5.6.21 NBIFOM container
+ */
+static guint16
+de_sm_nbifom_cont(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
+{
+       if (nbifom_handle) {
+               tvbuff_t *nbifom_tvb = tvb_new_subset_length(tvb, offset, len);
+
+               call_dissector(nbifom_handle, nbifom_tvb, pinfo, tree);
+       } else {
+               proto_tree_add_item(tree, hf_gsm_a_sm_nbifom_cont, tvb, offset, len, ENC_NA);
+       }
+
+       return len;
+}
 
 guint16 (*gm_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string, int string_len) = {
        /* GPRS Mobility Management Information Elements 10.5.5 */
        de_gmm_add_upd_type,               /* Additional Update Type */
        de_gmm_attach_res,                 /* Attach Result */
        de_gmm_attach_type,                /* Attach Type */
-       de_gmm_ciph_alg,                   /* Cipher Algorithm */
+       de_gmm_ciph_alg,                   /* Ciphering Algorithm */
+       de_gmm_integ_alg,                  /* Integrity Algorithm */
        de_gmm_tmsi_stat,                  /* TMSI Status */
        de_gmm_detach_type,                /* Detach Type */
        de_gmm_drx_param,                  /* DRX Parameter */
@@ -5508,12 +6194,21 @@ guint16 (*gm_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_
        de_gmm_ptmsi_type,                 /* P-TMSI type */
        de_gmm_lai_2,                      /* Location Area Identification 2 */
        de_gmm_net_res_id_cont,            /* Network resource identifier container */
+       de_gmm_ext_drx_params,             /* Extended DRX parameters */
+       de_gmm_mac,                        /* Message authentication code */
+       de_gmm_up_integ_ind,               /* User Plane integrity indicator */
+       de_gmm_dcn_id,                     /* DCN-ID */
+       de_gmm_plmn_id_cn_operator,        /* PLMN identity of the CN operator */
+       de_gmm_non_3gpp_nw_prov_pol,       /* Non-3GPP NW provided policies */
        /* Session Management Information Elements 10.5.6 */
        de_sm_apn,                         /* Access Point Name */
        de_sm_nsapi,                       /* Network Service Access Point Identifier */
        de_sm_pco,                         /* Protocol Configuration Options */
+       de_sm_pco,                         /* Extended Protocol Configuration Options */
        de_sm_pdp_addr,                    /* Packet Data Protocol Address */
        de_sm_qos,                         /* Quality Of Service */
+       de_sm_re_attempt_ind,              /* Re-attempt indicator */
+       de_sm_ext_qos,                     /* Extended quality of service */
        de_sm_cause,                       /* SM Cause */
        de_sm_cause_2,                     /* SM Cause 2 */
        de_sm_linked_ti,                   /* Linked TI */
@@ -5528,6 +6223,8 @@ guint16 (*gm_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_
        de_sm_req_type,                    /* Request type */
        de_sm_notif_ind,                   /* Notification indicator */
        de_sm_connectivity_type,           /* Connectivity type */
+       de_sm_wlan_offload_accept,         /* WLAN offload acceptability */
+       de_sm_nbifom_cont,                 /* NBIFOM container */
        /* GPRS Common Information Elements 10.5.7 */
        de_gc_context_stat,                /* PDP Context Status */
        de_gc_radio_prio,                  /* Radio Priority */
@@ -5558,24 +6255,17 @@ dtap_gmm_attach_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MS_NET_CAP, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MS_NET_CAP, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       /* Included in attach type
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_ATTACH_TYPE, GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, NULL);
-       curr_offset--;
-       curr_len++;
-       */
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_ATTACH_TYPE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_DRX_PARAM, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_DRX_PARAM, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, " - Old routing area identification", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, " - Old routing area identification");
-
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TV( 0x19, GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG, " - Old P-TMSI Signature");
 
@@ -5611,7 +6301,13 @@ dtap_gmm_attach_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        ELEM_OPT_TLV(0x10, GSM_A_PDU_TYPE_GM, DE_NET_RES_ID_CONT, " - TMSI based NRI container");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x6A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3324 value");
+
+       ELEM_OPT_TLV(0x39, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - T3312 extended value");
+
+       ELEM_OPT_TLV(0x6E, GSM_A_PDU_TYPE_GM, DE_EXT_DRX_PARAMS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5629,21 +6325,17 @@ dtap_gmm_attach_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, NULL);
-       curr_len++;
-       curr_offset--;
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_ATTACH_RES, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_ATTACH_RES, GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO_2, " - Radio priority for TOM8");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO_2, " - Radio priority for TOM8", ei_gsm_a_gm_missing_mandatory_element);
        curr_len++;
        curr_offset--;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, " - Radio priority for SMS");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, " - Radio priority for SMS", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TV( 0x19, GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG, NULL);
 
@@ -5675,7 +6367,23 @@ dtap_gmm_attach_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        ELEM_OPT_TLV(0x66, GSM_A_PDU_TYPE_GM, DE_ADD_NET_FEAT_SUP, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x6A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3324 value");
+
+       ELEM_OPT_TLV(0x6E, GSM_A_PDU_TYPE_GM, DE_EXT_DRX_PARAMS, NULL);
+
+       ELEM_OPT_TV_SHORT(0xC0, GSM_A_PDU_TYPE_GM, DE_UP_INTEG_IND, NULL);
+
+       ELEM_OPT_TLV(0x31, GSM_A_PDU_TYPE_GM, DE_MS_NET_CAP, " - Replayed MS network capability");
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP, " - Replayed MS Radio Access capability");
+
+       ELEM_OPT_TLV(0x65, GSM_A_PDU_TYPE_GM, DE_DCN_ID, NULL);
+
+       ELEM_OPT_TLV(0x63, GSM_A_PDU_TYPE_GM, DE_PLMN_ID_CN_OPERATOR, NULL);
+
+       ELEM_OPT_TV_SHORT(0xD0, GSM_A_PDU_TYPE_GM, DE_NON_3GPP_NW_PROV_POL, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5698,7 +6406,7 @@ dtap_gmm_attach_com(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        ELEM_OPT_TLV( 0x2B, GSM_A_PDU_TYPE_GM, DE_EUTRAN_IRAT_INFO_CONTAINER, " - E-UTRAN inter RAT handover information");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5716,20 +6424,39 @@ dtap_gmm_attach_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x2A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3302 value" );
 
        ELEM_OPT_TLV(0x3A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3346 value");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
+}
+
+/*
+ * [7] 9.4.5
+ */
+static void
+dtap_gmm_detach_req_MT(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len)
+{
+       guint32 curr_offset;
+       guint32 consumed;
+       guint   curr_len;
+
+       curr_offset = offset;
+       curr_len    = len;
+
+       pinfo->p2p_dir = P2P_DIR_SENT;
+
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_DETACH_TYPE, GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, ei_gsm_a_gm_missing_mandatory_element);
+
+       ELEM_OPT_TV( 0x25, GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
-/*
- * [7] 9.4.5
- */
 static void
-dtap_gmm_detach_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len)
+dtap_gmm_detach_req_MO(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len)
 {
        guint32 curr_offset;
        guint32 consumed;
@@ -5738,22 +6465,34 @@ dtap_gmm_detach_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
        curr_offset = offset;
        curr_len    = len;
 
-       pinfo->p2p_dir = P2P_DIR_SENT;
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, NULL);
-       /* Force to standy might be wrong - To decode it correct, we need the direction */
-       curr_len++;
-       curr_offset--;
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_DETACH_TYPE, NULL);
+       pinfo->p2p_dir = P2P_DIR_RECV;
 
-       ELEM_OPT_TV( 0x25, GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_DETACH_TYPE, GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_OPT_TLV( 0x18, GSM_A_PDU_TYPE_COMMON, DE_MID, " - P-TMSI" );
+       ELEM_OPT_TLV( 0x18, GSM_A_PDU_TYPE_COMMON, DE_MID, NULL);
 
        ELEM_OPT_TLV( 0x19, GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG_2, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
+}
+
+static void
+dtap_gmm_detach_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len)
+{
+       if (pinfo->link_dir == P2P_DIR_UL) {
+               dtap_gmm_detach_req_MO(tvb, tree, pinfo, offset, len);
+               return;
+       }else if (pinfo->link_dir == P2P_DIR_DL) {
+               dtap_gmm_detach_req_MT(tvb, tree, pinfo, offset, len);
+               return;
+       } else {
+               /* Unknown direction. Try heuristics based on message length. */
+               if (len > 5) {
+                       dtap_gmm_detach_req_MO(tvb, tree, pinfo, offset, len);
+               } else {
+                       dtap_gmm_detach_req_MT(tvb, tree, pinfo, offset, len);
+               }
+       }
 }
 
 /*
@@ -5763,7 +6502,6 @@ static void
 dtap_gmm_detach_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len)
 {
        guint32 curr_offset;
-       guint32 consumed;
        guint   curr_len;
 
        curr_offset = offset;
@@ -5771,16 +6509,13 @@ dtap_gmm_detach_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       if (curr_len != 0 )
-       {
-               ELEM_MAND_V( GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, NULL);
-               curr_len++;
-               curr_offset--;
-
-               ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, NULL);
+       if (curr_len == 0) {
+               return;
        }
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, ei_gsm_a_gm_missing_mandatory_element);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5798,19 +6533,17 @@ dtap_gmm_ptmsi_realloc_cmd(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, " - Allocated P-TMSI" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, " - Allocated P-TMSI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, NULL);
-       curr_len++;
-       curr_offset--;
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TV( 0x19, GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG, " - P-TMSI Signature" );
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x65, GSM_A_PDU_TYPE_GM, DE_DCN_ID, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5828,7 +6561,7 @@ dtap_gmm_ptmsi_realloc_com(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5840,56 +6573,31 @@ dtap_gmm_auth_ciph_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guin
        guint32 curr_offset;
        guint32 consumed;
        guint   curr_len;
-       guint8  oct;
 
        curr_offset = offset;
        curr_len    = len;
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_IMEISV_REQ, NULL);
-       curr_offset--;
-       curr_len++;
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_CIPH_ALG, GSM_A_PDU_TYPE_GM, DE_IMEISV_REQ, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_CIPH_ALG, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, GSM_A_PDU_TYPE_GM, DE_AC_REF_NUM_H, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_AC_REF_NUM_H, NULL);
-       curr_offset--;
-       curr_len++;
+       ELEM_OPT_TV(0x21, GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND, NULL);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, NULL);
+       ELEM_OPT_TV_SHORT(0x80, GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, NULL);
 
-       ELEM_OPT_TV( 0x21, GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND, NULL);
+       ELEM_OPT_TLV(0x28, GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN, NULL);
 
-#if 0
-       ELEM_OPT_TV_SHORT( 0x08, GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, NULL);
-#else
-       if (curr_len > 0)
-       {
-               oct = tvb_get_guint8(tvb, curr_offset);
-               if ((oct & 0xf0) == 0x80 )
-               {
-                       /* The ciphering key sequence number is added here */
-                       proto_tree_add_text(tree,
-                               tvb, curr_offset, 1,
-                               "Ciphering key sequence number: 0x%02x (%u)",
-                               oct&7,
-                               oct&7);
-                       curr_offset++;
-                       curr_len--;
-               }
-       }
-#endif
+       ELEM_OPT_TLV(0x31, GSM_A_PDU_TYPE_GM, DE_MS_NET_CAP, " - Replayed MS network capability");
 
-       if (curr_len == 0  )
-       {
-               EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
-       return;
-       }
+       ELEM_OPT_TLV(0x42, GSM_A_PDU_TYPE_GM, DE_INTEG_ALG, NULL);
+
+       ELEM_OPT_TLV(0x43, GSM_A_PDU_TYPE_GM, DE_MAC, NULL);
 
-       ELEM_OPT_TLV( 0x28, GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN, NULL);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP, " - Replayed MS Radio Access capability");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5907,19 +6615,17 @@ dtap_gmm_auth_ciph_resp(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, NULL);
-       curr_offset--;
-       curr_len++;
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_AC_REF_NUM, GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_AC_REF_NUM, NULL);
+       ELEM_OPT_TV(0x22, GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM, NULL);
 
-       ELEM_OPT_TV( 0x22, GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM, NULL);
+       ELEM_OPT_TLV(0x23, GSM_A_PDU_TYPE_COMMON, DE_MID, " - IMEISV" );
 
-       ELEM_OPT_TLV( 0x23, GSM_A_PDU_TYPE_COMMON, DE_MID, " - IMEISV" );
+       ELEM_OPT_TLV(0x29, GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT, NULL);
 
-       ELEM_OPT_TLV( 0x29, GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT, NULL);
+       ELEM_OPT_TLV(0x43, GSM_A_PDU_TYPE_GM, DE_MAC, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5936,7 +6642,7 @@ dtap_gmm_auth_ciph_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guin
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5954,11 +6660,11 @@ dtap_gmm_auth_ciph_fail(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x30, GSM_A_PDU_TYPE_DTAP, DE_AUTH_FAIL_PARAM, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -5975,21 +6681,9 @@ dtap_gmm_ident_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-/*  If the half octet that are about to get decoded is the LAST in the octetstream, the macro will call return BEFORE we get a chance to fix the index. The end result will be that the first half-octet will be decoded but not the last. */
-#if 0
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_ID_TYPE_2, NULL);
-       curr_offset--;
-       curr_len++;
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, NULL);
-#endif
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_ID_TYPE_2, GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, ei_gsm_a_gm_missing_mandatory_element);
 
-       elem_v(tvb, tree, pinfo, GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, curr_offset, NULL);
-       elem_v(tvb, tree, pinfo, GSM_A_PDU_TYPE_GM, DE_ID_TYPE_2, curr_offset, NULL);
-
-       curr_offset += 1;
-       curr_len    -= 1;
-
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6007,9 +6701,9 @@ dtap_gmm_ident_res(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6027,17 +6721,11 @@ dtap_gmm_rau_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       /* is included in update type
-       ELEM_MAND_V( GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, NULL);
-       curr_offset--;
-       curr_len++;
-       */
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_UPD_TYPE, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_UPD_TYPE, GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, " - Old routing area identification");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, " - Old routing area identification", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TV( 0x19, GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG, " - Old P-TMSI Signature" );
 
@@ -6083,7 +6771,13 @@ dtap_gmm_rau_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
 
        ELEM_OPT_TLV(0x10, GSM_A_PDU_TYPE_GM, DE_NET_RES_ID_CONT, " - TMSI based NRI container");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x6A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3324 value");
+
+       ELEM_OPT_TLV(0x39, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - T3312 extended value");
+
+       ELEM_OPT_TLV(0x6E, GSM_A_PDU_TYPE_GM, DE_EXT_DRX_PARAMS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6101,15 +6795,11 @@ dtap_gmm_rau_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_UPD_RES, NULL);
-       curr_offset--;
-       curr_len++;
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, GSM_A_PDU_TYPE_GM, DE_UPD_RES, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER, " - Periodic RA update timer");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER, " - Periodic RA update timer", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAI, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TV( 0x19, GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG, NULL);
 
@@ -6147,7 +6837,23 @@ dtap_gmm_rau_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
 
        ELEM_OPT_TLV(0x66, GSM_A_PDU_TYPE_GM, DE_ADD_NET_FEAT_SUP, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x6A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3324 value");
+
+       ELEM_OPT_TLV(0x6E, GSM_A_PDU_TYPE_GM, DE_EXT_DRX_PARAMS, NULL);
+
+       ELEM_OPT_TV_SHORT(0xC0, GSM_A_PDU_TYPE_GM, DE_UP_INTEG_IND, NULL);
+
+       ELEM_OPT_TLV(0x31, GSM_A_PDU_TYPE_GM, DE_MS_NET_CAP, " - Replayed MS network capability");
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP, " - Replayed MS Radio Access capability");
+
+       ELEM_OPT_TLV(0x65, GSM_A_PDU_TYPE_GM, DE_DCN_ID, NULL);
+
+       ELEM_OPT_TLV(0x63, GSM_A_PDU_TYPE_GM, DE_PLMN_ID_CN_OPERATOR, NULL);
+
+       ELEM_OPT_TV_SHORT(0xD0, GSM_A_PDU_TYPE_GM, DE_NON_3GPP_NW_PROV_POL, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6171,7 +6877,7 @@ dtap_gmm_rau_com(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
 
        ELEM_OPT_TLV( 0x2B, GSM_A_PDU_TYPE_GM, DE_EUTRAN_IRAT_INFO_CONTAINER, " - E-UTRAN inter RAT handover information");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6189,19 +6895,15 @@ dtap_gmm_rau_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 of
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL);
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, NULL);
-       curr_offset--;
-       curr_len++;
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND, GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV(0x2A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3302 value");
 
        ELEM_OPT_TLV(0x3A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3346 value");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6219,9 +6921,9 @@ dtap_gmm_status(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 off
 
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6251,7 +6953,7 @@ dtap_gmm_information(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        ELEM_OPT_TLV( 0x49, GSM_A_PDU_TYPE_DTAP, DE_DAY_SAVING_TIME, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6269,16 +6971,10 @@ dtap_gmm_service_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       /* Is included in SRVC TYPE
-       ELEM_MAND_V( GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, NULL);
-       curr_offset--;
-       curr_len++;
-       */
-
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SRVC_TYPE, NULL);
+       ELEM_MAND_VV_SHORT(GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM, GSM_A_PDU_TYPE_GM, DE_SRVC_TYPE, ei_gsm_a_gm_missing_mandatory_element);
 
        /* P-TMSI Mobile station identity 10.5.1.4 M LV 6 */
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_COMMON, DE_MID, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x32, GSM_A_PDU_TYPE_GM, DE_PDP_CONTEXT_STAT, NULL);
 
@@ -6289,7 +6985,7 @@ dtap_gmm_service_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        ELEM_OPT_TV_SHORT(0xD0, GSM_A_PDU_TYPE_GM, DE_DEVICE_PROPERTIES, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6312,7 +7008,7 @@ dtap_gmm_service_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
        /* MBMS context status 10.5.7.6 TLV 2 - 18 */
        ELEM_OPT_TLV( 0x35, GSM_A_PDU_TYPE_GM, DE_MBMS_CTX_STATUS, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6330,11 +7026,11 @@ dtap_gmm_service_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV(0x3A, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2, " - T3346 value");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6355,13 +7051,13 @@ dtap_sm_act_pdp_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
        /* MS to network */
        pinfo->link_dir = P2P_DIR_UL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_NET_SAPI, " - Requested NSAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_NET_SAPI, " - Requested NSAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Requested QoS" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Requested QoS", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Requested PDP address" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Requested PDP address", ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x28, GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME, NULL);
 
@@ -6371,7 +7067,13 @@ dtap_sm_act_pdp_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        ELEM_OPT_TV_SHORT(0xC0, GSM_A_PDU_TYPE_GM, DE_DEVICE_PROPERTIES, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6392,18 +7094,18 @@ dtap_sm_act_pdp_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
        /* Network to MS*/
        pinfo->link_dir = P2P_DIR_DL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Negotiated LLC SAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Negotiated LLC SAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Negotiated QoS" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Negotiated QoS", ei_gsm_a_gm_missing_mandatory_element);
 
 #if 0
        /* This is done automatically */
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SPARE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SPARE, NULL, ei_gsm_a_gm_missing_mandatory_element);
        curr_offset--;
        curr_len++;
 #endif
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x2B, GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - PDP address");
 
@@ -6415,7 +7117,15 @@ dtap_sm_act_pdp_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
 
        ELEM_OPT_TV_SHORT(0xB0 , GSM_A_PDU_TYPE_GM, DE_SM_CONNECTIVITY_TYPE, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TV_SHORT(0xC0 , GSM_A_PDU_TYPE_GM, DE_SM_WLAN_OFFLOAD_ACCEPT, " - WLAN offload indication");
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6436,13 +7146,19 @@ dtap_sm_act_pdp_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
        /* Network to MS*/
        pinfo->link_dir = P2P_DIR_DL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - T3396 value");
+       ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - Back-off timer value");
+
+       ELEM_OPT_TLV(0x6B, GSM_A_PDU_TYPE_GM, DE_RE_ATTEMPT_IND, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6463,13 +7179,13 @@ dtap_sm_act_sec_pdp_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
        /* MS to Network */
        pinfo->link_dir = P2P_DIR_UL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_NET_SAPI, " - Requested NSAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_NET_SAPI, " - Requested NSAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Requested QoS" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Requested QoS", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_LINKED_TI, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_LINKED_TI, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        /* 3GPP TS 24.008 version 6.8.0 Release 6, 36 TFT Traffic Flow Template 10.5.6.12 O TLV 3-257 */
        ELEM_OPT_TLV( 0x36, GSM_A_PDU_TYPE_GM, DE_TRAFFIC_FLOW_TEMPLATE, NULL);
@@ -6478,7 +7194,13 @@ dtap_sm_act_sec_pdp_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
        ELEM_OPT_TV_SHORT(0xC0, GSM_A_PDU_TYPE_GM, DE_DEVICE_PROPERTIES, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6499,15 +7221,15 @@ dtap_sm_act_sec_pdp_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
        /* Network to MS*/
        pinfo->link_dir = P2P_DIR_DL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Negotiated LLC SAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Negotiated LLC SAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Negotiated QoS" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Negotiated QoS", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
 #if 0
        /* This is done automatically */
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SPARE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SPARE, NULL, ei_gsm_a_gm_missing_mandatory_element);
        curr_offset--;
        curr_len++;
 #endif
@@ -6516,7 +7238,15 @@ dtap_sm_act_sec_pdp_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TV_SHORT(0xC0 , GSM_A_PDU_TYPE_GM, DE_SM_WLAN_OFFLOAD_ACCEPT, " - WLAN offload indication");
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6537,13 +7267,19 @@ dtap_sm_act_sec_pdp_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
        /* Network to MS*/
        pinfo->link_dir = P2P_DIR_DL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - T3396 value");
+       ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - Back-off timer value");
+
+       ELEM_OPT_TLV(0x6B, GSM_A_PDU_TYPE_GM, DE_RE_ATTEMPT_IND, NULL);
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6564,13 +7300,17 @@ dtap_sm_req_pdp_act(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
        /* Network to MS*/
        pinfo->link_dir = P2P_DIR_DL;
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Offered PDP address" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Offered PDP address", ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x28, GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME, NULL);
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6591,11 +7331,15 @@ dtap_sm_req_pdp_act_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
        /* MS to  Network */
        pinfo->link_dir = P2P_DIR_UL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6616,17 +7360,17 @@ dtap_sm_mod_pdp_req_net(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
        /* Network to MS */
        pinfo->link_dir = P2P_DIR_DL;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_RAD_PRIO, NULL, ei_gsm_a_gm_missing_mandatory_element);
 #if 0
        /* This is done automatically */
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SPARE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SPARE, NULL, ei_gsm_a_gm_missing_mandatory_element);
        curr_offset--;
        curr_len++;
 #endif
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - New QoS" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - New QoS", ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x2B, GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - PDP address");
 
@@ -6636,7 +7380,15 @@ dtap_sm_mod_pdp_req_net(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
        ELEM_OPT_TLV( 0x36, GSM_A_PDU_TYPE_GM, DE_TRAFFIC_FLOW_TEMPLATE, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TV_SHORT(0xC0 , GSM_A_PDU_TYPE_GM, DE_SM_WLAN_OFFLOAD_ACCEPT, " - WLAN offload indication");
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6667,7 +7419,13 @@ dtap_sm_mod_pdp_req_ms(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guin
 
        ELEM_OPT_TV_SHORT(0xC0, GSM_A_PDU_TYPE_GM, DE_DEVICE_PROPERTIES, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6690,7 +7448,11 @@ dtap_sm_mod_pdp_acc_ms(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guin
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6721,7 +7483,15 @@ dtap_sm_mod_pdp_acc_net(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TV_SHORT(0xC0 , GSM_A_PDU_TYPE_GM, DE_SM_WLAN_OFFLOAD_ACCEPT, " - WLAN offload indication");
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6739,17 +7509,23 @@ dtap_sm_mod_pdp_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32
        curr_len    = len;
 
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
-       /* Network or the MS */
-       pinfo->link_dir = LINK_DIR_UNKNOWN;
+       /* Network or the MS; do not reset link_dir in case it was set by lower layers */
+       /* pinfo->link_dir = LINK_DIR_UNKNOWN; */
 
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - T3396 value");
+       ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - Back-off timer value");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x6B, GSM_A_PDU_TYPE_GM, DE_RE_ATTEMPT_IND, NULL);
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6769,7 +7545,7 @@ dtap_sm_deact_pdp_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
        pinfo->link_dir = LINK_DIR_UNKNOWN;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TV_SHORT( 0x90, GSM_A_PDU_TYPE_GM, DE_TEAR_DOWN_IND, NULL);
 
@@ -6779,7 +7555,11 @@ dtap_sm_deact_pdp_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint
 
        ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - T3396 value");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TV_SHORT(0xC0 , GSM_A_PDU_TYPE_GM, DE_SM_WLAN_OFFLOAD_ACCEPT, " - WLAN offload indication");
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6803,7 +7583,9 @@ dtap_sm_deact_pdp_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint
 
        ELEM_OPT_TLV( 0x35, GSM_A_PDU_TYPE_GM, DE_MBMS_PROT_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6824,10 +7606,10 @@ dtap_sm_req_sec_pdp_act(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
        pinfo->link_dir = P2P_DIR_DL;
 
        /* Required QoS Quality of service 10.5.6.5 M LV 13-17 */
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Required QoS");
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_QOS, " - Required QoS", ei_gsm_a_gm_missing_mandatory_element);
 
        /* Linked TI Linked TI 10.5.6.7 M LV 2-3 */
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_LINKED_TI, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_LINKED_TI, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        /* 36 TFT Traffic Flow Template 10.5.6.12 O TLV 3-257 */
        ELEM_OPT_TLV( 0x36, GSM_A_PDU_TYPE_GM, DE_TRAFFIC_FLOW_TEMPLATE, NULL);
@@ -6835,7 +7617,16 @@ dtap_sm_req_sec_pdp_act(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gui
        /* 27 Protocol configuration options Protocol configuration options 10.5.6.3 O TLV 3 - 253 */
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       /* C- WLAN offload acceptability 10.5.6.20 O TV 1 */
+       ELEM_OPT_TV_SHORT(0xC0 , GSM_A_PDU_TYPE_GM, DE_SM_WLAN_OFFLOAD_ACCEPT, " - WLAN offload indication");
+
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       ELEM_OPT_TLV(0x5C, GSM_A_PDU_TYPE_GM, DE_EXT_QOS, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6856,12 +7647,16 @@ dtap_sm_req_sec_pdp_act_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
        pinfo->link_dir = P2P_DIR_UL;
 
        /* SM cause SM cause 10.5.6.6 M V 1 */
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        /* 27 Protocol configuration options Protocol configuration options 10.5.6.3 O TLV 3 - 253 */
        ELEM_OPT_TLV( 0x27, GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x33, GSM_A_PDU_TYPE_GM, DE_NBIFOM_CONT, NULL);
+
+       ELEM_OPT_TLV_E(0x7B, GSM_A_PDU_TYPE_GM, DE_EXT_PRO_CONF_OPT, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6881,9 +7676,9 @@ dtap_sm_notif(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offse
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
        pinfo->link_dir = P2P_DIR_DL;
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_SM_NOTIF_IND, NULL);
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_SM_NOTIF_IND, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6903,9 +7698,9 @@ dtap_sm_status(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offs
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
        pinfo->link_dir = LINK_DIR_UNKNOWN;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6925,26 +7720,26 @@ dtap_sm_act_mbms_req(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
        pinfo->p2p_dir = P2P_DIR_RECV;
 
        /* Requested MBMS NSAPI Enhanced Network service access point identifier 10.5.6.16 M V */
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_ENH_NSAPI, " - Requested MBMS NSAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_ENH_NSAPI, " - Requested MBMS NSAPI", ei_gsm_a_gm_missing_mandatory_element);
 
        /* Requested LLC SAPI LLC service access point identifier 10.5.6.9 M V 1 */
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Requested LLC SAPI", ei_gsm_a_gm_missing_mandatory_element);
 
        /* Supported MBMS bearer capabilities MBMS bearer capabilities 10.5.6.14 M LV 2 - 3 */
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MBMS_BEARER_CAP, NULL );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_MBMS_BEARER_CAP, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        /* Requested multicast address Packet data protocol address 10.5.6.4 M LV 3 - 19 */
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Requested multicast address" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Requested multicast address", ei_gsm_a_gm_missing_mandatory_element);
 
        /* Access point name Access point name 10.5.6.1 M LV 2 - 101 */
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME, NULL );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        /* 35 MBMS protocol configuration options MBMS protocol configuration options 10.5.6.15 O TLV 3 - 253 */
        ELEM_OPT_TLV( 0x35, GSM_A_PDU_TYPE_GM, DE_MBMS_PROT_CONF_OPT, NULL);
 
        ELEM_OPT_TV_SHORT(0xC0, GSM_A_PDU_TYPE_GM, DE_DEVICE_PROPERTIES, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6963,13 +7758,13 @@ dtap_sm_act_mbms_acc(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_LV(  GSM_A_PDU_TYPE_GM, DE_TMGI, NULL);
+       ELEM_MAND_LV(  GSM_A_PDU_TYPE_GM, DE_TMGI, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_V(  GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Negotiated LLC SAPI");
+       ELEM_MAND_V(  GSM_A_PDU_TYPE_GM, DE_LLC_SAPI, " - Negotiated LLC SAPI", ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x35, GSM_A_PDU_TYPE_GM, DE_MBMS_PROT_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -6988,13 +7783,15 @@ dtap_sm_act_mbms_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x35, GSM_A_PDU_TYPE_GM, DE_MBMS_PROT_CONF_OPT, NULL);
 
        ELEM_OPT_TLV(0x37, GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_3, " - T3396 value");
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       ELEM_OPT_TLV(0x6B, GSM_A_PDU_TYPE_GM, DE_RE_ATTEMPT_IND, NULL);
+
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -7013,15 +7810,15 @@ dtap_sm_req_mbms_act(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        pinfo->p2p_dir = P2P_DIR_SENT;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_NET_SAPI, " - Linked NSAPI");
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_NET_SAPI, " - Linked NSAPI", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Offered multicast address" );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR, " - Offered multicast address", ei_gsm_a_gm_missing_mandatory_element);
 
-       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME, NULL );
+       ELEM_MAND_LV( GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x35, GSM_A_PDU_TYPE_GM, DE_MBMS_PROT_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 /*
@@ -7040,11 +7837,11 @@ dtap_sm_req_mbms_rej(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint3
 
        pinfo->p2p_dir = P2P_DIR_RECV;
 
-       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL);
+       ELEM_MAND_V( GSM_A_PDU_TYPE_GM, DE_SM_CAUSE, NULL, ei_gsm_a_gm_missing_mandatory_element);
 
        ELEM_OPT_TLV( 0x35, GSM_A_PDU_TYPE_GM, DE_MBMS_PROT_CONF_OPT, NULL);
 
-       EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0, pinfo);
+       EXTRANEOUS_DATA_CHECK(curr_len, 0, pinfo, &ei_gsm_a_gm_extraneous_data);
 }
 
 #define        NUM_GSM_DTAP_MSG_GMM (sizeof(gsm_a_dtap_msg_gmm_strings)/sizeof(value_string))
@@ -7068,9 +7865,9 @@ static void (*dtap_msg_gmm_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info *
        dtap_gmm_auth_ciph_req,         /* Authentication and Ciphering Req */
        dtap_gmm_auth_ciph_resp,        /* Authentication and Ciphering Resp */
        dtap_gmm_auth_ciph_rej,         /* Authentication and Ciphering Rej */
-       dtap_gmm_auth_ciph_fail,        /* Authentication and Ciphering Failure */
        dtap_gmm_ident_req,             /* Identity Request */
        dtap_gmm_ident_res,             /* Identity Response */
+       dtap_gmm_auth_ciph_fail,        /* Authentication and Ciphering Failure */
        dtap_gmm_status,                /* GMM Status */
        dtap_gmm_information,           /* GMM Information */
        NULL,   /* NONE */
@@ -7116,10 +7913,12 @@ get_gmm_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf_idx
 {
        gint idx;
 
-       *msg_str      = match_strval_idx((guint32) (oct & DTAP_GMM_IEI_MASK), gsm_a_dtap_msg_gmm_strings, &idx);
-       *ett_tree     = ett_gsm_dtap_msg_gmm[idx];
+       *msg_str      = try_val_to_str_idx_ext((guint32) (oct & DTAP_GMM_IEI_MASK), &gsm_a_dtap_msg_gmm_strings_ext, &idx);
        *hf_idx       = hf_gsm_a_dtap_msg_gmm_type;
-       *dtap_msg_fcn = dtap_msg_gmm_fcn[idx];
+       if (*msg_str != NULL) {
+               *ett_tree     = ett_gsm_dtap_msg_gmm[idx];
+               *dtap_msg_fcn = dtap_msg_gmm_fcn[idx];
+       }
 
        return;
 }
@@ -7129,10 +7928,12 @@ get_sm_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf_idx,
 {
        gint idx;
 
-       *msg_str      = match_strval_idx((guint32) (oct & DTAP_SM_IEI_MASK), gsm_a_dtap_msg_sm_strings, &idx);
-       *ett_tree     = ett_gsm_dtap_msg_sm[idx];
+       *msg_str      = try_val_to_str_idx_ext((guint32) (oct & DTAP_SM_IEI_MASK), &gsm_a_dtap_msg_sm_strings_ext, &idx);
        *hf_idx       = hf_gsm_a_dtap_msg_sm_type;
-       *dtap_msg_fcn = dtap_msg_sm_fcn[idx];
+       if (*msg_str != NULL) {
+               *ett_tree     = ett_gsm_dtap_msg_sm[idx];
+               *dtap_msg_fcn = dtap_msg_sm_fcn[idx];
+       }
 
        return;
 }
@@ -7149,12 +7950,12 @@ proto_register_gsm_a_gm(void)
        static hf_register_info hf[] = {
                { &hf_gsm_a_dtap_msg_gmm_type,
                  { "DTAP GPRS Mobility Management Message Type",       "gsm_a.dtap.msg_gmm_type",
-                   FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_gmm_strings), 0x0,
+                   FT_UINT8, BASE_HEX | BASE_EXT_STRING, &gsm_a_dtap_msg_gmm_strings_ext, 0x0,
                    NULL, HFILL }
                },
                { &hf_gsm_a_dtap_msg_sm_type,
                  { "DTAP GPRS Session Management Message Type",        "gsm_a.dtap.msg_sm_type",
-                   FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sm_strings), 0x0,
+                   FT_UINT8, BASE_HEX | BASE_EXT_STRING, &gsm_a_dtap_msg_sm_strings_ext, 0x0,
                    NULL, HFILL }
                },
                { &hf_gsm_a_gm_elem_id,
@@ -7202,6 +8003,11 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_DEC, VALS(gsm_a_sm_qos_traff_hdl_pri_vals), 0x03,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gmm_split_pg_cycle_code,
+                 { "SPLIT PG CYCLE CODE", "gsm_a.gm.gmm.split_pg_cycle_code",
+                   FT_UINT8, BASE_DEC|BASE_EXT_STRING, &gsm_a_gmm_split_pg_cycle_code_strings_ext, 0x00,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gmm_split_on_ccch,
                  { "SPLIT on CCCH", "gsm_a.gm.gmm.split_on_ccch",
                    FT_BOOLEAN, 8, TFS(&gsm_a_gmm_split_on_ccch_value), 0x08,
@@ -7212,9 +8018,9 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_DEC, VALS(gsm_a_gmm_non_drx_timer_strings), 0x07,
                    NULL, HFILL }
                },
-               { &hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef,
-                 { "CN Specific DRX cycle length coefficient", "gsm_a.gm.gmm.cn_spec_drs_cycle_len_coef",
-                   FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_a_gmm_cn_spec_drs_cycle_len_coef_strings), 0xf0,
+               { &hf_gsm_a_gmm_cn_spec_drx_cycle_len_coef,
+                 { "CN Specific DRX cycle length coefficient", "gsm_a.gm.gmm.cn_spec_drx_cycle_len_coef",
+                   FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_a_gmm_cn_spec_drx_cycle_len_coef_strings), 0xf0,
                    NULL, HFILL }
                },
                { &hf_gsm_a_sm_tft_op_code,
@@ -7269,7 +8075,7 @@ proto_register_gsm_a_gm(void)
                },
                { &hf_gsm_a_sm_tft_protocol_header,
                  { "Protocol/header", "gsm_a.gm.sm.tft.protocol_header",
-                   FT_UINT8, BASE_HEX|BASE_EXT_STRING, (&ipproto_val_ext), 0x0,
+                   FT_UINT8, BASE_HEX|BASE_EXT_STRING, &ipproto_val_ext, 0x0,
                    NULL, HFILL }
                },
                { &hf_gsm_a_sm_tft_port,
@@ -7372,11 +8178,21 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_ciph_alg_vals), 0x07,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_type_of_integ_alg,
+                 { "Type of integrity algorithm", "gsm_a.gm.gmm.type_of_integ_alg",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_integ_alg_vals), 0x07,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_imeisv_req,
                  { "IMEISV request", "gsm_a.gm.gmm.imeisv_req",
                    FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_a_gm_imeisv_req_vals), 0x00,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_nsapi,
+                 { "NSAPI", "gsm_a.gm.gmm.nsapi",
+                   FT_UINT16, BASE_HEX_DEC, NULL, 0x0,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_ac_ref_nr,
                  { "A&C reference number", "gsm_a.gm.gmm.ac_ref_nr",
                    FT_UINT8, BASE_DEC, NULL, 0x0,
@@ -7387,11 +8203,6 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_a_gm_force_to_standby_vals), 0x00,
                    NULL, HFILL }
                },
-               { &hf_gsm_a_gm_ciph_key_seq_num,
-                 { "Ciphering key sequence number", "gsm_a.gm.gmm.ciph_key_seq_num",
-                   FT_UINT8, BASE_DEC, NULL, 0x00,
-                   NULL, HFILL }
-               },
                { &hf_gsm_a_gm_serv_type,
                  { "Service type", "gsm_a.gm.gmm.serv_type",
                    FT_UINT8, BASE_DEC, VALS(gsm_a_gm_serv_type_vals), 0x00,
@@ -7412,11 +8223,31 @@ proto_register_gsm_a_gm(void)
                    FT_BOOLEAN, 8, TFS(&gsm_a_gm_tmsi_flag_value), 0x01,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_power_off,
+                 { "Power off", "gsm_a.gm.gmm.power_off",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_power_off_value), 0x08,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_type_of_detach_mo,
+                 { "Type of detach", "gsm_a.gm.gmm.type_of_detach",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_detach_mo_vals), 0x07,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_type_of_detach_mt,
+                 { "Type of detach", "gsm_a.gm.gmm.type_of_detach",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_detach_mt_vals), 0x07,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_update_type,
                  { "Update type", "gsm_a.gm.gmm.update_type",
                    FT_UINT8, BASE_DEC, VALS(gsm_a_gm_update_type_vals), 0x07,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_gprs_timer,
+                 { "GPRS Timer", "gsm_a.gm.gmm.gprs_timer",
+                   FT_UINT8, BASE_HEX, NULL, 0x0,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_gprs_timer_unit,
                  { "Unit", "gsm_a.gm.gmm.gprs_timer_unit",
                    FT_UINT8, BASE_DEC, VALS(gsm_a_gm_gprs_timer_unit_vals), 0xe0,
@@ -7427,6 +8258,11 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_DEC, NULL, 0x1f,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_gprs_timer2,
+                 { "GPRS Timer", "gsm_a.gm.gmm.gprs_timer2",
+                   FT_UINT8, BASE_HEX, NULL, 0x0,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_gprs_timer2_unit,
                  { "Unit", "gsm_a.gm.gmm.gprs_timer2_unit",
                    FT_UINT8, BASE_DEC, VALS(gsm_a_gm_gprs_timer_unit_vals), 0xe0,
@@ -7437,6 +8273,11 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_DEC, NULL, 0x1f,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_gprs_timer3,
+                 { "GPRS Timer", "gsm_a.gm.gmm.gprs_timer3",
+                   FT_UINT8, BASE_HEX, NULL, 0x0,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_gprs_timer3_unit,
                  { "Unit", "gsm_a.gm.gmm.gprs_timer3_unit",
                    FT_UINT8, BASE_DEC, VALS(gsm_a_gm_gprs_timer3_unit_vals), 0xe0,
@@ -7514,7 +8355,7 @@ proto_register_gsm_a_gm(void)
                },
                { &hf_gsm_a_gm_pco_pid,
                  { "Protocol or Container ID", "gsm_a.gm.sm.pco_pid",
-                   FT_UINT16, BASE_DEC, NULL, 0x0,
+                   FT_UINT16, BASE_HEX, NULL, 0x0,
                    NULL, HFILL }
                },
                { &hf_gsm_a_gm_pco_app_spec_info,
@@ -7532,6 +8373,16 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_HEX_DEC, NULL, 0x00,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_mta_e,
+                 { "MTA-E", "gsm_a.gm.gmm.mta_e",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_mta_e_vals), 0x80,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_mta_r,
+                 { "MTA-R", "gsm_a.gm.gmm.mta_r",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_mta_r_vals), 0x40,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_apc,
                  { "APC", "gsm_a.gm.gmm.apc",
                    FT_BOOLEAN, 8, TFS(&gsm_a_gm_apc_vals), 0x20,
@@ -7562,6 +8413,16 @@ proto_register_gsm_a_gm(void)
                    FT_BOOLEAN, 8, TFS(&gsm_a_gm_gps_c_vals), 0x01,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_motd,
+                 { "MOTD", "gsm_a.gm.gmm.motd",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_motd_vals), 0x02,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_mta_a,
+                 { "MTA-A", "gsm_a.gm.gmm.mta_a",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_mta_a_vals), 0x01,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_lcs_molr,
                  { "LCS-MOLR", "gsm_a.gm.gmm.lcs_molr",
                    FT_BOOLEAN, 8, TFS(&gsm_a_gm_lcs_molr_value), 0x08,
@@ -7582,6 +8443,16 @@ proto_register_gsm_a_gm(void)
                    FT_BOOLEAN, 8, TFS(&gsm_a_gm_emc_bs_value), 0x01,
                    "Emergency bearer services indicator", HFILL }
                },
+               { &hf_gsm_a_gm_epco,
+                 { "ePCO", "gsm_a.gm.gmm.epco",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_epco_value), 0x04,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_restrict_ec,
+                 { "RestrictEC", "gsm_a.gm.gmm.restrict_ec",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_restrict_ec_value), 0x02,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_gprs_sms,
                  { "GPRS-SMS", "gsm_a.gm.gmm.gprs_sms",
                    FT_BOOLEAN, 8, TFS(&gsm_a_gm_gprs_sms_value), 0x01,
@@ -7617,6 +8488,36 @@ proto_register_gsm_a_gm(void)
                    FT_UINT16, BASE_HEX, NULL, 0xffc0,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_paging_time_window,
+                 { "Paging Time Window", "gsm_a.gm.gmm.paging_time_window",
+                   FT_UINT8, BASE_HEX, VALS(gsm_a_gm_paging_time_window_vals), 0xf0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_edrx_value,
+                 { "eDRX value", "gsm_a.gm.gmm.edrx_value",
+                   FT_UINT8, BASE_HEX, VALS(gsm_a_gm_edrx_vals), 0x0f,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_mac,
+                 { "Message authentication code value", "gsm_a.gm.gmm.mac",
+                   FT_UINT32, BASE_HEX, NULL, 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_up_integ_ind,
+                 { "Integrity indicator", "gsm_a.gm.gmm.up_integ_ind",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_up_integ_ind_value), 0x01,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_dcn_id,
+                 { "DCN-ID", "gsm_a.gm.gmm.dcn_id",
+                   FT_UINT16, BASE_HEX, NULL, 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_n3en_ind,
+                 { "N3EN indicator", "gsm_a.gm.gmm.n3en_ind",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_n3en_ind_value), 0x01,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_sm_pdp_type_org,
                  { "PDP type organization", "gsm_a.gm.sm.pdp_type_org",
                    FT_UINT8, BASE_DEC, VALS(gsm_a_sm_pdp_type_org_vals), 0x0f,
@@ -7712,6 +8613,16 @@ proto_register_gsm_a_gm(void)
                    FT_UINT8, BASE_DEC, NULL, 0x0,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_sm_eplmnc,
+                 { "EPLMNC", "gsm_a.gm.sm.re_attempt_ind.eplmnc",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_eplmnc_value), 0x02,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_sm_ratc,
+                 { "RATC", "gsm_a.gm.sm.re_attempt_ind.ratc",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_ratc_value), 0x01,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_sm_cause,
                  { "SM Cause", "gsm_a.gm.sm.cause",
                    FT_UINT8, BASE_DEC, NULL, 0x0,
@@ -7754,7 +8665,7 @@ proto_register_gsm_a_gm(void)
                },
                { &hf_gsm_a_gmm_net_cap_ucs2,
                  { "UCS2 support", "gsm_a.gm.gmm.net_cap.ucs2",
-                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_smgprs_vals), 0x10,
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_ucs2_vals), 0x10,
                    NULL, HFILL }
                },
                { &hf_gsm_a_gmm_net_cap_ss_scr_ind,
@@ -7857,6 +8768,46 @@ proto_register_gsm_a_gm(void)
                    FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_geran_net_vals), 0x01,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gmm_net_cap_up_int_prot,
+                 { "User plane integrity protection support", "gsm_a.gm.gmm.net_cap.up_int_prot",
+                   FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x80,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gmm_net_cap_up_gia4,
+                 { "GIA/4", "gsm_a.gm.gmm.net_cap.gia4",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_gia_vals), 0x40,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gmm_net_cap_up_gia5,
+                 { "GIA/5", "gsm_a.gm.gmm.net_cap.gia5",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_gia_vals), 0x20,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gmm_net_cap_up_gia6,
+                 { "GIA/6", "gsm_a.gm.gmm.net_cap.gia6",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_gia_vals), 0x10,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gmm_net_cap_up_gia7,
+                 { "GIA/7", "gsm_a.gm.gmm.net_cap.gia7",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_gia_vals), 0x08,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gmm_net_cap_epco_ie_ind,
+                 { "ePCO IE indicator", "gsm_a.gm.gmm.net_cap.epco_ie_ind",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_epco_ie_ind_vals), 0x04,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gmm_net_cap_restrict_use_enh_cov,
+                 { "Restriction on use of enhanced coverage capability", "gsm_a.gm.gmm.net_cap.restrict_use_enh_cov",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_restrict_use_enh_cov_vals), 0x02,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gmm_net_cap_dc_eutra_nr_cap,
+                 { "Dual connectivity of E-UTRA with NR capability", "gsm_a.gm.gmm.net_cap.dc_eutra_nr_cap",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_net_cap_dc_eutra_nr_cap_vals), 0x01,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_sm_tmgi,
                  { "Temporary Mobile Group Identity (TMGI)", "gsm_a.gm.sm.tmgi",
                    FT_UINT24, BASE_HEX, NULL, 0x0,
@@ -7873,15 +8824,30 @@ proto_register_gsm_a_gm(void)
                    NULL, HFILL }
                },
                { &hf_gsm_a_sm_notif_ind,
-                 { "Notification indicator value", "gsm_a.gm.sm.notif_ind",
+                 { "Notification indicator", "gsm_a.gm.sm.notif_ind",
                    FT_UINT8, BASE_DEC, VALS(gsm_a_sm_notif_ind_vals), 0x0,
                    NULL, HFILL }
                },
                { &hf_gsm_a_sm_connectivity_type,
-                 { "Connectivity type value", "gsm_a.gm.sm.connectivity_type",
+                 { "Connectivity type", "gsm_a.gm.sm.connectivity_type",
                    FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_a_sm_connectivity_type_vals), 0x0F,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_sm_wlan_utran_offload_accept,
+                 { "WLAN UTRAN offload acceptability", "gsm_a.gm.sm.wlan_utran_offload_accept",
+                   FT_BOOLEAN, BASE_NONE, TFS(&gsm_a_sm_wlan_utran_offload_accept_value), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_sm_wlan_eutran_offload_accept,
+                 { "WLAN E-UTRAN offload acceptability", "gsm_a.gm.sm.wlan_eutran_offload_accept",
+                   FT_BOOLEAN, BASE_NONE, TFS(&gsm_a_sm_wlan_eutran_offload_accept_value), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_sm_nbifom_cont,
+                 { "NBIFOM container content", "gsm_a.gm.sm.nbifom_cont",
+                   FT_BYTES, BASE_NONE, NULL, 0x0,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_gm_rac_ctrled_early_cm_sending,
                  { "Controlled early Classmark Sending", "gsm_a.gm.gmm.rac.ctrled_early_cm_sending",
                    FT_BOOLEAN, BASE_NONE, TFS(&tfs_implemented_not_implemented), 0x0,
@@ -8177,6 +9143,76 @@ proto_register_gsm_a_gm(void)
                    FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x0,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_rac_geran_nw_sharing_support,
+                 { "GERAN Network Sharing support", "gsm_a.gm.gmm.rac.geran_nw_sharing_support",
+                   FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_eutra_wb_rsrq_support,
+                 { "E-UTRA Wideband RSRQ measurements support", "gsm_a.gm.gmm.rac.eutra_wb_rsrq_support",
+                   FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_utra_mfbi_support,
+                 { "UTRA Multiple Frequency Band Indicators support", "gsm_a.gm.gmm.rac.utra_mfbi_support",
+                   FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_eutra_mfbi_support,
+                 { "E-UTRA Multiple Frequency Band Indicators support", "gsm_a.gm.gmm.rac.eutra_mfbi_support",
+                   FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_dlmc_non_contig_intra_band_recep,
+                 { "DLMC - Non-contiguous intra-band reception", "gsm_a.gm.gmm.rac.dlmc.non_contig_intra_band_recep",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_dlmc_non_contig_intra_band_recep_vals), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_dlmc_inter_band_recep,
+                 { "DLMC - Inter-band reception", "gsm_a.gm.gmm.rac.dlmc.inter_band_recep",
+                   FT_BOOLEAN, BASE_NONE, TFS(&gsm_a_gm_dlmc_inter_band_recep_val), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_dlmc_max_bandwidth,
+                 { "DLMC - Maximum Bandwidth", "gsm_a.gm.gmm.rac.dlmc.max_bandwidth",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_dlmc_max_bandwidth_vals), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_dlmc_max_nb_dl_ts,
+                 { "DLMC - Maximum Number of Downlink Timeslots", "gsm_a.gm.gmm.rac.dlmc.max_nb_dl_ts",
+                   FT_UINT8, BASE_CUSTOM, CF_FUNC(gsm_a_gm_dlmc_max_nb_dl_ts_fmt), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_dlmc_max_nb_dl_carriers,
+                 { "DLMC - Maximum Number of Downlink Carriers", "gsm_a.gm.gmm.rac.dlmc.max_nb_dl_carriers",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_dlmc_max_nb_dl_carriers_vals), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_ext_tsc_set_cap_support,
+                 { "Extended TSC Set Capability support", "gsm_a.gm.gmm.rac.ext_tsc_set_cap_support",
+                   FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_ext_earfcn_value_range,
+                 { "Extended EARFCN value range", "gsm_a.gm.gmm.rac.ext_earfcn_value_range",
+                   FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_ec_pch_mon_support,
+                 { "(EC-)PCH monitoring support", "gsm_a.gm.gmm.rac.ec_pch_mon_support",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_ec_pch_mon_support_vals), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_ms_sync_accuracy,
+                 { "MS Sync Accuracy", "gsm_a.gm.gmm.rac.ms_sync_accuracy",
+                   FT_UINT8, BASE_DEC, NULL, 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_rac_ext_ec_ul_cov_enh_support,
+                 { "EC uplink coverage enhancement support", "gsm_a.gm.gmm.rac.ec_ul_cov_enh_support",
+                   FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x0,
+                   NULL, HFILL }
+               },
                { &hf_gsm_a_sm_ti_flag,
                  { "TI Flag", "gsm_a.gm.sm.ti_flag",
                    FT_BOOLEAN, 8, TFS(&gsm_a_sm_ti_flag_vals), 0x80,
@@ -8187,33 +9223,113 @@ proto_register_gsm_a_gm(void)
                    FT_BOOLEAN, 8, NULL, 0x80,
                    NULL, HFILL }
                },
+               { &hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_aer,
+                 { "AER", "gsm_a.gm.sm.pco.apn_rate_ctrl_params.aer",
+                   FT_BOOLEAN, 8, TFS(&gsm_a_gm_apn_rate_ctrl_params_aer_value), 0x08,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_ul_time_unit,
+                 { "Uplink time unit", "gsm_a.gm.sm.pco.apn_rate_ctrl_params.ul_time_unit",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_apn_rate_ctrl_ul_time_unit_vals), 0x07,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_sm_pco_apn_rate_ctrl_params_max_ul_rate,
+                 { "Maximum uplink rate", "gsm_a.gm.sm.pco.apn_rate_ctrl_params.max_ul_rate",
+                   FT_UINT24, BASE_DEC|BASE_UNIT_STRING, &units_message_messages, 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_sm_pco_3gpp_data_off_ue_status,
+                 { "3GPP PS data off UE status", "gsm_a.gm.sm.pco.3gpp_data_off_ue_status",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_sm_pco_3gpp_data_off_ue_status_vals), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_sm_pco_add_apn_rate_ctrl_params_ul_time_unit,
+                 { "Uplink time unit", "gsm_a.gm.sm.pco.add_apn_rate_ctrl_params.ul_time_unit",
+                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_apn_rate_ctrl_ul_time_unit_vals), 0x07,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_sm_pco_add_apn_rate_ctrl_params_max_ul_rate,
+                 { "Additional uplink rate for exception data", "gsm_a.gm.sm.pco.add_apn_rate_ctrl_params.max_ul_rate",
+                   FT_UINT16, BASE_DEC|BASE_UNIT_STRING, &units_message_messages, 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_sm_pco_pdu_session_id,
+                 { "PDU session identity", "gsm_a.gm.sm.pco.pdu_session_id",
+                   FT_UINT8, BASE_DEC, VALS(nas_5gs_pdu_session_id_vals), 0x0,
+                   NULL, HFILL }
+               },
+               { &hf_gsm_a_gm_sm_pco_pdu_session_address_lifetime,
+                 { "PDU session address lifetime", "gsm_a.gm.sm.pco.pdu_session_address_lifetime",
+                   FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_second_seconds, 0x0,
+                   NULL, HFILL }
+               },
+               /* Generated from convert_proto_tree_add_text.pl */
+               { &hf_gsm_a_gm_presence, { "Presence", "gsm_a.gm.gmm.presence", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_8psk_power_class, { "8PSK Power Class", "gsm_a.gm.8psk_power_class", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_8psk_power_class_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_rf_power_capability, { "RF Power Capability", "gsm_a.gm.rf_power_capability", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_a5_bits, { "A5 Bits", "gsm_a.gm.a5_bits", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_8psk_power_capability, { "8PSK Power Capability", "gsm_a.gm.8psk_power_capability", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_8psk_power_cap_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_extended_dtm_gprs_multi_slot_class, { "Extended DTM GPRS Multi Slot Class", "gsm_a.gm.extended_dtm_gprs_multi_slot_class", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_extended_dtm_gprs_multi_slot_class_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_extended_dtm_egprs_multi_slot_class, { "Extended DTM EGPRS Multi Slot Class", "gsm_a.gm.extended_dtm_egprs_multi_slot_class", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_extended_dtm_gprs_multi_slot_class_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_high_multislot_capability, { "High Multislot Capability", "gsm_a.gm.high_multislot_capability", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_gmsk_multislot_power_profile, { "GMSK Multislot Power Profile", "gsm_a.gm.gmsk_multislot_power_profile", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_gmsk_multislot_power_profile_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_8psk_multislot_power_profile, { "8-PSK Multislot Power Profile", "gsm_a.gm.8psk_multislot_power_profile", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_8psk_multislot_power_profile_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_update_result, { "Update Result", "gsm_a.gm.gmm.update_result", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_update_res_vals), 0x70, NULL, HFILL }},
+               { &hf_gsm_a_gm_radio_priority_pdp, { "Radio Priority (PDP or SMS)", "gsm_a.gm.radio_priority_pdp", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_radio_prio_vals), 0x07, NULL, HFILL }},
+               { &hf_gsm_a_gm_radio_priority_tom8, { "Radio Priority (TOM8)", "gsm_a.gm.radio_priority_tom8", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_radio_prio_vals), 0x70, NULL, HFILL }},
+               { &hf_gsm_a_gm_configuration_protocol, { "Configuration Protocol", "gsm_a.gm.configuration_protocol", FT_UINT8, BASE_DEC, NULL, 0x7, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_length, { "Length", "gsm_a.gm.sm.pco.length", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_pcscf_ipv6, { "IPv6", "gsm_a.gm.sm.pco.pcscf.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_dns_ipv6, { "IPv6", "gsm_a.gm.sm.pco.dns.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_dsmipv6_home_agent_ipv6, { "IPv6", "gsm_a.gm.sm.pco.dsmipv6_home_agent.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_dsmipv6_home_network_ipv6, { "IPv6", "gsm_a.gm.sm.pco.dsmipv6_home_network.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_dsmipv6_home_network_prefix_length, { "Prefix length", "gsm_a.gm.sm.pco.dsmipv6_home_network.ipv6_prefix_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_reject_code, { "Reject Code", "gsm_a.gm.sm.pco.reject_code", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_dsmipv6_home_agent_ipv4, { "IPv4", "gsm_a.gm.sm.pco.dsmipv6_home_agent.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_pcscf_ipv4, { "IPv4", "gsm_a.gm.sm.pco.pcscf.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_dns_ipv4, { "IPv4", "gsm_a.gm.sm.pco.dns.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_ipv4_link_mtu_size, { "IPv4 link MTU size", "gsm_a.gm.sm.pco.ipv4_link_mtu_size", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, &units_octet_octets, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_nbifom_mode, { "NBIFOM mode", "gsm_a.gm.sm.pco.nbifom_mode", FT_UINT8, BASE_HEX, VALS(gsm_a_gm_nbifom_mode_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_non_ip_link_mtu_size, { "Non-IP link MTU size", "gsm_a.gm.sm.pco.non_ip_link_mtu_size", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, &units_octet_octets, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_sm_pco_sel_bearer_ctrl_mode, { "Selected Bearer Control Mode", "gsm_a.gm.sm.pco.sel_bearer_ctrl_mode", FT_UINT8, BASE_DEC, VALS(gsm_a_gm_sel_bearer_ctrl_mode_vals), 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_pdp_type_number, { "PDP type number", "gsm_a.gm.sm.pdp_type_number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_pdp_address, { "PDP address", "gsm_a.gm.sm.pdp_address", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_qos_maximum_sdu_size, { "Maximum SDU size", "gsm_a.gm.sm.qos.maximum_sdu_size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_gm_ti_value, { "TI value", "gsm_a.gm.ti_value", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_packet_filter, { "Packet filter", "gsm_a.gm.sm.tft.packet_filter", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_packet_evaluation_precedence, { "Packet evaluation precedence", "gsm_a.gm.sm.tft.packet_evaluation_precedence", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_packet_filter_length, { "Packet filter length", "gsm_a.gm.sm.tft.packet_filter_length", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_authorization_token_value, { "Authorization token value", "gsm_a.gm.sm.tft.authorization_token_value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_media_component_number_value, { "Media Component number value", "gsm_a.gm.sm.tft.media_component_number_value", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_ip_flow_number, { "IP flow number", "gsm_a.gm.sm.tft.ip_flow_number", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_packet_filter_identifier, { "Packet filter identifier", "gsm_a.gm.sm.tft.packet_filter_identifier", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_parameter_content, { "Parameter content", "gsm_a.gm.sm.tft.parameter_content", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_gsm_a_sm_tft_packet_filter_component_type_id, { "Packet filter component type identifier", "gsm_a.gm.sm.tft.packet_filter_component_type_id", FT_UINT8, BASE_DEC, VALS(packet_filter_component_type_vals), 0x0, NULL, HFILL }},
        };
 
+       static ei_register_info ei[] = {
+               { &ei_gsm_a_gm_extraneous_data, { "gsm_a.gm.extraneous_data", PI_PROTOCOL, PI_NOTE, "Extraneous Data, dissector bug or later version spec (report to wireshark.org)", EXPFILL }},
+               { &ei_gsm_a_gm_not_enough_data, { "gsm_a.gm.not_enough_data", PI_PROTOCOL, PI_WARN, "Not enough data", EXPFILL }},
+               { &ei_gsm_a_gm_undecoded, { "gsm_a.gm.undecoded", PI_UNDECODED, PI_WARN, "Not decoded", EXPFILL }},
+               { &ei_gsm_a_gm_apn_too_long, { "gsm_a.gm.apn_to_long", PI_PROTOCOL, PI_ERROR, "APN encoding has more than 100 octets", EXPFILL }},
+               { &ei_gsm_a_gm_missing_mandatory_element, { "gsm_a.gm.missing_mandatory_element", PI_PROTOCOL, PI_ERROR, "Missing Mandatory element, rest of dissection is suspect", EXPFILL }},
+       };
+
+       expert_module_t* expert_gsm_a_gm;
+
        /* Setup protocol subtree array */
-#define        NUM_INDIVIDUAL_ELEMS    19
+#define        NUM_INDIVIDUAL_ELEMS    7
        gint *ett[NUM_INDIVIDUAL_ELEMS +
                  NUM_GSM_DTAP_MSG_GMM + NUM_GSM_DTAP_MSG_SM +
                  NUM_GSM_GM_ELEM];
 
-       ett[0]  = &ett_tc_component;
-       ett[1]  = &ett_tc_invoke_id;
-       ett[2]  = &ett_tc_linked_id;
-       ett[3]  = &ett_tc_opr_code;
-       ett[4]  = &ett_tc_err_code;
-       ett[5]  = &ett_tc_prob_code;
-       ett[6]  = &ett_tc_sequence;
-       ett[7]  = &ett_gmm_drx;
-       ett[8]  = &ett_gmm_detach_type;
-       ett[9]  = &ett_gmm_attach_type;
-       ett[10] = &ett_gmm_context_stat;
-       ett[11] = &ett_gmm_update_type;
-       ett[12] = &ett_gmm_radio_cap;
-       ett[13] = &ett_gmm_rai;
-       ett[14] = &ett_sm_tft;
-       ett[15] = &ett_gmm_gprs_timer;
-       ett[16] = &ett_gmm_network_cap;
-       ett[17] = &ett_gsm_a_gm_msrac_multislot_capability;
-       ett[18] = &ett_sm_pco;
+       ett[0]  = &ett_gmm_radio_cap;
+       ett[1]  = &ett_gmm_rai;
+       ett[2]  = &ett_sm_tft;
+       ett[3]  = &ett_gmm_gprs_timer;
+       ett[4]  = &ett_gmm_network_cap;
+       ett[5]  = &ett_gsm_a_gm_msrac_multislot_capability;
+       ett[6]  = &ett_sm_pco;
 
        last_offset = NUM_INDIVIDUAL_ELEMS;
 
@@ -8241,16 +9357,31 @@ proto_register_gsm_a_gm(void)
        proto_register_field_array(proto_a_gm, hf, array_length(hf));
 
        proto_register_subtree_array(ett, array_length(ett));
+       expert_gsm_a_gm = expert_register_protocol(proto_a_gm);
+       expert_register_field_array(expert_gsm_a_gm, ei, array_length(ei));
 
        /* subdissector code */
        gprs_sm_pco_subdissector_table = register_dissector_table("sm_pco.protocol",
-               "GPRS SM PCO PPP protocol", FT_UINT16, BASE_HEX);
+               "GPRS SM PCO PPP protocol", proto_a_gm, FT_UINT16, BASE_HEX);
 }
 
 void
 proto_reg_handoff_gsm_a_gm(void)
 {
-       data_handle = find_dissector("data");
-       rrc_irat_ho_info_handle = find_dissector("rrc.irat.irat_ho_info");
-       lte_rrc_ue_eutra_cap_handle = find_dissector("lte-rrc.ue_eutra_cap");
+       rrc_irat_ho_info_handle = find_dissector_add_dependency("rrc.irat.irat_ho_info", proto_a_gm);
+       lte_rrc_ue_eutra_cap_handle = find_dissector_add_dependency("lte-rrc.ue_eutra_cap", proto_a_gm);
+       nbifom_handle = find_dissector_add_dependency("nbifom", proto_a_gm);
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */