diff options
-rw-r--r-- | src/isi-gps.c | 1004 | ||||
-rw-r--r-- | src/isi-gps.h | 4 | ||||
-rw-r--r-- | src/packet-isi.c | 6 | ||||
-rw-r--r-- | src/packet-isi.h | 1 |
4 files changed, 756 insertions, 259 deletions
diff --git a/src/isi-gps.c b/src/isi-gps.c index 188fb74..c262cf6 100644 --- a/src/isi-gps.c +++ b/src/isi-gps.c @@ -1,6 +1,6 @@ /* isi-gps.c - * Dissector for ISI's GPS resource - * Copyright 2010, Sebastian Reichel <sre@ring0.de> + * Dissector for ISI's Location resource + * Copyright 2010-2015, Sebastian Reichel <sre@ring0.de> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -32,314 +32,808 @@ #define CMS_TO_KMH 0.036 #define SAT_PKG_LEN 12 -static const value_string isi_gps_id[] = { - //{0x0d, "GPS_UNKNOWN_0D"}, - //{0x0e, "GPS_UNKNOWN_0E"}, - {0x7d, "GPS_STATUS_IND"}, - //{0x7e, "GPS_UNKNOWN_7E"}, - //{0x7f, "GPS_UNKNOWN_7F"}, - //{0x82, "GPS_UNKNOWN_82"}, - //{0x83, "GPS_UNKNOWN_83"}, - //{0x84, "GPS_UNKNOWN_84"}, - //{0x85, "GPS_UNKNOWN_85"}, - //{0x90, "GPS_UNKNOWN_90"}, - //{0x91, "GPS_UNKNOWN_91"}, - {0x90, "GPS_POWER_STATUS_REQ"}, - {0x91, "GPS_POWER_STATUS_RSP"}, - {0x92, "GPS_DATA_IND"}, +static const value_string isi_location_id[] = { + {0x00, "LS_LOCATION_REQ"}, + {0x01, "LS_LOCATION_RESP"}, + {0x02, "LS_LOCATION_NTF"}, + {0x03, "LS_LOCATION_STOP_REQ"}, + {0x04, "LS_LOCATION_STOP_RESP"}, + {0x07, "LS_METHOD_INFORMATION_REQ"}, + {0x08, "LS_METHOD_INFORMATION_RESP"}, + {0x09, "LS_METHOD_INFORMATION_IND"}, + {0x0A, "LS_SERVICE_REQUIRED_REQ"}, + {0x0B, "LS_SERVICE_REQUIRED_RESP"}, + {0x0C, "LS_SERVICE_REQUIRED_IND"}, + {0x0D, "LS_PRIVACY_REGISTRATION_REQ"}, + {0x0E, "LS_PRIVACY_REGISTRATION_RESP"}, + {0x0F, "LS_PRIVACY_NTF"}, + {0x10, "LS_PRIVACY_NOTIFICATION_RESULT_REQ"}, + {0x11, "LS_PRIVACY_NOTIFICATION_RESULT_RESP"}, + {0x12, "LS_METHOD_REGISTRATION_REQ"}, + {0x13, "LS_METHOD_REGISTRATION_RESP"}, + {0x14, "LS_METHOD_ASSISTANCE_REQ"}, + {0x15, "LS_METHOD_ASSISTANCE_RESP"}, + {0x20, "LS_NMEA_LISTENER_REQ"}, + {0x21, "LS_NMEA_LISTENER_RESP"}, + {0x22, "LS_NMEA_LISTENER_NTF"}, + {0x30, "LS_CLEAR_GPS_DATA_REQ"}, + {0x31, "LS_CLEAR_GPS_DATA_RESP"}, + {0x32, "LS_PING_REQ"}, + {0x33, "LS_PING_RESP"}, + {0x34, "LS_PING_NTF"}, + {0x36, "LS_LTM_TEST_REQ"}, + {0x37, "LS_LTM_TEST_RESP"}, + {0x38, "LS_LTM_TEST_NTF"}, + {0x39, "LS_HW_CONN_TEST_REQ"}, + {0x3A, "LS_HW_CONN_TEST_RESP"}, + {0x40, "LS_GSM_PRIVACY_REQ"}, + {0x41, "LS_GSM_PRIVACY_RESP"}, + {0x42, "LS_GSM_PRIVACY_TIMEOUT_REQ"}, + {0x43, "LS_GSM_PRIVACY_TIMEOUT_RESP"}, + {0x44, "LS_GSM_LOCATE_REQ"}, + {0x45, "LS_GSM_LOCATE_RESP"}, + {0x50, "LS_SUPL_LISTENER_REGISTRATION_REQ"}, + {0x51, "LS_SUPL_LISTENER_REGISTRATION_RESP"}, + {0x52, "LS_SUPL_CREATE_SESSION_REQUEST_NTF"}, + {0x53, "LS_SUPL_CREATE_SESSION_RESPONSE_NTF"}, + {0x54, "LS_SUPL_SESSION_END_NTF"}, + {0x55, "LS_SUPL_GET_SUPL_INFO_REQ"}, + {0x56, "LS_SUPL_GET_SUPL_INFO_RESP"}, + {0x57, "LS_SUPL_CANCEL_SUPL_INFO_REQ"}, + {0x58, "LS_SUPL_CANCEL_SUPL_INFO_RESP"}, + {0x59, "LS_SUPL_POS_NTF"}, + {0x5A, "LS_SUPL_POS_ACK_NTF"}, + {0x5B, "LS_SUPL_POS_END_NTF"}, + {0x5C, "LS_SUPL_SESSION_STATUS_REQUEST_NTF"}, + {0x5D, "LS_SUPL_SESSION_STATUS_RESPONSE_NTF"}, + {0x5E, "LS_SUPL_POSITION_FIX_NTF"}, + {0x60, "LS_WCDMA_LOCATE_REQ"}, + {0x61, "LS_WCDMA_LOCATE_RESP"}, + {0x62, "LS_WCDMA_LOCATE_NTF"}, + {0x63, "LS_SOURCE_LIST_REQ"}, + {0x64, "LS_SOURCE_LIST_RESP"}, + {0x65, "LS_TRACKING_START_REQ"}, + {0x66, "LS_TRACKING_START_RESP"}, + {0x67, "LS_TRACKING_DATA_NTF"}, + {0x68, "LS_TRACKING_STOP_REQ"}, + {0x69, "LS_TRACKING_STOP_RESP"}, + {0x70, "LS_POSITIONING_SUPPORT_REQ"}, + {0x71, "LS_POSITIONING_SUPPORT_RESP"}, + {0x72, "LS_POSITIONING_SUPPORT_NTF"}, + {0x73, "LS_GPS_STATUS_REQ"}, + {0x74, "LS_GPS_STATUS_RESP"}, + {0x76, "LS_SUPL_ALLOWED_REQ"}, + {0x77, "LS_SUPL_ALLOWED_RESP"}, + {0x78, "LS_SENSOR_REGISTRATION_REQ"}, + {0x79, "LS_SENSOR_REGISTRATION_RESP"}, + {0x7A, "LS_SENSOR_EVENT_REQ"}, + {0x7B, "LS_SENSOR_EVENT_RESP"}, + {0x7C, "LS_SENSOR_NTF"}, + {0x7D, "LS_GPS_STATUS_IND"}, + {0x7E, "LS_SUPL_SERVER_CONF_REQ"}, + {0x7F, "LS_SUPL_SERVER_CONF_RESP"}, + {0x80, "LS_SUPL_NW_INIT_REQ"}, + {0x81, "LS_SUPL_NW_INIT_RESP"}, + {0x82, "LS_SOCKET_REGISTRATION_REQ"}, + {0x83, "LS_SOCKET_REGISTRATION_RESP"}, + {0x84, "LS_SOCKET_OPEN_REQUEST_NTF"}, + {0x85, "LS_SOCKET_OPEN_RESPONSE_NTF"}, + {0x86, "LS_SOCKET_SEND_REQUEST_NTF"}, + {0x87, "LS_SOCKET_SEND_RESPONSE_NTF"}, + {0x88, "LS_SOCKET_RECV_REQ"}, + {0x89, "LS_SOCKET_RECV_RESP"}, + {0x8A, "LS_SOCKET_CLOSE_REQUEST_NTF"}, + {0x8B, "LS_SOCKET_CLOSE_RESPONSE_NTF"}, + {0x8C, "LS_SOCKET_CLOSED_REQ"}, + {0x8D, "LS_SOCKET_CLOSED_RESP"}, + {0x90, "LS_HYBRID_TRACKING_REQ"}, + {0x91, "LS_HYBRID_TRACKING_RESP"}, + {0x92, "LS_HYBRID_TRACKING_NTF"}, + {0xA0, "LS_GPS_ANTENNA_CTRL_REQ"}, + {0xA1, "LS_GPS_ANTENNA_CTRL_RESP"}, + {0xE0, "LS_DEBUG_REQ"}, + {0xE1, "LS_DEBUG_RESP"}, {0x00, NULL } }; -static const value_string isi_gps_sub_id[] = { - {0x02, "GPS_POSITION"}, - {0x03, "GPS_TIME_DATE"}, - {0x04, "GPS_MOVEMENT"}, - {0x05, "GPS_SAT_INFO"}, - {0x07, "GPS_CELL_INFO_GSM"}, - {0x08, "GPS_CELL_INFO_WCDMA"}, +static const value_string isi_location_sub_id[] = { + {0x0103, "LS_SB_PRIVACY"}, + {0x0105, "LS_SB_JAVA_INFO"}, + {0x0108, "LS_SB_CDMA_WAP_INFO"}, + {0x0109, "LS_SB_SS_REQUESTOR_ID"}, + {0x010A, "LS_SB_SS_CODEWORD"}, + {0x010B, "LS_SB_SS_SERVICE_TYPE_ID"}, + {0x0130, "LS_SB_LATITUDE_LONGITUDE"}, + {0x0131, "LS_SB_ALTITUDE"}, + {0x0132, "LS_SB_VELOCITY"}, + {0x0133, "LS_SB_NMEA_0183"}, + {0x0134, "LS_SB_TIMESTAMP"}, + {0x0135, "LS_SB_NMEA_OPTIONS"}, + {0x0160, "LS_SB_GPS_EXACT_TIME"}, + {0x0161, "LS_SB_GPS_USER_DOPS"}, + {0x0162, "LS_SB_GPS_SAT_LIST"}, + {0x0163, "LS_SB_GPS_CHANNEL_STATUS"}, + {0x0524, "LS_SB_GSM_MULTIPLE_SETS"}, + {0x0529, "LS_SB_GSM_MEAS_ERROR_INFO"}, + {0x052A, "LS_SB_GSM_POSITIONING_INSTR"}, + {0x052B, "LS_SB_GSM_LOCATION_INFO"}, + {0x052C, "LS_SB_GSM_GPS_MEAS_INFO"}, + {0x052D, "LS_SB_GSM_EXT_REF_ID"}, + {0x0530, "LS_SB_GSM_GPS_TIME_ASSIST_MEAS"}, + {0x0531, "LS_SB_GSM_REQUIRED_RESPONSE_TIME"}, + {0x0551, "LS_SB_SS_CLIENT_EXT_ID"}, + {0x0554, "LS_SB_SS_CLIENT_NAME"}, + {0x0556, "LS_SB_SS_NOTIFICATION_INFO"}, + {0x0689, "LS_SB_LTM_TEST_ABORT"}, + {0x070B, "LS_SB_LTM_AI2_CMD_PACKET"}, + {0x070C, "LS_SB_LTM_AI2_RSP_PACKET"}, + {0x070D, "LS_SB_LTM_DELETE_ASSISTANCE_DATA"}, + {0x0800, "LS_SB_SUPL_TIMESTAMP"}, + {0x0801, "LS_SB_SUPL_POSITION"}, + {0x0802, "LS_SB_SUPL_VELOCITY"}, + {0x0803, "LS_SB_SUPL_ALLOWED_CAPABILITIES"}, + {0x0804, "LS_SB_SUPL_INFO_SET_CAPABILITIES"}, + {0x0805, "LS_SB_SUPL_INFO_AD_REQUEST"}, + {0x0806, "LS_SB_SUPL_POS"}, + {0x0807, "LS_SB_SUPL_RRLP_LOOPBACK"}, + {0x0808, "LS_SB_SUPL_QOP"}, + {0x0809, "LS_SB_SUPL_SESSION_POSITION"}, + {0x080A, "LS_SB_SUPL_SERVER_METHOD"}, + {0x0900, "LS_SB_CLIENT_IDENT"}, + {0x0901, "LS_SB_HYBRID_TRACKING_INSTR"}, + {0x0902, "LS_SB_NPE_POSITION"}, + {0x0903, "LS_SB_NPE_TIME"}, + {0x0904, "LS_SB_NPE_VELOCITY"}, + {0x0905, "LS_SB_NPE_CHANNELS"}, + {0x0906, "LS_SB_NPE_NMEA"}, + {0x0907, "LS_SB_CELL_INFO_GSM"}, + {0x0908, "LS_SB_CELL_INFO_WCDMA"}, + {0x0999, "CLMI_SB_ASTNC_GPS_CURR_NAV_MODEL"}, + {0x0A00, "LS_SB_WCDMA_POSITIONING_INSTR"}, + {0x0A01, "LS_SB_WCDMA_LOCATION_INFO"}, + {0x0A02, "LS_SB_WCDMA_MEAS_ERROR_INFO"}, + {0x0A03, "LS_SB_WCDMA_GPS_MEAS_INFO"}, + {0x1012, "CLMI_SB_ASTNC_GPS_DGPS_CORRECTIONS"}, + {0x1013, "CLMI_SB_ASTNC_GPS_EPHEMERIS"}, + {0x1014, "CLMI_SB_ASTNC_GPS_IONOSPHERIC"}, + {0x1015, "CLMI_SB_ASTNC_GPS_UTC"}, + {0x1016, "CLMI_SB_ASTNC_GPS_ALMANAC"}, + {0x1017, "CLMI_SB_ASTNC_GPS_BAD_SATELLITES"}, + {0x101B, "CLMI_SB_ASTNC_GPS_ACQUISITION"}, + {0x1030, "CLMI_SB_ASTNC_GPS_REF_TIME"}, + {0x1031, "CLMI_SB_ASTNC_GPS_REF_TIME_UMTS"}, + {0x1032, "CLMI_SB_ASTNC_GPS_REF_TIME_GSM"}, + {0x1048, "CLMI_SB_ASTNC_FRAME_TRIGGER_UMTS"}, + {0x1049, "CLMI_SB_ASTNC_FRAME_TRIGGER_GSM"}, + {0x104A, "CLMI_SB_GPS_TOW_RELATION_UMTS"}, + {0x104B, "CLMI_SB_GPS_TOW_RELATION_GSM"}, + {0x1100, "LS_SB_SENSOR_REGISTRATION_STATUS"}, + {0x1101, "LS_SB_SENSOR_TYPE"}, + {0x1102, "LS_SB_SENSOR_ACCELEROMETER_ACTION"}, + {0x1200, "LS_SB_SOCKET_ADDR"}, + {0x1201, "LS_SB_SOCKET_ADDR_EXT"}, + {0x1202, "LS_SB_SOCKET_BEARER_TYPE"}, + {0x1203, "LS_SB_SOCKET_IPADDR"}, + {0xEFEE, "LS_SB_METHOD_INFORMATION"}, + {0xEEEF, "CLMI_SB_GPS_PSEUDORANGE_MEAS"}, + {0x0000, NULL} +}; + +static const value_string isi_location_socket_addr_type[] = { + {0x00, "IPV4"}, + {0x01, "IPv6"}, + {0x02, "FQDN"}, + {0x00, NULL } +}; + +static const value_string isi_location_gps_power[] = { + {0x00, "GPS_OFF"}, + {0x01, "GPS_ON"}, + {0x00, NULL } +}; + +static const value_string isi_location_gps_status[] = { + {0x00, "GPS_STATE_NONE"}, + {0x01, "GPS_STATE_SEARCH"}, + {0x02, "GPS_STATE_FIX"}, + {0x03, "GPS_STATE_SLEEP"}, + {0x00, NULL } +}; + +static const value_string isi_location_bearer_type[] = { + {0x02, "BEARER_GPRS"}, + {0x04, "BEARER_WLAN"}, {0x00, NULL } }; -static const value_string isi_gps_status[] = { - {0x00, "GPS_DISABLED"}, - {0x01, "GPS_NO_LOCK"}, - {0x02, "GPS_LOCK"}, +static const value_string isi_location_hybrid_cmd[] = { + {0x00, "MEASUREMENT_START"}, + {0x01, "MEASUREMENT_MODIFY"}, + {0x02, "MEASUREMENT_STOP"}, {0x00, NULL } }; -static dissector_handle_t isi_gps_handle; -static void dissect_isi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_item *tree); - -static gint32 hf_isi_gps_cmd = -1; -static gint32 hf_isi_gps_sub_pkgs = -1; -static gint32 hf_isi_gps_sub_type = -1; -static gint32 hf_isi_gps_sub_len = -1; -static gint32 hf_isi_gps_status = -1; -static gint32 hf_isi_gps_year = -1; -static gint32 hf_isi_gps_month = -1; -static gint32 hf_isi_gps_day = -1; -static gint32 hf_isi_gps_hour = -1; -static gint32 hf_isi_gps_minute = -1; -static gint32 hf_isi_gps_second = -1; -static gint32 hf_isi_gps_latitude = -1; -static gint32 hf_isi_gps_longitude = -1; -static gint32 hf_isi_gps_eph = -1; -static gint32 hf_isi_gps_altitude = -1; -static gint32 hf_isi_gps_epv = -1; -static gint32 hf_isi_gps_course = -1; -static gint32 hf_isi_gps_epd = -1; -static gint32 hf_isi_gps_speed = -1; -static gint32 hf_isi_gps_eps = -1; -static gint32 hf_isi_gps_climb = -1; -static gint32 hf_isi_gps_epc = -1; -static gint32 hf_isi_gps_mcc = -1; -static gint32 hf_isi_gps_mnc = -1; -static gint32 hf_isi_gps_lac = -1; -static gint32 hf_isi_gps_cid = -1; -static gint32 hf_isi_gps_ucid = -1; -static gint32 hf_isi_gps_satellites = -1; -static gint32 hf_isi_gps_prn = -1; -static gint32 hf_isi_gps_sat_used = -1; -static gint32 hf_isi_gps_sat_strength = -1; -static gint32 hf_isi_gps_sat_elevation = -1; -static gint32 hf_isi_gps_sat_azimuth = -1; - -void proto_reg_handoff_isi_gps(void) { +static const value_string isi_location_hybrid_report_criteria[] = { + {0x00, "LS_HYBRID_REPORT_AT_ALL_INTERVALS"}, + {0x01, "LS_HYBRID_REPORT_ONLY_POSITION_CHANGES"}, + {0x00, NULL } +}; + +static const value_string isi_location_hybrid_cause[] = { + {0x00, "LS_HYBRID_CAUSE_SUCCESS"}, + {0x01, "LS_HYBRID_CAUSE_NO_POSITION_YET"}, + {0x02, "LS_HYBRID_CAUSE_ERROR_UNSPECIFIED"}, + {0x03, "LS_HYBRID_CAUSE_ERROR_NO_METHODS"}, + {0x00, NULL } +}; + +static const value_string isi_location_socket_status[] = { + {0x00, "OK"}, + {0x01, "ERROR"}, + {0x02, "SERVER_NOT_AUTHENTICATED"}, + {0x00, NULL } +}; + +static dissector_handle_t isi_location_handle; +static void dissect_isi_location(tvbuff_t *tvb, packet_info *pinfo, proto_item *tree); + +static gint32 hf_isi_location_cmd = -1; +static gint32 hf_isi_location_sub_pkgs = -1; +static gint32 hf_isi_location_sub_type = -1; +static gint32 hf_isi_location_sub_len = -1; +static gint32 hf_isi_location_gps_power = -1; +static gint32 hf_isi_location_gps_status = -1; +static gint32 hf_isi_location_year = -1; +static gint32 hf_isi_location_month = -1; +static gint32 hf_isi_location_day = -1; +static gint32 hf_isi_location_hour = -1; +static gint32 hf_isi_location_minute = -1; +static gint32 hf_isi_location_second = -1; +static gint32 hf_isi_location_latitude = -1; +static gint32 hf_isi_location_longitude = -1; +static gint32 hf_isi_location_eph = -1; +static gint32 hf_isi_location_altitude = -1; +static gint32 hf_isi_location_epv = -1; +static gint32 hf_isi_location_course = -1; +static gint32 hf_isi_location_epd = -1; +static gint32 hf_isi_location_speed = -1; +static gint32 hf_isi_location_eps = -1; +static gint32 hf_isi_location_climb = -1; +static gint32 hf_isi_location_epc = -1; +static gint32 hf_isi_location_mcc = -1; +static gint32 hf_isi_location_mnc = -1; +static gint32 hf_isi_location_lac = -1; +static gint32 hf_isi_location_cid = -1; +static gint32 hf_isi_location_ucid = -1; +static gint32 hf_isi_location_satellites = -1; +static gint32 hf_isi_location_prn = -1; +static gint32 hf_isi_location_sat_used = -1; +static gint32 hf_isi_location_sat_strength = -1; +static gint32 hf_isi_location_sat_elevation = -1; +static gint32 hf_isi_location_sat_azimuth = -1; +static gint32 hf_isi_location_socket_addr_port = -1; +static gint32 hf_isi_location_socket_addr_type = -1; +static gint32 hf_isi_location_socket_addr_ip_len = -1; +static gint32 hf_isi_location_socket_addr_fqdn_len = -1; +static gint32 hf_isi_location_socket_addr_ipv4 = -1; +static gint32 hf_isi_location_socket_addr_ipv6 = -1; +static gint32 hf_isi_location_socket_addr_fqdn = -1; +static gint32 hf_isi_location_socket_bearer = -1; +static gint32 hf_isi_location_hybrid_cmd = -1; +static gint32 hf_isi_location_hybrid_allowed_methods = -1; +static gint32 hf_isi_location_hybrid_options = -1; +static gint32 hf_isi_location_hybrid_interval = -1; +static gint32 hf_isi_location_hybrid_report_criteria = -1; +static gint32 hf_isi_location_hybrid_acwp_timer = -1; +static gint32 hf_isi_location_hybrid_method_cwp = -1; +static gint32 hf_isi_location_hybrid_method_acwp = -1; +static gint32 hf_isi_location_hybrid_method_gnss = -1; +static gint32 hf_isi_location_hybrid_method_agnss = -1; +static gint32 hf_isi_location_hybrid_option_channel_status = -1; +static gint32 hf_isi_location_hybrid_option_cell_info = -1; +static gint32 hf_isi_location_hybrid_option_nmea_0183 = -1; +static gint32 hf_isi_location_hybrid_client_id = -1; +static gint32 hf_isi_location_hybrid_npe_id = -1; +static gint32 hf_isi_location_cause = -1; +static gint32 hf_isi_location_status = -1; +static gint32 hf_isi_location_status_ok = -1; +static gint32 hf_isi_location_status_complete = -1; +static gint32 hf_isi_location_status_fix = -1; +static gint32 hf_isi_location_status_meas_fix = -1; +static gint32 hf_isi_location_socket_descriptor = -1; +static gint32 hf_isi_location_socket_status = -1; +static gint32 hf_isi_location_socket_error = -1; +static gint32 hf_isi_location_data_len = -1; +static gint32 hf_isi_location_data = -1; + +static gint ett_flags_methods = -1; +static gint ett_flags_options = -1; +static gint ett_flags_status = -1; + +static dissector_handle_t supl_handle; + +static const int *isi_location_hybrid_method_flags[] = { + &hf_isi_location_hybrid_method_cwp, + &hf_isi_location_hybrid_method_acwp, + &hf_isi_location_hybrid_method_gnss, + &hf_isi_location_hybrid_method_agnss, + NULL +}; + +static const int *isi_location_hybrid_option_flags[] = { + &hf_isi_location_hybrid_option_channel_status, + &hf_isi_location_hybrid_option_cell_info, + &hf_isi_location_hybrid_option_nmea_0183, + NULL +}; + +static const int *isi_location_hybrid_status_flags[] = { + &hf_isi_location_status_ok, + &hf_isi_location_status_complete, + &hf_isi_location_status_fix, + &hf_isi_location_status_meas_fix, + NULL +}; + + +void proto_reg_handoff_isi_location(void) { static gboolean initialized=FALSE; if (!initialized) { - isi_gps_handle = create_dissector_handle(dissect_isi_gps, proto_isi); - dissector_add_uint("isi.resource", 0x54, isi_gps_handle); + isi_location_handle = create_dissector_handle(dissect_isi_location, proto_isi); + dissector_add_uint("isi.resource", 0x54, isi_location_handle); + + supl_handle = find_dissector("ulp"); } } -void proto_register_isi_gps(void) { +void proto_register_isi_location(void) { static hf_register_info hf[] = { - { &hf_isi_gps_cmd, - { "Command", "isi.gps.cmd", FT_UINT8, BASE_HEX, isi_gps_id, 0x0, "Command", HFILL }}, - { &hf_isi_gps_sub_pkgs, - { "Number of Subpackets", "isi.gps.pkgs", FT_UINT8, BASE_DEC, NULL, 0x0, "Number of Subpackets", HFILL }}, - { &hf_isi_gps_sub_type, - { "Subpacket Type", "isi.gps.sub.type", FT_UINT8, BASE_HEX, isi_gps_sub_id, 0x0, "Subpacket Type", HFILL }}, - { &hf_isi_gps_sub_len, - { "Subpacket Length", "isi.gps.sub.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Subpacket Length", HFILL }}, - { &hf_isi_gps_status, - { "Status", "isi.gps.status", FT_UINT8, BASE_HEX, isi_gps_status, 0x0, "Status", HFILL }}, - { &hf_isi_gps_year, - { "Year", "isi.gps.date.year", FT_UINT16, BASE_DEC, NULL, 0x0, "Year", HFILL }}, - { &hf_isi_gps_month, - { "Month", "isi.gps.date.month", FT_UINT8, BASE_DEC, NULL, 0x0, "Month", HFILL }}, - { &hf_isi_gps_day, - { "Day", "isi.gps.date.day", FT_UINT8, BASE_DEC, NULL, 0x0, "Day", HFILL }}, - { &hf_isi_gps_hour, - { "Hour", "isi.gps.time.hour", FT_UINT8, BASE_DEC, NULL, 0x0, "Hour", HFILL }}, - { &hf_isi_gps_minute, - { "Minute", "isi.gps.time.minute", FT_UINT8, BASE_DEC, NULL, 0x0, "Minute", HFILL }}, - { &hf_isi_gps_second, - { "Second", "isi.gps.time.second", FT_FLOAT, BASE_NONE, NULL, 0x0, "Second", HFILL }}, - { &hf_isi_gps_latitude, - { "Latitude", "isi.gps.lat", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Latitude", HFILL }}, - { &hf_isi_gps_longitude, - { "Longitude", "isi.gps.lon", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Longitude", HFILL }}, - { &hf_isi_gps_eph, - { "Position Accuracy", "isi.gps.eph", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPH (position accuracy) in meter", HFILL }}, - { &hf_isi_gps_altitude, - { "Altitude", "isi.gps.alt", FT_INT16, BASE_DEC, NULL, 0x0, "Altitude in meter", HFILL }}, - { &hf_isi_gps_epv, - { "Altitude Accuracy", "isi.gps.epv", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPV (altitude accuracy) in meter", HFILL }}, - { &hf_isi_gps_course, - { "Course", "isi.gps.course", FT_FLOAT, BASE_NONE, NULL, 0x0, "Course in degree", HFILL }}, - { &hf_isi_gps_epd, - { "Course Accuracy", "isi.gps.epd", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPD (course accuracy) in degree", HFILL }}, - { &hf_isi_gps_speed, - { "Speed", "isi.gps.speed", FT_FLOAT, BASE_NONE, NULL, 0x0, "Speed in km/h", HFILL }}, - { &hf_isi_gps_eps, - { "Speed Accuracy", "isi.gps.eps", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPS (speed accuracy) in km/h", HFILL }}, - { &hf_isi_gps_climb, - { "Climb", "isi.gps.climb", FT_FLOAT, BASE_NONE, NULL, 0x0, "Climb in km/h", HFILL }}, - { &hf_isi_gps_satellites, - { "Visible Satellites", "isi.gps.satellites", FT_UINT8, BASE_DEC, NULL, 0x0, "Visible Satellites", HFILL }}, - { &hf_isi_gps_prn, - { "Pseudeorandom Noise (PRN)", "isi.gps.sat.prn", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, "Pseudeorandom Noise (PRN)", HFILL }}, - { &hf_isi_gps_sat_used, - { "in use", "isi.gps.sat.used", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "in use", HFILL }}, - { &hf_isi_gps_sat_strength, - { "Signal Strength", "isi.gps.sat.strength", FT_FLOAT, BASE_NONE, NULL, 0x0, "Signal Strength", HFILL }}, - { &hf_isi_gps_sat_elevation, - { "Elevation", "isi.gps.sat.elevation", FT_FLOAT, BASE_NONE, NULL, 0x0, "Elevation", HFILL }}, - { &hf_isi_gps_sat_azimuth, - { "Azimuth", "isi.gps.sat.azimuth", FT_FLOAT, BASE_NONE, NULL, 0x0, "Azimuth", HFILL }}, - { &hf_isi_gps_epc, - { "Climb Accuracy", "isi.gps.epc", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPC (climb accuracy) in km/h", HFILL }}, - { &hf_isi_gps_mcc, - { "Mobile Country Code (MCC)", "isi.gps.gsm.mcc", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Mobile Country Code (MCC)", HFILL }}, - { &hf_isi_gps_mnc, - { "Mobile Network Code (MNC)", "isi.gps.gsm.mnc", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Mobile Network Code (MNC)", HFILL }}, - { &hf_isi_gps_lac, - { "Location Area Code (LAC)", "isi.gps.gsm.lac", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Location Area Code (LAC)", HFILL }}, - { &hf_isi_gps_cid, - { "Cell ID (CID)", "isi.gps.gsm.cid", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Cell ID (CID)", HFILL }}, - { &hf_isi_gps_ucid, - { "Cell ID (UCID)", "isi.gps.gsm.ucid", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, "Cell ID (UCID)", HFILL }} + { &hf_isi_location_cmd, + { "Command", "isi.location.cmd", FT_UINT8, BASE_HEX, isi_location_id, 0x0, "Command", HFILL }}, + { &hf_isi_location_sub_pkgs, + { "Number of Subpackets", "isi.location.pkgs", FT_UINT8, BASE_DEC, NULL, 0x0, "Number of Subpackets", HFILL }}, + { &hf_isi_location_sub_type, + { "Subpacket Type", "isi.location.sub.type", FT_UINT16, BASE_HEX, isi_location_sub_id, 0x0, "Subpacket Type", HFILL }}, + { &hf_isi_location_sub_len, + { "Subpacket Length", "isi.location.sub.len", FT_UINT16, BASE_DEC, NULL, 0x0, "Subpacket Length", HFILL }}, + { &hf_isi_location_gps_power, + { "Power", "isi.location.power", FT_UINT8, BASE_HEX, isi_location_gps_power, 0x0, "Power", HFILL }}, + { &hf_isi_location_gps_status, + { "Status", "isi.location.status", FT_UINT8, BASE_HEX, isi_location_gps_status, 0x0, "Status", HFILL }}, + { &hf_isi_location_year, + { "Year", "isi.location.date.year", FT_UINT16, BASE_DEC, NULL, 0x0, "Year", HFILL }}, + { &hf_isi_location_month, + { "Month", "isi.location.date.month", FT_UINT8, BASE_DEC, NULL, 0x0, "Month", HFILL }}, + { &hf_isi_location_day, + { "Day", "isi.location.date.day", FT_UINT8, BASE_DEC, NULL, 0x0, "Day", HFILL }}, + { &hf_isi_location_hour, + { "Hour", "isi.location.time.hour", FT_UINT8, BASE_DEC, NULL, 0x0, "Hour", HFILL }}, + { &hf_isi_location_minute, + { "Minute", "isi.location.time.minute", FT_UINT8, BASE_DEC, NULL, 0x0, "Minute", HFILL }}, + { &hf_isi_location_second, + { "Second", "isi.location.time.second", FT_FLOAT, BASE_NONE, NULL, 0x0, "Second", HFILL }}, + { &hf_isi_location_latitude, + { "Latitude", "isi.location.lat", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Latitude", HFILL }}, + { &hf_isi_location_longitude, + { "Longitude", "isi.location.lon", FT_DOUBLE, BASE_NONE, NULL, 0x0, "Longitude", HFILL }}, + { &hf_isi_location_eph, + { "Position Accuracy", "isi.location.eph", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPH (position accuracy) in meter", HFILL }}, + { &hf_isi_location_altitude, + { "Altitude", "isi.location.alt", FT_INT16, BASE_DEC, NULL, 0x0, "Altitude in meter", HFILL }}, + { &hf_isi_location_epv, + { "Altitude Accuracy", "isi.location.epv", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPV (altitude accuracy) in meter", HFILL }}, + { &hf_isi_location_course, + { "Course", "isi.location.course", FT_FLOAT, BASE_NONE, NULL, 0x0, "Course in degree", HFILL }}, + { &hf_isi_location_epd, + { "Course Accuracy", "isi.location.epd", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPD (course accuracy) in degree", HFILL }}, + { &hf_isi_location_speed, + { "Speed", "isi.location.speed", FT_FLOAT, BASE_NONE, NULL, 0x0, "Speed in km/h", HFILL }}, + { &hf_isi_location_eps, + { "Speed Accuracy", "isi.location.eps", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPS (speed accuracy) in km/h", HFILL }}, + { &hf_isi_location_climb, + { "Climb", "isi.location.climb", FT_FLOAT, BASE_NONE, NULL, 0x0, "Climb in km/h", HFILL }}, + { &hf_isi_location_satellites, + { "Visible Satellites", "isi.location.satellites", FT_UINT8, BASE_DEC, NULL, 0x0, "Visible Satellites", HFILL }}, + { &hf_isi_location_prn, + { "Pseudeorandom Noise (PRN)", "isi.location.sat.prn", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, "Pseudeorandom Noise (PRN)", HFILL }}, + { &hf_isi_location_sat_used, + { "in use", "isi.location.sat.used", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "in use", HFILL }}, + { &hf_isi_location_sat_strength, + { "Signal Strength", "isi.location.sat.strength", FT_FLOAT, BASE_NONE, NULL, 0x0, "Signal Strength", HFILL }}, + { &hf_isi_location_sat_elevation, + { "Elevation", "isi.location.sat.elevation", FT_FLOAT, BASE_NONE, NULL, 0x0, "Elevation", HFILL }}, + { &hf_isi_location_sat_azimuth, + { "Azimuth", "isi.location.sat.azimuth", FT_FLOAT, BASE_NONE, NULL, 0x0, "Azimuth", HFILL }}, + { &hf_isi_location_epc, + { "Climb Accuracy", "isi.location.epc", FT_FLOAT, BASE_NONE, NULL, 0x0, "EPC (climb accuracy) in km/h", HFILL }}, + { &hf_isi_location_mcc, + { "Mobile Country Code (MCC)", "isi.location.gsm.mcc", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Mobile Country Code (MCC)", HFILL }}, + { &hf_isi_location_mnc, + { "Mobile Network Code (MNC)", "isi.location.gsm.mnc", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Mobile Network Code (MNC)", HFILL }}, + { &hf_isi_location_lac, + { "Location Area Code (LAC)", "isi.location.gsm.lac", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Location Area Code (LAC)", HFILL }}, + { &hf_isi_location_cid, + { "Cell ID (CID)", "isi.location.gsm.cid", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "Cell ID (CID)", HFILL }}, + { &hf_isi_location_ucid, + { "Cell ID (UCID)", "isi.location.gsm.ucid", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, "Cell ID (UCID)", HFILL }}, + { &hf_isi_location_socket_addr_port, + { "Port", "isi.location.socket.addr.port", FT_UINT16, BASE_DEC, NULL, 0x0, "Port", HFILL }}, + { &hf_isi_location_socket_addr_type, + { "Type", "isi.location.socket.addr.type", FT_UINT8, BASE_HEX, isi_location_socket_addr_type, 0x0, "Type", HFILL }}, + { &hf_isi_location_socket_addr_ip_len, + { "IP Length", "isi.location.socket.addr.ip.len", FT_UINT8, BASE_DEC, NULL, 0x0, "IP Length", HFILL }}, + { &hf_isi_location_socket_addr_fqdn_len, + { "Domain Length", "isi.location.socket.addr.fqdn.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Domain Length", HFILL }}, + { &hf_isi_location_socket_addr_ipv4, + { "IPv4", "isi.location.socket.addr.ip", FT_IPv4, BASE_NONE, NULL, 0x0, "IPv6", HFILL }}, + { &hf_isi_location_socket_addr_ipv6, + { "IPv6", "isi.location.socket.addr.ip", FT_IPv6, BASE_NONE, NULL, 0x0, "IPv6", HFILL }}, + { &hf_isi_location_socket_addr_fqdn, + { "Domain", "isi.location.socket.addr.fqdn", FT_STRING, BASE_NONE, NULL, 0x0, "Domain", HFILL }}, + { &hf_isi_location_socket_bearer, + { "Bearer Type", "isi.location.bearer", FT_UINT8, BASE_HEX, isi_location_bearer_type, 0x0, "Bearer Type", HFILL }}, + { &hf_isi_location_hybrid_cmd, + { "Hybrid Command", "isi.location.hybrid.cmd", FT_UINT8, BASE_HEX, isi_location_hybrid_cmd, 0x0, "Hybrid Command", HFILL }}, + { &hf_isi_location_hybrid_allowed_methods, + { "Allowed Methods", "isi.location.hybrid.allowed_methods", FT_UINT32, BASE_HEX, NULL, 0x0, "Allowed Methods", HFILL }}, + { &hf_isi_location_hybrid_options, + { "Options", "isi.location.hybrid.options", FT_UINT32, BASE_HEX, NULL, 0x0, "Options", HFILL }}, + { &hf_isi_location_hybrid_interval, + { "Interval", "isi.location.hybrid.interval", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, "Interval", HFILL }}, + { &hf_isi_location_hybrid_report_criteria, + { "Report Criteria", "isi.location.hybrid.report_criteria", FT_UINT8, BASE_HEX, isi_location_hybrid_report_criteria, 0x0, "Report Criteria", HFILL }}, + { &hf_isi_location_hybrid_acwp_timer, + { "ACWP Timer", "isi.location.hybrid.acwp_timer", FT_UINT8, BASE_DEC, NULL, 0x0, "ACWP Timer", HFILL }}, + { &hf_isi_location_hybrid_option_channel_status, + { "Channel Status", "isi.location.hybrid.options.channel_status", FT_BOOLEAN, BASE_NONE, NULL, 0x000000001, "Channel Status", HFILL }}, + { &hf_isi_location_hybrid_option_cell_info, + { "Cell Info", "isi.location.hybrid.options.cell_info", FT_BOOLEAN, BASE_NONE, NULL, 0x000000002, "Cell Info", HFILL }}, + { &hf_isi_location_hybrid_option_nmea_0183, + { "NMEA 0183", "isi.location.hybrid.options.nmea_0183", FT_BOOLEAN, BASE_NONE, NULL, 0x000000004, "NMEA 0183", HFILL }}, + { &hf_isi_location_hybrid_method_cwp, + { "CWP", "isi.location.hybrid.methods.cwp", FT_BOOLEAN, BASE_NONE, NULL, 0x000000001, "CWP", HFILL }}, + { &hf_isi_location_hybrid_method_acwp, + { "ACWP", "isi.location.hybrid.methods.acwp", FT_BOOLEAN, BASE_NONE, NULL, 0x000000002, "ACWP", HFILL }}, + { &hf_isi_location_hybrid_method_gnss, + { "GNSS", "isi.location.hybrid.methods.gnss", FT_BOOLEAN, BASE_NONE, NULL, 0x000000004, "GNSS", HFILL }}, + { &hf_isi_location_hybrid_method_agnss, + { "AGNSS", "isi.location.hybrid.methods.agnss", FT_BOOLEAN, BASE_NONE, NULL, 0x000000008, "AGNSS", HFILL }}, + { &hf_isi_location_hybrid_client_id, + { "Client ID", "isi.location.hybrid.client_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Client ID", HFILL }}, + { &hf_isi_location_hybrid_npe_id, + { "NPE ID", "isi.location.hybrid.npe_id", FT_UINT32, BASE_HEX, NULL, 0x0, "NPE ID", HFILL }}, + { &hf_isi_location_cause, + { "Cause", "isi.location.hybrid.cause", FT_UINT8, BASE_HEX, isi_location_hybrid_cause, 0x0, "Cause", HFILL }}, + { &hf_isi_location_status, + { "Status", "isi.location.status", FT_UINT8, BASE_HEX, NULL, 0x0, "Status", HFILL }}, + { &hf_isi_location_status_ok, + { "OK", "isi.location.status.ok", FT_BOOLEAN, BASE_NONE, NULL, 0x01, "OK", HFILL }}, + { &hf_isi_location_status_complete, + { "Complete", "isi.location.status.complete", FT_BOOLEAN, BASE_NONE, NULL, 0x20, "Complete", HFILL }}, + { &hf_isi_location_status_fix, + { "Fix", "isi.location.status.fix", FT_BOOLEAN, BASE_NONE, NULL, 0x40, "Fix", HFILL }}, + { &hf_isi_location_status_meas_fix, + { "Measure Fix", "isi.location.status.meas_fix", FT_BOOLEAN, BASE_NONE, NULL, 0x80, "Measure Fix", HFILL }}, + { &hf_isi_location_socket_descriptor, + { "Descriptor", "isi.location.socket.status", FT_UINT8, BASE_HEX, NULL, 0x0, "Descriptor", HFILL }}, + { &hf_isi_location_socket_status, + { "Status", "isi.location.socket.status", FT_UINT8, BASE_HEX, isi_location_socket_status, 0x0, "Status", HFILL }}, + { &hf_isi_location_socket_error, + { "Error Number", "isi.location.socket.error", FT_UINT16, BASE_HEX, NULL, 0x0, "Error Number", HFILL }}, + { &hf_isi_location_data_len, + { "Data Length", "isi.location.data.len", FT_UINT16, BASE_DEC, NULL, 0x0, "Data Length", HFILL }}, + { &hf_isi_location_data, + { "Data", "isi.location.data", FT_BYTES, BASE_NONE, NULL, 0x0, "Data Length", HFILL }} + }; + + static gint *ett[] = { + &ett_flags_status, + &ett_flags_methods, + &ett_flags_options }; proto_register_field_array(proto_isi, hf, array_length(hf)); - register_dissector("isi.gps", dissect_isi_gps, proto_isi); + proto_register_subtree_array(ett, array_length(ett)); + + register_dissector("isi.location", dissect_isi_location, proto_isi); } -static void dissect_isi_gps_data(tvbuff_t *tvb, packet_info *pinfo, proto_item *item, proto_tree *tree) { +static size_t dissect_isi_location_subpkg(tvbuff_t *tvb, packet_info *pinfo, proto_item *item, proto_tree *tree, size_t offset) { + guint16 sptype = tvb_get_ntohs(tvb, offset+0); + guint16 splen = tvb_get_ntohs(tvb, offset+2); + + proto_item *subitem = proto_tree_add_text(tree, tvb, offset, splen, "Subpacket (%s)", val_to_str(sptype, isi_location_sub_id, "unknown: 0x%x")); + proto_tree *subtree = proto_item_add_subtree(subitem, ett_isi_msg); + + proto_tree_add_item(subtree, hf_isi_location_sub_type, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_sub_len, tvb, offset+2, 2, FALSE); + + offset += 4; + switch(sptype) { + case 0x1200: ; /* LS_SB_SOCKET_ADDR */ + proto_tree_add_item(subtree, hf_isi_location_socket_addr_port, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_socket_addr_type, tvb, offset+2, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_location_socket_addr_ip_len, tvb, offset+3, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_location_socket_addr_fqdn_len, tvb, offset+4, 1, FALSE); + + guint8 type = tvb_get_guint8(tvb, offset+2); + guint8 ip_len = tvb_get_guint8(tvb, offset+3); + guint8 fqdn_len = tvb_get_guint8(tvb, offset+4); + + if(type == 0x00 && ip_len >= FT_IPv4_LEN) + proto_tree_add_item(subtree, hf_isi_location_socket_addr_ipv4, tvb, offset+8, ip_len, FALSE); + if(type == 0x01 && ip_len >= FT_IPv6_LEN) + proto_tree_add_item(subtree, hf_isi_location_socket_addr_ipv6, tvb, offset+8, ip_len, FALSE); + if(type == 0x02) + proto_tree_add_item(subtree, hf_isi_location_socket_addr_fqdn, tvb, offset+8+ip_len, fqdn_len, FALSE); + + break; + case 0x1202: ; /* LS_SB_SOCKET_BEARER_TYPE */ + proto_tree_add_item(subtree, hf_isi_location_socket_bearer, tvb, offset+0, 1, FALSE); + + break; + case 0x0901: ; /* LS_SB_HYBRID_TRACKING_INSTR */ + proto_tree_add_bitmask(subtree, tvb, offset+0, hf_isi_location_hybrid_allowed_methods, ett_flags_methods, isi_location_hybrid_method_flags, ENC_BIG_ENDIAN); + proto_tree_add_bitmask(subtree, tvb, offset+4, hf_isi_location_hybrid_options, ett_flags_options, isi_location_hybrid_option_flags, ENC_BIG_ENDIAN); + + guint16 time_raw = tvb_get_ntohs(tvb, offset+8); + nstime_t time_conv; + time_conv.nsecs = (time_raw % 10) * 100000; + time_conv.secs = time_raw / 10; + proto_tree_add_time(subtree, hf_isi_location_hybrid_interval, tvb, offset+8, 2, &time_conv); + + proto_tree_add_item(subtree, hf_isi_location_hybrid_report_criteria, tvb, offset+10, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_location_hybrid_acwp_timer, tvb, offset+11, 1, FALSE); + + break; + case 0x0902: ; /* LS_SB_NPE_POSITION */ + double lat = tvb_get_ntohl(tvb, offset+0); + lat = (lat*360)/4294967296; + if(lat > 180.0) lat -= 360.0; + proto_tree_add_double(subtree, hf_isi_location_latitude, tvb, offset+0, 4, lat); + + double lon = tvb_get_ntohl(tvb, offset+4); + lon = (lon*360)/4294967296; + if(lon > 180.0) lon -= 360.0; + proto_tree_add_double(subtree, hf_isi_location_longitude, tvb, offset+4, 4, lon); + + float eph = tvb_get_ntohl(tvb, offset+12) / 100.0; + proto_tree_add_float(subtree, hf_isi_location_eph, tvb, offset+12, 4, eph); + + gint32 altitude = (tvb_get_ntohs(tvb, offset+18) - tvb_get_ntohs(tvb, offset+22))/2; + proto_tree_add_int(subtree, hf_isi_location_altitude, tvb, offset+18, 6, altitude); + + float epv = tvb_get_ntohs(tvb, offset+20) / 2; + proto_tree_add_float(subtree, hf_isi_location_epv, tvb, offset+20, 2, epv); + + break; + case 0x0903: ; /* LS_SB_NPE_TIME */ + proto_tree_add_item(subtree, hf_isi_location_year, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_month, tvb, offset+2, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_location_day, tvb, offset+3, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_location_hour, tvb, offset+5, 1, FALSE); + proto_tree_add_item(subtree, hf_isi_location_minute, tvb, offset+6, 1, FALSE); + + float second = tvb_get_ntohs(tvb, offset+8) / 1000.0; + proto_tree_add_float(subtree, hf_isi_location_second, tvb, offset+8, 2, second); + + break; + case 0x0904: ; /* LS_SB_NPE_VELOCITY */ + float course = tvb_get_ntohs(tvb, offset+0) / 100.0; + proto_tree_add_float(subtree, hf_isi_location_course, tvb, offset+0, 2, course); + + float epd = tvb_get_ntohs(tvb, offset+2) / 100.0; + proto_tree_add_float(subtree, hf_isi_location_epd, tvb, offset+2, 2, epd); + + float speed = tvb_get_ntohs(tvb, offset+6) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_location_speed, tvb, offset+6, 2, speed); + + float eps = tvb_get_ntohs(tvb, offset+8) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_location_eps, tvb, offset+8, 2, eps); + + float climb = tvb_get_ntohs(tvb, offset+10) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_location_climb, tvb, offset+10, 2, climb); + + float epc = tvb_get_ntohs(tvb, offset+12) * CMS_TO_KMH; + proto_tree_add_float(subtree, hf_isi_location_epc, tvb, offset+12, 2, epc); + + break; + case 0x0905: ; /* LS_SB_NPE_CHANNELS */ + guint8 satellites = tvb_get_guint8(tvb, offset+0); + proto_tree_add_item(subtree, hf_isi_location_satellites, tvb, offset+0, 1, FALSE); + + int sat; + for(sat = 0; sat < satellites ; sat++) { + int pos = offset+4+(sat*SAT_PKG_LEN); + proto_item *satitem = proto_tree_add_text(subtree, tvb, pos, SAT_PKG_LEN, "Satellite %d", sat); + proto_tree *sattree = proto_item_add_subtree(satitem, ett_isi_msg); + + float signal_strength = tvb_get_ntohs(tvb, pos+3) / 100.0; + float elevation = tvb_get_ntohs(tvb, pos+6) / 100.0; + float azimuth = tvb_get_ntohs(tvb, pos+8) / 100.0; + + proto_tree_add_item(sattree, hf_isi_location_prn, tvb, pos+1, 1, FALSE); + proto_tree_add_item(sattree, hf_isi_location_sat_used, tvb, pos+2, 1, FALSE); + proto_tree_add_float(sattree, hf_isi_location_sat_strength, tvb, pos+3, 2, signal_strength); + proto_tree_add_float(sattree, hf_isi_location_sat_elevation, tvb, pos+6, 2, elevation); + proto_tree_add_float(sattree, hf_isi_location_sat_azimuth, tvb, pos+8, 2, azimuth); + } + + break; + case 0x0907: /* LS_SB_CELL_INFO_GSM */ + proto_tree_add_item(subtree, hf_isi_location_mcc, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_mnc, tvb, offset+2, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_lac, tvb, offset+4, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_cid, tvb, offset+6, 2, FALSE); + + break; + case 0x0908: /* LS_SB_CELL_INFO_WCDMA */ + proto_tree_add_item(subtree, hf_isi_location_mcc, tvb, offset+0, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_mnc, tvb, offset+2, 2, FALSE); + proto_tree_add_item(subtree, hf_isi_location_ucid, tvb, offset+4, 4, FALSE); + + break; + default: + expert_add_info_format(pinfo, subitem, &ei_isi_unsupported_packet, "unsupported sub-packet"); + + break; + } + + return splen; +} + +static void dissect_isi_location(tvbuff_t *tvb, packet_info *pinfo, proto_item *isitree) { + proto_item *item = NULL; + proto_tree *tree = NULL; + guint8 cmd, pkgcount; + guint16 data_len; + size_t offset; int i; - guint8 pkgcount = tvb_get_guint8(tvb, 0x07); - proto_tree_add_item(tree, hf_isi_gps_sub_pkgs, tvb, 0x07, 1, FALSE); + if(isitree) { + item = proto_tree_add_text(isitree, tvb, 0, -1, "Payload"); + tree = proto_item_add_subtree(item, ett_isi_msg); - size_t offset = 0x0b; // subpackets start here - for(i=0; i<pkgcount; i++) { - guint8 sptype = tvb_get_guint8(tvb, offset+1); - guint8 splen = tvb_get_guint8(tvb, offset+3); + proto_tree_add_item(tree, hf_isi_location_cmd, tvb, 0, 1, FALSE); + cmd = tvb_get_guint8(tvb, 0); - proto_item *subitem = proto_tree_add_text(tree, tvb, offset, splen, "Subpacket (%s)", val_to_str(sptype, isi_gps_sub_id, "unknown: 0x%x")); - proto_tree *subtree = proto_item_add_subtree(subitem, ett_isi_msg); + switch(cmd) { + case 0x7D: /* LS_GPS_STATUS_IND */ + proto_tree_add_item(tree, hf_isi_location_gps_power, tvb, 1, 1, FALSE); + proto_tree_add_item(tree, hf_isi_location_gps_status, tvb, 2, 1, FALSE); + guint8 status = tvb_get_guint8(tvb, 2); + col_add_fstr(pinfo->cinfo, COL_INFO, "GPS Status Indication: %s", val_to_str(status, isi_location_gps_status, "unknown (0x%x)")); + break; + case 0x84: /* LS_SOCKET_OPEN_REQUEST_NTF */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Open Request"); - proto_tree_add_item(subtree, hf_isi_gps_sub_type, tvb, offset+1, 1, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_sub_len, tvb, offset+3, 1, FALSE); + pkgcount = tvb_get_guint8(tvb, 1); + proto_tree_add_item(tree, hf_isi_location_sub_pkgs, tvb, 1, 1, FALSE); - offset += 4; - switch(sptype) { - case 0x02: ; // Position - double lat = tvb_get_ntohl(tvb, offset+0); - lat = (lat*360)/4294967296; - if(lat > 180.0) lat -= 360.0; - proto_tree_add_double(subtree, hf_isi_gps_latitude, tvb, offset+0, 4, lat); + offset = 0x03; + for(i=0; i<pkgcount; i++) { + offset += dissect_isi_location_subpkg(tvb, pinfo, item, tree, offset); + } - double lon = tvb_get_ntohl(tvb, offset+4); - lon = (lon*360)/4294967296; - if(lon > 180.0) lon -= 360.0; - proto_tree_add_double(subtree, hf_isi_gps_longitude, tvb, offset+4, 4, lon); + break; + case 0x85: /* LS_SOCKET_OPEN_RESPONSE_NTF */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Open Response"); - float eph = tvb_get_ntohl(tvb, offset+12) / 100.0; - proto_tree_add_float(subtree, hf_isi_gps_eph, tvb, offset+12, 4, eph); + proto_tree_add_item(tree, hf_isi_location_socket_descriptor, tvb, 1, 1, FALSE); + proto_tree_add_item(tree, hf_isi_location_socket_status, tvb, 2, 1, FALSE); - gint32 altitude = (tvb_get_ntohs(tvb, offset+18) - tvb_get_ntohs(tvb, offset+22))/2; - proto_tree_add_int(subtree, hf_isi_gps_altitude, tvb, offset+18, 6, altitude); + pkgcount = tvb_get_guint8(tvb, 3); + proto_tree_add_item(tree, hf_isi_location_sub_pkgs, tvb, 3, 1, FALSE); - float epv = tvb_get_ntohs(tvb, offset+20) / 2; - proto_tree_add_float(subtree, hf_isi_gps_epv, tvb, offset+20, 2, epv); + offset = 0x07; + for(i=0; i<pkgcount; i++) { + offset += dissect_isi_location_subpkg(tvb, pinfo, item, tree, offset); + } break; - case 0x03: // Date and Time - proto_tree_add_item(subtree, hf_isi_gps_year, tvb, offset+0, 2, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_month, tvb, offset+2, 1, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_day, tvb, offset+3, 1, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_hour, tvb, offset+5, 1, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_minute, tvb, offset+6, 1, FALSE); - - float second = tvb_get_ntohs(tvb, offset+8) / 1000.0; - proto_tree_add_float(subtree, hf_isi_gps_second, tvb, offset+8, 2, second); - break; - case 0x04: ; // Movement - float course = tvb_get_ntohs(tvb, offset+0) / 100.0; - proto_tree_add_float(subtree, hf_isi_gps_course, tvb, offset+0, 2, course); + case 0x86: /* LS_SOCKET_SEND_REQUEST_NTF */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Send Request"); - float epd = tvb_get_ntohs(tvb, offset+2) / 100.0; - proto_tree_add_float(subtree, hf_isi_gps_epd, tvb, offset+2, 2, epd); + proto_tree_add_item(tree, hf_isi_location_socket_descriptor, tvb, 1, 1, FALSE); - float speed = tvb_get_ntohs(tvb, offset+6) * CMS_TO_KMH; - proto_tree_add_float(subtree, hf_isi_gps_speed, tvb, offset+6, 2, speed); + proto_tree_add_item(tree, hf_isi_location_data_len, tvb, 3, 2, FALSE); + data_len = tvb_get_ntohs(tvb, 3); - float eps = tvb_get_ntohs(tvb, offset+8) * CMS_TO_KMH; - proto_tree_add_float(subtree, hf_isi_gps_eps, tvb, offset+8, 2, eps); + if(supl_handle == NULL) { + proto_tree_add_item(tree, hf_isi_location_data, tvb, 7, data_len, FALSE); + } else { + tvbuff_t *data_tvb = tvb_new_subset(tvb, 7, data_len, data_len); + call_dissector(supl_handle, data_tvb, pinfo, tree); + } + + break; + case 0x87: /* LS_SOCKET_SEND_RESPONSE_NTF */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Send Response"); - float climb = tvb_get_ntohs(tvb, offset+10) * CMS_TO_KMH; - proto_tree_add_float(subtree, hf_isi_gps_climb, tvb, offset+10, 2, climb); + proto_tree_add_item(tree, hf_isi_location_socket_descriptor, tvb, 1, 1, FALSE); + proto_tree_add_item(tree, hf_isi_location_socket_status, tvb, 2, 1, FALSE); + proto_tree_add_item(tree, hf_isi_location_socket_error, tvb, 3, 2, FALSE); - float epc = tvb_get_ntohs(tvb, offset+12) * CMS_TO_KMH; - proto_tree_add_float(subtree, hf_isi_gps_epc, tvb, offset+12, 2, epc); break; - case 0x05: ; // Satellite Info - guint8 satellites = tvb_get_guint8(tvb, offset+0); - proto_tree_add_item(subtree, hf_isi_gps_satellites, tvb, offset+0, 1, FALSE); - - int sat; - for(sat = 0; sat < satellites ; sat++) { - int pos = offset+4+(sat*SAT_PKG_LEN); - proto_item *satitem = proto_tree_add_text(subtree, tvb, pos, SAT_PKG_LEN, "Satellite %d", sat); - proto_tree *sattree = proto_item_add_subtree(satitem, ett_isi_msg); - - float signal_strength = tvb_get_ntohs(tvb, pos+3) / 100.0; - float elevation = tvb_get_ntohs(tvb, pos+6) / 100.0; - float azimuth = tvb_get_ntohs(tvb, pos+8) / 100.0; - - proto_tree_add_item(sattree, hf_isi_gps_prn, tvb, pos+1, 1, FALSE); - proto_tree_add_item(sattree, hf_isi_gps_sat_used, tvb, pos+2, 1, FALSE); - proto_tree_add_float(sattree, hf_isi_gps_sat_strength, tvb, pos+3, 2, signal_strength); - proto_tree_add_float(sattree, hf_isi_gps_sat_elevation, tvb, pos+6, 2, elevation); - proto_tree_add_float(sattree, hf_isi_gps_sat_azimuth, tvb, pos+8, 2, azimuth); + case 0x88: /* LS_SOCKET_RECV_REQ */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Receive Request"); + + proto_tree_add_item(tree, hf_isi_location_socket_descriptor, tvb, 1, 1, FALSE); + + proto_tree_add_item(tree, hf_isi_location_data_len, tvb, 3, 2, FALSE); + data_len = tvb_get_ntohs(tvb, 3); + + if(supl_handle == NULL) { + proto_tree_add_item(tree, hf_isi_location_data, tvb, 7, data_len, FALSE); + } else { + tvbuff_t *data_tvb = tvb_new_subset(tvb, 7, data_len, data_len); + call_dissector(supl_handle, data_tvb, pinfo, tree); } + break; - case 0x07: // CellInfo GSM - proto_tree_add_item(subtree, hf_isi_gps_mcc, tvb, offset+0, 2, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_mnc, tvb, offset+2, 2, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_lac, tvb, offset+4, 2, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_cid, tvb, offset+6, 2, FALSE); - break; - case 0x08: // CellInfo WCDMA - proto_tree_add_item(subtree, hf_isi_gps_mcc, tvb, offset+0, 2, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_mnc, tvb, offset+2, 2, FALSE); - proto_tree_add_item(subtree, hf_isi_gps_ucid, tvb, offset+4, 4, FALSE); - break; - default: - break; - } + case 0x89: /* LS_SOCKET_RECV_RESP */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Receive Response"); - offset += splen - 4; - } + proto_tree_add_item(tree, hf_isi_location_socket_descriptor, tvb, 1, 1, FALSE); -} + break; + case 0x8a: /* LS_SOCKET_CLOSE_REQUEST_NTF */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Close Request"); -static void dissect_isi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_item *isitree) { - proto_item *item = NULL; - proto_tree *tree = NULL; - guint8 cmd; + proto_tree_add_item(tree, hf_isi_location_socket_descriptor, tvb, 1, 1, FALSE); - if(isitree) { - item = proto_tree_add_text(isitree, tvb, 0, -1, "Payload"); - tree = proto_item_add_subtree(item, ett_isi_msg); + break; + case 0x8b: /* LS_SOCKET_CLOSE_RESPONSE_NTF */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Socket Close Response"); - proto_tree_add_item(tree, hf_isi_gps_cmd, tvb, 0, 1, FALSE); - cmd = tvb_get_guint8(tvb, 0); + proto_tree_add_item(tree, hf_isi_location_socket_descriptor, tvb, 1, 1, FALSE); + proto_tree_add_item(tree, hf_isi_location_socket_status, tvb, 2, 1, FALSE); - switch(cmd) { - case 0x7d: /* GPS Status */ - proto_tree_add_item(tree, hf_isi_gps_status, tvb, 2, 1, FALSE); - guint8 status = tvb_get_guint8(tvb, 2); - col_add_fstr(pinfo->cinfo, COL_INFO, "GPS Status Indication: %s", val_to_str(status, isi_gps_status, "unknown (0x%x)")); - break; - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - col_add_fstr(pinfo->cinfo, COL_INFO, "unknown A-GPS packet (0x%02x)", cmd); break; - case 0x90: /* GPS Power Request */ - col_set_str(pinfo->cinfo, COL_INFO, "GPS Power Request"); + case 0x90: /* LS_HYBRID_TRACKING_REQ */ + col_set_str(pinfo->cinfo, COL_INFO, "Hybrid Tracking Request"); + + proto_tree_add_item(tree, hf_isi_location_hybrid_cmd, tvb, 1, 1, FALSE); + proto_tree_add_item(tree, hf_isi_location_sub_pkgs, tvb, 2, 1, FALSE); + pkgcount = tvb_get_guint8(tvb, 2); + proto_tree_add_item(tree, hf_isi_location_hybrid_client_id, tvb, 3, 4, FALSE); + proto_tree_add_item(tree, hf_isi_location_hybrid_npe_id, tvb, 7, 4, FALSE); + + offset = 0x0b; + for(i=0; i<pkgcount; i++) { + offset += dissect_isi_location_subpkg(tvb, pinfo, item, tree, offset); + } + break; - case 0x91: /* GPS Power Request */ - col_set_str(pinfo->cinfo, COL_INFO, "GPS Power Response"); + case 0x91: /* LS_HYBRID_TRACKING_RESP */ + col_set_str(pinfo->cinfo, COL_INFO, "Hybrid Tracking Response"); + + proto_tree_add_bitmask(tree, tvb, 1, hf_isi_location_status, ett_flags_status, isi_location_hybrid_status_flags, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_isi_location_cause, tvb, 2, 1, FALSE); + proto_tree_add_item(tree, hf_isi_location_hybrid_client_id, tvb, 3, 4, FALSE); + proto_tree_add_item(tree, hf_isi_location_hybrid_npe_id, tvb, 7, 4, FALSE); + break; - case 0x92: /* GPS Data */ - col_set_str(pinfo->cinfo, COL_INFO, "GPS Data"); - dissect_isi_gps_data(tvb, pinfo, item, tree); + case 0x92: /* LS_HYBRID_TRACKING_NTF */ + col_set_str(pinfo->cinfo, COL_INFO, "Hybrid Tracking Notification"); + + pkgcount = tvb_get_guint8(tvb, 0x07); + proto_tree_add_item(tree, hf_isi_location_sub_pkgs, tvb, 0x07, 1, FALSE); + + offset = 0x0b; + for(i=0; i<pkgcount; i++) { + offset += dissect_isi_location_subpkg(tvb, pinfo, item, tree, offset); + } + break; case 0xF0: /* COMMON_MESSAGE */ dissect_isi_common("GPS", tvb, pinfo, tree); + break; default: - col_add_fstr(pinfo->cinfo, COL_INFO, "unknown GPS packet (0x%02x)", cmd); + expert_add_info_format(pinfo, item, &ei_isi_unsupported_packet, "unsupported location packet"); + break; } } diff --git a/src/isi-gps.h b/src/isi-gps.h index 1a20ab1..ce943d8 100644 --- a/src/isi-gps.h +++ b/src/isi-gps.h @@ -1,7 +1,7 @@ #ifndef _ISI_GPS_H #define _ISI_GPS_H -void proto_reg_handoff_isi_gps(void); -void proto_register_isi_gps(void); +void proto_reg_handoff_isi_location(void); +void proto_register_isi_location(void); #endif diff --git a/src/packet-isi.c b/src/packet-isi.c index 07b0b31..0726227 100644 --- a/src/packet-isi.c +++ b/src/packet-isi.c @@ -330,6 +330,7 @@ gint32 ett_isi_nameservice_entry = -1; gint32 ett_isi_info = -1; expert_field ei_isi_unknown_packet = EI_INIT; +expert_field ei_isi_unsupported_packet = EI_INIT; #ifdef ISI_USB /* Experimental approach based upon the one used for PPP*/ @@ -359,7 +360,7 @@ void proto_reg_handoff_isi(void) { proto_reg_handoff_isi_sim_auth(); proto_reg_handoff_isi_sim(); proto_reg_handoff_isi_network(); - proto_reg_handoff_isi_gps(); + proto_reg_handoff_isi_location(); proto_reg_handoff_isi_ss(); proto_reg_handoff_isi_gss(); proto_reg_handoff_isi_sms(); @@ -416,6 +417,7 @@ void proto_register_isi(void) { static ei_register_info ei[] = { { &ei_isi_unknown_packet, { "isi.unknown.packet", PI_UNDECODED, PI_WARN, "Unknown packet", EXPFILL }}, + { &ei_isi_unsupported_packet, { "isi.unsupported.packet", PI_UNDECODED, PI_WARN, "Unsupported packet", EXPFILL }}, }; static gint *ett[] = { @@ -444,7 +446,7 @@ void proto_register_isi(void) { proto_register_isi_sim(); proto_register_isi_sim_auth(); proto_register_isi_network(); - proto_register_isi_gps(); + proto_register_isi_location(); proto_register_isi_ss(); proto_register_isi_gss(); proto_register_isi_sms(); diff --git a/src/packet-isi.h b/src/packet-isi.h index fba7569..1d1ee06 100644 --- a/src/packet-isi.h +++ b/src/packet-isi.h @@ -17,5 +17,6 @@ void dissect_isi_common(const char *resource, tvbuff_t *tvb, packet_info *pinfo, void dissect_isi_subpacket(gint32 hf_sub_type, guint8 offset, tvbuff_t *tvb, packet_info *pinfo, proto_item *item, proto_tree *tree, void (*detail_cb)(guint8, tvbuff_t*, packet_info*, proto_item*, proto_tree*)); extern expert_field ei_isi_unknown_packet; +extern expert_field ei_isi_unsupported_packet; #endif |