VRT: add decoding of more CIF1 fields to VITA 49 dissector

This commit is contained in:
Cody Planteen 2023-01-31 12:50:36 +00:00 committed by Alexis La Goutte
parent b376b340af
commit 9e7c15fcb5
1 changed files with 174 additions and 8 deletions

View File

@ -116,8 +116,16 @@ static int hf_vrt_cif0_cif4 = -1; /* 1-bit CIF4 */
static int hf_vrt_cif0_cif3 = -1; /* 1-bit CIF3 */
static int hf_vrt_cif0_cif2 = -1; /* 1-bit CIF2 */
static int hf_vrt_cif0_cif1 = -1; /* 1-bit CIF1 */
/* TODO: complete CIF1 support (have partial CIF1 support) */
static int hf_vrt_cif1_phase_offset = -1; /* 1-bit phase offset */
static int hf_vrt_cif1_polarization = -1; /* 1-bit polarization */
static int hf_vrt_cif1_range = -1; /* 1-bit range (distance) */
static int hf_vrt_cif1_aux_freq = -1; /* 1-bit aux frequency */
static int hf_vrt_cif1_aux_bandwidth = -1; /* 1-bit aux bandwidth */
static int hf_vrt_cif1_io32 = -1; /* 1-bit discrete I/O (32-bit) */
static int hf_vrt_cif1_io64 = -1; /* 1-bit discrete I/O (64-bit) */
static int hf_vrt_cif1_v49_spec = -1; /* 1-bit V49 spec compliance */
static int hf_vrt_cif1_ver = -1; /* 1-bit version and build code */
static int hf_vrt_context_ref_pt_id = -1; /* 32-bit reference point identifier */
static int hf_vrt_context_bandwidth = -1; /* 64-bit bandwidth */
static int hf_vrt_context_if_freq = -1; /* 64-bit IF reference frequency */
@ -183,6 +191,16 @@ static int hf_vrt_context_assoc_lists_asy_tag_data; /* Variable asynchronous-cha
static int hf_vrt_context_phase_offset = -1; /* 16-bit phase offset */
static int hf_vrt_context_pol_tilt = -1; /* 16-bit polarization tilt angle */
static int hf_vrt_context_pol_ellipticity = -1; /* 16-bit polarization ellipticity angle */
static int hf_vrt_context_range = -1; /* 32-bit range (distance) */
static int hf_vrt_context_aux_freq = -1; /* 64-bit aux frequency */
static int hf_vrt_context_aux_bandwidth = -1; /* 64-bit aux bandwidth */
static int hf_vrt_context_io32 = -1; /* 32-bit discrete I/O */
static int hf_vrt_context_io64 = -1; /* 64-bit discrete I/O */
static int hf_vrt_context_v49_spec = -1; /* 32-bit V49 spec compliance */
static int hf_vrt_context_ver_year = -1; /* 7-bit year */
static int hf_vrt_context_ver_day = -1; /* 9-bit day */
static int hf_vrt_context_ver_rev = -1; /* 6-bit revision */
static int hf_vrt_context_ver_user = -1; /* 10-bit user defined */
static int hf_vrt_ts_int = -1; /* 32-bit integer timestamp (opt.) */
static int hf_vrt_ts_frac_picosecond = -1; /* 64-bit fractional timestamp (opt.) */
static int hf_vrt_ts_frac_sample = -1; /* 64-bit fractional timestamp (opt.) */
@ -220,9 +238,8 @@ static int hf_vrt_trailer_ind_user3 = -1; /* User indicator 3 */
/* fixed sizes (in bytes) of context packet CIF field bits */
static int context_size_cif0[32] = { 0, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, 52, 52, 44, 44, 8,
4, 8, 4, 4, 8, 8, 4, 4, 4, 8, 8, 8, 8, 8, 4, 0 };
/* partial CIF1 support - only upper 2 fields supported right now */
static int context_size_cif1[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4 };
static int context_size_cif1[32] = { 0, 8, 4, 4, 4, 8, 4, 0, 0, 0, 52, 0, 0, 8, 4, 8,
4, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 0, 4, 4, 4 };
/* subtree state variables */
static gint ett_vrt = -1;
@ -244,6 +261,7 @@ static gint ett_rel_ephem = -1;
static gint ett_gps_ascii = -1;
static gint ett_assoc_lists = -1;
static gint ett_pol = -1;
static gint ett_ver = -1;
/* constants (unit conversion) */
static const double FEMTOSEC_PER_SEC = 1e-15;
@ -253,6 +271,7 @@ static const double RADIX_DECIBEL_MILLIWATT = 1.0/128.0;
static const double RADIX_DEGREES = 1.0/4194304.0;
static const double RADIX_HERTZ = 1.0/1048576.0;
static const double RADIX_METER = 1.0/32.0;
static const double RADIX_METER_UNSIGNED = 1.0/64.0;
static const double RADIX_METERS_PER_SECOND = 1.0/65536.0;
static const double RADIX_RADIAN_PHASE = 1.0/128.0;
static const double RADIX_RADIAN_POL = 1.0/8192.0;
@ -269,6 +288,7 @@ static const int ETT_IDX_REL_EPHEM = 15;
static const int ETT_IDX_GPS_ASCII = 16;
static const int ETT_IDX_ASSOC_LISTS = 17;
static const int ETT_IDX_POL = 18;
static const int ETT_IDX_VER = 19;
static const value_string packet_types[] = {
{0x00, "IF data packet without stream ID"},
@ -338,6 +358,14 @@ static const value_string data_item_format[] = {
{0, NULL}
};
static const value_string standard_version_codes[] = {
{0x01, "Implements V49.0"},
{0x02, "Implements V49.1"},
{0x03, "Implements V49A"},
{0x04, "Implements V49.2"},
{0, NULL}
};
static int * const enable_hfs[] = {
&hf_vrt_trailer_en_user3,
&hf_vrt_trailer_en_user2,
@ -374,6 +402,7 @@ static void dissect_cid(tvbuff_t *tvb, proto_tree *tree, int offset);
static int dissect_context(tvbuff_t *tvb, proto_tree *tree, int offset);
static int dissect_context_as_cif(tvbuff_t *tvb, proto_tree *tree, int offset, uint32_t cif, complex_dissector_t
*complex_fptr, int **item_ptr, const int *size_ptr, int stop);
static int dissect_context_array_of_records(proto_tree *tree _U_, tvbuff_t *tvb, int offset);
static int dissect_context_assoc_lists(proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_context_cif0(proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_context_cif1(proto_tree *tree, tvbuff_t *tvb, int offset);
@ -391,6 +420,7 @@ static int dissect_context_rel_ephemeris(proto_tree *tree, tvbuff_t *tvb, int of
static int dissect_context_signal_data_format(proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_context_state_event(proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_context_temperature(proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_context_ver(proto_tree *tree, tvbuff_t *tvb, int offset);
static const char* get_engr_prefix(double *val);
/* context simple field dissector function pointer array (mutually exclusive with complex below) */
@ -401,9 +431,10 @@ static int* hf_vrt_context_cif0[32] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL
&hf_vrt_context_rf_freq_offset, &hf_vrt_context_rf_freq, &hf_vrt_context_if_freq,
&hf_vrt_context_bandwidth, &hf_vrt_context_ref_pt_id, NULL };
static int* hf_vrt_context_cif1[32] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL };
static int* hf_vrt_context_cif1[32] = { NULL, NULL, NULL, &hf_vrt_context_v49_spec, NULL,
&hf_vrt_context_io64, &hf_vrt_context_io32, NULL, NULL, NULL, NULL, NULL, NULL,
&hf_vrt_context_aux_bandwidth, NULL, &hf_vrt_context_aux_freq, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, &hf_vrt_context_range, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
/* context complex field dissector function pointer array */
@ -415,9 +446,12 @@ static complex_dissector_t complex_dissector_cif0[32] = {
NULL, NULL, NULL, dissect_context_gain, dissect_context_ref_level, NULL, NULL, NULL, NULL,
NULL, NULL, NULL };
/* partial CIF1 support */
static complex_dissector_t complex_dissector_cif1[32] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, dissect_context_ver, NULL, NULL, NULL, NULL, dissect_context_array_of_records,
NULL, dissect_context_array_of_records, NULL, dissect_context_array_of_records, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
dissect_context_array_of_records, NULL,
dissect_context_polarization, dissect_context_phase_offset };
@ -655,6 +689,12 @@ static int dissect_context_as_cif(tvbuff_t *tvb, proto_tree *tree, int offset, u
return offset;
}
static int dissect_context_array_of_records(proto_tree *tree _U_, tvbuff_t *tvb, int offset) {
// This is a placeholder that does not populate a proto tree, but computes & returns the
// variable field length so subsequent field indexing is correct.
return tvb_get_ntohl(tvb, offset)*4;
}
static int dissect_context_assoc_lists(proto_tree *tree, tvbuff_t *tvb, int offset) {
// compute number of variable words in field
guint32 word1 = tvb_get_ntohl(tvb, offset);
@ -749,6 +789,13 @@ static int dissect_context_cif1(proto_tree *tree, tvbuff_t *tvb, int offset) {
proto_tree *cif1_tree = proto_item_add_subtree(cif1_item, ett_cif1);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_phase_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_polarization, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_range, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_aux_freq, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_aux_bandwidth, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_io32, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_io64, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_v49_spec, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(cif1_tree, hf_vrt_cif1_ver, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
return 0;
}
@ -919,6 +966,16 @@ static int dissect_context_temperature(proto_tree *tree, tvbuff_t *tvb, int offs
return 0;
}
static int dissect_context_ver(proto_tree *tree, tvbuff_t *tvb, int offset) {
proto_tree *ver_tree = proto_tree_add_subtree(tree, tvb, offset, 4, ETT_IDX_VER, NULL,
"Version and build code");
proto_tree_add_item(ver_tree, hf_vrt_context_ver_year, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(ver_tree, hf_vrt_context_ver_day, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(ver_tree, hf_vrt_context_ver_rev, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(ver_tree, hf_vrt_context_ver_user, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
return 0;
}
static void format_celsius(char *str, int16_t val) {
snprintf(str, ITEM_LABEL_LENGTH, "%f °C", (double)val*RADIX_CELSIUS);
}
@ -947,6 +1004,12 @@ static void format_meter(char *str, int32_t val) {
snprintf(str, ITEM_LABEL_LENGTH, "%f %sm", val_f64, prefix);
}
static void format_meter_unsigned(char *str, uint32_t val) {
double val_f64 = (double)val*RADIX_METER_UNSIGNED;
const char *prefix = get_engr_prefix(&val_f64);
snprintf(str, ITEM_LABEL_LENGTH, "%f %sm", val_f64, prefix);
}
static void format_meters_per_second(char *str, int32_t val) {
double val_f64 = (double)val*RADIX_METERS_PER_SECOND;
const char *prefix = get_engr_prefix(&val_f64);
@ -1307,6 +1370,48 @@ proto_register_vrt(void)
NULL, 0x40,
NULL, HFILL }
},
{ &hf_vrt_cif1_range,
{ "Range (distance)", "vrt.cif1.range",
FT_BOOLEAN, 8,
NULL, 0x01,
NULL, HFILL }
},
{ &hf_vrt_cif1_aux_freq,
{ "Aux frequency", "vrt.cif1.auxfreq",
FT_BOOLEAN, 8,
NULL, 0x80,
NULL, HFILL }
},
{ &hf_vrt_cif1_aux_bandwidth,
{ "Aux bandwidth", "vrt.cif1.auxbw",
FT_BOOLEAN, 8,
NULL, 0x20,
NULL, HFILL }
},
{ &hf_vrt_cif1_io32,
{ "Discrete I/O (32-bit)", "vrt.cif1.io32",
FT_BOOLEAN, 8,
NULL, 0x40,
NULL, HFILL }
},
{ &hf_vrt_cif1_io64,
{ "Discrete I/O (64-bit)", "vrt.cif1.io64",
FT_BOOLEAN, 8,
NULL, 0x20,
NULL, HFILL }
},
{ &hf_vrt_cif1_v49_spec,
{ "V49 spec compliance", "vrt.cif1.v49spec",
FT_BOOLEAN, 8,
NULL, 0x08,
NULL, HFILL }
},
{ &hf_vrt_cif1_ver,
{ "Version and build code", "vrt.cif1.ver",
FT_BOOLEAN, 8,
NULL, 0x04,
NULL, HFILL }
},
{ &hf_vrt_cif[1],
{ "CIF1", "vrt.cif1",
FT_UINT32, BASE_HEX,
@ -2051,6 +2156,66 @@ proto_register_vrt(void)
CF_FUNC(format_radian_pol), 0x00,
NULL, HFILL }
},
{ &hf_vrt_context_range,
{ "Range (distance)", "vrt.context.range",
FT_UINT32, BASE_CUSTOM,
CF_FUNC(format_meter_unsigned), 0x00,
NULL, HFILL }
},
{ &hf_vrt_context_aux_freq,
{ "Aux frequency", "vrt.context.auxfreq",
FT_INT64, BASE_CUSTOM,
CF_FUNC(format_hertz), 0x00,
NULL, HFILL }
},
{ &hf_vrt_context_aux_bandwidth,
{ "Aux bandwidth", "vrt.context.auxbw",
FT_INT64, BASE_CUSTOM,
CF_FUNC(format_hertz), 0x00,
NULL, HFILL }
},
{ &hf_vrt_context_io32,
{ "Discrete I/O (32-bit)", "vrt.context.io32",
FT_UINT32, BASE_HEX,
NULL, 0x00,
NULL, HFILL }
},
{ &hf_vrt_context_io64,
{ "Discrete I/O (64-bit)", "vrt.context.io64",
FT_UINT64, BASE_HEX,
NULL, 0x00,
NULL, HFILL }
},
{ &hf_vrt_context_v49_spec,
{ "V49 spec compliance", "vrt.context.v49spec",
FT_UINT32, BASE_HEX,
VALS(standard_version_codes), 0x00,
NULL, HFILL }
},
{ &hf_vrt_context_ver_year,
{ "Year", "vrt.context.ver.year",
FT_UINT16, BASE_DEC,
NULL, 0xFE00,
NULL, HFILL }
},
{ &hf_vrt_context_ver_day,
{ "Day", "vrt.context.ver.day",
FT_UINT16, BASE_DEC,
NULL, 0x01FF,
NULL, HFILL }
},
{ &hf_vrt_context_ver_rev,
{ "Revision", "vrt.context.ver.rev",
FT_UINT16, BASE_DEC,
NULL, 0xFC00,
NULL, HFILL }
},
{ &hf_vrt_context_ver_user,
{ "User defined", "vrt.context.ver.user",
FT_UINT16, BASE_DEC,
NULL, 0x03FF,
NULL, HFILL }
},
{ &hf_vrt_data,
{ "Data", "vrt.data",
FT_BYTES, BASE_NONE,
@ -2271,7 +2436,8 @@ proto_register_vrt(void)
&ett_rel_ephem, // ETT_IDX_REL_EPHEM
&ett_gps_ascii, // ETT_IDX_GPS_ASCII
&ett_assoc_lists, // ETT_IDX_ASSOC_LISTS
&ett_pol // ETT_IDX_POL
&ett_pol, // ETT_IDX_POL
&ett_ver, // ETT_IDX_VER
};
proto_vrt = proto_register_protocol ("VITA 49 radio transport protocol", "VITA 49", "vrt");