forked from osmocom/wireshark
1ba3426f18
As requested by bug 10969 add a link to OSM for locationEstimate. Bug: 10969 Change-Id: I715b3b5eae9728999d5c8f8c155bbcef3911ee93 Reviewed-on: https://code.wireshark.org/review/17375 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com> Reviewed-by: Roland Knall <rknall@gmail.com>
4897 lines
179 KiB
C
4897 lines
179 KiB
C
/* packet-gsm_a_common.c
|
|
* Common routines for GSM A Interface dissection
|
|
*
|
|
* Copyright 2003, Michael Lum <mlum [AT] telostech.com>
|
|
* In association with Telos Technology Inc.
|
|
*
|
|
* Split from packet-gsm_a.c by Neil Piercy <Neil [AT] littlebriars.co.uk>
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include <epan/packet.h>
|
|
#include <epan/to_str.h>
|
|
#include <epan/expert.h>
|
|
#include <epan/tap.h>
|
|
#include <epan/stat_tap_ui.h>
|
|
#include <wsutil/str_util.h>
|
|
#include "packet-gsm_a_common.h"
|
|
#include "packet-bssap.h"
|
|
#include "packet-gmr1_common.h"
|
|
#include "packet-e212.h"
|
|
|
|
void proto_register_gsm_a_common(void);
|
|
|
|
static const value_string gsm_common_elem_strings[] = {
|
|
/* Common Information Elements 10.5.1 */
|
|
{ DE_CELL_ID, "Cell Identity" },
|
|
{ DE_CIPH_KEY_SEQ_NUM, "Ciphering Key Sequence Number" },
|
|
{ DE_LAI, "Location Area Identification (LAI)" },
|
|
{ DE_MID, "Mobile Identity" },
|
|
{ DE_MS_CM_1, "Mobile Station Classmark 1" },
|
|
{ DE_MS_CM_2, "Mobile Station Classmark 2" },
|
|
{ DE_MS_CM_3, "Mobile Station Classmark 3" },
|
|
{ DE_SPARE_NIBBLE, "Spare Half Octet" },
|
|
{ DE_D_GB_CALL_REF, "Descriptive group or broadcast call reference" },
|
|
{ DE_G_CIPH_KEY_NUM, "Group Cipher Key Number" },
|
|
{ DE_PD_SAPI, "PD and SAPI $(CCBS)$" },
|
|
{ DE_PRIO, "Priority Level" },
|
|
{ DE_CN_COMMON_GSM_MAP_NAS_SYS_INFO, "CN Common GSM-MAP NAS system information" },
|
|
{ DE_CS_DOMAIN_SPEC_SYS_INFO, "CS domain specific system information" },
|
|
{ DE_PS_DOMAIN_SPEC_SYS_INFO, "PS domain specific system information" },
|
|
{ DE_PLMN_LIST, "PLMN List" },
|
|
{ DE_NAS_CONT_FOR_PS_HO, "NAS container for PS HO" },
|
|
{ DE_MS_NET_FEAT_SUP, "MS network feature support" },
|
|
{ 0, NULL }
|
|
};
|
|
value_string_ext gsm_common_elem_strings_ext = VALUE_STRING_EXT_INIT(gsm_common_elem_strings);
|
|
|
|
static const value_string gsm_a_skip_ind_vals[] = {
|
|
{ 0, "No indication of selected PLMN"},
|
|
{ 1, "PLMN identity of the Common PLMN in the broadcast system information"},
|
|
{ 2, "PLMN identity of the first Additional PLMN in the broadcast system information"},
|
|
{ 3, "PLMN identity of the second Additional PLMN in the broadcast system information"},
|
|
{ 4, "PLMN identity of the third Additional PLMN in the broadcast system information"},
|
|
{ 5, "PLMN identity of the fourth Additional PLMN in the broadcast system information"},
|
|
{ 6, "Reserved"},
|
|
{ 7, "Reserved"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const true_false_string gsm_a_extension_value = {
|
|
"No Extension",
|
|
"Extended"
|
|
};
|
|
|
|
|
|
/* Mobile Station Classmark Value strings
|
|
*/
|
|
|
|
/* Mobile Station Classmark
|
|
* Revision level
|
|
*/
|
|
static const value_string gsm_a_msc_rev_vals[] = {
|
|
{ 0, "Reserved for GSM phase 1"},
|
|
{ 1, "Used by GSM phase 2 mobile stations"},
|
|
{ 2, "Used by mobile stations supporting R99 or later versions of the protocol"},
|
|
{ 3, "Reserved for future use"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* ES IND (octet 3, bit 5) "Controlled Early Classmark Sending" option implementation */
|
|
static const true_false_string ES_IND_vals = {
|
|
"Controlled Early Classmark Sending option is implemented in the MS",
|
|
"Controlled Early Classmark Sending option is not implemented in the MS"
|
|
};
|
|
/* A5/1 algorithm supported (octet 3, bit 4) */
|
|
static const true_false_string A5_1_algorithm_sup_vals = {
|
|
"encryption algorithm A5/1 not available",
|
|
"encryption algorithm A5/1 available"
|
|
};
|
|
/* RF Power Capability (Octet 3) */
|
|
static const value_string RF_power_capability_vals[] = {
|
|
{ 0, "class 1"},
|
|
{ 1, "class 2"},
|
|
{ 2, "class 3"},
|
|
{ 3, "class 4"},
|
|
{ 4, "class 5"},
|
|
{ 7, "RF Power capability is irrelevant in this information element"},
|
|
{ 0, NULL }
|
|
};
|
|
/* PS capability (pseudo-synchronization capability) (octet 4) */
|
|
static const true_false_string ps_sup_cap_vals = {
|
|
"PS capability present",
|
|
"PS capability not present"
|
|
};
|
|
/* SS Screening Indicator (octet 4)defined in 3GPP TS 24.080 */
|
|
static const value_string SS_screening_indicator_vals[] = {
|
|
{ 0, "Default value of phase 1"},
|
|
{ 1, "Capability of handling of ellipsis notation and phase 2 error handling "},
|
|
{ 2, "For future use"},
|
|
{ 3, "For future use"},
|
|
{ 0, NULL }
|
|
};
|
|
/* SM capability (MT SMS pt to pt capability) (octet 4)*/
|
|
static const true_false_string SM_capability_vals = {
|
|
"Mobile station supports mobile terminated point to point SMS",
|
|
"Mobile station does not support mobile terminated point to point SMS"
|
|
};
|
|
/* VBS notification reception (octet 4) */
|
|
static const true_false_string VBS_notification_rec_vals = {
|
|
"VBS capability and notifications wanted",
|
|
"no VBS capability or no notifications wanted"
|
|
};
|
|
/* VGCS notification reception (octet 4) */
|
|
static const true_false_string VGCS_notification_rec_vals = {
|
|
"VGCS capability and notifications wanted",
|
|
"no VGCS capability or no notifications wanted"
|
|
};
|
|
/* FC Frequency Capability (octet 4 ) */
|
|
static const true_false_string FC_frequency_cap_vals = {
|
|
"The MS does support the E-GSM or R-GSM",
|
|
"The MS does not support the E-GSM or R-GSM band"
|
|
};
|
|
/* CM3 (octet 5, bit 8) */
|
|
static const true_false_string CM3_vals = {
|
|
"The MS supports options that are indicated in classmark 3 IE",
|
|
"The MS does not support any options that are indicated in CM3"
|
|
};
|
|
/* LCS VA capability (LCS value added location request notification capability) (octet 5,bit 6) */
|
|
static const true_false_string LCS_VA_cap_vals = {
|
|
"LCS value added location request notification capability supported",
|
|
"LCS value added location request notification capability not supported"
|
|
};
|
|
/* UCS2 treatment (octet 5, bit 5) */
|
|
static const true_false_string UCS2_treatment_vals = {
|
|
"the ME has no preference between the use of the default alphabet and the use of UCS2",
|
|
"the ME has a preference for the default alphabet"
|
|
};
|
|
/* SoLSA (octet 5, bit 4) */
|
|
static const true_false_string SoLSA_vals = {
|
|
"The ME supports SoLSA",
|
|
"The ME does not support SoLSA"
|
|
};
|
|
/* CMSP: CM Service Prompt (octet 5, bit 3) */
|
|
static const true_false_string CMSP_vals = {
|
|
"Network initiated MO CM connection request supported for at least one CM protocol",
|
|
"Network initiated MO CM connection request not supported"
|
|
};
|
|
/* A5/7 algorithm supported */
|
|
static const true_false_string A5_7_algorithm_sup_vals = {
|
|
"encryption algorithm A5/7 available",
|
|
"encryption algorithm A5/7 not available"
|
|
};
|
|
/* A5/6 algorithm supported */
|
|
static const true_false_string A5_6_algorithm_sup_vals = {
|
|
"encryption algorithm A5/6 available",
|
|
"encryption algorithm A5/6 not available"
|
|
};
|
|
/* A5/5 algorithm supported */
|
|
static const true_false_string A5_5_algorithm_sup_vals = {
|
|
"encryption algorithm A5/5 available",
|
|
"encryption algorithm A5/5 not available"
|
|
};
|
|
/* A5/4 algorithm supported */
|
|
static const true_false_string A5_4_algorithm_sup_vals = {
|
|
"encryption algorithm A5/4 available",
|
|
"encryption algorithm A5/4 not available"
|
|
};
|
|
/* A5/3 algorithm supported (octet 5, bit 2) */
|
|
static const true_false_string A5_3_algorithm_sup_vals = {
|
|
"encryption algorithm A5/3 available",
|
|
"encryption algorithm A5/3 not available"
|
|
};
|
|
/* A5/2 algorithm supported (octet 5, bit 1) */
|
|
static const true_false_string A5_2_algorithm_sup_vals = {
|
|
"encryption algorithm A5/2 available",
|
|
"encryption algorithm A5/2 not available"
|
|
};
|
|
|
|
static const value_string mobile_identity_type_vals[] = {
|
|
{ 0, "No Identity"},
|
|
{ 1, "IMSI"},
|
|
{ 2, "IMEI"},
|
|
{ 3, "IMEISV"},
|
|
{ 4, "TMSI/P-TMSI/M-TMSI"},
|
|
{ 5, "TMGI and optional MBMS Session Identity"}, /* ETSI TS 124 008 V6.8.0 (2005-03) p326 */
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const true_false_string oddevenind_vals = {
|
|
"Odd number of identity digits",
|
|
"Even number of identity digits"
|
|
};
|
|
|
|
static const true_false_string true_false_vals = {
|
|
"true",
|
|
"false"
|
|
};
|
|
|
|
const value_string gsm_a_sms_vals[] = {
|
|
{ 0, "1/4 timeslot (~144 microseconds)" },
|
|
{ 1, "2/4 timeslot (~288 microseconds)" },
|
|
{ 2, "3/4 timeslot (~433 microseconds)" },
|
|
{ 3, "4/4 timeslot (~577 microseconds)" },
|
|
{ 4, "5/4 timeslot (~721 microseconds)" },
|
|
{ 5, "6/4 timeslot (~865 microseconds)" },
|
|
{ 6, "7/4 timeslot (~1009 microseconds)" },
|
|
{ 7, "8/4 timeslot (~1154 microseconds)" },
|
|
{ 8, "9/4 timeslot (~1298 microseconds)" },
|
|
{ 9, "10/4 timeslot (~1442 microseconds)" },
|
|
{ 10, "11/4 timeslot (~1586 microseconds)" },
|
|
{ 11, "12/4 timeslot (~1730 microseconds)" },
|
|
{ 12, "13/4 timeslot (~1874 microseconds)" },
|
|
{ 13, "14/4 timeslot (~2019 microseconds)" },
|
|
{ 14, "15/4 timeslot (~2163 microseconds)" },
|
|
{ 15, "16/4 timeslot (~2307 microseconds)" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const true_false_string ms_assisted_e_otd_vals = {
|
|
"MS assisted E-OTD supported",
|
|
"MS assisted E-OTD not supported"
|
|
};
|
|
|
|
static const true_false_string ms_based_e_otd_vals = {
|
|
"MS based E-OTD supported",
|
|
"MS based E-OTD not supported"
|
|
};
|
|
|
|
static const true_false_string ms_assisted_gps_vals = {
|
|
"MS assisted GPS supported",
|
|
"MS assisted GPS not supported"
|
|
};
|
|
|
|
static const true_false_string ms_based_gps_vals = {
|
|
"MS based GPS supported",
|
|
"MS based GPS not supported"
|
|
};
|
|
|
|
static const true_false_string ms_conventional_gps_vals = {
|
|
"Conventional GPS supported",
|
|
"Conventional GPS not supported"
|
|
};
|
|
|
|
static const true_false_string modulation_capability_vals = {
|
|
"8-PSK supported for uplink transmission and downlink reception",
|
|
"8-PSK supported for downlink reception only"
|
|
};
|
|
|
|
static const value_string eight_psk_rf_power_capability_vals[] = {
|
|
{ 0, "Reserved" },
|
|
{ 1, "Power class E1" },
|
|
{ 2, "Power class E2" },
|
|
{ 3, "Power class E3" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const value_string gsm_400_bands_supported_vals[] = {
|
|
{ 1, "GSM 480 supported, GSM 450 not supported" },
|
|
{ 2, "GSM 450 supported, GSM 480 not supported" },
|
|
{ 3, "GSM 450 supported, GSM 480 supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const true_false_string umts_fdd_rat_cap_vals = {
|
|
"UMTS FDD supported",
|
|
"UMTS FDD not supported"
|
|
};
|
|
|
|
static const true_false_string umts_384_mcps_tdd_rat_cap_vals = {
|
|
"UMTS 3.84 Mcps TDD supported",
|
|
"UMTS 3.84 Mcps TDD not supported"
|
|
};
|
|
|
|
static const true_false_string cdma_2000_rat_cap_vals = {
|
|
"CDMA 2000 supported",
|
|
"CDMA 2000 not supported"
|
|
};
|
|
|
|
static const value_string dtm_gprs_multi_slot_class_vals[] = {
|
|
{ 0, "Unused. If received, the network shall interpret this as 1" },
|
|
{ 1, "Multislot class 5 supported" },
|
|
{ 2, "Multislot class 9 supported" },
|
|
{ 3, "Multislot class 11 supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const true_false_string single_slot_dtm_vals = {
|
|
"Single Slot DTM supported",
|
|
"Single Slot DTM not supported"
|
|
};
|
|
|
|
static const value_string gsm_band_vals[] = {
|
|
{ 0, "E-GSM is supported" },
|
|
{ 1, "P-GSM is supported" },
|
|
{ 2, "GSM 1800 is supported" },
|
|
{ 3, "GSM 450 is supported" },
|
|
{ 4, "GSM 480 is supported" },
|
|
{ 5, "GSM 850 is supported" },
|
|
{ 6, "GSM 1900 is supported" },
|
|
{ 7, "GSM 750 is supported" },
|
|
{ 8, "GSM 710 is supported" },
|
|
{ 9, "T-GSM 810 is supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const true_false_string umts_128_mcps_tdd_rat_cap_vals = {
|
|
"UMTS 1.28 Mcps TDD supported",
|
|
"UMTS 1.28 Mcps TDD not supported"
|
|
};
|
|
|
|
static const true_false_string geran_feature_package_1_vals = {
|
|
"GERAN feature package 1 supported",
|
|
"GERAN feature package 1 not supported"
|
|
};
|
|
|
|
static const true_false_string flo_iu_cap_vals = {
|
|
"FLO in GERAN Iu Mode supported",
|
|
"FLO in GERAN Iu Mode not supported"
|
|
};
|
|
|
|
static const true_false_string geran_feature_package_2_vals = {
|
|
"GERAN feature package 2 supported",
|
|
"GERAN feature package 2 not supported"
|
|
};
|
|
|
|
static const value_string gmsk_multislot_power_prof_vals[] = {
|
|
{ 0, "GMSK_MULTISLOT_POWER_PROFILE 0" },
|
|
{ 1, "GMSK_MULTISLOT_POWER_PROFILE 1" },
|
|
{ 2, "GMSK_MULTISLOT_POWER_PROFILE 2" },
|
|
{ 3, "GMSK_MULTISLOT_POWER_PROFILE 3" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const value_string eight_psk_multislot_power_prof_vals[] = {
|
|
{ 0, "8-PSK_MULTISLOT_POWER_PROFILE 0" },
|
|
{ 1, "8-PSK_MULTISLOT_POWER_PROFILE 1" },
|
|
{ 2, "8-PSK_MULTISLOT_POWER_PROFILE 2" },
|
|
{ 3, "8-PSK_MULTISLOT_POWER_PROFILE 3" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const value_string t_gsm_400_bands_supported_vals[] = {
|
|
{ 1, "T-GSM 380 supported, T-GSM 410 not supported" },
|
|
{ 2, "T-GSM 410 supported, T-GSM 380 not supported" },
|
|
{ 3, "T-GSM 410 supported, T-GSM 380 supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const value_string downlink_adv_receiver_perf_vals[] = {
|
|
{ 0, "Downlink Advanced Receiver Performance not supported" },
|
|
{ 1, "Downlink Advanced Receiver Performance - phase I supported" },
|
|
{ 2, "Downlink Advanced Receiver Performance - phase II supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const true_false_string dtm_enhancements_cap_vals = {
|
|
"The mobile station supports enhanced DTM CS establishment and release procedures",
|
|
"The mobile station does not support enhanced DTM CS establishment and release procedures"
|
|
};
|
|
|
|
static const true_false_string offset_required_vals = {
|
|
"The mobile station requires the offset",
|
|
"The mobile station does not require the offset"
|
|
};
|
|
|
|
static const value_string dtm_gprs_high_multi_slot_class_vals[] = {
|
|
{ 0, "Unused. If received, the network shall interpret this as \"0 0 1\"" },
|
|
{ 1, "Multislot class 31 or 36 supported" },
|
|
{ 2, "Multislot class 32 or 37 supported" },
|
|
{ 3, "Multislot class 33 or 38 supported" },
|
|
{ 4, "Multislot class 41 supported" },
|
|
{ 5, "Multislot class 42 supported" },
|
|
{ 6, "Multislot class 43 supported" },
|
|
{ 7, "Multislot class 44 supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const true_false_string repeated_acch_cap_vals = {
|
|
"The mobile station supports Repeated SACCH and Repeated Downlink FACCH",
|
|
"The mobile station does not support Repeated SACCH"
|
|
};
|
|
|
|
static const true_false_string ciphering_mode_setting_cap_vals = {
|
|
"The mobile station supports the Ciphering Mode Setting IE in the DTM ASSIGNMENT COMMAND message",
|
|
"The mobile station does not support the Ciphering Mode Setting IE in the DTM ASSIGNMENT COMMAND message"
|
|
};
|
|
|
|
static const true_false_string additional_positioning_caps_vals = {
|
|
"The mobile station supports additional positioning capabilities which can be retrieved using RRLP",
|
|
"The mobile station does not support additional positioning capabilities which can be retrieved using RRLP"
|
|
};
|
|
|
|
static const true_false_string e_utra_fdd_support_vals = {
|
|
"E-UTRA FDD supported",
|
|
"E-UTRA FDD not supported"
|
|
};
|
|
|
|
static const true_false_string e_utra_tdd_support_vals = {
|
|
"E-UTRA TDD supported",
|
|
"E-UTRA TDD not supported"
|
|
};
|
|
|
|
static const true_false_string e_utra_meas_and_report_support_vals = {
|
|
"E-UTRAN Neighbour Cell measurements and measurement reporting while having an RR connection supported",
|
|
"E-UTRAN Neighbour Cell measurements and measurement reporting while having an RR connection not supported"
|
|
};
|
|
|
|
static const true_false_string prio_based_resel_support_vals = {
|
|
"Priority-based cell reselection supported",
|
|
"Priority-based cell reselection not supported"
|
|
};
|
|
|
|
static const true_false_string utra_csg_cells_reporting_vals = {
|
|
"Reporting of UTRAN CSG cells supported",
|
|
"Reporting of UTRAN CSG cells not supported"
|
|
};
|
|
|
|
static const value_string vamos_level_vals[] = {
|
|
{ 0, "VAMOS not supported" },
|
|
{ 1, "VAMOS I supported" },
|
|
{ 2, "VAMOS II supported" },
|
|
{ 3, "VAMOS III supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
const value_string tighter_cap_level_vals[] = {
|
|
{ 0, "TIGHTER not supported" },
|
|
{ 1, "TIGHTER supported for speech and signalling channels only" },
|
|
{ 2, "TIGHTER supported for speech and signalling channels and for GPRS and EGPRS, but not for EGPRS2" },
|
|
{ 3, "TIGHTER supported for speech and signalling channels and for GPRS, EGPRS and EGPRS2" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
const value_string cs_to_ps_srvcc_geran_to_utra_vals[] = {
|
|
{ 0, "CS to PS SRVCC from GERAN to UMTS FDD and 1.28 Mcps TDD not supported" },
|
|
{ 1, "CS to PS SRVCC from GERAN to UMTS FDD supported" },
|
|
{ 2, "CS to PS SRVCC from GERAN to UMTS 1.28 Mcps TDD supported" },
|
|
{ 3, "CS to PS SRVCC from GERAN to UMTS FDD and 1.28 Mcps TDD supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
const value_string cs_to_ps_srvcc_geran_to_eutra_vals[] = {
|
|
{ 0, "CS to PS SRVCC from GERAN to E-UTRA FDD and TDD not supported" },
|
|
{ 1, "CS to PS SRVCC from GERAN to E-UTRA FDD supported" },
|
|
{ 2, "CS to PS SRVCC from GERAN to E-UTRA TDD supported" },
|
|
{ 3, "CS to PS SRVCC from GERAN to E-UTRA FDD and TDD supported" },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
static const value_string gsm_a_rr_rxlev_vals [] = {
|
|
{ 0, "< -110 dBm"},
|
|
{ 1, "-110 <= x < -109 dBm"},
|
|
{ 2, "-109 <= x < -108 dBm"},
|
|
{ 3, "-108 <= x < -107 dBm"},
|
|
{ 4, "-107 <= x < -106 dBm"},
|
|
{ 5, "-106 <= x < -105 dBm"},
|
|
{ 6, "-105 <= x < -104 dBm"},
|
|
{ 7, "-104 <= x < -103 dBm"},
|
|
{ 8, "-103 <= x < -102 dBm"},
|
|
{ 9, "-102 <= x < -101 dBm"},
|
|
{ 10, "-101 <= x < -100 dBm"},
|
|
{ 11, "-100 <= x < -99 dBm"},
|
|
{ 12, "-99 <= x < -98 dBm"},
|
|
{ 13, "-98 <= x < -97 dBm"},
|
|
{ 14, "-97 <= x < -96 dBm"},
|
|
{ 15, "-96 <= x < -95 dBm"},
|
|
{ 16, "-95 <= x < -94 dBm"},
|
|
{ 17, "-94 <= x < -93 dBm"},
|
|
{ 18, "-93 <= x < -92 dBm"},
|
|
{ 19, "-92 <= x < -91 dBm"},
|
|
{ 20, "-91 <= x < -90 dBm"},
|
|
{ 21, "-90 <= x < -89 dBm"},
|
|
{ 22, "-89 <= x < -88 dBm"},
|
|
{ 23, "-88 <= x < -87 dBm"},
|
|
{ 24, "-87 <= x < -86 dBm"},
|
|
{ 25, "-86 <= x < -85 dBm"},
|
|
{ 26, "-85 <= x < -84 dBm"},
|
|
{ 27, "-84 <= x < -83 dBm"},
|
|
{ 28, "-83 <= x < -82 dBm"},
|
|
{ 29, "-82 <= x < -81 dBm"},
|
|
{ 30, "-81 <= x < -80 dBm"},
|
|
{ 31, "-80 <= x < -79 dBm"},
|
|
{ 32, "-79 <= x < -78 dBm"},
|
|
{ 33, "-78 <= x < -77 dBm"},
|
|
{ 34, "-77 <= x < -76 dBm"},
|
|
{ 35, "-76 <= x < -75 dBm"},
|
|
{ 36, "-75 <= x < -74 dBm"},
|
|
{ 37, "-74 <= x < -73 dBm"},
|
|
{ 38, "-73 <= x < -72 dBm"},
|
|
{ 39, "-72 <= x < -71 dBm"},
|
|
{ 40, "-71 <= x < -70 dBm"},
|
|
{ 41, "-70 <= x < -69 dBm"},
|
|
{ 42, "-69 <= x < -68 dBm"},
|
|
{ 43, "-68 <= x < -67 dBm"},
|
|
{ 44, "-67 <= x < -66 dBm"},
|
|
{ 45, "-66 <= x < -65 dBm"},
|
|
{ 46, "-65 <= x < -64 dBm"},
|
|
{ 47, "-64 <= x < -63 dBm"},
|
|
{ 48, "-63 <= x < -62 dBm"},
|
|
{ 49, "-62 <= x < -61 dBm"},
|
|
{ 50, "-61 <= x < -60 dBm"},
|
|
{ 51, "-60 <= x < -59 dBm"},
|
|
{ 52, "-59 <= x < -58 dBm"},
|
|
{ 53, "-58 <= x < -57 dBm"},
|
|
{ 54, "-57 <= x < -56 dBm"},
|
|
{ 55, "-56 <= x < -55 dBm"},
|
|
{ 56, "-55 <= x < -54 dBm"},
|
|
{ 57, "-54 <= x < -53 dBm"},
|
|
{ 58, "-53 <= x < -52 dBm"},
|
|
{ 59, "-52 <= x < -51 dBm"},
|
|
{ 60, "-51 <= x < -50 dBm"},
|
|
{ 61, "-50 <= x < -49 dBm"},
|
|
{ 62, "-49 <= x < -48 dBm"},
|
|
{ 63, ">= -48 dBm"},
|
|
{ 0, NULL}
|
|
};
|
|
value_string_ext gsm_a_rr_rxlev_vals_ext = VALUE_STRING_EXT_INIT(gsm_a_rr_rxlev_vals);
|
|
|
|
/* Initialize the protocol and registered fields */
|
|
static int proto_a_common = -1;
|
|
|
|
int gsm_a_tap = -1;
|
|
|
|
int hf_gsm_a_common_elem_id = -1;
|
|
static int hf_gsm_a_common_elem_id_f0 = -1;
|
|
static int hf_gsm_a_l_ext = -1;
|
|
int hf_gsm_a_tmsi = -1;
|
|
static int hf_gsm_a_imei = -1;
|
|
static int hf_gsm_a_imeisv = -1;
|
|
|
|
static int hf_gsm_a_MSC_rev = -1;
|
|
static int hf_gsm_a_ES_IND = -1;
|
|
static int hf_gsm_a_A5_1_algorithm_sup = -1;
|
|
static int hf_gsm_a_RF_power_capability = -1;
|
|
static int hf_gsm_a_ps_sup_cap = -1;
|
|
static int hf_gsm_a_SS_screening_indicator = -1;
|
|
static int hf_gsm_a_SM_capability = -1;
|
|
static int hf_gsm_a_VBS_notification_rec = -1;
|
|
static int hf_gsm_a_VGCS_notification_rec = -1;
|
|
static int hf_gsm_a_FC_frequency_cap = -1;
|
|
static int hf_gsm_a_CM3 = -1;
|
|
static int hf_gsm_a_LCS_VA_cap = -1;
|
|
static int hf_gsm_a_UCS2_treatment = -1;
|
|
static int hf_gsm_a_SoLSA = -1;
|
|
static int hf_gsm_a_CMSP = -1;
|
|
static int hf_gsm_a_A5_7_algorithm_sup = -1;
|
|
static int hf_gsm_a_A5_6_algorithm_sup = -1;
|
|
static int hf_gsm_a_A5_5_algorithm_sup = -1;
|
|
static int hf_gsm_a_A5_4_algorithm_sup = -1;
|
|
static int hf_gsm_a_A5_3_algorithm_sup = -1;
|
|
static int hf_gsm_a_A5_2_algorithm_sup = -1;
|
|
|
|
static int hf_gsm_a_odd_even_ind = -1;
|
|
static int hf_gsm_a_id_dig_1 = -1;
|
|
static int hf_gsm_a_unused = -1;
|
|
static int hf_gsm_a_mobile_identity_type = -1;
|
|
static int hf_gsm_a_tmgi_mcc_mnc_ind = -1;
|
|
static int hf_gsm_a_mbs_ses_id_ind = -1;
|
|
static int hf_gsm_a_mbs_service_id = -1;
|
|
static int hf_gsm_a_mbs_session_id = -1;
|
|
static int hf_gsm_a_length = -1;
|
|
static int hf_gsm_a_element_value = -1;
|
|
int hf_gsm_a_extension = -1;
|
|
int hf_gsm_a_L3_protocol_discriminator = -1;
|
|
int hf_gsm_a_call_prio = -1;
|
|
int hf_gsm_a_skip_ind = -1;
|
|
int hf_gsm_a_spare_bits = -1;
|
|
int hf_gsm_a_lac = -1;
|
|
|
|
static int hf_gsm_a_spare_nibble = -1;
|
|
static int hf_gsm_a_type_of_ciph_alg = -1;
|
|
static int hf_gsm_a_att = -1;
|
|
static int hf_gsm_a_nmo_1 = -1;
|
|
static int hf_gsm_a_nmo = -1;
|
|
static int hf_gsm_a_old_xid = -1;
|
|
static int hf_gsm_a_iov_ui = -1;
|
|
static int hf_gsm_a_ext_periodic_timers = -1;
|
|
static int hf_gsm_a_b7spare = -1;
|
|
int hf_gsm_a_b8spare = -1;
|
|
static int hf_gsm_a_multi_bnd_sup_fields = -1;
|
|
static int hf_gsm_a_pgsm_supported = -1;
|
|
static int hf_gsm_a_egsm_supported = -1;
|
|
static int hf_gsm_a_gsm1800_supported = -1;
|
|
static int hf_gsm_a_ass_radio_cap1 = -1;
|
|
static int hf_gsm_a_ass_radio_cap2 = -1;
|
|
static int hf_gsm_a_rsupport = -1;
|
|
static int hf_gsm_a_r_capabilities = -1;
|
|
static int hf_gsm_a_multislot_capabilities = -1;
|
|
static int hf_gsm_a_multislot_class = -1;
|
|
static int hf_gsm_a_ucs2_treatment = -1;
|
|
static int hf_gsm_a_extended_measurement_cap = -1;
|
|
static int hf_gsm_a_ms_measurement_capability = -1;
|
|
static int hf_gsm_a_sms_value =-1;
|
|
static int hf_gsm_a_sm_value =-1;
|
|
static int hf_gsm_a_key_seq = -1;
|
|
static int hf_gsm_a_ms_pos_method_cap_present = -1;
|
|
static int hf_gsm_a_ms_pos_method = -1;
|
|
static int hf_gsm_a_ms_assisted_e_otd = -1;
|
|
static int hf_gsm_a_ms_based_e_otd = -1;
|
|
static int hf_gsm_a_ms_assisted_gps = -1;
|
|
static int hf_gsm_a_ms_based_gps = -1;
|
|
static int hf_gsm_a_ms_conventional_gps = -1;
|
|
static int hf_gsm_a_ecsd_multi_slot_capability = -1;
|
|
static int hf_gsm_a_ecsd_multi_slot_class = -1;
|
|
static int hf_gsm_a_8_psk_struct_present = -1;
|
|
static int hf_gsm_a_8_psk_struct = -1;
|
|
static int hf_gsm_a_modulation_capability = -1;
|
|
static int hf_gsm_a_8_psk_rf_power_capability_1_present = -1;
|
|
static int hf_gsm_a_8_psk_rf_power_capability_1 = -1;
|
|
static int hf_gsm_a_8_psk_rf_power_capability_2_present = -1;
|
|
static int hf_gsm_a_8_psk_rf_power_capability_2 = -1;
|
|
static int hf_gsm_a_gsm_400_band_info_present = -1;
|
|
static int hf_gsm_a_gsm_400_bands_supported = -1;
|
|
static int hf_gsm_a_gsm_400_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_gsm_850_assoc_radio_cap_present = -1;
|
|
static int hf_gsm_a_gsm_850_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_gsm_1900_assoc_radio_cap_present = -1;
|
|
static int hf_gsm_a_gsm_1900_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_cm3_A5_bits = -1;
|
|
static int hf_gsm_a_umts_fdd_rat_cap = -1;
|
|
static int hf_gsm_a_umts_384_mcps_tdd_rat_cap = -1;
|
|
static int hf_gsm_a_cdma_2000_rat_cap = -1;
|
|
static int hf_gsm_a_dtm_e_gprs_multi_slot_info_present = -1;
|
|
static int hf_gsm_a_dtm_gprs_multi_slot_class = -1;
|
|
static int hf_gsm_a_single_slot_dtm = -1;
|
|
static int hf_gsm_a_dtm_egprs_multi_slot_class_present = -1;
|
|
static int hf_gsm_a_dtm_egprs_multi_slot_class = -1;
|
|
static int hf_gsm_a_single_band_support = -1;
|
|
static int hf_gsm_a_gsm_band = -1;
|
|
static int hf_gsm_a_gsm_750_assoc_radio_cap_present = -1;
|
|
static int hf_gsm_a_gsm_750_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_umts_128_mcps_tdd_rat_cap = -1;
|
|
static int hf_gsm_a_geran_feature_package_1 = -1;
|
|
static int hf_gsm_a_ext_dtm_e_gprs_multi_slot_info_present = -1;
|
|
static int hf_gsm_a_ext_dtm_gprs_multi_slot_class = -1;
|
|
static int hf_gsm_a_ext_dtm_egprs_multi_slot_class = -1;
|
|
static int hf_gsm_a_high_multislot_cap_present = -1;
|
|
static int hf_gsm_a_high_multislot_cap = -1;
|
|
static int hf_gsm_a_geran_iu_mode_support = -1;
|
|
static int hf_gsm_a_geran_iu_mode_cap = -1;
|
|
static int hf_gsm_a_geran_iu_mode_cap_length = -1;
|
|
static int hf_gsm_a_flo_iu_cap = -1;
|
|
static int hf_gsm_a_geran_feature_package_2 = -1;
|
|
static int hf_gsm_a_gmsk_multislot_power_prof = -1;
|
|
static int hf_gsm_a_8_psk_multislot_power_prof = -1;
|
|
static int hf_gsm_a_t_gsm_400_band_info_present = -1;
|
|
static int hf_gsm_a_t_gsm_400_bands_supported = -1;
|
|
static int hf_gsm_a_t_gsm_400_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_t_gsm_900_assoc_radio_cap_present = -1;
|
|
static int hf_gsm_a_t_gsm_900_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_downlink_adv_receiver_perf = -1;
|
|
static int hf_gsm_a_dtm_enhancements_cap = -1;
|
|
static int hf_gsm_a_dtm_e_gprs_high_multi_slot_info_present = -1;
|
|
static int hf_gsm_a_dtm_gprs_high_multi_slot_class = -1;
|
|
static int hf_gsm_a_offset_required = -1;
|
|
static int hf_gsm_a_dtm_egprs_high_multi_slot_class_present = -1;
|
|
static int hf_gsm_a_dtm_egprs_high_multi_slot_class = -1;
|
|
static int hf_gsm_a_repeated_acch_cap = -1;
|
|
static int hf_gsm_a_gsm_710_assoc_radio_cap_present = -1;
|
|
static int hf_gsm_a_gsm_710_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_t_gsm_810_assoc_radio_cap_present = -1;
|
|
static int hf_gsm_a_t_gsm_810_assoc_radio_cap = -1;
|
|
static int hf_gsm_a_ciphering_mode_setting_cap = -1;
|
|
static int hf_gsm_a_additional_positioning_caps = -1;
|
|
static int hf_gsm_a_e_utra_fdd_support = -1;
|
|
static int hf_gsm_a_e_utra_tdd_support = -1;
|
|
static int hf_gsm_a_e_utra_meas_and_report_support = -1;
|
|
static int hf_gsm_a_prio_based_resel_support = -1;
|
|
static int hf_gsm_a_utra_csg_cells_reporting = -1;
|
|
static int hf_gsm_a_vamos_level = -1;
|
|
static int hf_gsm_a_tighter_cap = -1;
|
|
static int hf_gsm_a_selective_ciph_down_sacch = -1;
|
|
static int hf_gsm_a_cs_to_ps_srvcc_geran_to_utra = -1;
|
|
static int hf_gsm_a_cs_to_ps_srvcc_geran_to_eutra = -1;
|
|
static int hf_gsm_a_geran_network_sharing_support = -1;
|
|
static int hf_gsm_a_eutra_wb_rsrq_support = -1;
|
|
static int hf_gsm_a_er_band_support = -1;
|
|
static int hf_gsm_a_utra_mfbi_support = -1;
|
|
static int hf_gsm_a_eutra_mfbi_support = -1;
|
|
static int hf_gsm_a_ext_tsc_set_cap_support = -1;
|
|
static int hf_gsm_a_ext_earfcn_value_range = -1;
|
|
|
|
static int hf_gsm_a_geo_loc_type_of_shape = -1;
|
|
static int hf_gsm_a_geo_loc_sign_of_lat = -1;
|
|
static int hf_gsm_a_geo_loc_deg_of_lat =-1;
|
|
static int hf_gsm_a_geo_loc_deg_of_long =-1;
|
|
static int hf_gsm_a_geo_loc_osm_uri =-1;
|
|
static int hf_gsm_a_geo_loc_uncertainty_code = -1;
|
|
static int hf_gsm_a_geo_loc_uncertainty_semi_major = -1;
|
|
static int hf_gsm_a_geo_loc_uncertainty_semi_minor = -1;
|
|
static int hf_gsm_a_geo_loc_orientation_of_major_axis = -1;
|
|
static int hf_gsm_a_geo_loc_uncertainty_altitude = -1;
|
|
static int hf_gsm_a_geo_loc_confidence = -1;
|
|
static int hf_gsm_a_geo_loc_no_of_points = -1;
|
|
static int hf_gsm_a_velocity_type = -1;
|
|
static int hf_gsm_a_bearing = -1;
|
|
static int hf_gsm_a_horizontal_speed = -1;
|
|
static int hf_gsm_a_uncertainty_speed = -1;
|
|
static int hf_gsm_a_h_uncertainty_speed = -1;
|
|
static int hf_gsm_a_v_uncertainty_speed = -1;
|
|
static int hf_gsm_a_vertical_speed = -1;
|
|
static int hf_gsm_a_d = -1;
|
|
static int hf_gsm_a_geo_loc_D = -1;
|
|
static int hf_gsm_a_geo_loc_altitude = -1;
|
|
static int hf_gsm_a_geo_loc_inner_radius = -1;
|
|
static int hf_gsm_a_geo_loc_uncertainty_radius = -1;
|
|
static int hf_gsm_a_geo_loc_offset_angle = -1;
|
|
static int hf_gsm_a_geo_loc_included_angle = -1;
|
|
|
|
/* Generated from convert_proto_tree_add_text.pl */
|
|
static int hf_gsm_a_filler = -1;
|
|
static int hf_gsm_a_identity_digit1 = -1;
|
|
static int hf_gsm_a_group_call_reference = -1;
|
|
static int hf_gsm_a_service_flag = -1;
|
|
static int hf_gsm_a_af_acknowledgement = -1;
|
|
static int hf_gsm_a_call_priority = -1;
|
|
static int hf_gsm_a_ciphering_info = -1;
|
|
static int hf_gsm_a_sapi = -1;
|
|
static int hf_gsm_a_mobile_country_code = -1;
|
|
static int hf_gsm_a_mobile_network_code = -1;
|
|
|
|
static int ett_gsm_a_plmn = -1;
|
|
|
|
static expert_field ei_gsm_a_extraneous_data = EI_INIT;
|
|
static expert_field ei_gsm_a_unknown_element = EI_INIT;
|
|
static expert_field ei_gsm_a_unknown_pdu_type = EI_INIT;
|
|
static expert_field ei_gsm_a_no_element_dissector = EI_INIT;
|
|
static expert_field ei_gsm_a_format_not_supported = EI_INIT;
|
|
static expert_field ei_gsm_a_mobile_identity_type = EI_INIT;
|
|
|
|
sccp_assoc_info_t* sccp_assoc;
|
|
|
|
#define NUM_GSM_COMMON_ELEM (sizeof(gsm_common_elem_strings)/sizeof(value_string))
|
|
gint ett_gsm_common_elem[NUM_GSM_COMMON_ELEM];
|
|
|
|
|
|
#define ELLIPSOID_POINT 0
|
|
#define ELLIPSOID_POINT_WITH_UNCERT_CIRC 1
|
|
#define ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE 3
|
|
#define POLYGON 5
|
|
#define ELLIPSOID_POINT_WITH_ALT 8
|
|
#define ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID 9
|
|
#define ELLIPSOID_ARC 10
|
|
/*
|
|
4 3 2 1
|
|
0 0 0 0 Ellipsoid Point
|
|
0 0 0 1 Ellipsoid point with uncertainty Circle
|
|
0 0 1 1 Ellipsoid point with uncertainty Ellipse
|
|
0 1 0 1 Polygon
|
|
1 0 0 0 Ellipsoid point with altitude
|
|
1 0 0 1 Ellipsoid point with altitude and uncertainty Ellipsoid
|
|
1 0 1 0 Ellipsoid Arc
|
|
other values reserved for future use
|
|
*/
|
|
|
|
/* TS 23 032 Table 2a: Coding of Type of Shape */
|
|
static const value_string type_of_shape_vals[] = {
|
|
{ ELLIPSOID_POINT, "Ellipsoid Point"},
|
|
{ ELLIPSOID_POINT_WITH_UNCERT_CIRC, "Ellipsoid point with uncertainty Circle"},
|
|
{ ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE, "Ellipsoid point with uncertainty Ellipse"},
|
|
{ POLYGON, "Polygon"},
|
|
{ ELLIPSOID_POINT_WITH_ALT, "Ellipsoid point with altitude"},
|
|
{ ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID, "Ellipsoid point with altitude and uncertainty Ellipsoid"},
|
|
{ ELLIPSOID_ARC, "Ellipsoid Arc"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* 3GPP TS 23.032 7.3.1 */
|
|
static const value_string sign_of_latitude_vals[] = {
|
|
{ 0, "North"},
|
|
{ 1, "South"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string dir_of_alt_vals[] = {
|
|
{ 0, "Altitude expresses height"},
|
|
{ 1, "Altitude expresses depth"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
typedef guint16 (**elem_func_hander)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
|
|
|
|
void
|
|
dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) {
|
|
|
|
proto_item *lat_item, *long_item, *major_item, *minor_item, *alt_item, *uncer_item, *loc_uri_item;
|
|
/*proto_tree *subtree; */
|
|
guint8 type_of_shape;
|
|
/*guint8 no_of_points;*/
|
|
int offset = 0;
|
|
int length;
|
|
guint8 value;
|
|
guint32 uvalue32;
|
|
gint32 svalue32;
|
|
gchar *deg_lat_str;
|
|
gchar *deg_lon_str;
|
|
gchar *osm_uri;
|
|
int loc_offset;
|
|
|
|
/*subtree = proto_item_add_subtree(item, ett_gsm_a_geo_desc);*/
|
|
|
|
length = tvb_reported_length_remaining(tvb, 0);
|
|
/* Geographical Location
|
|
* The Location Estimate field is composed of 1 or more octets with an internal structure
|
|
* according to section 7 in [23.032].
|
|
*/
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_type_of_shape, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
if (length < 2)
|
|
return;
|
|
type_of_shape = tvb_get_guint8(tvb,offset)>>4;
|
|
switch (type_of_shape) {
|
|
case ELLIPSOID_POINT:
|
|
/* Ellipsoid Point */
|
|
case ELLIPSOID_POINT_WITH_UNCERT_CIRC:
|
|
/* Ellipsoid Point with uncertainty Circle */
|
|
case ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE:
|
|
/* Ellipsoid Point with uncertainty Ellipse */
|
|
case ELLIPSOID_POINT_WITH_ALT:
|
|
/* Ellipsoid Point with Altitude */
|
|
case ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID:
|
|
/* Ellipsoid Point with altitude and uncertainty ellipsoid */
|
|
case ELLIPSOID_ARC:
|
|
/* Ellipsoid Arc */
|
|
offset++;
|
|
if (length < 4)
|
|
return;
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_sign_of_lat, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
uvalue32 = tvb_get_ntoh24(tvb,offset);
|
|
/* convert degrees (X/0x7fffff) * 90 = degrees */
|
|
lat_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_deg_of_lat, tvb, offset, 3, ENC_BIG_ENDIAN);
|
|
deg_lat_str = wmem_strdup_printf(wmem_packet_scope(), "%s%.5f",
|
|
(uvalue32 & 0x00800000) ? "-" : "",
|
|
((double)(uvalue32 & 0x7fffff)/8388607.0) * 90);
|
|
proto_item_append_text(lat_item, " (%s degrees)", deg_lat_str);
|
|
loc_offset = offset;
|
|
if (length < 7)
|
|
return;
|
|
offset = offset + 3;
|
|
svalue32 = tvb_get_ntoh24(tvb,offset);
|
|
svalue32 |= (svalue32 & 0x800000) ? 0xff000000 : 0x00000000;
|
|
long_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_deg_of_long, tvb, offset, 3, ENC_BIG_ENDIAN);
|
|
/* (X/0xffffff) *360 = degrees */
|
|
deg_lon_str = wmem_strdup_printf(wmem_packet_scope(), "%.5f",
|
|
((double)svalue32/16777215.0) * 360);
|
|
proto_item_append_text(long_item, " (%s degrees)", deg_lon_str);
|
|
offset = offset + 3;
|
|
if (type_of_shape == ELLIPSOID_POINT_WITH_UNCERT_CIRC) {
|
|
/* Ellipsoid Point with uncertainty Circle */
|
|
if (length < 8)
|
|
return;
|
|
/* Uncertainty code */
|
|
value = tvb_get_guint8(tvb,offset)&0x7f;
|
|
uncer_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_code, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(uncer_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
|
|
}else if (type_of_shape == ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE) {
|
|
/* Ellipsoid Point with uncertainty Ellipse */
|
|
/* Uncertainty semi-major octet 10
|
|
* To convert to metres 10*(((1.1)^X)-1)
|
|
*/
|
|
value = tvb_get_guint8(tvb,offset) & 0x7f;
|
|
major_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_major, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(major_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
|
|
offset++;
|
|
/* Uncertainty semi-minor Octet 11
|
|
* To convert to metres 10*(((1.1)^X)-1)
|
|
*/
|
|
value = tvb_get_guint8(tvb,offset)&0x7f;
|
|
minor_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_minor, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(minor_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
|
|
offset++;
|
|
/* Orientation of major axis octet 12
|
|
* allowed value from 0-179 to convert
|
|
* to actual degrees multiply by 2.
|
|
*/
|
|
value = tvb_get_guint8(tvb,offset)&0x7f;
|
|
proto_tree_add_uint(tree, hf_gsm_a_geo_loc_orientation_of_major_axis, tvb, offset, 1, value*2);
|
|
offset++;
|
|
/* Confidence */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_confidence, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset++;
|
|
}else if (type_of_shape == ELLIPSOID_POINT_WITH_ALT) {
|
|
/* Ellipsoid Point with Altitude */
|
|
/*D: Direction of Altitude */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_D, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
/* Altitude */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_altitude, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
}else if (type_of_shape == ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID) {
|
|
/* Ellipsoid Point with altitude and uncertainty ellipsoid */
|
|
/*D: Direction of Altitude octet 8,9 */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_D, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
/* Altitude Octet 8,9*/
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_altitude, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset = offset +2;
|
|
/* Uncertainty semi-major octet 10
|
|
* To convert to metres 10*(((1.1)^X)-1)
|
|
*/
|
|
value = tvb_get_guint8(tvb,offset)&0x7f;
|
|
major_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_major, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(major_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
|
|
offset++;
|
|
/* Uncertainty semi-minor Octet 11
|
|
* To convert to metres 10*(((1.1)^X)-1)
|
|
*/
|
|
value = tvb_get_guint8(tvb,offset)&0x7f;
|
|
minor_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_minor, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(minor_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
|
|
offset++;
|
|
/* Orientation of major axis octet 12
|
|
* allowed value from 0-179 to convert
|
|
* to actual degrees multiply by 2.
|
|
*/
|
|
value = tvb_get_guint8(tvb,offset)&0x7f;
|
|
proto_tree_add_uint(tree, hf_gsm_a_geo_loc_orientation_of_major_axis, tvb, offset, 1, value*2);
|
|
offset++;
|
|
/* Uncertainty Altitude 13
|
|
* to convert to metres 45*(((1.025)^X)-1)
|
|
*/
|
|
value = tvb_get_guint8(tvb,offset)&0x7f;
|
|
alt_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_altitude, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(alt_item, " (%.1f m)", 45 * (pow(1.025, (double)value) - 1));
|
|
offset++;
|
|
/* Confidence octet 14
|
|
*/
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_confidence, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
}else if (type_of_shape == ELLIPSOID_ARC) {
|
|
/* Ellipsoid Arc */
|
|
/* Inner radius */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_inner_radius, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset = offset + 2;
|
|
/* Uncertainty radius */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_radius, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset++;
|
|
/* Offset angle */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_offset_angle, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset++;
|
|
/* Included angle */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_included_angle, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset++;
|
|
/* Confidence */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_confidence, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
}
|
|
osm_uri = wmem_strdup_printf(wmem_packet_scope(), "https://www.openstreetmap.org/?mlat=%s&mlon=%s&zoom=12", deg_lat_str, deg_lon_str);
|
|
loc_uri_item = proto_tree_add_string(tree, hf_gsm_a_geo_loc_osm_uri, tvb, loc_offset, 6, osm_uri);
|
|
PROTO_ITEM_SET_URL(loc_uri_item);
|
|
PROTO_ITEM_SET_GENERATED(loc_uri_item);
|
|
|
|
break;
|
|
case POLYGON: /* Polygon */
|
|
/* Number of points */
|
|
proto_tree_add_item(tree, hf_gsm_a_geo_loc_no_of_points, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
#if 0
|
|
no_of_points = tvb_get_guint8(tvb,offset)&0x0f;
|
|
while ( no_of_points > 0) {
|
|
offset++;
|
|
|
|
no_of_points--;
|
|
}
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/* TS 23.032
|
|
* Ch. 8 Description of Velocity
|
|
*/
|
|
/* 8.6 Coding of Velocity Type */
|
|
static const value_string gsm_a_velocity_type_vals[] = {
|
|
{ 0, "Horizontal Velocity"},
|
|
{ 1, "Horizontal with Vertical Velocity"},
|
|
{ 2, "Horizontal Velocity with Uncertainty"},
|
|
{ 3, "Horizontal with Vertical Velocity and Uncertainty"},
|
|
{ 4, "reserved for future use"},
|
|
{ 5, "reserved for future use"},
|
|
{ 6, "reserved for future use"},
|
|
{ 7, "reserved for future use"},
|
|
{ 8, "reserved for future use"},
|
|
{ 9, "reserved for future use"},
|
|
{ 10, "reserved for future use"},
|
|
{ 11, "reserved for future use"},
|
|
{ 12, "reserved for future use"},
|
|
{ 13, "reserved for future use"},
|
|
{ 14, "reserved for future use"},
|
|
{ 15, "reserved for future use"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const true_false_string gsm_a_dir_of_ver_speed_vals = {
|
|
"Downward",
|
|
"Upward"
|
|
};
|
|
|
|
guint16
|
|
dissect_description_of_velocity(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 *velocity_item;
|
|
guint32 curr_offset;
|
|
guint8 velocity_type, uncertainty_speed = 0;
|
|
|
|
curr_offset = offset;
|
|
|
|
/* Bit 8 - 5 Velocity Type */
|
|
velocity_type = tvb_get_guint8(tvb,curr_offset);
|
|
proto_tree_add_item(tree, hf_gsm_a_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
switch (velocity_type) {
|
|
case 0:
|
|
/* 8.12 Coding of Horizontal Velocity */
|
|
/* Spare bits */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 3, ENC_BIG_ENDIAN);
|
|
/* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
|
|
curr_offset += 2;
|
|
/* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
curr_offset += 2;
|
|
break;
|
|
case 1:
|
|
/* 8.13 Coding of Horizontal with Vertical Velocity */
|
|
/* Spare bits */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 2, ENC_BIG_ENDIAN);
|
|
/* D: Direction of Vertical Speed */
|
|
proto_tree_add_item(tree, hf_gsm_a_d, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
/* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
|
|
curr_offset += 2;
|
|
/* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
curr_offset += 2;
|
|
/* Vertical Speed Octet 5
|
|
* Vertical speed is encoded in increments of 1 kilometre per hour using 8 bits giving a number N between 0 and 28-1.
|
|
*/
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_vertical_speed, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
curr_offset++;
|
|
break;
|
|
case 2:
|
|
/* 8.14 Coding of Horizontal Velocity with Uncertainty */
|
|
/* Spare bits */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 3, ENC_BIG_ENDIAN);
|
|
/* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
|
|
curr_offset += 2;
|
|
/* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
curr_offset += 2;
|
|
/* Uncertainty Speed Octet 5
|
|
* Uncertainty speed is encoded in increments of 1 kilometre per hour using an 8 bit binary coded number N. The value of
|
|
* N gives the uncertainty speed except for N=255 which indicates that the uncertainty is not specified.
|
|
*/
|
|
uncertainty_speed = tvb_get_guint8(tvb,curr_offset);
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_uncertainty_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
if (uncertainty_speed == 255) {
|
|
proto_item_append_text(velocity_item, " not specified");
|
|
}else{
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
}
|
|
offset++;
|
|
break;
|
|
case 3:
|
|
/* 8.15 Coding of Horizontal with Vertical Velocity and Uncertainty */
|
|
/* Spare bits */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 2, ENC_BIG_ENDIAN);
|
|
/* D: Direction of Vertical Speed */
|
|
proto_tree_add_item(tree, hf_gsm_a_d, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
/* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
|
|
curr_offset += 2;
|
|
/* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
curr_offset += 2;
|
|
/* Vertical Speed Octet 5
|
|
* Vertical speed is encoded in increments of 1 kilometre per hour using 8 bits giving a number N between 0 and 28-1.
|
|
*/
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_vertical_speed, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
curr_offset++;
|
|
|
|
/* Horizontal Uncertainty Speed Octet 6 */
|
|
uncertainty_speed = tvb_get_guint8(tvb,curr_offset);
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_h_uncertainty_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
if (uncertainty_speed == 255) {
|
|
proto_item_append_text(velocity_item, " not specified");
|
|
}else{
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
}
|
|
offset++;
|
|
|
|
/* Vertical Uncertainty Speed Octet 7 */
|
|
uncertainty_speed = tvb_get_guint8(tvb,curr_offset);
|
|
velocity_item = proto_tree_add_item(tree, hf_gsm_a_v_uncertainty_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
if (uncertainty_speed == 255) {
|
|
proto_item_append_text(velocity_item, " not specified");
|
|
}else{
|
|
proto_item_append_text(velocity_item, " km/h");
|
|
}
|
|
offset++;
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
const char* get_gsm_a_msg_string(int pdu_type, int idx)
|
|
{
|
|
const char *msg_string = NULL;
|
|
|
|
switch (pdu_type) {
|
|
case GSM_A_PDU_TYPE_BSSMAP:
|
|
msg_string = val_to_str_ext(idx, &gsm_bssmap_elem_strings_ext, "GSM_A_PDU_TYPE_BSSMAP (%u)");
|
|
break;
|
|
case GSM_A_PDU_TYPE_DTAP:
|
|
msg_string = val_to_str_ext(idx, &gsm_dtap_elem_strings_ext, "GSM_A_PDU_TYPE_DTAP (%u)");
|
|
break;
|
|
case GSM_A_PDU_TYPE_RP:
|
|
msg_string = val_to_str_ext(idx, &gsm_rp_elem_strings_ext, "GSM_A_PDU_TYPE_RP (%u)");
|
|
break;
|
|
case GSM_A_PDU_TYPE_RR:
|
|
msg_string = val_to_str_ext(idx, &gsm_rr_elem_strings_ext, "GSM_A_PDU_TYPE_RR (%u)");
|
|
break;
|
|
case GSM_A_PDU_TYPE_COMMON:
|
|
msg_string = val_to_str_ext(idx, &gsm_common_elem_strings_ext, "GSM_A_PDU_TYPE_COMMON (%u)");
|
|
break;
|
|
case GSM_A_PDU_TYPE_GM:
|
|
msg_string = val_to_str_ext(idx, &gsm_gm_elem_strings_ext, "GSM_A_PDU_TYPE_GM (%u)");
|
|
break;
|
|
case GSM_A_PDU_TYPE_BSSLAP:
|
|
msg_string = val_to_str_ext(idx, &gsm_bsslap_elem_strings_ext, "GSM_A_PDU_TYPE_BSSLAP (%u)");
|
|
break;
|
|
case GSM_PDU_TYPE_BSSMAP_LE:
|
|
msg_string = val_to_str_ext(idx, &gsm_bssmap_le_elem_strings_ext, "GSM_PDU_TYPE_BSSMAP_LE (%u)");
|
|
break;
|
|
case NAS_PDU_TYPE_COMMON:
|
|
msg_string = val_to_str_ext(idx, &nas_eps_common_elem_strings_ext, "NAS_PDU_TYPE_COMMON (%u)");
|
|
break;
|
|
case NAS_PDU_TYPE_EMM:
|
|
msg_string = val_to_str_ext(idx, &nas_emm_elem_strings_ext, "NAS_PDU_TYPE_EMM (%u)");
|
|
break;
|
|
case NAS_PDU_TYPE_ESM:
|
|
msg_string = val_to_str_ext(idx, &nas_esm_elem_strings_ext, "NAS_PDU_TYPE_ESM (%u)");
|
|
break;
|
|
case SGSAP_PDU_TYPE:
|
|
msg_string = val_to_str_ext(idx, &sgsap_elem_strings_ext, "SGSAP_PDU_TYPE (%u)");
|
|
break;
|
|
case BSSGP_PDU_TYPE:
|
|
msg_string = val_to_str_ext(idx, &bssgp_elem_strings_ext, "BSSGP_PDU_TYPE (%u)");
|
|
break;
|
|
case GMR1_IE_COMMON:
|
|
msg_string = val_to_str_ext(idx, &gmr1_ie_common_strings_ext, "GMR1_IE_COMMON (%u)");
|
|
break;
|
|
case GMR1_IE_RR:
|
|
msg_string = val_to_str_ext(idx, &gmr1_ie_rr_strings_ext, "GMR1_IE_RR (%u)");
|
|
break;
|
|
default:
|
|
DISSECTOR_ASSERT_NOT_REACHED();
|
|
}
|
|
|
|
return msg_string;
|
|
}
|
|
|
|
static int get_hf_elem_id(int pdu_type)
|
|
{
|
|
int hf_elem_id = 0;
|
|
|
|
switch (pdu_type) {
|
|
case GSM_A_PDU_TYPE_BSSMAP:
|
|
hf_elem_id = hf_gsm_a_bssmap_elem_id;
|
|
break;
|
|
case GSM_A_PDU_TYPE_DTAP:
|
|
hf_elem_id = hf_gsm_a_dtap_elem_id;
|
|
break;
|
|
case GSM_A_PDU_TYPE_RP:
|
|
hf_elem_id = hf_gsm_a_rp_elem_id;
|
|
break;
|
|
case GSM_A_PDU_TYPE_RR:
|
|
hf_elem_id = hf_gsm_a_rr_elem_id;
|
|
break;
|
|
case GSM_A_PDU_TYPE_COMMON:
|
|
hf_elem_id = hf_gsm_a_common_elem_id;
|
|
break;
|
|
case GSM_A_PDU_TYPE_GM:
|
|
hf_elem_id = hf_gsm_a_gm_elem_id;
|
|
break;
|
|
case GSM_A_PDU_TYPE_BSSLAP:
|
|
hf_elem_id = hf_gsm_a_bsslap_elem_id;
|
|
break;
|
|
case GSM_PDU_TYPE_BSSMAP_LE:
|
|
hf_elem_id = hf_gsm_bssmap_le_elem_id;
|
|
break;
|
|
case NAS_PDU_TYPE_COMMON:
|
|
hf_elem_id = hf_nas_eps_common_elem_id;
|
|
break;
|
|
case NAS_PDU_TYPE_EMM:
|
|
hf_elem_id = hf_nas_eps_emm_elem_id;
|
|
break;
|
|
case NAS_PDU_TYPE_ESM:
|
|
hf_elem_id = hf_nas_eps_esm_elem_id;
|
|
break;
|
|
case SGSAP_PDU_TYPE:
|
|
hf_elem_id = hf_sgsap_elem_id;
|
|
break;
|
|
case BSSGP_PDU_TYPE:
|
|
hf_elem_id = hf_bssgp_elem_id;
|
|
break;
|
|
case GMR1_IE_COMMON:
|
|
case GMR1_IE_RR:
|
|
hf_elem_id = hf_gmr1_elem_id;
|
|
break;
|
|
default:
|
|
DISSECTOR_ASSERT_NOT_REACHED();
|
|
}
|
|
|
|
return hf_elem_id;
|
|
}
|
|
|
|
/*
|
|
* Type Length Value (TLV) element dissector
|
|
*/
|
|
guint16 elem_tlv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
|
|
{
|
|
guint8 oct;
|
|
guint16 parm_len;
|
|
guint8 lengt_length = 1;
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
oct = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
if (oct == iei) {
|
|
parm_len = tvb_get_guint8(tvb, curr_offset + 1);
|
|
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, parm_len + 1 + lengt_length,
|
|
"Unknown - aborting dissection%s", (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, parm_len + 1 + lengt_length, elem_ett[idx], &item,
|
|
"%s%s", elem_name, (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
get_hf_elem_id(pdu_type), tvb,
|
|
curr_offset, 1, oct);
|
|
|
|
proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
|
|
curr_offset + 1, lengt_length, parm_len);
|
|
|
|
if (parm_len > 0)
|
|
{
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
proto_tree_add_item(subtree, hf_gsm_a_element_value, tvb, curr_offset + 1 + lengt_length, parm_len, ENC_NA);
|
|
/* See ASSERT above */
|
|
consumed = (guint8)parm_len;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
a_add_string = (gchar *)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed =
|
|
(*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 2,
|
|
parm_len, a_add_string, 1024);
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
}
|
|
}
|
|
|
|
consumed += 1 + lengt_length;
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
/*
|
|
* Type Extendable Length Value (TELV) element dissector
|
|
* This is a version where the length field can be one or two octets depending
|
|
* if the extension bit is set or not (TS 48.016 p 10.1.2).
|
|
* 8 7 6 5 4 3 2 1
|
|
* octet 2 0/1 ext length
|
|
* octet 2a length
|
|
*/
|
|
guint16 elem_telv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
|
|
{
|
|
guint8 oct;
|
|
guint16 parm_len;
|
|
guint8 lengt_length = 1;
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
oct = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
if (oct == iei) {
|
|
parm_len = tvb_get_guint8(tvb, curr_offset + 1);
|
|
if ((parm_len&0x80) == 0) {
|
|
/* length in 2 octets */
|
|
parm_len = tvb_get_ntohs(tvb, curr_offset + 1);
|
|
lengt_length = 2;
|
|
}else{
|
|
parm_len = parm_len & 0x7f;
|
|
}
|
|
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, parm_len + 1 + lengt_length,
|
|
"Unknown - aborting dissection%s", (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, parm_len + 1 + lengt_length, elem_ett[idx], &item,
|
|
"%s%s", elem_name, (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
get_hf_elem_id(pdu_type), tvb,
|
|
curr_offset, 1, oct);
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_l_ext, tvb, curr_offset+1, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
|
|
curr_offset + 1, lengt_length, parm_len);
|
|
|
|
if (parm_len > 0)
|
|
{
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
proto_tree_add_item(subtree, hf_gsm_a_element_value, tvb, curr_offset + 1 + lengt_length, parm_len, ENC_NA);
|
|
/* See ASSERT above */
|
|
consumed = parm_len;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed =
|
|
(*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1 + lengt_length,
|
|
parm_len, a_add_string, 1024);
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
}
|
|
}
|
|
|
|
consumed += 1 + lengt_length;
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
/*
|
|
* Type Length Value Extended(TLV-E) element dissector
|
|
* TS 24.007
|
|
* information elements of format LV-E or TLV-E with value part consisting of zero,
|
|
* one or more octets and a maximum of 65535 octets (type 6). This category is used in EPS only.
|
|
*/
|
|
guint16 elem_tlv_e(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
|
|
{
|
|
guint8 oct;
|
|
guint16 parm_len;
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
oct = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
if (oct == iei) {
|
|
parm_len = tvb_get_ntohs(tvb, curr_offset + 1);
|
|
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, parm_len + 1 + 2,
|
|
"Unknown - aborting dissection%s", (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, parm_len + 1 + 2, elem_ett[idx], &item,
|
|
"%s%s", elem_name, (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
get_hf_elem_id(pdu_type), tvb,
|
|
curr_offset, 1, oct);
|
|
|
|
proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
|
|
curr_offset + 1, 2, parm_len);
|
|
|
|
if (parm_len > 0)
|
|
{
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
proto_tree_add_item(subtree, hf_gsm_a_element_value, tvb, curr_offset + 1 + 2, parm_len, ENC_NA);
|
|
/* See ASSERT above */
|
|
consumed = parm_len;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed =
|
|
(*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1 + 2,
|
|
parm_len, a_add_string, 1024);
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
}
|
|
}
|
|
|
|
consumed += 1 + 2;
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
/*
|
|
* Type Value (TV) element dissector
|
|
*
|
|
* Length cannot be used in these functions, big problem if a element dissector
|
|
* is not defined for these.
|
|
*/
|
|
guint16 elem_tv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
|
|
{
|
|
guint8 oct;
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
oct = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
if (oct == iei)
|
|
{
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, -1,
|
|
"Unknown - aborting dissection%s", (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, -1, elem_ett[idx], &item,
|
|
"%s%s", elem_name, (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
proto_tree_add_uint(subtree,
|
|
get_hf_elem_id(pdu_type), tvb,
|
|
curr_offset, 1, oct);
|
|
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
/* BAD THING, CANNOT DETERMINE LENGTH */
|
|
expert_add_info(pinfo, item, &ei_gsm_a_no_element_dissector);
|
|
|
|
consumed = 1;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed = (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1, -1, a_add_string, 1024);
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
}
|
|
|
|
consumed++;
|
|
|
|
proto_item_set_len(item, consumed);
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
/*
|
|
* Type Value (TV) element dissector
|
|
* Where top half nibble is IEI and bottom half nibble is value.
|
|
*
|
|
* Length cannot be used in these functions, big problem if a element dissector
|
|
* is not defined for these.
|
|
*/
|
|
guint16 elem_tv_short(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
|
|
{
|
|
guint8 oct;
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
oct = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
if ((oct & 0xf0) == (iei & 0xf0))
|
|
{
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, -1,
|
|
"Unknown - aborting dissection%s", (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, -1, elem_ett[idx], &item,
|
|
"%s%s", elem_name, (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
proto_tree_add_uint_format_value(subtree, hf_gsm_a_common_elem_id_f0, tvb, curr_offset, 1, oct, "0x%1x-", oct>>4);
|
|
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
/* BAD THING, CANNOT DETERMINE LENGTH */
|
|
|
|
expert_add_info(pinfo, item, &ei_gsm_a_no_element_dissector);
|
|
|
|
consumed++;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed = (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset, RIGHT_NIBBLE, a_add_string, 1024);
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
}
|
|
|
|
proto_item_set_len(item, consumed);
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
/*
|
|
* Type (T) element dissector
|
|
*/
|
|
guint16 elem_t(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
|
|
{
|
|
guint8 oct;
|
|
guint32 curr_offset;
|
|
guint16 consumed;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
(void)elem_ett;
|
|
(void)elem_funcs;
|
|
|
|
oct = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
if (oct == iei)
|
|
{
|
|
proto_tree_add_uint_format(tree,
|
|
get_hf_elem_id(pdu_type), tvb,
|
|
curr_offset, 1, oct,
|
|
"%s%s",
|
|
val_to_str_ext(idx, &elem_names_ext, "Unknown (%u)"),
|
|
(name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
consumed = 1;
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
/*
|
|
* Length Value (LV) element dissector
|
|
*/
|
|
guint16
|
|
elem_lv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
|
|
{
|
|
guint8 parm_len;
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
parm_len = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, parm_len + 1,
|
|
"Unknown - aborting dissection%s", (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, parm_len + 1, elem_ett[idx], &item,
|
|
"%s%s", elem_name, (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
|
|
curr_offset, 1, parm_len);
|
|
|
|
if (parm_len > 0)
|
|
{
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
proto_tree_add_item(subtree, hf_gsm_a_element_value, tvb, curr_offset + 1, parm_len, ENC_NA);
|
|
|
|
consumed = parm_len;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed =
|
|
(*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1,
|
|
parm_len, a_add_string, 1024);
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (consumed + 1);
|
|
}
|
|
|
|
/*
|
|
* Length Value Extended(LV-E) element dissector
|
|
*/
|
|
guint16 elem_lv_e(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
|
|
{
|
|
guint16 parm_len;
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
parm_len = tvb_get_ntohs(tvb, curr_offset);
|
|
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, parm_len + 2,
|
|
"Unknown - aborting dissection%s", (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, parm_len + 2, elem_ett[idx], &item,
|
|
"%s%s", elem_name, (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
|
|
curr_offset, 2, parm_len);
|
|
|
|
if (parm_len > 0)
|
|
{
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
proto_tree_add_item(subtree, hf_gsm_a_element_value, tvb, curr_offset + 2, parm_len, ENC_NA);
|
|
|
|
consumed = parm_len;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed =
|
|
(*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 2,
|
|
parm_len, a_add_string, 1024);
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (consumed + 2);
|
|
}
|
|
/*
|
|
* Value (V) element dissector
|
|
*
|
|
* Length cannot be used in these functions, big problem if a element dissector
|
|
* is not defined for these.
|
|
*/
|
|
guint16 elem_v(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
|
|
{
|
|
guint16 consumed;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
const gchar *elem_name;
|
|
elem_func_hander elem_funcs;
|
|
|
|
curr_offset = offset;
|
|
consumed = 0;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
if (elem_name == NULL || elem_funcs[idx] == NULL)
|
|
{
|
|
/* BAD THING, CANNOT DETERMINE LENGTH */
|
|
proto_tree_add_expert(tree, pinfo, &ei_gsm_a_no_element_dissector, tvb, curr_offset, 1);
|
|
|
|
consumed = 1;
|
|
}
|
|
else
|
|
{
|
|
gchar *a_add_string;
|
|
|
|
subtree =
|
|
proto_tree_add_subtree_format(tree,
|
|
tvb, curr_offset, 0,
|
|
elem_ett[idx], &item, "%s%s", elem_name,
|
|
(name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
|
|
|
|
a_add_string= (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
consumed = (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset, -1, a_add_string, 1024);
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
proto_item_set_len(item, consumed);
|
|
}
|
|
|
|
return (consumed);
|
|
}
|
|
|
|
/*
|
|
* Short Value (V_SHORT) element dissector
|
|
*
|
|
* nibble is used in this function to indicate right or left nibble of the octet
|
|
* This is expected to be used right nibble first, as the tables of 24.008.
|
|
*/
|
|
|
|
guint16 elem_v_short(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, guint32 nibble)
|
|
{
|
|
guint16 consumed = 1;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
value_string_ext elem_names_ext;
|
|
gint *elem_ett;
|
|
elem_fcn *elem_funcs;
|
|
gchar *a_add_string;
|
|
const gchar *elem_name;
|
|
|
|
curr_offset = offset;
|
|
|
|
SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs, &ei_gsm_a_unknown_pdu_type);
|
|
|
|
elem_name = try_val_to_str_ext(idx, &elem_names_ext);
|
|
|
|
/* idx is out of range */
|
|
if (elem_name == NULL) {
|
|
proto_tree_add_expert(tree, pinfo, &ei_gsm_a_unknown_element,
|
|
tvb, curr_offset, 0);
|
|
return consumed;
|
|
}
|
|
|
|
subtree = proto_tree_add_subtree(tree, tvb, curr_offset, 0, elem_ett[idx], &item, elem_name);
|
|
|
|
a_add_string= (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
|
|
a_add_string[0] = '\0';
|
|
|
|
if (elem_funcs[idx] == NULL)
|
|
{
|
|
/* NOT NECESSARILY A BAD THING - LENGTH IS HALF OCTET */
|
|
(void)de_spare_nibble(tvb, subtree, pinfo, curr_offset, nibble, a_add_string, 1024);
|
|
}
|
|
else
|
|
{
|
|
(void)(*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset, nibble, a_add_string, 1024);
|
|
}
|
|
|
|
if (a_add_string[0] != '\0')
|
|
{
|
|
proto_item_append_text(item, "%s", a_add_string);
|
|
}
|
|
proto_item_set_len(item, consumed);
|
|
|
|
return consumed;
|
|
}
|
|
|
|
|
|
static dgt_set_t Dgt_tbcd = {
|
|
{
|
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
'0','1','2','3','4','5','6','7','8','9','?','B','C','*','#','?'
|
|
}
|
|
};
|
|
|
|
static dgt_set_t Dgt1_9_bcd = {
|
|
{
|
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
'0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
|
|
}
|
|
};
|
|
|
|
/* FUNCTIONS */
|
|
|
|
/*
|
|
* Decode the MCC/MNC from 3 octets in 'octs'
|
|
*/
|
|
static void
|
|
mcc_mnc_aux(guint8 *octs, gchar *mcc, gchar *mnc)
|
|
{
|
|
if ((octs[0] & 0x0f) <= 9)
|
|
{
|
|
mcc[0] = Dgt_tbcd.out[octs[0] & 0x0f];
|
|
}
|
|
else
|
|
{
|
|
mcc[0] = (octs[0] & 0x0f) + 55;
|
|
}
|
|
|
|
if (((octs[0] & 0xf0) >> 4) <= 9)
|
|
{
|
|
mcc[1] = Dgt_tbcd.out[(octs[0] & 0xf0) >> 4];
|
|
}
|
|
else
|
|
{
|
|
mcc[1] = ((octs[0] & 0xf0) >> 4) + 55;
|
|
}
|
|
|
|
if ((octs[1] & 0x0f) <= 9)
|
|
{
|
|
mcc[2] = Dgt_tbcd.out[octs[1] & 0x0f];
|
|
}
|
|
else
|
|
{
|
|
mcc[2] = (octs[1] & 0x0f) + 55;
|
|
}
|
|
|
|
mcc[3] = '\0';
|
|
|
|
if (((octs[1] & 0xf0) >> 4) <= 9)
|
|
{
|
|
mnc[2] = Dgt_tbcd.out[(octs[1] & 0xf0) >> 4];
|
|
}
|
|
else
|
|
{
|
|
mnc[2] = ((octs[1] & 0xf0) >> 4) + 55;
|
|
}
|
|
|
|
if ((octs[2] & 0x0f) <= 9)
|
|
{
|
|
mnc[0] = Dgt_tbcd.out[octs[2] & 0x0f];
|
|
}
|
|
else
|
|
{
|
|
mnc[0] = (octs[2] & 0x0f) + 55;
|
|
}
|
|
|
|
if (((octs[2] & 0xf0) >> 4) <= 9)
|
|
{
|
|
mnc[1] = Dgt_tbcd.out[(octs[2] & 0xf0) >> 4];
|
|
}
|
|
else
|
|
{
|
|
mnc[1] = ((octs[2] & 0xf0) >> 4) + 55;
|
|
}
|
|
|
|
if (mnc[1] == 'F')
|
|
{
|
|
/*
|
|
* only a 1 digit MNC (very old)
|
|
*/
|
|
mnc[1] = '\0';
|
|
}
|
|
else if (mnc[2] == 'F')
|
|
{
|
|
/*
|
|
* only a 2 digit MNC
|
|
*/
|
|
mnc[2] = '\0';
|
|
}
|
|
else
|
|
{
|
|
mnc[3] = '\0';
|
|
}
|
|
}
|
|
|
|
/* 3GPP TS 24.008
|
|
* [3] 10.5.1.1 Cell Identity
|
|
*/
|
|
guint16
|
|
de_cell_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string, int string_len)
|
|
{
|
|
guint32 curr_offset;
|
|
|
|
curr_offset = offset;
|
|
|
|
curr_offset +=
|
|
/* 0x02 CI */
|
|
be_cell_id_aux(tvb, tree, pinfo, offset, len, add_string, string_len, 0x02);
|
|
|
|
/* no length check possible */
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
/*
|
|
* 10.5.1.2 Ciphering Key Sequence Number
|
|
*/
|
|
|
|
|
|
/*
|
|
* Key sequence (octet 1)
|
|
* Bits
|
|
* 3 2 1
|
|
* 0 0 0
|
|
* through
|
|
* 1 1 0
|
|
* Possible values for the ciphering key sequence number
|
|
* 1 1 1 No key is available (MS to network);Reserved (network to MS)
|
|
*/
|
|
|
|
static const value_string gsm_a_key_seq_vals[] = {
|
|
{ 0, "Ciphering key sequence number"},
|
|
{ 1, "Ciphering key sequence number"},
|
|
{ 2, "Ciphering key sequence number"},
|
|
{ 3, "Ciphering key sequence number"},
|
|
{ 4, "Ciphering key sequence number"},
|
|
{ 5, "Ciphering key sequence number"},
|
|
{ 6, "Ciphering key sequence number"},
|
|
{ 7, "No key is available (MS to network)"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static guint16
|
|
de_ciph_key_seq_num( tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint32 curr_offset, bit_offset;
|
|
|
|
curr_offset = offset;
|
|
|
|
if (RIGHT_NIBBLE == len)
|
|
bit_offset = 4;
|
|
else
|
|
bit_offset = 0;
|
|
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+bit_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_key_seq, tvb, (curr_offset<<3)+bit_offset+1, 3, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
|
|
/*
|
|
* [3] 10.5.1.3
|
|
*/
|
|
|
|
guint16
|
|
de_lai(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint8 octs[3];
|
|
guint16 value;
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
gchar mcc[4];
|
|
gchar mnc[4];
|
|
|
|
curr_offset = offset;
|
|
|
|
subtree = proto_tree_add_subtree(tree,
|
|
tvb, curr_offset, 5, ett_gsm_common_elem[DE_LAI], &item,
|
|
val_to_str_ext_const(DE_LAI, &gsm_common_elem_strings_ext, ""));
|
|
|
|
octs[0] = tvb_get_guint8(tvb, curr_offset);
|
|
octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
|
|
octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
|
|
|
|
mcc_mnc_aux(octs, mcc, mnc);
|
|
|
|
curr_offset = dissect_e212_mcc_mnc(tvb, pinfo, subtree, curr_offset, E212_LAI, TRUE);
|
|
|
|
value = tvb_get_ntohs(tvb, curr_offset);
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_lac, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
|
|
|
|
proto_item_append_text(item, " - %s/%s/%u", mcc,mnc,value);
|
|
|
|
curr_offset += 2;
|
|
|
|
/* no length check possible */
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.4 Mobile Identity
|
|
* 3GPP TS 24.008 version 7.8.0 Release 7
|
|
*/
|
|
static const true_false_string gsm_a_present_vals = {
|
|
"Present" ,
|
|
"Not present"
|
|
};
|
|
|
|
guint16
|
|
de_mid(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len)
|
|
{
|
|
guint8 oct;
|
|
guint32 curr_offset;
|
|
guint32 value;
|
|
gboolean odd;
|
|
const gchar *digit_str;
|
|
proto_item* ti;
|
|
|
|
curr_offset = offset;
|
|
|
|
oct = tvb_get_guint8(tvb, curr_offset);
|
|
|
|
switch (oct & 0x07)
|
|
{
|
|
case 0: /* No Identity */
|
|
proto_tree_add_item(tree, hf_gsm_a_unused, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
if (add_string)
|
|
g_snprintf(add_string, string_len, " - No Identity Code");
|
|
|
|
curr_offset++;
|
|
|
|
if (len > 1)
|
|
{
|
|
expert_add_info(pinfo, tree, &ei_gsm_a_format_not_supported);
|
|
}
|
|
|
|
curr_offset += len - 1;
|
|
break;
|
|
|
|
case 3: /* IMEISV */
|
|
/* FALLTHRU */
|
|
|
|
case 1: /* IMSI */
|
|
odd = oct & 0x08;
|
|
proto_tree_add_item(tree, hf_gsm_a_id_dig_1, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
if (curr_offset - offset >= len) /* Sanity check */
|
|
return (curr_offset - offset);
|
|
|
|
if((oct & 0x07) == 3){
|
|
/* imeisv */
|
|
digit_str = tvb_bcd_dig_to_wmem_packet_str(tvb ,curr_offset , len - (curr_offset - offset), NULL, TRUE);
|
|
proto_tree_add_string_format(tree,
|
|
hf_gsm_a_imeisv,
|
|
tvb, curr_offset, len - (curr_offset - offset),
|
|
digit_str,
|
|
"BCD Digits: %s",
|
|
digit_str);
|
|
}else{
|
|
digit_str = dissect_e212_imsi(tvb, pinfo, tree, curr_offset, len - (curr_offset - offset), TRUE);
|
|
}
|
|
|
|
if (sccp_assoc && ! sccp_assoc->calling_party) {
|
|
sccp_assoc->calling_party = wmem_strdup_printf(wmem_file_scope(),
|
|
((oct & 0x07) == 3) ? "IMEISV: %s" : "IMSI: %s",
|
|
digit_str );
|
|
}
|
|
|
|
if (add_string)
|
|
g_snprintf(add_string, string_len, " - %s (%s)",
|
|
((oct & 0x07) == 3) ? "IMEISV" : "IMSI",
|
|
digit_str);
|
|
|
|
curr_offset += len - (curr_offset - offset);
|
|
|
|
if (!odd)
|
|
{
|
|
proto_tree_add_item(tree, hf_gsm_a_filler, tvb, curr_offset - 1, 1, ENC_NA);
|
|
}
|
|
break;
|
|
|
|
case 2: /* IMEI */
|
|
proto_tree_add_uint_format_value(tree, hf_gsm_a_identity_digit1, tvb, curr_offset, 1, oct, "%c", Dgt1_9_bcd.out[(oct & 0xf0) >> 4]);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
if (curr_offset - offset >= len) /* Sanity check */
|
|
return (curr_offset - offset);
|
|
|
|
digit_str = tvb_bcd_dig_to_wmem_packet_str(tvb, curr_offset, len - (curr_offset - offset), NULL, TRUE);
|
|
|
|
proto_tree_add_string_format(tree,
|
|
hf_gsm_a_imei,
|
|
tvb, curr_offset, len - (curr_offset - offset),
|
|
digit_str,
|
|
"BCD Digits: %s",
|
|
digit_str);
|
|
|
|
if (add_string)
|
|
g_snprintf(add_string, string_len, " - IMEI (%s)", digit_str);
|
|
|
|
curr_offset += len - (curr_offset - offset);
|
|
break;
|
|
|
|
case 4: /* TMSI/P-TMSI/M-TMSI */
|
|
proto_tree_add_item(tree, hf_gsm_a_unused, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
value = tvb_get_ntohl(tvb, curr_offset);
|
|
|
|
proto_tree_add_uint(tree, hf_gsm_a_tmsi,
|
|
tvb, curr_offset, 4,
|
|
value);
|
|
|
|
if (add_string)
|
|
g_snprintf(add_string, string_len, " - TMSI/P-TMSI (0x%04x)", value);
|
|
|
|
curr_offset += 4;
|
|
break;
|
|
|
|
case 5: /* TMGI and optional MBMS Session Identity */
|
|
/* Spare bits (octet 3) Bits 8-7 */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset<<3, 2, ENC_BIG_ENDIAN);
|
|
/* MBMS Session Identity indication (octet 3) Bit 6 */
|
|
proto_tree_add_item(tree, hf_gsm_a_mbs_ses_id_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* MCC/MNC indication (octet 3) Bit 5 */
|
|
proto_tree_add_item(tree, hf_gsm_a_tmgi_mcc_mnc_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* Odd/even indication (octet 3) Bit 4 */
|
|
proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* Type of identity (octet 3) Bits 3-1 */
|
|
proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
/* MBMS Service ID (octet 4, 5 and 6) */
|
|
proto_tree_add_item(tree, hf_gsm_a_mbs_service_id, tvb, curr_offset, 3, ENC_BIG_ENDIAN);
|
|
curr_offset += 3;
|
|
if ((oct&0x10) == 0x10) {
|
|
/* MCC/MNC*/
|
|
/* MCC, Mobile country code (octet 6a, octet 6b bits 1 to 4)*/
|
|
/* MNC, Mobile network code (octet 6b bits 5 to 8, octet 6c) */
|
|
curr_offset = dissect_e212_mcc_mnc(tvb, pinfo, tree, curr_offset, E212_NONE, TRUE);
|
|
}
|
|
if ((oct&0x20) == 0x20) {
|
|
/* MBMS Session Identity (octet 7)
|
|
* The MBMS Session Identity field is encoded as the value part
|
|
* of the MBMS Session Identity IE as specified in 3GPP TS 48.018 [86].
|
|
*/
|
|
proto_tree_add_item(tree, hf_gsm_a_mbs_session_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
}
|
|
break;
|
|
|
|
default: /* Reserved */
|
|
proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
ti = proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
expert_add_info_format(pinfo, ti, &ei_gsm_a_mobile_identity_type, "Unknown format %u", (oct & 0x07));
|
|
|
|
if (add_string)
|
|
g_snprintf(add_string, string_len, " - Format Unknown");
|
|
|
|
curr_offset += len;
|
|
break;
|
|
}
|
|
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.5
|
|
*/
|
|
guint16
|
|
de_ms_cm_1(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
|
|
curr_offset = offset;
|
|
|
|
subtree =
|
|
proto_tree_add_subtree(tree,
|
|
tvb, curr_offset, 1, ett_gsm_common_elem[DE_MS_CM_1], NULL,
|
|
val_to_str_ext_const(DE_MS_CM_1, &gsm_common_elem_strings_ext, ""));
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_MSC_rev, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_ES_IND, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_A5_1_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_RF_power_capability, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
curr_offset++;
|
|
|
|
/* no length check possible */
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.6 Mobile Station Classmark 2
|
|
* 3GPP TS 24.008 version 7.8.0 Release 7
|
|
*/
|
|
guint16
|
|
de_ms_cm_2(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_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_MSC_rev, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_ES_IND, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_A5_1_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_RF_power_capability, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
curr_offset++;
|
|
|
|
NO_MORE_DATA_CHECK(len);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_ps_sup_cap, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_SS_screening_indicator, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
/* SM capability (MT SMS pt to pt capability) (octet 4)*/
|
|
proto_tree_add_item(tree, hf_gsm_a_SM_capability, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* VBS notification reception (octet 4) */
|
|
proto_tree_add_item(tree, hf_gsm_a_VBS_notification_rec, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/*VGCS notification reception (octet 4)*/
|
|
proto_tree_add_item(tree, hf_gsm_a_VGCS_notification_rec, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* FC Frequency Capability (octet 4 ) */
|
|
proto_tree_add_item(tree, hf_gsm_a_FC_frequency_cap, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
curr_offset++;
|
|
|
|
NO_MORE_DATA_CHECK(len);
|
|
|
|
/* CM3 (octet 5, bit 8) */
|
|
proto_tree_add_item(tree, hf_gsm_a_CM3, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* spare bit 7 */
|
|
proto_tree_add_item(tree, hf_gsm_a_b7spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* LCS VA capability (LCS value added location request notification capability) (octet 5,bit 6) */
|
|
proto_tree_add_item(tree, hf_gsm_a_LCS_VA_cap, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* UCS2 treatment (octet 5, bit 5) */
|
|
proto_tree_add_item(tree, hf_gsm_a_UCS2_treatment, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* SoLSA (octet 5, bit 4) */
|
|
proto_tree_add_item(tree, hf_gsm_a_SoLSA, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* CMSP: CM Service Prompt (octet 5, bit 3) */
|
|
proto_tree_add_item(tree, hf_gsm_a_CMSP, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* A5/3 algorithm supported (octet 5, bit 2) */
|
|
proto_tree_add_item(tree, hf_gsm_a_A5_3_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
/* A5/2 algorithm supported (octet 5, bit 1) */
|
|
proto_tree_add_item(tree, hf_gsm_a_A5_2_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
curr_offset++;
|
|
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.7 Mobile Station Classmark 3
|
|
* 3GPP TS 24.008 version 12.10.0 Release 12
|
|
*/
|
|
#define AVAILABLE_BITS_CHECK(n) \
|
|
bits_left = ((len + offset) << 3) - bit_offset; \
|
|
if (bits_left < (n)) { \
|
|
if (bits_left) \
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, bits_left, ENC_BIG_ENDIAN); \
|
|
return len; \
|
|
}
|
|
|
|
guint16
|
|
de_ms_cm_3(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 bit_offset; /* Offset in bits */
|
|
guint8 length;
|
|
proto_tree *subtree;
|
|
proto_item *item;
|
|
guint32 bits_left, target_bit_offset, old_bit_offset;
|
|
guint64 multi_bnd_sup_fields, rsupport, multislotCapability;
|
|
guint64 msMeasurementCapability, msPosMethodCapPresent;
|
|
guint64 ecsdMultiSlotCapability, eightPskStructPresent, eightPskStructRfPowerCapPresent;
|
|
guint64 gsm400BandInfoPresent, gsm850AssocRadioCapabilityPresent;
|
|
guint64 gsm1900AssocRadioCapabilityPresent, dtmEGprsMultiSlotInfoPresent;
|
|
guint64 dtmEgprsMultiSlotClassPresent, singleBandSupport;
|
|
guint64 gsm750AssocRadioCapabilityPresent, extDtmEGprsMultiSlotInfoPresent;
|
|
guint64 highMultislotCapPresent, geranIuModeSupport;
|
|
guint64 tGsm400BandInfoPresent, tGsm900AssocRadioCapabilityPresent, dtmEGprsHighMultiSlotInfoPresent;
|
|
guint64 dtmEgprsHighMultiSlotClassPresent, gsm710AssocRadioCapabilityPresent;
|
|
guint64 tGsm810AssocRadioCapabilityPresent;
|
|
|
|
curr_offset = offset;
|
|
|
|
bit_offset = curr_offset << 3;
|
|
|
|
/* Spare bit */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
/* Multiband supported field
|
|
* { < Multiband supported : { 000 } >
|
|
* < A5 bits >
|
|
* | < Multiband supported : { 101 | 110 } >
|
|
* < A5 bits >
|
|
* < Associated Radio Capability 2 : bit(4) >
|
|
* < Associated Radio Capability 1 : bit(4) >
|
|
* | < Multiband supported : { 001 | 010 | 100 } >
|
|
* < A5 bits >
|
|
* < spare bit >(4)
|
|
* < Associated Radio Capability 1 : bit(4) > }
|
|
*/
|
|
|
|
item = proto_tree_add_bits_ret_val(tree, hf_gsm_a_multi_bnd_sup_fields, tvb, bit_offset, 3, &multi_bnd_sup_fields, ENC_BIG_ENDIAN);
|
|
subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_gsm1800_supported, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_egsm_supported, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_pgsm_supported, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
item = proto_tree_add_bits_item(tree, hf_gsm_a_cm3_A5_bits, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
|
|
|
|
/* < A5 bits > */
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_A5_7_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_A5_6_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_A5_5_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_A5_4_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
switch (multi_bnd_sup_fields) {
|
|
case 0:
|
|
/* A5 bits dissected is done */
|
|
break;
|
|
/*
|
|
* | < Multiband supported : { 001 | 010 | 100 } >
|
|
*/
|
|
case 1:
|
|
case 2:
|
|
case 4:
|
|
/* < spare bit >(4) */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset += 4;
|
|
/* < Associated Radio Capability 1 : bit(4) > */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ass_radio_cap1, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset += 4;
|
|
break;
|
|
/* < Multiband supported : { 101 | 110 } > */
|
|
case 5:
|
|
/* fall trough */
|
|
case 6:
|
|
/* < Associated Radio Capability 2 : bit(4) > */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ass_radio_cap2, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset += 4;
|
|
/* < Associated Radio Capability 1 : bit(4) > */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ass_radio_cap1, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset += 4;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
/* Extract R Support */
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_rsupport, tvb, bit_offset, 1, &rsupport, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
if (rsupport == 1)
|
|
{
|
|
/*
|
|
* { 0 | 1 < R Support > }
|
|
* Extract R Capabilities
|
|
*/
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_r_capabilities, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 3;
|
|
}
|
|
|
|
/*
|
|
* { 0 | 1 < HSCSD Multi Slot Capability > }
|
|
* Extract Multislot capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_multislot_capabilities, tvb, bit_offset, 1, &multislotCapability, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
if (multislotCapability == 1)
|
|
{
|
|
/* Extract Multislot Class */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_multislot_class, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 5;
|
|
}
|
|
|
|
/* < UCS2 treatment: bit > */
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ucs2_treatment, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* < Extended Measurement Capability : bit > */
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_extended_measurement_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* { 0 | 1 < MS measurement capability > }
|
|
* Extract MS Measurement capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_ms_measurement_capability, tvb, bit_offset, 1, &msMeasurementCapability, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (msMeasurementCapability == 1)
|
|
{
|
|
/* Extract SMS Value n/4 */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_sms_value, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
|
|
/* Extract SM Value n/4 */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_sm_value, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* { 0 | 1 < MS Positioning Method Capability > }
|
|
* Extract MS Positioning Method Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_ms_pos_method_cap_present, tvb, bit_offset, 1, &msPosMethodCapPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (msPosMethodCapPresent == 1)
|
|
{
|
|
/* Extract MS Positioning Method */
|
|
item = proto_tree_add_bits_item(tree, hf_gsm_a_ms_pos_method, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
|
|
subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_ms_assisted_e_otd, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_ms_based_e_otd, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_ms_assisted_gps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_ms_based_gps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_ms_conventional_gps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset++;
|
|
}
|
|
|
|
/* { 0 | 1 < ECSD Multi Slot Capability > }
|
|
* Extract ECSD Multi Slot Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_ecsd_multi_slot_capability, tvb, bit_offset, 1, &ecsdMultiSlotCapability, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (ecsdMultiSlotCapability == 1)
|
|
{
|
|
/* Extract ECSD Multi Slot Class */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ecsd_multi_slot_class, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 5;
|
|
}
|
|
|
|
/* { 0 | 1 < 8-PSK Struct > }
|
|
* Extract 8-PSK struct presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_8_psk_struct_present, tvb, bit_offset, 1, &eightPskStructPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (eightPskStructPresent == 1)
|
|
{
|
|
/* At lest Modulation Capability and cap1,cap2 presens indicators is present */
|
|
guint8 psk_struct_len = 3;
|
|
guint32 tmp_bit_offset = bit_offset;
|
|
|
|
/* Check if Power Capability 1 is present */
|
|
tmp_bit_offset++;
|
|
if (tvb_get_bits8(tvb,tmp_bit_offset,1) == 1){
|
|
psk_struct_len += 2;
|
|
tmp_bit_offset += 2;
|
|
}
|
|
tmp_bit_offset++;
|
|
/* Check if Power Capability 2 is present */
|
|
if (tvb_get_bits8(tvb,tmp_bit_offset,1) == 1){
|
|
psk_struct_len += 2;
|
|
}
|
|
/* Extract 8-PSK struct */
|
|
item = proto_tree_add_bits_item(tree, hf_gsm_a_8_psk_struct, tvb, bit_offset, psk_struct_len, ENC_BIG_ENDIAN);
|
|
subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
|
|
old_bit_offset = bit_offset;
|
|
|
|
/* Extract Modulation Capability */
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_modulation_capability, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* Extract 8_PSK RF Power Capability 1 */
|
|
proto_tree_add_bits_ret_val(subtree, hf_gsm_a_8_psk_rf_power_capability_1_present, tvb, bit_offset,
|
|
1, &eightPskStructRfPowerCapPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
if (eightPskStructRfPowerCapPresent == 1)
|
|
{
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_8_psk_rf_power_capability_1, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
}
|
|
|
|
/* Extract 8_PSK RF Power Capability 2 */
|
|
proto_tree_add_bits_ret_val(subtree, hf_gsm_a_8_psk_rf_power_capability_2_present, tvb, bit_offset,
|
|
1, &eightPskStructRfPowerCapPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
if (eightPskStructRfPowerCapPresent == 1)
|
|
{
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_8_psk_rf_power_capability_2, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
}
|
|
length = (guint8)((bit_offset - old_bit_offset)>>3);
|
|
if ((bit_offset - old_bit_offset) & 0x07)
|
|
length++;
|
|
proto_item_set_len(item, length);
|
|
}
|
|
|
|
/* { 0 | 1 < GSM 400 Bands Supported : { 01 | 10 | 11 } >
|
|
* < GSM 400 Associated Radio Capability: bit(4) > }
|
|
* Extract GSM 400 Band Information presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_400_band_info_present, tvb, bit_offset, 1, &gsm400BandInfoPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (gsm400BandInfoPresent == 1)
|
|
{
|
|
/* Extract GSM 400 Bands Supported */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gsm_400_bands_supported, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/* Extract GSM 400 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gsm_400_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* { 0 | 1 <GSM 850 Associated Radio Capability : bit(4) > }
|
|
* Extract GSM 850 Associated Radio Capability presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_850_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm850AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (gsm850AssocRadioCapabilityPresent == 1)
|
|
{
|
|
/* Extract GSM 850 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gsm_850_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* { 0 | 1 <GSM 1900 Associated Radio Capability : bit(4) > }
|
|
* Extract GSM 1900 Associated Radio Capability presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_1900_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm1900AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (gsm1900AssocRadioCapabilityPresent == 1)
|
|
{
|
|
/* Extract GSM 1900 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gsm_1900_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* < UMTS FDD Radio Access Technology Capability : bit >
|
|
* Extract UMTS FDD Radio Access Technology Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_umts_fdd_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* < UMTS 3.84 Mcps TDD Radio Access Technology Capability : bit >
|
|
* Extract UMTS 3.84 Mcps TDD Radio Access Technology Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_umts_384_mcps_tdd_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* < CDMA 2000 Radio Access Technology Capability : bit >
|
|
* Extract CDMA 2000 Radio Access Technology Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_cdma_2000_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* { 0 | 1 < DTM GPRS Multi Slot Class : bit(2) >
|
|
* < Single Slot DTM : bit >
|
|
* {0 | 1< DTM EGPRS Multi Slot Class : bit(2) > } }
|
|
* Extract DTM E/GPRS Information presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_e_gprs_multi_slot_info_present, tvb, bit_offset, 1, &dtmEGprsMultiSlotInfoPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (dtmEGprsMultiSlotInfoPresent == 1)
|
|
{
|
|
/* Extract DTM GPRS Multi Slot Class */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_dtm_gprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/* Extract Single Slot DTM */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_single_slot_dtm, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* Extract DTM EGPRS Multi Slot Class Presence */
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_egprs_multi_slot_class_present, tvb, bit_offset, 1, &dtmEgprsMultiSlotClassPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* Extract DTM EGPRS Multi Slot Class */
|
|
if (dtmEgprsMultiSlotClassPresent == 1)
|
|
{
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_dtm_egprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Release 4 starts here
|
|
*
|
|
* { 0 | 1 < Single Band Support > } -- Release 4 starts here:
|
|
* Extract Single Band Support
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_single_band_support, tvb, bit_offset, 1, &singleBandSupport, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (singleBandSupport == 1)
|
|
{
|
|
/* Extract Single Band Support */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gsm_band, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* { 0 | 1 <GSM 750 Associated Radio Capability : bit(4) > }
|
|
* Extract GSM 750 Associated Radio Capability presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_750_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm750AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (gsm750AssocRadioCapabilityPresent == 1)
|
|
{
|
|
/* Extract GSM 750 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gsm_750_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* < UMTS 1.28 Mcps TDD Radio Access Technology Capability : bit >
|
|
* Extract UMTS 1.28 Mcps TDD Radio Access Technology Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_umts_128_mcps_tdd_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* < GERAN Feature Package 1 : bit >
|
|
* Extract GERAN Feature Package 1
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_geran_feature_package_1, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* { 0 | 1 < Extended DTM GPRS Multi Slot Class : bit(2) >
|
|
* < Extended DTM EGPRS Multi Slot Class : bit(2) > }
|
|
* Extract Extended DTM E/GPRS Information presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_ext_dtm_e_gprs_multi_slot_info_present, tvb, bit_offset, 1, &extDtmEGprsMultiSlotInfoPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (extDtmEGprsMultiSlotInfoPresent == 1)
|
|
{
|
|
/* Extract Extended DTM GPRS Multi Slot Class */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ext_dtm_gprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/* Extract Extended DTM EGPRS Multi Slot Class */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ext_dtm_egprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
}
|
|
|
|
/*
|
|
* Release 5 starts here
|
|
*
|
|
* { 0 | 1 < High Multislot Capability : bit(2) > } -- Release 5 starts here.
|
|
* Extract High Multislot Capability presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_high_multislot_cap_present, tvb, bit_offset, 1, &highMultislotCapPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (highMultislotCapPresent == 1)
|
|
{
|
|
/* Extract High Multislot Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_high_multislot_cap, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
}
|
|
|
|
/*
|
|
* { 0 | 1 < GERAN Iu Mode Capabilities > } -- "1" also means support of GERAN Iu mode
|
|
* Extract GERAN Iu Mode Capabilities presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_geran_iu_mode_support, tvb, bit_offset, 1, &geranIuModeSupport, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (geranIuModeSupport == 1)
|
|
{
|
|
/* Extract GERAN Iu Mode Capabilities Length */
|
|
length = tvb_get_bits8(tvb, bit_offset, 4);
|
|
|
|
/* Extract GERAN Iu Mode Capabilities */
|
|
item = proto_tree_add_bits_item(tree, hf_gsm_a_geran_iu_mode_cap, tvb, bit_offset, length + 4, ENC_BIG_ENDIAN);
|
|
subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
|
|
|
|
/* Add GERAN Iu Mode Capabilities Length in subtree */
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_geran_iu_mode_cap_length, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset += 4;
|
|
target_bit_offset = bit_offset + length;
|
|
|
|
/* Extract FLO Iu Capability */
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_flo_iu_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset += 1;
|
|
|
|
/* If needed, add spare bits */
|
|
if (target_bit_offset > bit_offset)
|
|
{
|
|
proto_tree_add_bits_item(subtree, hf_gsm_a_spare_bits, tvb, bit_offset, target_bit_offset - bit_offset, ENC_BIG_ENDIAN);
|
|
bit_offset = target_bit_offset;
|
|
}
|
|
}
|
|
|
|
/* < GERAN Feature Package 2 : bit >
|
|
* Extract GERAN Feature Package 2
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_geran_feature_package_2, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* < GMSK Multislot Power Profile : bit (2) >
|
|
* Extract GMSK Multislot Power Profile
|
|
*/
|
|
AVAILABLE_BITS_CHECK(2);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gmsk_multislot_power_prof, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/* < 8-PSK Multislot Power Profile : bit (2) >
|
|
* Extract GMSK Multislot Power Profile
|
|
*/
|
|
AVAILABLE_BITS_CHECK(2);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_8_psk_multislot_power_prof, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/*
|
|
* Release 6 starts here
|
|
*
|
|
* { 0 | 1 < T-GSM 400 Bands Supported : { 01 | 10 | 11 } > -- Release 6 starts here.
|
|
* < T-GSM 400 Associated Radio Capability: bit(4) > }
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_t_gsm_400_band_info_present, tvb, bit_offset, 1, &tGsm400BandInfoPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (tGsm400BandInfoPresent == 1)
|
|
{
|
|
/* Extract T-GSM 400 Bands Supported */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_400_bands_supported, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/* Extract T-GSM 400 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_400_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* { 0 | 1 < T-GSM 900 Associated Radio Capability: bit(4) > }
|
|
* Extract T-GSM 900 Associated Radio Capability presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_t_gsm_900_assoc_radio_cap_present, tvb, bit_offset, 1, &tGsm900AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (tGsm900AssocRadioCapabilityPresent == 1)
|
|
{
|
|
/* Extract T-GSM 900 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_900_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* < Downlink Advanced Receiver Performance : bit (2)>
|
|
* Extract Downlink Advanced Receiver Performance
|
|
*/
|
|
AVAILABLE_BITS_CHECK(2);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_downlink_adv_receiver_perf, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/* < DTM Enhancements Capability : bit >
|
|
* Extract DTM Enhancements Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_dtm_enhancements_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* { 0 | 1 < DTM GPRS High Multi Slot Class : bit(3) >
|
|
* < Offset required : bit>
|
|
* { 0 | 1 < DTM EGPRS High Multi Slot Class : bit(3) > } }
|
|
* Extract DTM E/GPRS High Multi Slot Information presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_e_gprs_high_multi_slot_info_present, tvb, bit_offset, 1, &dtmEGprsHighMultiSlotInfoPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (dtmEGprsHighMultiSlotInfoPresent == 1)
|
|
{
|
|
/* Extract DTM GPRS High Multi Slot Class */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_dtm_gprs_high_multi_slot_class, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 3;
|
|
|
|
/* Extract Offset Required */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_offset_required, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* Extract DTM EGPRS High Multi Slot Class Presence */
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_egprs_high_multi_slot_class_present, tvb, bit_offset, 1, &dtmEgprsHighMultiSlotClassPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* Extract DTM EGPRS High Multi Slot Class */
|
|
if (dtmEgprsHighMultiSlotClassPresent == 1)
|
|
{
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_dtm_egprs_high_multi_slot_class, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 3;
|
|
}
|
|
}
|
|
|
|
/* < Repeated ACCH Capability : bit >
|
|
* Extract Repeated ACCH Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_repeated_acch_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* Release 7 starts here
|
|
*
|
|
* { 0 | 1 <GSM 710 Associated Radio Capability : bit(4) > } -- Release 7 starts here.
|
|
* Extract GSM 710 Associated Radio Capability presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_710_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm710AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (gsm710AssocRadioCapabilityPresent == 1)
|
|
{
|
|
/* Extract GSM 710 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_gsm_710_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* { 0 | 1 < T-GSM 810 Associated Radio Capability: bit(4) > }
|
|
* Extract T-GSM 810 Associated Radio Capability presence
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_ret_val(tree, hf_gsm_a_t_gsm_810_assoc_radio_cap_present, tvb, bit_offset, 1, &tGsm810AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
if (tGsm810AssocRadioCapabilityPresent == 1)
|
|
{
|
|
/* Extract T-GSM 810 Associated Radio Capability */
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_810_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 4;
|
|
}
|
|
|
|
/* < Ciphering Mode Setting Capability : bit >
|
|
* Extract Ciphering Mode Setting Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ciphering_mode_setting_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/* < Additional Positioning Capabilities : bit >
|
|
* Extract Additional Positioning Capabilities
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_additional_positioning_caps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* Release 8 starts here
|
|
*
|
|
* <E-UTRA FDD support : bit > -- Release 8 starts here.
|
|
* Extract E-UTRA FDD support
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_e_utra_fdd_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* <E-UTRA TDD support : bit >
|
|
* Extract E-UTRA TDD support
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_e_utra_tdd_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* <E-UTRA Measurement and Reporting support : bit >
|
|
* Extract E-UTRA Measurement and Reporting support
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_e_utra_meas_and_report_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* <Priority-based reselection support : bit >
|
|
* Extract Priority-based reselection support
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_prio_based_resel_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* Release 9 starts here
|
|
*
|
|
* <UTRA CSG Cells Reporting : bit > -- Release 9 starts here.
|
|
* Extract UTRA CSG Cells Reporting
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_utra_csg_cells_reporting, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* <VAMOS Level : bit(2) >
|
|
* Extract VAMOS Level
|
|
*/
|
|
AVAILABLE_BITS_CHECK(2);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_vamos_level, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/*
|
|
* Release 10 starts here
|
|
*
|
|
* < TIGHTER Capability : bit(2) > -- Release 10 starts here.
|
|
* Extract TIGHTER Capability
|
|
*/
|
|
AVAILABLE_BITS_CHECK(2);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_tighter_cap, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/*
|
|
* < Selective Ciphering of Downlink SACCH : bit >
|
|
* Extract Selective Ciphering of Downlink SACCH
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_selective_ciph_down_sacch, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* Release 11 starts here
|
|
*
|
|
* < CS to PS SRVCC from GERAN to UTRA : bit(2) > -- Release 11 starts here
|
|
*/
|
|
AVAILABLE_BITS_CHECK(2);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_cs_to_ps_srvcc_geran_to_utra, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/*
|
|
* < CS to PS SRVCC from GERAN to E-UTRA : bit(2)>
|
|
*/
|
|
AVAILABLE_BITS_CHECK(2);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_cs_to_ps_srvcc_geran_to_eutra, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 2;
|
|
|
|
/*
|
|
* < GERAN Network Sharing support : bit(1)>
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_geran_network_sharing_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* < E-UTRA Wideband RSRQ measurements support : bit(1)>
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_eutra_wb_rsrq_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* Release 12 starts here
|
|
*
|
|
* < ER Band support : bit(1) > -- Release 12 starts here
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_er_band_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* < UTRA Multiple Frequency Band Indicators support : bit(1)>
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_utra_mfbi_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* < E-UTRA Multiple Frequency Band Indicators support : bit(1)>
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_eutra_mfbi_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* < Extended TSC Set Capability support : bit(1)>
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ext_tsc_set_cap_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* < Extended EARFCN value range : bit(1)>
|
|
*/
|
|
AVAILABLE_BITS_CHECK(1);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ext_earfcn_value_range, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
bit_offset = bit_offset + 1;
|
|
|
|
/*
|
|
* Add spare bits until we reach an octet boundary
|
|
*/
|
|
bits_left = (((len + offset) << 3) - bit_offset) & 0x07;
|
|
if (bits_left != 0)
|
|
{
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, bits_left, ENC_BIG_ENDIAN);
|
|
bit_offset += bits_left;
|
|
}
|
|
|
|
/* translate to byte offset (we already know that we are on an octet boundary) */
|
|
curr_offset = bit_offset >> 3;
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return len;
|
|
}
|
|
/*
|
|
* [3] 10.5.1.8
|
|
*/
|
|
guint16 de_spare_nibble(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint32 curr_offset;
|
|
gint bit_offset;
|
|
|
|
curr_offset = offset;
|
|
if (RIGHT_NIBBLE == len)
|
|
bit_offset = 4;
|
|
else
|
|
bit_offset = 0;
|
|
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_nibble, tvb, (curr_offset<<3)+bit_offset, 4, ENC_BIG_ENDIAN);
|
|
curr_offset = curr_offset + 1;
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.9 Descriptive group or broadcast call reference
|
|
*/
|
|
static const true_false_string tfs_vgcs_vbs = { "VGCS (Group call reference)", "VBS (Broadcast call reference)" };
|
|
|
|
static const value_string gsm_a_call_priority_vals[] = {
|
|
{ 0, "no priority applied"},
|
|
{ 1, "call priority level 4"},
|
|
{ 2, "call priority level 3"},
|
|
{ 3, "call priority level 2"},
|
|
{ 4, "call priority level 1"},
|
|
{ 5, "call priority level 0"},
|
|
{ 6, "call priority level B"},
|
|
{ 7, "call priority level A"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
guint16
|
|
de_d_gb_call_ref(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint32 curr_offset = offset;
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_group_call_reference, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_service_flag, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_af_acknowledgement, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_call_priority, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
|
|
curr_offset += 4;
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_ciphering_info, tvb, curr_offset, 1, ENC_NA);
|
|
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 4, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
/* no length check possible */
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.10a PD and SAPI $(CCBS)$
|
|
*/
|
|
static const value_string gsm_a_sapi_vals[] = {
|
|
{ 0, "SAPI 0"},
|
|
{ 1, "Reserved"},
|
|
{ 2, "Reserved"},
|
|
{ 3, "SAPI 3"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static guint16
|
|
de_pd_sapi(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint32 curr_offset;
|
|
proto_tree *subtree;
|
|
|
|
curr_offset = offset;
|
|
|
|
subtree =
|
|
proto_tree_add_subtree(tree,
|
|
tvb, curr_offset, 1, ett_gsm_dtap_elem[DE_PD_SAPI], NULL,
|
|
val_to_str_ext_const(DE_PD_SAPI, &gsm_dtap_elem_strings_ext, ""));
|
|
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset<<3, 2, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item(subtree, hf_gsm_a_sapi, tvb, curr_offset, 1, ENC_NA);
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_L3_protocol_discriminator, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
|
|
curr_offset++;
|
|
|
|
/* no length check possible */
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.11 Priority Level
|
|
*/
|
|
static const value_string gsm_a_call_prio_vals[] = {
|
|
{ 0x00, "no priority applied" },
|
|
{ 0x01, "call priority level 4" },
|
|
{ 0x02, "call priority level 3" },
|
|
{ 0x03, "call priority level 2" },
|
|
{ 0x04, "call priority level 1" },
|
|
{ 0x05, "call priority level 0" },
|
|
{ 0x06, "call priority level B" },
|
|
{ 0x07, "call priority level A" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static guint16
|
|
de_prio(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint32 curr_offset;
|
|
|
|
curr_offset = offset;
|
|
|
|
proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_call_prio, tvb, (curr_offset<<3)+5, 3, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
/* no length check possible */
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.12.1 CN Common GSM-MAP NAS system information
|
|
*/
|
|
guint16
|
|
de_cn_common_gsm_map_nas_sys_info(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_item(tree, hf_gsm_a_lac, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
|
|
curr_offset += 2;
|
|
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.12.2 CS domain specific system information
|
|
*/
|
|
const true_false_string gsm_a_att_value = {
|
|
"MSs shall apply IMSI attach and detach procedure",
|
|
"MSs shall not apply IMSI attach and detach procedure"
|
|
};
|
|
|
|
guint16
|
|
de_cs_domain_spec_sys_info(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_item(tree, hf_gsm_a_rr_t3212, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3), 7, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_att, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.12.3 PS domain specific system information
|
|
*/
|
|
const true_false_string gsm_a_nmo_1_value = {
|
|
"Network Mode of Operation I is used for MS configured for NMO_I_Behaviour",
|
|
"Network Mode of Operation indicated in Bit 1 (NMO) is used for MS configured for NMO_I_Behaviour"
|
|
};
|
|
|
|
const true_false_string gsm_a_nmo_value = {
|
|
"Network Mode of Operation II",
|
|
"Network Mode of Operation I"
|
|
};
|
|
|
|
guint16
|
|
de_ps_domain_spec_sys_info(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_item(tree, hf_gsm_a_gm_rac, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
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_nmo_1, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_nmo, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* [3] 10.5.1.13 PLMN list
|
|
*/
|
|
guint16
|
|
de_plmn_list(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len)
|
|
{
|
|
guint8 octs[3];
|
|
guint32 curr_offset;
|
|
gchar mcc[4];
|
|
gchar mnc[4];
|
|
guint8 num_plmn;
|
|
proto_tree* subtree;
|
|
|
|
curr_offset = offset;
|
|
|
|
num_plmn = 0;
|
|
while ((len - (curr_offset - offset)) >= 3)
|
|
{
|
|
octs[0] = tvb_get_guint8(tvb, curr_offset);
|
|
octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
|
|
octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
|
|
|
|
mcc_mnc_aux(octs, mcc, mnc);
|
|
|
|
subtree = proto_tree_add_subtree_format(tree, tvb, curr_offset, 3, ett_gsm_a_plmn, NULL, "PLMN[%u]", num_plmn + 1);
|
|
proto_tree_add_string(subtree, hf_gsm_a_mobile_country_code, tvb, curr_offset, 3, mcc);
|
|
proto_tree_add_string(subtree, hf_gsm_a_mobile_network_code, tvb, curr_offset, 3, mnc);
|
|
|
|
curr_offset += 3;
|
|
|
|
num_plmn++;
|
|
}
|
|
|
|
if (add_string)
|
|
g_snprintf(add_string, string_len, " - %u PLMN%s",
|
|
num_plmn, plurality(num_plmn, "", "s"));
|
|
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* 10.5.1.14 NAS container for PS HO
|
|
*/
|
|
|
|
static const value_string gsm_a_pld_xid_vals[] = {
|
|
{ 0x00, "The MS shall perform a Reset of LLC and SNDCP without old XID indicator" },
|
|
{ 0x01, "The MS shall perform a Reset of LLC and SNDCP with old XID indicator" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static guint16
|
|
de_nas_cont_for_ps_ho(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;
|
|
|
|
/* 8 7 6 5 4 3 2 1
|
|
* 0 0 0 old 0 Type of ciphering
|
|
* spare spare spare XID spare algorithm
|
|
*/
|
|
proto_tree_add_item(tree, hf_gsm_a_old_xid, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(tree, hf_gsm_a_type_of_ciph_alg, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
/* IOV-UI value (octet 2 to 5)
|
|
* The IOV-UI value consists of 32 bits, the format is defined in 3GPP TS 44.064 [78a].
|
|
*/
|
|
proto_tree_add_item(tree, hf_gsm_a_iov_ui, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
|
|
curr_offset += 4;
|
|
|
|
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
/*
|
|
* 10.5.1.15 MS network feature support
|
|
*/
|
|
static const true_false_string gsm_a_ext_periodic_timers_value = {
|
|
"MS supports the extended periodic timer in this domain",
|
|
"MS does not support the extended periodic timer in this domain"
|
|
};
|
|
|
|
static guint16
|
|
de_ms_net_feat_sup(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
|
|
{
|
|
guint32 curr_offset, bit_offset;
|
|
|
|
curr_offset = offset;
|
|
bit_offset = (curr_offset<<3)+4;
|
|
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
|
|
bit_offset += 3;
|
|
proto_tree_add_bits_item(tree, hf_gsm_a_ext_periodic_timers, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
|
|
curr_offset++;
|
|
|
|
return (curr_offset - offset);
|
|
}
|
|
|
|
|
|
guint16 (*common_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len) = {
|
|
/* Common Information Elements 10.5.1 */
|
|
de_cell_id, /* Cell Identity */
|
|
de_ciph_key_seq_num, /* Ciphering Key Sequence Number */
|
|
de_lai, /* Location Area Identification */
|
|
de_mid, /* Mobile Identity */
|
|
de_ms_cm_1, /* Mobile Station Classmark 1 */
|
|
de_ms_cm_2, /* Mobile Station Classmark 2 */
|
|
de_ms_cm_3, /* Mobile Station Classmark 3 */
|
|
de_spare_nibble, /* Spare Half Octet */
|
|
de_d_gb_call_ref, /* Descriptive group or broadcast call reference */
|
|
NULL /* handled inline */, /* Group Cipher Key Number */
|
|
de_pd_sapi, /* PD and SAPI $(CCBS)$ */
|
|
/* Pos 10 */
|
|
de_prio /* handled inline */, /* Priority Level */
|
|
de_cn_common_gsm_map_nas_sys_info, /* 10.5.1.12.1 CN Common GSM-MAP NAS system information */
|
|
de_cs_domain_spec_sys_info, /* 10.5.1.12.2 CS domain specific system information */
|
|
de_ps_domain_spec_sys_info, /* 10.5.1.12.2 PS domain specific system information */
|
|
de_plmn_list, /* 10.5.1.13 PLMN list */
|
|
de_nas_cont_for_ps_ho, /* 10.5.1.14 NAS container for PS HO */
|
|
de_ms_net_feat_sup, /* 10.5.1.15 MS network feature support */
|
|
NULL, /* NONE */
|
|
};
|
|
|
|
/* TAP STAT INFO */
|
|
typedef enum
|
|
{
|
|
IEI_COLUMN,
|
|
MSG_NAME_COLUMN,
|
|
COUNT_COLUMN
|
|
} gsm_a_stat_columns;
|
|
|
|
static stat_tap_table_item gsm_a_stat_fields[] = {
|
|
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "IEI", "%d"},
|
|
{TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Message Name", "%-25s"},
|
|
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Count", "%d"}
|
|
};
|
|
|
|
static void gsm_a_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data, const char *table_title, const value_string *msg_strings)
|
|
{
|
|
int num_fields = sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item);
|
|
stat_tap_table* table;
|
|
guint i;
|
|
stat_tap_table_item_type items[sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item)];
|
|
|
|
items[IEI_COLUMN].type = TABLE_ITEM_UINT;
|
|
items[MSG_NAME_COLUMN].type = TABLE_ITEM_STRING;
|
|
items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
|
|
items[COUNT_COLUMN].value.uint_value = 0;
|
|
|
|
table = new_stat_tap_init_table(table_title, num_fields, 0, NULL, gui_callback, gui_data);
|
|
new_stat_tap_add_table(new_stat, table);
|
|
|
|
/* Add a row for each value type */
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
const char *msg_str = try_val_to_str(i, msg_strings);
|
|
char *col_str;
|
|
if (msg_str) {
|
|
col_str = g_strdup(msg_str);
|
|
} else {
|
|
col_str = g_strdup_printf("Unknown message %d", i);
|
|
}
|
|
|
|
items[IEI_COLUMN].value.uint_value = i;
|
|
items[MSG_NAME_COLUMN].value.string_value = col_str;
|
|
new_stat_tap_init_table_row(table, i, num_fields, items);
|
|
}
|
|
}
|
|
|
|
static void gsm_a_bssmap_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F BSSMAP Statistics", gsm_a_bssmap_msg_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_mm_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP Mobility Management Statistics", gsm_a_dtap_msg_mm_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_rr_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP Radio Resource Management Statistics", gsm_a_dtap_msg_rr_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_cc_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP Call Control Statistics", gsm_a_dtap_msg_cc_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_gmm_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP GPRS Mobility Management Statistics", gsm_a_dtap_msg_gmm_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_sm_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP GPRS Session Management Statistics", gsm_a_dtap_msg_sm_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_sms_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP Short Message Service Statistics", gsm_a_dtap_msg_sms_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_tp_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP Special Conformance Testing Functions", gsm_a_dtap_msg_tp_strings);
|
|
}
|
|
|
|
static void gsm_a_dtap_ss_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F DTAP Supplementary Services Statistics", gsm_a_dtap_msg_ss_strings);
|
|
}
|
|
|
|
static void gsm_a_sacch_rr_stat_init(stat_tap_table_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
|
|
{
|
|
gsm_a_stat_init(new_stat, gui_callback, gui_data,
|
|
"GSM A-I/F SACCH Statistics", gsm_a_rr_short_pd_msg_strings);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_stat_packet(void *tapdata, const void *gatr_ptr, guint8 pdu_type, int protocol_disc)
|
|
{
|
|
new_stat_data_t* stat_data = (new_stat_data_t*)tapdata;
|
|
const gsm_a_tap_rec_t *gatr = (const gsm_a_tap_rec_t *) gatr_ptr;
|
|
stat_tap_table* table;
|
|
stat_tap_table_item_type* msg_data;
|
|
guint i = 0;
|
|
|
|
if (gatr->pdu_type != pdu_type) return FALSE;
|
|
if (pdu_type == BSSAP_PDU_TYPE_DTAP && (int)gatr->protocol_disc != protocol_disc) return FALSE;
|
|
if (pdu_type == GSM_A_PDU_TYPE_SACCH && gatr->protocol_disc != 0) return FALSE;
|
|
|
|
table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, i);
|
|
msg_data = new_stat_tap_get_field_data(table, gatr->message_type, COUNT_COLUMN);
|
|
msg_data->value.uint_value++;
|
|
new_stat_tap_set_field_data(table, gatr->message_type, COUNT_COLUMN, msg_data);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_bssmap_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_BSSMAP, 0);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_mm_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_MM);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_rr_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_RR);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_cc_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_CC);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_gmm_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_GMM);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_sms_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_SMS);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_sm_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_SM);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_ss_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_SS);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_dtap_tp_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, BSSAP_PDU_TYPE_DTAP, PD_TP);
|
|
}
|
|
|
|
static gboolean
|
|
gsm_a_sacch_rr_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gatr_ptr)
|
|
{
|
|
return gsm_a_stat_packet(tapdata, gatr_ptr, GSM_A_PDU_TYPE_SACCH, 0);
|
|
}
|
|
|
|
static void
|
|
gsm_a_stat_reset(stat_tap_table* table)
|
|
{
|
|
guint element;
|
|
stat_tap_table_item_type* item_data;
|
|
|
|
for (element = 0; element < table->num_elements; element++)
|
|
{
|
|
item_data = new_stat_tap_get_field_data(table, element, COUNT_COLUMN);
|
|
item_data->value.uint_value = 0;
|
|
new_stat_tap_set_field_data(table, element, COUNT_COLUMN, item_data);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gsm_a_stat_free_table_item(stat_tap_table* table _U_, guint row _U_, guint column, stat_tap_table_item_type* field_data)
|
|
{
|
|
if (column != MSG_NAME_COLUMN) return;
|
|
g_free((char*)field_data->value.string_value);
|
|
}
|
|
|
|
/* Register the protocol with Wireshark */
|
|
void
|
|
proto_register_gsm_a_common(void)
|
|
{
|
|
guint i;
|
|
guint last_offset;
|
|
|
|
/* Setup list of header fields */
|
|
static hf_register_info hf[] =
|
|
{
|
|
{ &hf_gsm_a_common_elem_id,
|
|
{ "Element ID", "gsm_a.common.elem_id",
|
|
FT_UINT8, BASE_HEX, NULL, 0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_common_elem_id_f0,
|
|
{ "Element ID", "gsm_a.common.elem_id",
|
|
FT_UINT8, BASE_HEX, NULL, 0xF0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_l_ext,
|
|
{ "ext", "gsm_a.l_ext",
|
|
FT_UINT8, BASE_DEC, NULL, 0x80,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_tmsi,
|
|
{ "TMSI/P-TMSI", "gsm_a.tmsi",
|
|
FT_UINT32, BASE_HEX, 0, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_imei,
|
|
{ "IMEI", "gsm_a.imei",
|
|
FT_STRING, BASE_NONE, 0, 0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_imeisv,
|
|
{ "IMEISV", "gsm_a.imeisv",
|
|
FT_STRING, BASE_NONE, 0, 0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_MSC_rev,
|
|
{ "Revision Level", "gsm_a.MSC_rev",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_msc_rev_vals), 0x60,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_ES_IND,
|
|
{ "ES IND", "gsm_a.ES_IND",
|
|
FT_BOOLEAN, 8, TFS(&ES_IND_vals), 0x10,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_A5_1_algorithm_sup,
|
|
{ "A5/1 algorithm supported", "gsm_a.A5_1_algorithm_sup",
|
|
FT_BOOLEAN, 8, TFS(&A5_1_algorithm_sup_vals), 0x08,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_RF_power_capability,
|
|
{ "RF Power Capability", "gsm_a.RF_power_capability",
|
|
FT_UINT8, BASE_DEC, VALS(RF_power_capability_vals), 0x07,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_ps_sup_cap,
|
|
{ "PS capability (pseudo-synchronization capability)", "gsm_a.ps_sup_cap",
|
|
FT_BOOLEAN, 8, TFS(&ps_sup_cap_vals), 0x40,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_SS_screening_indicator,
|
|
{ "SS Screening Indicator", "gsm_a.SS_screening_indicator",
|
|
FT_UINT8, BASE_DEC, VALS(SS_screening_indicator_vals), 0x30,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_SM_capability,
|
|
{ "SM capability (MT SMS pt to pt capability)", "gsm_a.SM_cap",
|
|
FT_BOOLEAN, 8, TFS(&SM_capability_vals), 0x08,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_VBS_notification_rec,
|
|
{ "VBS notification reception", "gsm_a.VBS_notification_rec",
|
|
FT_BOOLEAN, 8, TFS(&VBS_notification_rec_vals), 0x04,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_VGCS_notification_rec,
|
|
{ "VGCS notification reception", "gsm_a.VGCS_notification_rec",
|
|
FT_BOOLEAN, 8, TFS(&VGCS_notification_rec_vals), 0x02,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_FC_frequency_cap,
|
|
{ "FC Frequency Capability", "gsm_a.FC_frequency_cap",
|
|
FT_BOOLEAN, 8, TFS(&FC_frequency_cap_vals), 0x01,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_CM3,
|
|
{ "CM3", "gsm_a.CM3",
|
|
FT_BOOLEAN, 8, TFS(&CM3_vals), 0x80,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_LCS_VA_cap,
|
|
{ "LCS VA capability (LCS value added location request notification capability)", "gsm_a.LCS_VA_cap",
|
|
FT_BOOLEAN, 8, TFS(&LCS_VA_cap_vals), 0x20,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_UCS2_treatment,
|
|
{ "UCS2 treatment", "gsm_a.UCS2_treatment",
|
|
FT_BOOLEAN, 8, TFS(&UCS2_treatment_vals), 0x10,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_SoLSA,
|
|
{ "SoLSA", "gsm_a.SoLSA",
|
|
FT_BOOLEAN, 8, TFS(&SoLSA_vals), 0x08,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_CMSP,
|
|
{ "CMSP: CM Service Prompt", "gsm_a.CMSP",
|
|
FT_BOOLEAN, 8, TFS(&CMSP_vals), 0x04,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_A5_7_algorithm_sup,
|
|
{ "A5/7 algorithm supported", "gsm_a.A5_7_algorithm_sup",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&A5_7_algorithm_sup_vals), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_A5_6_algorithm_sup,
|
|
{ "A5/6 algorithm supported", "gsm_a.A5_6_algorithm_sup",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&A5_6_algorithm_sup_vals), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_A5_5_algorithm_sup,
|
|
{ "A5/5 algorithm supported", "gsm_a.A5_5_algorithm_sup",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&A5_5_algorithm_sup_vals), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_A5_4_algorithm_sup,
|
|
{ "A5/4 algorithm supported", "gsm_a.A5_4_algorithm_sup",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&A5_4_algorithm_sup_vals), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_A5_3_algorithm_sup,
|
|
{ "A5/3 algorithm supported", "gsm_a.A5_3_algorithm_sup",
|
|
FT_BOOLEAN, 8, TFS(&A5_3_algorithm_sup_vals), 0x02,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_A5_2_algorithm_sup,
|
|
{ "A5/2 algorithm supported", "gsm_a.A5_2_algorithm_sup",
|
|
FT_BOOLEAN, 8, TFS(&A5_2_algorithm_sup_vals), 0x01,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_mobile_identity_type,
|
|
{ "Mobile Identity Type", "gsm_a.ie.mobileid.type",
|
|
FT_UINT8, BASE_DEC, VALS(mobile_identity_type_vals), 0x07,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_id_dig_1,
|
|
{ "Identity Digit 1", "gsm_a.id_dig_1",
|
|
FT_UINT8, BASE_DEC, NULL, 0xf0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_odd_even_ind,
|
|
{ "Odd/even indication", "gsm_a.oddevenind",
|
|
FT_BOOLEAN, 8, TFS(&oddevenind_vals), 0x08,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_unused,
|
|
{ "Unused", "gsm_a.unused",
|
|
FT_UINT8, BASE_HEX, NULL, 0xf0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_tmgi_mcc_mnc_ind,
|
|
{ "MCC/MNC indication", "gsm_a.tmgi_mcc_mnc_ind",
|
|
FT_BOOLEAN, 8, TFS(&gsm_a_present_vals), 0x10,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_mbs_ses_id_ind,
|
|
{ "MBMS Session Identity indication", "gsm_a.mbs_session_id_ind",
|
|
FT_BOOLEAN, 8, TFS(&gsm_a_present_vals), 0x20,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_mbs_service_id,
|
|
{ "MBMS Service ID", "gsm_a.mbs_service_id",
|
|
FT_UINT24, BASE_HEX, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_mbs_session_id,
|
|
{ "MBMS Session ID", "gsm_a.mbs_session_id",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_length,
|
|
{ "Length", "gsm_a.len",
|
|
FT_UINT16, BASE_DEC, NULL, 0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_element_value,
|
|
{ "Element Value", "gsm_a.element_value",
|
|
FT_BYTES, BASE_NONE, NULL, 0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_extension,
|
|
{ "Extension", "gsm_a.extension",
|
|
FT_BOOLEAN, 8, TFS(&gsm_a_extension_value), 0x80,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_L3_protocol_discriminator,
|
|
{ "Protocol discriminator", "gsm_a.L3_protocol_discriminator",
|
|
FT_UINT8, BASE_HEX, VALS(protocol_discriminator_vals), 0x0f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_call_prio,
|
|
{ "Call priority", "gsm_a.call_prio",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_call_prio_vals), 0x00,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_type_of_ciph_alg,
|
|
{ "Call priority", "gsm_a.call_prio",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_ciph_alg_vals), 0x07,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_att,
|
|
{ "ATT", "gsm_a.att",
|
|
FT_BOOLEAN, 8, TFS(&gsm_a_att_value), 0x01,
|
|
"ttach-detach allowed", HFILL }
|
|
},
|
|
{ &hf_gsm_a_nmo_1,
|
|
{ "NMO I", "gsm_a.nmo_1",
|
|
FT_BOOLEAN, 8, TFS(&gsm_a_nmo_1_value), 0x02,
|
|
"Network Mode of Operation I", HFILL }
|
|
},
|
|
{ &hf_gsm_a_nmo,
|
|
{ "NMO", "gsm_a.nmo",
|
|
FT_BOOLEAN, 8, TFS(&gsm_a_nmo_value), 0x01,
|
|
"Network Mode of Operation", HFILL }
|
|
},
|
|
{ &hf_gsm_a_old_xid,
|
|
{ "Old XID", "gsm_a.old_xid",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_pld_xid_vals), 0x10,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_iov_ui,
|
|
{ "IOV-UI", "gsm_a.iov_ui",
|
|
FT_UINT32, BASE_HEX, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_ext_periodic_timers,
|
|
{ "Extended periodic timers", "gsm_a.ext_periodic_timers",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&gsm_a_ext_periodic_timers_value), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_skip_ind,
|
|
{ "Skip Indicator", "gsm_a.skip.ind",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_skip_ind_vals), 0xf0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_b7spare,
|
|
{ "Spare", "gsm_a.spareb7",
|
|
FT_UINT8, BASE_DEC, NULL, 0x40,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_b8spare,
|
|
{ "Spare", "gsm_a.spareb8",
|
|
FT_UINT8, BASE_DEC, NULL, 0x80,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_spare_bits,
|
|
{ "Spare bit(s)", "gsm_a.spare_bits",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_multi_bnd_sup_fields,
|
|
{ "Multiband supported field", "gsm_a.multi_bnd_sup_fields",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_pgsm_supported,
|
|
{ "P-GSM Supported", "gsm_a.classmark3.pgsmSupported",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_egsm_supported,
|
|
{ "E-GSM or R-GSM Supported", "gsm_a.classmark3.egsmSupported",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm1800_supported,
|
|
{ "GSM 1800 Supported", "gsm_a.classmark3.gsm1800Supported",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ass_radio_cap1,
|
|
{ "Associated Radio Capability 1", "gsm_a.classmark3.ass_radio_cap1",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ass_radio_cap2,
|
|
{ "Associated Radio Capability 2", "gsm_a.classmark3.ass_radio_cap2",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_cm3_A5_bits,
|
|
{ "A5 bits", "gsm_a.classmark3.a5_bits",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_rsupport,
|
|
{ "R Support", "gsm_a.classmark3.rsupport",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_r_capabilities,
|
|
{ "R-GSM band Associated Radio Capability", "gsm_a.classmark3.r_capabilities",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_multislot_capabilities,
|
|
{ "HSCSD Multi Slot Capability", "gsm_a.classmark3.multislot_capabilities",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_multislot_class,
|
|
{ "HSCSD Multi Slot Class", "gsm_a.classmark3.multislot_cap",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ucs2_treatment,
|
|
{ "UCS2 treatment", "gsm_a.UCS2_treatment",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&UCS2_treatment_vals), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_extended_measurement_cap,
|
|
{ "Extended Measurement Capability", "gsm_a.classmark3.ext_meas_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_measurement_capability,
|
|
{ "MS measurement capability", "gsm_a.classmark3.ms_measurement_capability",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_sms_value,
|
|
{ "SMS_VALUE (Switch-Measure-Switch)", "gsm_a.classmark3.sms_value",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_sms_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_sm_value,
|
|
{ "SM_VALUE (Switch-Measure)", "gsm_a.classmark3.sm_value",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_sms_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_pos_method_cap_present,
|
|
{ "MS Positioning Method Capability present", "gsm_a.classmark3.ms_pos_method_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_pos_method,
|
|
{ "MS Positioning Method", "gsm_a.classmark3.ms_pos_method",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_assisted_e_otd,
|
|
{ "MS assisted E-OTD", "gsm_a.classmark3.ms_assisted_e_otd",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&ms_assisted_e_otd_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_based_e_otd,
|
|
{ "MS based E-OTD", "gsm_a.classmark3.ms_based_e_otd",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&ms_based_e_otd_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_assisted_gps,
|
|
{ "MS assisted GPS", "gsm_a.classmark3.ms_assisted_gps",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&ms_assisted_gps_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_based_gps,
|
|
{ "MS based GPS", "gsm_a.classmark3.ms_based_gps",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&ms_based_gps_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ms_conventional_gps,
|
|
{ "MS Conventional GPS", "gsm_a.classmark3.ms_conventional_gps",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&ms_conventional_gps_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ecsd_multi_slot_capability,
|
|
{ "ECSD Multi Slot Capability present", "gsm_a.classmark3.ecsd_multi_slot_capability",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ecsd_multi_slot_class,
|
|
{ "ECSD Multi Slot Class", "gsm_a.classmark3.ecsd_multi_slot_class",
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_8_psk_struct_present,
|
|
{ "8-PSK Struct present", "gsm_a.classmark3.8_psk_struct_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_8_psk_struct,
|
|
{ "8-PSK Struct", "gsm_a.classmark3.8_psk_struct",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_modulation_capability,
|
|
{ "Modulation Capability", "gsm_a.classmark3.modulation_capability",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&modulation_capability_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_8_psk_rf_power_capability_1_present,
|
|
{ "8-PSK RF Power Capability 1 present", "gsm_a.classmark3.8_psk_rf_power_capability_1_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_8_psk_rf_power_capability_1,
|
|
{ "8-PSK RF Power Capability 1", "gsm_a.classmark3.8_psk_rf_power_capability_1",
|
|
FT_UINT8, BASE_HEX, VALS(eight_psk_rf_power_capability_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_8_psk_rf_power_capability_2_present,
|
|
{ "8-PSK RF Power Capability 2 present", "gsm_a.classmark3.8_psk_rf_power_capability_2_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_8_psk_rf_power_capability_2,
|
|
{ "8-PSK RF Power Capability 2", "gsm_a.classmark3.8_psk_rf_power_capability_2",
|
|
FT_UINT8, BASE_HEX, VALS(eight_psk_rf_power_capability_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_400_band_info_present,
|
|
{ "GSM 400 Band Information present", "gsm_a.classmark3.gsm_400_band_info_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_400_bands_supported,
|
|
{ "GSM 400 Bands Supported", "gsm_a.classmark3.gsm_400_bands_supported",
|
|
FT_UINT8, BASE_HEX, VALS(gsm_400_bands_supported_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_400_assoc_radio_cap,
|
|
{ "GSM 400 Associated Radio Capability", "gsm_a.classmark3.gsm_400_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_850_assoc_radio_cap_present,
|
|
{ "GSM 850 Associated Radio Capability present", "gsm_a.classmark3.gsm_850_assoc_radio_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_850_assoc_radio_cap,
|
|
{ "GSM 850 Associated Radio Capability", "gsm_a.classmark3.gsm_850_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_1900_assoc_radio_cap_present,
|
|
{ "GSM 1900 Associated Radio Capability present", "gsm_a.classmark3.gsm_1900_assoc_radio_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_1900_assoc_radio_cap,
|
|
{ "GSM 1900 Associated Radio Capability", "gsm_a.classmark3.gsm_1900_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_umts_fdd_rat_cap,
|
|
{ "UMTS FDD Radio Access Technology Capability", "gsm_a.classmark3.umts_fdd_rat_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&umts_fdd_rat_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_umts_384_mcps_tdd_rat_cap,
|
|
{ "UMTS 3.84 Mcps TDD Radio Access Technology Capability", "gsm_a.classmark3.umts_384_mcps_tdd_rat_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&umts_384_mcps_tdd_rat_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_cdma_2000_rat_cap,
|
|
{ "CDMA 2000 Radio Access Technology Capability", "gsm_a.classmark3.cdma_2000_rat_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&cdma_2000_rat_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_e_gprs_multi_slot_info_present,
|
|
{ "DTM E/GPRS Multi Slot Information present", "gsm_a.classmark3.dtm_e_gprs_multi_slot_info_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_gprs_multi_slot_class,
|
|
{ "DTM GPRS Multi Slot Class", "gsm_a.classmark3.dtm_gprs_multi_slot_class",
|
|
FT_UINT8, BASE_DEC, VALS(dtm_gprs_multi_slot_class_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_single_slot_dtm,
|
|
{ "Single Slot DTM", "gsm_a.classmark3.single_slot_dtm_supported",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&single_slot_dtm_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_egprs_multi_slot_class_present,
|
|
{ "DTM EGPRS Multi Slot Class present", "gsm_a.classmark3.dtm_egprs_multi_slot_class_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_egprs_multi_slot_class,
|
|
{ "DTM EGPRS Multi Slot Class", "gsm_a.classmark3.dtm_egprs_multi_slot_class",
|
|
FT_UINT8, BASE_DEC, VALS(dtm_gprs_multi_slot_class_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_single_band_support,
|
|
{ "Single Band Support", "gsm_a.classmark3.single_band_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_band,
|
|
{ "GSM Band", "gsm_a.classmark3.gsm_band",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_band_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_750_assoc_radio_cap_present,
|
|
{ "GSM 750 Associated Radio Capability present", "gsm_a.classmark3.gsm_750_assoc_radio_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_750_assoc_radio_cap,
|
|
{ "GSM 750 Associated Radio Capability", "gsm_a.classmark3.gsm_750_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_umts_128_mcps_tdd_rat_cap,
|
|
{ "UMTS 1.28 Mcps TDD Radio Access Technology Capability", "gsm_a.classmark3.umts_128_mcps_tdd_rat_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&umts_128_mcps_tdd_rat_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geran_feature_package_1,
|
|
{ "GERAN Feature Package 1", "gsm_a.classmark3.geran_feature_package_1",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&geran_feature_package_1_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ext_dtm_e_gprs_multi_slot_info_present,
|
|
{ "Extended DTM E/GPRS Multi Slot Information present", "gsm_a.classmark3.ext_dtm_e_gprs_info_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ext_dtm_gprs_multi_slot_class,
|
|
{ "Extended DTM GPRS Multi Slot Class", "gsm_a.classmark3.ext_dtm_gprs_multi_slot_class",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ext_dtm_egprs_multi_slot_class,
|
|
{ "Extended DTM EGPRS Multi Slot Class", "gsm_a.classmark3.ext_dtm_egprs_multi_slot_class",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_high_multislot_cap_present,
|
|
{ "High Multislot Capability present", "gsm_a.classmark3.high_multislot_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_high_multislot_cap,
|
|
{ "High Multislot Capability", "gsm_a.classmark3.high_multislot_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geran_iu_mode_support,
|
|
{ "GERAN Iu Mode Support", "gsm_a.classmark3.geran_iu_mode_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geran_iu_mode_cap,
|
|
{ "GERAN Iu Mode Capabilities", "gsm_a.classmark3.geran_iu_mode_cap",
|
|
FT_UINT24, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geran_iu_mode_cap_length,
|
|
{ "Length", "gsm_a.classmark3.geran_iu_mode_cap.length",
|
|
FT_UINT8, BASE_DEC, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_flo_iu_cap,
|
|
{ "FLO Iu Capability", "gsm_a.classmark3.geran_iu_mode_cap.flo_iu_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&flo_iu_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geran_feature_package_2,
|
|
{ "GERAN Feature Package 2", "gsm_a.classmark3.geran_feature_package_2",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&geran_feature_package_2_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gmsk_multislot_power_prof,
|
|
{ "GMSK Multislot Power Profile", "gsm_a.classmark3.gmsk_multislot_power_prof",
|
|
FT_UINT8, BASE_DEC, VALS(gmsk_multislot_power_prof_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_8_psk_multislot_power_prof,
|
|
{ "8-PSK Multislot Power Profile", "gsm_a.classmark3.8_psk_multislot_power_prof",
|
|
FT_UINT8, BASE_DEC, VALS(eight_psk_multislot_power_prof_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_t_gsm_400_band_info_present,
|
|
{ "T-GSM 400 Band Information present", "gsm_a.classmark3.gsm_400_band_info_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_t_gsm_400_bands_supported,
|
|
{ "T-GSM 400 Bands Supported", "gsm_a.classmark3.t_gsm_400_bands_supported",
|
|
FT_UINT8, BASE_HEX, VALS(t_gsm_400_bands_supported_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_t_gsm_400_assoc_radio_cap,
|
|
{ "T-GSM 400 Associated Radio Capability", "gsm_a.classmark3.t_gsm_400_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_t_gsm_900_assoc_radio_cap_present,
|
|
{ "T-GSM 900 Associated Radio Capability present", "gsm_a.classmark3.t_gsm_900_assoc_radio_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_t_gsm_900_assoc_radio_cap,
|
|
{ "T-GSM 900 Associated Radio Capability", "gsm_a.classmark3.t_gsm_900_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_downlink_adv_receiver_perf,
|
|
{ "Downlink Advanced Receiver Performance", "gsm_a.classmark3.downlink_adv_receiver_perf",
|
|
FT_UINT8, BASE_DEC, VALS(downlink_adv_receiver_perf_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_enhancements_cap,
|
|
{ "DTM Enhancements Capability", "gsm_a.classmark3.dtm_enhancements_capability",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&dtm_enhancements_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_e_gprs_high_multi_slot_info_present,
|
|
{ "DTM E/GPRS High Multi Slot Information present", "gsm_a.classmark3.dtm_e_gprs_high_mutli_slot_info_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_gprs_high_multi_slot_class,
|
|
{ "DTM GPRS Multi Slot Class", "gsm_a.classmark3.dtm_gprs_multi_slot_class",
|
|
FT_UINT8, BASE_DEC, VALS(dtm_gprs_high_multi_slot_class_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_offset_required,
|
|
{ "Offset required", "gsm_a.classmark3.offset_required",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&offset_required_vals), 0x0,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_egprs_high_multi_slot_class_present,
|
|
{ "DTM EGPRS High Multi Slot Class present", "gsm_a.classmark3.dtm_egprs_high_multi_slot_class_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_dtm_egprs_high_multi_slot_class,
|
|
{ "DTM EGPRS High Multi Slot Class", "gsm_a.classmark3.dtm_egprs_high_multi_slot_class",
|
|
FT_UINT8, BASE_DEC, VALS(dtm_gprs_high_multi_slot_class_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_repeated_acch_cap,
|
|
{ "Repeated ACCH Capability", "gsm_a.classmark3.repeated_acch_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&repeated_acch_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_710_assoc_radio_cap_present,
|
|
{ "GSM 710 Associated Radio Capability present", "gsm_a.classmark3.gsm_710_assoc_radio_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_gsm_710_assoc_radio_cap,
|
|
{ "GSM 710 Associated Radio Capability", "gsm_a.classmark3.gsm_710_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_t_gsm_810_assoc_radio_cap_present,
|
|
{ "T-GSM 810 Associated Radio Capability present", "gsm_a.classmark3.t_gsm_810_assoc_radio_cap_present",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_t_gsm_810_assoc_radio_cap,
|
|
{ "T-GSM 810 Associated Radio Capability", "gsm_a.classmark3.t_gsm_810_assoc_radio_cap",
|
|
FT_UINT8, BASE_HEX, NULL, 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ciphering_mode_setting_cap,
|
|
{ "Ciphering Mode Setting Capability", "gsm_a.classmark3.ciphering_mode_setting_cap",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&ciphering_mode_setting_cap_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_additional_positioning_caps,
|
|
{ "Additional Positioning Capabilities", "gsm_a.classmark3.additional_positioning_caps",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&additional_positioning_caps_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_e_utra_fdd_support,
|
|
{ "E-UTRA FDD support", "gsm_a.classmark3.e_utra_fdd_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&e_utra_fdd_support_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_e_utra_tdd_support,
|
|
{ "E-UTRA TDD support", "gsm_a.classmark3.e_utra_tdd_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&e_utra_tdd_support_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_e_utra_meas_and_report_support,
|
|
{ "E-UTRA Measurement and Reporting support", "gsm_a.classmark3.e_utra_meas_and_report_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&e_utra_meas_and_report_support_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_prio_based_resel_support,
|
|
{ "Priority-based reselection support", "gsm_a.classmark3.prio_based_resel_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&prio_based_resel_support_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_utra_csg_cells_reporting,
|
|
{ "UTRA CSG Cells Reporting", "gsm_a.classmark3.utra_csg_cells_reporting",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&utra_csg_cells_reporting_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_vamos_level,
|
|
{ "VAMOS Level", "gsm_a.classmark3.vamos_level",
|
|
FT_UINT8, BASE_DEC, VALS(vamos_level_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_tighter_cap,
|
|
{ "TIGHTER Capability", "gsm_a.classmark3.tighter_cap",
|
|
FT_UINT8, BASE_DEC, VALS(tighter_cap_level_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_selective_ciph_down_sacch,
|
|
{ "Selective Ciphering of Downlink SACCH", "gsm_a.classmark3.selective_ciph_down_sacch",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_cs_to_ps_srvcc_geran_to_utra,
|
|
{ "CS to PS SRVCC from GERAN to UTRA", "gsm_a.classmark3.cs_to_ps_srvcc_geran_to_utra",
|
|
FT_UINT8, BASE_DEC, VALS(cs_to_ps_srvcc_geran_to_utra_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_cs_to_ps_srvcc_geran_to_eutra,
|
|
{ "CS to PS SRVCC from GERAN to E-UTRA", "gsm_a.classmark3.cs_to_ps_srvcc_geran_to_eutra",
|
|
FT_UINT8, BASE_DEC, VALS(cs_to_ps_srvcc_geran_to_eutra_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geran_network_sharing_support,
|
|
{ "GERAN Network Sharing support", "gsm_a.classmark3.geran_network_sharing_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_eutra_wb_rsrq_support,
|
|
{ "E-UTRA Wideband RSRQ measurements support", "gsm_a.classmark3.eutra_wb_rsrq_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_er_band_support,
|
|
{ "ER Band support", "gsm_a.classmark3.er_band_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_utra_mfbi_support,
|
|
{ "UTRA Multiple Frequency Band Indicators support", "gsm_a.classmark3.utra_mfbi_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_eutra_mfbi_support,
|
|
{ "E-UTRA Multiple Frequency Band Indicators support", "gsm_a.classmark3.eutra_mfbi_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ext_tsc_set_cap_support,
|
|
{ "Extended TSC Set Capability support", "gsm_a.classmark3.ext_tsc_set_cap_support",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_ext_earfcn_value_range,
|
|
{ "Extended EARFCN value range", "gsm_a.classmark3.ext_earfcn_value_range",
|
|
FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x00,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geo_loc_type_of_shape,
|
|
{ "Location estimate", "gsm_a.gad.location_estimate",
|
|
FT_UINT8, BASE_DEC, VALS(type_of_shape_vals), 0xf0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_sign_of_lat,
|
|
{ "Sign of latitude", "gsm_a.gad.sign_of_latitude",
|
|
FT_UINT8, BASE_DEC, VALS(sign_of_latitude_vals), 0x80,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_deg_of_lat,
|
|
{ "Degrees of latitude", "gsm_a.gad.deg_of_latitude",
|
|
FT_UINT24, BASE_DEC, NULL, 0x7fffff,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_deg_of_long,
|
|
{ "Degrees of longitude", "gsm_a.gad.deg_of_longitude",
|
|
FT_INT24, BASE_DEC, NULL, 0xffffff,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_osm_uri,
|
|
{ "Location OSM URI", "gsm_a.gad.location_uri",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_uncertainty_code,
|
|
{ "Uncertainty code", "gsm_a.gad.uncertainty_code",
|
|
FT_UINT8, BASE_DEC, NULL, 0x7f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_uncertainty_semi_major,
|
|
{ "Uncertainty semi-major", "gsm_a.gad.uncertainty_semi_major",
|
|
FT_UINT8, BASE_DEC, NULL, 0x7f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_uncertainty_semi_minor,
|
|
{ "Uncertainty semi-minor", "gsm_a.gad.uncertainty_semi_minor",
|
|
FT_UINT8, BASE_DEC, NULL, 0x7f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_orientation_of_major_axis,
|
|
{ "Orientation of major axis", "gsm_a.gad.orientation_of_major_axis",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_uncertainty_altitude,
|
|
{ "Uncertainty Altitude", "gsm_a.gad.uncertainty_altitude",
|
|
FT_UINT8, BASE_DEC, NULL, 0x7f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_confidence,
|
|
{ "Confidence(%)", "gsm_a.gad.confidence",
|
|
FT_UINT8, BASE_DEC, NULL, 0x7f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_no_of_points,
|
|
{ "Number of points", "gsm_a.gad.no_of_points",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_velocity_type,
|
|
{ "Number of points", "gsm_a.gad.velocity_type",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_velocity_type_vals), 0xf0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_bearing,
|
|
{ "Bearing", "gsm_a.gad.bearing",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_horizontal_speed,
|
|
{ "Horizontal Speed", "gsm_a.gad.horizontal_velocity",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_vertical_speed,
|
|
{ "Vertical Speed", "gsm_a.gad.vertical_speed",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_uncertainty_speed,
|
|
{ "Uncertainty Speed", "gsm_a.gad.uncertainty_speed",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_h_uncertainty_speed,
|
|
{ "Horizontal Uncertainty Speed", "gsm_a.gad.v_uncertainty_speed",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_v_uncertainty_speed,
|
|
{ "Vertical Uncertainty Speed", "gsm_a.gad.h_uncertainty_speed",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_d,
|
|
{ "Direction of Vertical Speed", "gsm_a.gad.d",
|
|
FT_BOOLEAN, 8, TFS(&gsm_a_dir_of_ver_speed_vals), 0x08,
|
|
NULL, HFILL}
|
|
},
|
|
{ &hf_gsm_a_geo_loc_D,
|
|
{ "D: Direction of Altitude", "gsm_a.gad.D",
|
|
FT_UINT16, BASE_DEC, VALS(dir_of_alt_vals), 0x8000,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_altitude,
|
|
{ "Altitude in meters", "gsm_a.gad.altitude",
|
|
FT_UINT16, BASE_DEC, NULL, 0x7fff,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_inner_radius,
|
|
{ "Inner radius", "gsm_a.gad.altitude",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_uncertainty_radius,
|
|
{ "Uncertainty radius", "gsm_a.gad.no_of_points",
|
|
FT_UINT8, BASE_DEC, NULL, 0x7f,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_offset_angle,
|
|
{ "Offset angle", "gsm_a.gad.offset_angle",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_geo_loc_included_angle,
|
|
{ "Included angle", "gsm_a.gad.included_angle",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_key_seq,
|
|
{ "key sequence", "gsm_a.key_seq",
|
|
FT_UINT8, BASE_DEC, VALS(gsm_a_key_seq_vals), 0x00,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_lac,
|
|
{ "Location Area Code (LAC)", "gsm_a.lac",
|
|
FT_UINT16, BASE_HEX_DEC, NULL, 0x00,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_gsm_a_spare_nibble,
|
|
{ "Spare Nibble", "gsm_a.spare",
|
|
FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
|
|
NULL, HFILL }
|
|
},
|
|
/* Generated from convert_proto_tree_add_text.pl */
|
|
{ &hf_gsm_a_filler, { "Filler", "gsm_a.filler", FT_UINT8, BASE_HEX, NULL, 0xF0, NULL, HFILL }},
|
|
{ &hf_gsm_a_identity_digit1, { "Identity Digit 1", "gsm_a.identity_digit1", FT_UINT8, BASE_HEX, NULL, 0xF0, NULL, HFILL }},
|
|
{ &hf_gsm_a_group_call_reference, { "Group or Broadcast call reference", "gsm_a.group_call_reference", FT_UINT32, BASE_DEC_HEX, NULL, 0xffffffe0, NULL, HFILL }},
|
|
{ &hf_gsm_a_service_flag, { "SF Service Flag", "gsm_a.service_flag", FT_BOOLEAN, 32, TFS(&tfs_vgcs_vbs), 0x00000010, NULL, HFILL }},
|
|
{ &hf_gsm_a_af_acknowledgement, { "AF Acknowledgement", "gsm_a.af_acknowledgement", FT_BOOLEAN, 32, TFS(&tfs_required_not_required), 0x00000008, NULL, HFILL }},
|
|
{ &hf_gsm_a_call_priority, { "Call Priority", "gsm_a.call_priority", FT_UINT32, BASE_DEC, VALS(gsm_a_call_priority_vals), 0x00000007, NULL, HFILL }},
|
|
{ &hf_gsm_a_ciphering_info, { "Ciphering Information", "gsm_a.ciphering_info", FT_UINT8, BASE_HEX, NULL, 0xf0, NULL, HFILL }},
|
|
{ &hf_gsm_a_sapi, { "SAPI (Service Access Point Identifier)", "gsm_a.sapi", FT_UINT8, BASE_DEC, VALS(gsm_a_sapi_vals), 0x30, NULL, HFILL }},
|
|
{ &hf_gsm_a_mobile_country_code, { "Mobile Country Code (MCC)", "gsm_a.mobile_country_code", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_gsm_a_mobile_network_code, { "Mobile Network Code (MNC)", "gsm_a.mobile_network_code", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
};
|
|
|
|
/* Setup protocol subtree array */
|
|
#define NUM_INDIVIDUAL_ELEMS 1
|
|
static gint *ett[NUM_INDIVIDUAL_ELEMS +
|
|
NUM_GSM_COMMON_ELEM];
|
|
|
|
static ei_register_info ei[] = {
|
|
{ &ei_gsm_a_extraneous_data, { "gsm_a.extraneous_data", PI_PROTOCOL, PI_NOTE, "Extraneous Data, dissector bug or later version spec(report to wireshark.org)", EXPFILL }},
|
|
{ &ei_gsm_a_unknown_element, { "gsm_a.unknown_element", PI_PROTOCOL, PI_ERROR, "Unknown - aborting dissection", EXPFILL }},
|
|
{ &ei_gsm_a_unknown_pdu_type, { "gsm_a.unknown_pdu_type", PI_PROTOCOL, PI_WARN, "Unknown PDU type", EXPFILL }},
|
|
{ &ei_gsm_a_no_element_dissector, { "gsm_a.no_element_dissector", PI_PROTOCOL, PI_WARN, "No element dissector, rest of dissection may be incorrect", EXPFILL }},
|
|
{ &ei_gsm_a_format_not_supported, { "gsm_a.format_not_supported", PI_PROTOCOL, PI_WARN, "Format not supported", EXPFILL }},
|
|
{ &ei_gsm_a_mobile_identity_type, { "gsm_a.ie.mobileid.type.unknown", PI_PROTOCOL, PI_WARN, "Format unknown", EXPFILL }},
|
|
};
|
|
|
|
expert_module_t* expert_a_common;
|
|
|
|
static tap_param gsm_a_stat_params[] = {
|
|
{ PARAM_FILTER, "filter", "Filter", NULL, TRUE }
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_bssmap_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface BSSMAP",
|
|
"gsm_a",
|
|
"gsm_a,bssmap",
|
|
gsm_a_bssmap_stat_init,
|
|
gsm_a_bssmap_stat_packet,
|
|
gsm_a_stat_reset,
|
|
gsm_a_stat_free_table_item,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_mm_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP Mobility Management",
|
|
"gsm_a",
|
|
"gsm_a,dtap_mm",
|
|
gsm_a_dtap_mm_stat_init,
|
|
gsm_a_dtap_mm_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_rr_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP Radio Resource Management",
|
|
"gsm_a",
|
|
"gsm_a,dtap_rr",
|
|
gsm_a_dtap_rr_stat_init,
|
|
gsm_a_dtap_rr_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_cc_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP Call Control",
|
|
"gsm_a",
|
|
"gsm_a,dtap_cc",
|
|
gsm_a_dtap_cc_stat_init,
|
|
gsm_a_dtap_cc_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_gmm_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP GPRS Mobility Management",
|
|
"gsm_a",
|
|
"gsm_a,dtap_gmm",
|
|
gsm_a_dtap_gmm_stat_init,
|
|
gsm_a_dtap_gmm_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_sm_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP GPRS Session Management",
|
|
"gsm_a",
|
|
"gsm_a,dtap_sm",
|
|
gsm_a_dtap_sm_stat_init,
|
|
gsm_a_dtap_sm_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_sms_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP Short Message Service",
|
|
"gsm_a",
|
|
"gsm_a,dtap_sms",
|
|
gsm_a_dtap_sms_stat_init,
|
|
gsm_a_dtap_sms_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_tp_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP Special Conformance Testing Functions",
|
|
"gsm_a",
|
|
"gsm_a,dtap_tp",
|
|
gsm_a_dtap_tp_stat_init,
|
|
gsm_a_dtap_tp_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_dtap_ss_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface DTAP Supplementary Services",
|
|
"gsm_a",
|
|
"gsm_a,dtap_ss",
|
|
gsm_a_dtap_ss_stat_init,
|
|
gsm_a_dtap_ss_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
static stat_tap_table_ui gsm_a_sacch_rr_stat_table = {
|
|
REGISTER_STAT_GROUP_TELEPHONY_GSM,
|
|
"A-Interface SACCH",
|
|
"gsm_a",
|
|
"gsm_a,dtap_sacch",
|
|
gsm_a_sacch_rr_stat_init,
|
|
gsm_a_sacch_rr_stat_packet,
|
|
gsm_a_stat_reset,
|
|
NULL,
|
|
NULL,
|
|
sizeof(gsm_a_stat_fields)/sizeof(stat_tap_table_item), gsm_a_stat_fields,
|
|
sizeof(gsm_a_stat_params)/sizeof(tap_param), gsm_a_stat_params,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
last_offset = NUM_INDIVIDUAL_ELEMS;
|
|
|
|
ett[0] = &ett_gsm_a_plmn;
|
|
for (i=0; i < NUM_GSM_COMMON_ELEM; i++, last_offset++)
|
|
{
|
|
ett_gsm_common_elem[i] = -1;
|
|
ett[last_offset] = &ett_gsm_common_elem[i];
|
|
}
|
|
|
|
/* Register the protocol name and description */
|
|
|
|
proto_a_common =
|
|
proto_register_protocol("GSM A-I/F COMMON", "GSM COMMON", "gsm_a");
|
|
|
|
proto_register_field_array(proto_a_common, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
expert_a_common = expert_register_protocol(proto_a_common);
|
|
expert_register_field_array(expert_a_common, ei, array_length(ei));
|
|
|
|
|
|
gsm_a_tap = register_tap("gsm_a");
|
|
|
|
register_stat_tap_table_ui(&gsm_a_bssmap_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_mm_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_rr_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_cc_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_gmm_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_sms_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_sm_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_ss_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_dtap_tp_stat_table);
|
|
register_stat_tap_table_ui(&gsm_a_sacch_rr_stat_table);
|
|
}
|
|
|
|
/*
|
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
|
*
|
|
* Local variables:
|
|
* c-basic-offset: 4
|
|
* tab-width: 8
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
*/
|