diff options
author | Anders Broman <anders.broman@ericsson.com> | 2020-11-18 13:56:52 +0100 |
---|---|---|
committer | AndersBroman <a.broman58@gmail.com> | 2020-11-18 15:02:54 +0000 |
commit | 1d7bc367e943464f912a67ad436fabddb1a61a37 (patch) | |
tree | fb0d9d276ed3ecb140f3c8815e78030e25393df8 /epan | |
parent | 0250e4e2e44a73773dbaad64cfb244a0db463d7e (diff) |
GSM A Common: Dissect polygon points
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-gsm_a_common.c | 71 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_a_common.h | 2 |
2 files changed, 52 insertions, 21 deletions
diff --git a/epan/dissectors/packet-gsm_a_common.c b/epan/dissectors/packet-gsm_a_common.c index 9b31ce905b..a802ec1af8 100644 --- a/epan/dissectors/packet-gsm_a_common.c +++ b/epan/dissectors/packet-gsm_a_common.c @@ -759,6 +759,7 @@ static int hf_gsm_a_mobile_network_code = -1; int hf_3gpp_tmsi = -1; static int ett_gsm_a_plmn = -1; +static int ett_gsm_a_poly_pnt = -1; static expert_field ei_gsm_a_extraneous_data = EI_INIT; static expert_field ei_gsm_a_unknown_element = EI_INIT; @@ -826,13 +827,12 @@ static const value_string dir_of_alt_vals[] = { 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 +int 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;*/ + guint32 type_of_shape; int offset = 0; int length; guint8 value; @@ -850,11 +850,11 @@ dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr * 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; + proto_tree_add_item_ret_uint(tree, hf_gsm_a_geo_loc_type_of_shape, tvb, 0, 1, ENC_BIG_ENDIAN, &type_of_shape); offset++; + if (length < 2) { + return length; + } switch (type_of_shape) { case ELLIPSOID_POINT: /* Ellipsoid Point */ @@ -869,7 +869,7 @@ dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr case ELLIPSOID_ARC: /* Ellipsoid Arc */ if (length < 4) - return; + return length; 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); @@ -880,9 +880,9 @@ dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr ((double)(uvalue32 & 0x7fffff)/8388607.0) * 90); proto_item_append_text(lat_item, " (%s degrees)", deg_lat_str); loc_offset = offset; + offset = offset + 3; if (length < 7) - return; - offset = offset + 3; + return offset; 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); @@ -894,7 +894,7 @@ dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr if (type_of_shape == ELLIPSOID_POINT_WITH_UNCERT_CIRC) { /* Ellipsoid Point with uncertainty Circle */ if (length < 8) - return; + return offset; /* 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); @@ -992,16 +992,46 @@ dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr 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++; - + guint32 no_of_points; + guint point_no = 0; + proto_tree* sub_tree; + proto_item *ti; + + proto_tree_add_item_ret_uint(tree, hf_gsm_a_geo_loc_no_of_points, tvb, 0, 1, ENC_BIG_ENDIAN, &no_of_points); + /* offset increased with 1 after reading of shape abowe*/ + while (no_of_points > 0) { + point_no++; + sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, 6, + ett_gsm_a_poly_pnt, &ti, "Polygon point %u", point_no); + proto_tree_add_item(sub_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(sub_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; + offset = offset + 3; + svalue32 = tvb_get_ntoh24(tvb, offset); + svalue32 |= (svalue32 & 0x800000) ? 0xff000000 : 0x00000000; + long_item = proto_tree_add_item(sub_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; no_of_points--; + + 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); } -#endif + } break; case HIGH_ACC_ELLIPSOID_PNT_WITH_UNCERT_ELLIPSE: loc_offset = offset; @@ -1084,7 +1114,7 @@ dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr default: break; } - + return offset; } /* TS 23.032 @@ -4813,7 +4843,7 @@ proto_register_gsm_a_common(void) }; /* Setup protocol subtree array */ -#define NUM_INDIVIDUAL_ELEMS 1 +#define NUM_INDIVIDUAL_ELEMS 2 static gint *ett[NUM_INDIVIDUAL_ELEMS + NUM_GSM_COMMON_ELEM]; @@ -4996,6 +5026,7 @@ proto_register_gsm_a_common(void) last_offset = NUM_INDIVIDUAL_ELEMS; ett[0] = &ett_gsm_a_plmn; + ett[1] = &ett_gsm_a_poly_pnt; for (i=0; i < NUM_GSM_COMMON_ELEM; i++, last_offset++) { ett_gsm_common_elem[i] = -1; diff --git a/epan/dissectors/packet-gsm_a_common.h b/epan/dissectors/packet-gsm_a_common.h index 203af2dc69..0db80a929d 100644 --- a/epan/dissectors/packet-gsm_a_common.h +++ b/epan/dissectors/packet-gsm_a_common.h @@ -192,7 +192,7 @@ extern int gsm_a_tap; extern packet_info *gsm_a_dtap_pinfo; /* TS 23 032 */ -void dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +int dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); guint16 dissect_description_of_velocity(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len); |