1 /* packet-stanag4607.c
2 * Routines for STANAG 4607 dissection
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 #include "config.h"
7
8 #include <math.h>
9 #include <epan/packet.h>
10 #include <epan/expert.h>
11
12 #include <wiretap/stanag4607.h>
13
14 void proto_register_stanag4607(void);
15 void proto_reg_handoff_stanag4607(void);
16
17 static int proto_stanag4607 = -1;
18
19 static int hf_4607_version = -1;
20 static int hf_4607_packet_size = -1;
21 static int hf_4607_nationality = -1;
22 static int hf_4607_sec_class = -1;
23 static int hf_4607_sec_system = -1;
24 static int hf_4607_sec_code = -1;
25 static int hf_4607_exercise_indicator = -1;
26 static int hf_4607_platform_id = -1;
27 static int hf_4607_mission_id = -1;
28 static int hf_4607_job_id = -1;
29
30 static int hf_4607_segment_type = -1;
31 static int hf_4607_segment_size = -1;
32
33 /* Mission Segment */
34 static int hf_4607_mission_plan = -1;
35 static int hf_4607_mission_flight_plan = -1;
36 static int hf_4607_mission_platform = -1;
37 static int hf_4607_mission_platform_config = -1;
38 static int hf_4607_mission_time_year = -1;
39 static int hf_4607_mission_time_month = -1;
40 static int hf_4607_mission_time_day = -1;
41
42 /* Dwell Segment */
43 static int hf_4607_dwell_mask = -1;
44 static int hf_4607_dwell_revisit_index = -1;
45 static int hf_4607_dwell_dwell_index = -1;
46 static int hf_4607_dwell_last_dwell = -1;
47 static int hf_4607_dwell_count = -1;
48 static int hf_4607_dwell_time = -1;
49 static int hf_4607_dwell_sensor_lat = -1;
50 static int hf_4607_dwell_sensor_lon = -1;
51 static int hf_4607_dwell_sensor_alt = -1;
52 static int hf_4607_dwell_scale_lat = -1;
53 static int hf_4607_dwell_scale_lon = -1;
54 static int hf_4607_dwell_unc_along = -1;
55 static int hf_4607_dwell_unc_cross = -1;
56 static int hf_4607_dwell_unc_alt = -1;
57 static int hf_4607_dwell_track = -1;
58 static int hf_4607_dwell_speed = -1;
59 static int hf_4607_dwell_vert_velocity = -1;
60 static int hf_4607_dwell_track_unc = -1;
61 static int hf_4607_dwell_speed_unc = -1;
62 static int hf_4607_dwell_vv_unc = -1;
63
64 static int hf_4607_dwell_plat_heading = -1;
65 static int hf_4607_dwell_plat_pitch = -1;
66 static int hf_4607_dwell_plat_roll = -1;
67 static int hf_4607_dwell_da_lat = -1;
68 static int hf_4607_dwell_da_lon = -1;
69 static int hf_4607_dwell_da_range = -1;
70 static int hf_4607_dwell_da_angle = -1;
71 static int hf_4607_dwell_sensor_heading = -1;
72 static int hf_4607_dwell_sensor_pitch = -1;
73 static int hf_4607_dwell_sensor_roll = -1;
74 static int hf_4607_dwell_mdv = -1;
75
76 /* Target Report */
77 static int hf_4607_dwell_report_index = -1;
78 static int hf_4607_dwell_report_lat = -1;
79 static int hf_4607_dwell_report_lon = -1;
80 static int hf_4607_dwell_report_delta_lat = -1;
81 static int hf_4607_dwell_report_delta_lon = -1;
82 static int hf_4607_dwell_report_height = -1;
83 static int hf_4607_dwell_report_radial = -1;
84 static int hf_4607_dwell_report_wrap = -1;
85 static int hf_4607_dwell_report_snr = -1;
86 static int hf_4607_dwell_report_class = -1;
87 static int hf_4607_dwell_report_prob = -1;
88 static int hf_4607_dwell_report_unc_slant = -1;
89 static int hf_4607_dwell_report_unc_cross = -1;
90 static int hf_4607_dwell_report_unc_height = -1;
91 static int hf_4607_dwell_report_unc_radial = -1;
92 static int hf_4607_dwell_report_tag_app = -1;
93 static int hf_4607_dwell_report_tag_entity = -1;
94 static int hf_4607_dwell_report_section = -1;
95
96 /* Job Definition Segment */
97 static int hf_4607_jobdef_job_id = -1;
98 static int hf_4607_jobdef_sensor_type = -1;
99 static int hf_4607_jobdef_sensor_model = -1;
100 static int hf_4607_jobdef_filter = -1;
101 static int hf_4607_jobdef_priority = -1;
102 static int hf_4607_jobdef_ba_lat_a = -1;
103 static int hf_4607_jobdef_ba_lon_a = -1;
104 static int hf_4607_jobdef_ba_lat_b = -1;
105 static int hf_4607_jobdef_ba_lon_b = -1;
106 static int hf_4607_jobdef_ba_lat_c = -1;
107 static int hf_4607_jobdef_ba_lon_c = -1;
108 static int hf_4607_jobdef_ba_lat_d = -1;
109 static int hf_4607_jobdef_ba_lon_d = -1;
110 static int hf_4607_jobdef_radar_mode = -1;
111 static int hf_4607_jobdef_revisit_interval = -1;
112 static int hf_4607_jobdef_unc_along = -1;
113 static int hf_4607_jobdef_unc_cross = -1;
114 static int hf_4607_jobdef_unc_alt = -1;
115 static int hf_4607_jobdef_unc_heading = -1;
116 static int hf_4607_jobdef_unc_speed = -1;
117 static int hf_4607_jobdef_sense_slant = -1;
118 static int hf_4607_jobdef_sense_cross = -1;
119 static int hf_4607_jobdef_sense_vlos = -1;
120 static int hf_4607_jobdef_sense_mdv = -1;
121 static int hf_4607_jobdef_sense_prob = -1;
122 static int hf_4607_jobdef_sense_alarm = -1;
123 static int hf_4607_jobdef_terrain_model = -1;
124 static int hf_4607_jobdef_geoid_model = -1;
125
126 /* Platform Location Segment */
127 static int hf_4607_platloc_time = -1;
128 static int hf_4607_platloc_latitude = -1;
129 static int hf_4607_platloc_longitude = -1;
130 static int hf_4607_platloc_altitude = -1;
131 static int hf_4607_platloc_track = -1;
132 static int hf_4607_platloc_speed = -1;
133 static int hf_4607_platloc_vertical_velocity = -1;
134
135 /* Subtree pointers */
136 static gint ett_4607_hdr = -1;
137 static gint ett_4607_seg = -1;
138 static gint ett_4607_rpt = -1;
139
140 /* Error pointers */
141 static expert_field ei_bad_length = EI_INIT;
142 static expert_field ei_too_short = EI_INIT;
143 static expert_field ei_bad_packet_size = EI_INIT;
144
145 static dissector_handle_t stanag4607_handle;
146
147
148 static const value_string stanag4607_class_vals[] = {
149 { 1, "TOP SECRET" },
150 { 2, "SECRET" },
151 { 3, "CONFIDENTIAL" },
152 { 4, "RESTRICTED" },
153 { 5, "UNCLASSIFIED" },
154 { 0, NULL }
155 };
156
157 static const value_string stanag4607_exind_vals[] = {
158 { 0, "Operation, Real Data" },
159 { 1, "Operation, Simulated Data" },
160 { 2, "Operation, Synthesized Data" },
161 { 128, "Exercise, Real Data" },
162 { 129, "Exercise, Simulated Data" },
163 { 130, "Exercise, Synthesized Data" },
164 { 0, NULL }
165 };
166
167 #define MISSION_SEGMENT 1
168 #define DWELL_SEGMENT 2
169 #define JOB_DEFINITION_SEGMENT 5
170 #define PLATFORM_LOCATION_SEGMENT 13
171
172 static const value_string stanag4607_segment_vals[] = {
173 { 1, "Mission Segment" },
174 { 2, "Dwell Segment" },
175 { 3, "HRR Segment" },
176 { 5, "Job Definition Segment" },
177 { 6, "Free Text Segment" },
178 { 7, "Low Reflectivity Index Segment" },
179 { 8, "Group Segment" },
180 { 9, "Attached Target Segment" },
181 { 10, "Test and Status Segment" },
182 { 11, "System-Specific Segment" },
183 { 12, "Processing History Segment" },
184 { 13, "Platform Location Segment" },
185 { 101, "Job Request Segment" },
186 { 102, "Job Acknowledgment Segment" },
187 { 0, NULL }
188 };
189
190 static const value_string stanag4607_sensor_vals[] = {
191 { 0, "Unidentified" },
192 { 1, "Other" },
193 { 2, "HiSAR" },
194 { 3, "ASTOR" },
195 { 4, "Rotary Wing Radar" },
196 { 5, "Global Hawk Sensor" },
197 { 6, "HORIZON" },
198 { 7, "APY-3" },
199 { 8, "APY-6" },
200 { 9, "APY-8 (Lynx I)" },
201 { 10, "RADARSAT2" },
202 { 11, "ASARS-2A" },
203 { 12, "TESAR" },
204 { 13, "MP-RTIP" },
205 { 14, "APG-77" },
206 { 15, "APG-79" },
207 { 16, "APG-81" },
208 { 17, "APY-6v1" },
209 { 18, "SPY-I (Lynx II)" },
210 { 19, "SIDM" },
211 { 20, "LIMIT" },
212 { 21, "TCAR (AGS A321)" },
213 { 22, "LSRS Sensor" },
214 { 23, "UGS Single Sensor" },
215 { 24, "UGS Cluster Sensor" },
216 { 25, "IMASTER GMTI" },
217 { 26, "AN/ZPY-1 (STARLite)" },
218 { 27, "VADER" },
219 { 255, "No Statement" },
220 { 0, NULL }
221 };
222
223 static const value_string stanag4607_radar_mode_vals[] = {
224 { 0, "Unspecified Mode" },
225 { 1, "MTI (Moving Target Indicator)" },
226 { 2, "HRR (High Range Resolution)" },
227 { 3, "UHRR (Ultra High Range Resolution)" },
228 { 4, "HUR (High Update Rate)" },
229 { 5, "FTI" },
230 /* TODO: and many many more ... */
231 { 0, NULL }
232 };
233
234 static const value_string stanag4607_terrain_vals[] = {
235 { 0, "None Specified" },
236 { 1, "DTED0 (Digital Terrain Elevation Data, Level 0)" },
237 { 2, "DTED1 (Digital Terrain Elevation Data, Level 1)" },
238 { 3, "DTED2 (Digital Terrain Elevation Data, Level 2)" },
239 { 4, "DTED3 (Digital Terrain Elevation Data, Level 3)" },
240 { 5, "DTED4 (Digital Terrain Elevation Data, Level 4)" },
241 { 6, "DTED5 (Digital Terrain Elevation Data, Level 5)" },
242 { 7, "SRTM1 (Shuttle Radar Topography Mission, Level 1)" },
243 { 8, "SRTM2 (Shuttle Radar Topography Mission, Level 2)" },
244 { 9, "DGM50 M745 (Digitales Gelandemodell 1:50 000)" },
245 { 10, "DGM250 (Digitales Gelandemodell 1:250 000)" },
246 { 11, "ITHD (Interferometric Terrain Data Height)" },
247 { 12, "STHD (Stereometric Terrain Data Height)" },
248 { 13, "SEDRIS (SEDRIS Reference Model ISO/IEC 18026)" },
249 { 0, NULL }
250 };
251
252 static const value_string stanag4607_geoid_vals[] = {
253 { 0, "None Specified" },
254 { 1, "EGM96 (Earth Gravitional Model, Version 1996)" },
255 { 2, "GEO96 (Geoid Gravitional Model, Version 1996)" },
256 { 3, "Flat Earth" },
257 { 0, NULL }
258 };
259
260 static const value_string stanag4607_target_vals[] = {
261 { 0, "No Information, Live Target" },
262 { 1, "Tracked Vehicle, Live Target" },
263 { 2, "Wheeled Vehicle, Live Target" },
264 { 3, "Rotary Wing Aircraft, Live Target" },
265 { 4, "Fixed Wing Aircraft, Live Target" },
266 { 5, "Stationary Rotator, Live Target" },
267 { 6, "Maritime, Live Target" },
268 { 7, "Beacon, Live Target" },
269 { 8, "Amphibious, Live Target" },
270 { 9, "Person, Live Target" },
271 { 10, "Vehicle, Live Target" },
272 { 11, "Animal, Live Target" },
273 { 12, "Large Multiple-Return, Live Land Target" },
274 { 13, "Large Multiple-Return, Live Maritime Target" },
275
276 { 126, "Other, Live Target" },
277 { 127, "Unknown, Live Target" },
278 { 128, "No Information, Simulated Target" },
279 { 129, "Tracked Vehicle, Simulated Target" },
280 { 130, "Wheeled Vehicle, Simulated Target" },
281 { 131, "Rotary Wing Aircraft, Simulated Target" },
282 { 132, "Fixed Wing Aircraft, Simulated Target" },
283 { 133, "Stationary Rotator, Simulated Target" },
284 { 134, "Maritme, Simulated Target" },
285 { 135, "Beacon, Simulated Target" },
286 { 136, "Amphibious, Simulated Target" },
287 { 137, "Person, Simulated Target" },
288 { 138, "Vehicle, Simulated Target" },
289 { 139, "Animal, Simulated Target" },
290 { 140, "Large Multiple-Return, Simulated Land Target" },
291 { 141, "Large Multiple-Return, Simulated Maritime Target" },
292
293 { 143, "Tagging Device" },
294
295 { 254, "Other, Simulated Target" },
296 { 255, "Unknown, Simulated Target" },
297 { 0, NULL }
298 };
299
300 static const value_string stanag4607_platform_vals[] = {
301 { 0, "Unidentified" },
302 { 1, "ACS" },
303 { 2, "ARL-M" },
304 { 3, "Sentinel" },
305 { 4, "Rotary Wing Radar" },
306 { 5, "Global Hawk-Navy" },
307 { 6, "HORIZON" },
308 { 7, "E-8 (Joint STARS)" },
309 { 8, "P-3C" },
310 { 9, "Predator" },
311 { 10, "RADARSAT2" },
312 { 11, "U-2" },
313 { 12, "E-10" },
314 { 13, "UGS - Single" },
315 { 14, "UGS - Cluster" },
316 { 15, "Ground Based" },
317 { 16, "UAV-Army" },
318 { 17, "UAV-Marines" },
319 { 18, "UAV-Navy" },
320 { 19, "UAV-Air Force" },
321 { 20, "Global Hawk-Air Force" },
322 { 21, "Global Hawk-Australia" },
323 { 22, "Global Hawk-Germany" },
324 { 23, "Paul Revere" },
325 { 24, "Mariner UAV" },
326 { 25, "BAC-111" },
327 { 26, "Coyote" },
328 { 27, "King Air" },
329 { 28, "LIMIT" },
330 { 29, "NRL NP-3B" },
331 { 30, "SOSTAR-X" },
332 { 31, "WatchKeeper" },
333 { 32, "Alliance Ground Surveillance (AGS) (A321)" },
334 { 33, "Stryker" },
335 { 34, "AGS (HALE UAV)" },
336 { 35, "SIDM" },
337 { 36, "Reaper" },
338 { 37, "Warrior A" },
339 { 38, "Warrior" },
340 { 39, "Twin Otter" },
341 { 255, "Other" },
342 { 0, NULL }
343 };
344
345 static void
prt_sa32(gchar * buff,guint32 val)346 prt_sa32(gchar *buff, guint32 val)
347 {
348 double deg, min, sec;
349 double x = (double) ((gint32) val);
350 x /= (double) (1UL<<30);
351 x *= 45.0;
352 deg = floor(x);
353 min = floor(60.0 * (x - deg));
354 sec = 60.0 * (60.0 * (x - deg) - min);
355 /* checkAPI.pl doesn't like the unicode degree symbol, I don't know what to do... */
356 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.8f degrees (%.0f %.0f\' %.2f\")", x, deg, min, sec);
357 }
358
359 static void
prt_ba32(gchar * buff,guint32 val)360 prt_ba32(gchar *buff, guint32 val)
361 {
362 double deg, min, sec;
363 double x = (double) val;
364 x /= (double) (1UL<<30);
365 x *= 90.0;
366 deg = floor(x);
367 min = floor(60.0 * (x - deg));
368 sec = 60.0 * (60.0 * (x - deg) - min);
369 /* checkAPI.pl doesn't like the unicode degree symbol, I don't know what to do... */
370 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.8f degrees (%.0f %.0f\' %.2f\")", x, deg, min, sec);
371 }
372
373 static void
prt_sa16(gchar * buff,guint32 val)374 prt_sa16(gchar *buff, guint32 val)
375 {
376 double x = (double) ((gint32) val);
377 x /= (double) (1<<14);
378 x *= 90.0;
379 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.3f degrees", x);
380 }
381
382 static void
prt_ba16(gchar * buff,guint32 val)383 prt_ba16(gchar *buff, guint32 val)
384 {
385 double x = (double) val;
386 x /= (double) (1<<14);
387 x *= 90.0;
388 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.3f degrees", x);
389 }
390
391 static void
prt_ba16_none(gchar * buff,guint32 val)392 prt_ba16_none(gchar *buff, guint32 val)
393 {
394 double x = (double) val;
395 x /= (double) (1<<14);
396 x *= 90.0;
397 if (val <= 65536)
398 g_snprintf(buff, ITEM_LABEL_LENGTH, "No Statement");
399 else
400 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.3f degrees", x);
401 }
402
403 static void
prt_kilo(gchar * buff,guint32 val)404 prt_kilo(gchar *buff, guint32 val)
405 {
406 double x = (double) ((gint32) val);
407 x /= 128.0;
408 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.2f kilometers", x);
409 }
410
411 static void
prt_meters(gchar * buff,guint32 val)412 prt_meters(gchar *buff, guint32 val)
413 {
414 double x = (double) ((gint32) val);
415 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.0f meters", x);
416 }
417
418 static void
prt_decimeters(gchar * buff,guint32 val)419 prt_decimeters(gchar *buff, guint32 val)
420 {
421 double x = (double) ((gint32) val);
422 x /= 10.0;
423 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.1f meters", x);
424 }
425
426 static void
prt_centimeters(gchar * buff,guint32 val)427 prt_centimeters(gchar *buff, guint32 val)
428 {
429 double x = (double) ((gint32) val);
430 x /= 100.0;
431 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.2f meters", x);
432 }
433
434 static void
prt_speed(gchar * buff,guint32 val)435 prt_speed(gchar *buff, guint32 val)
436 {
437 double x = (double) val;
438 x /= 1000.0;
439 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.3f meters/second", x);
440 }
441
442 static void
prt_speed_centi(gchar * buff,guint32 val)443 prt_speed_centi(gchar *buff, guint32 val)
444 {
445 double x = (double) ((gint32) val);
446 x /= 100.0;
447 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.2f meters/second", x);
448 }
449
450 static void
prt_speed_deci(gchar * buff,guint32 val)451 prt_speed_deci(gchar *buff, guint32 val)
452 {
453 /* Usually 8-bit, signed */
454 double x = (double) ((gint32) val);
455 x /= 10.0;
456 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.1f meters/second", x);
457 }
458
459 static void
prt_millisec(gchar * buff,guint32 val)460 prt_millisec(gchar *buff, guint32 val)
461 {
462 double x = (double) val;
463 x /= 1000.0;
464 g_snprintf(buff, ITEM_LABEL_LENGTH, "%.3f seconds", x);
465 }
466
467 static void
prt_none8(gchar * buff,guint32 val)468 prt_none8(gchar *buff, guint32 val)
469 {
470 if (0xff == val)
471 g_snprintf(buff, ITEM_LABEL_LENGTH, "No Statement");
472 else
473 g_snprintf(buff, ITEM_LABEL_LENGTH, "%d", val);
474 }
475
476 static void
prt_none16(gchar * buff,guint32 val)477 prt_none16(gchar *buff, guint32 val)
478 {
479 if (0xffff == val)
480 g_snprintf(buff, ITEM_LABEL_LENGTH, "No Statement");
481 else
482 g_snprintf(buff, ITEM_LABEL_LENGTH, "%d", val);
483 }
484
485
486 static gint
dissect_mission(tvbuff_t * tvb,proto_tree * seg_tree,gint offset)487 dissect_mission(tvbuff_t *tvb, proto_tree *seg_tree, gint offset)
488 {
489 proto_tree_add_item(seg_tree, hf_4607_mission_plan, tvb, offset, 12, ENC_ASCII|ENC_NA);
490 offset += 12;
491 proto_tree_add_item(seg_tree, hf_4607_mission_flight_plan, tvb, offset, 12, ENC_ASCII|ENC_NA);
492 offset += 12;
493 proto_tree_add_item(seg_tree, hf_4607_mission_platform, tvb, offset, 1, ENC_BIG_ENDIAN);
494 offset += 1;
495 proto_tree_add_item(seg_tree, hf_4607_mission_platform_config, tvb, offset, 10, ENC_ASCII|ENC_NA);
496 offset += 10;
497 proto_tree_add_item(seg_tree, hf_4607_mission_time_year, tvb, offset, 2, ENC_BIG_ENDIAN);
498 offset += 2;
499 proto_tree_add_item(seg_tree, hf_4607_mission_time_month, tvb, offset, 1, ENC_BIG_ENDIAN);
500 offset += 1;
501 proto_tree_add_item(seg_tree, hf_4607_mission_time_day, tvb, offset, 1, ENC_BIG_ENDIAN);
502 offset += 1;
503
504 return offset;
505 }
506
507 /* Dwell Segment Existence Mask */
508 /* The Dxx fields are NOT bit locations! They are the field numbers
509 * as specified in Table 2-4 Dwell Segment. These field numbers DO NOT
510 * count bit locations in the existence mask (even though they come
511 * close to this). The m and n values of the m*8+n offset below are
512 * given in Figure 2-1 titled "Dwell Segment Existence Mask Mapping."
513 */
514 #define SET(MASK,OFF) (((MASK)>>(OFF)) & G_GINT64_CONSTANT(1))
515 #define D10 6*8+7
516 #define D12 6*8+5
517 #define D15 6*8+2
518 #define D18 5*8+7
519 #define D21 5*8+4
520 #define D24 5*8+1
521 #define D28 4*8+5
522 #define D31 4*8+2
523 #define D32_1 4*8+1
524 #define D32_2 4*8+0
525 #define D32_6 3*8+4
526 #define D32_7 3*8+3
527 #define D32_9 3*8+1
528 #define D32_10 3*8+0
529 #define D32_11 2*8+7
530 #define D32_12 2*8+6
531 #define D32_16 2*8+2
532 #define D32_18 2*8+0
533
534 /* Target Report */
535 static gint
dissect_target(tvbuff_t * tvb,proto_tree * seg_tree,gint offset,guint64 mask)536 dissect_target(tvbuff_t *tvb, proto_tree *seg_tree, gint offset, guint64 mask)
537 {
538 proto_item *rpt_item = NULL;
539 proto_tree *rpt_tree = seg_tree;
540
541 if (SET(mask, D32_1)) {
542 rpt_item = proto_tree_add_item(rpt_tree, hf_4607_dwell_report_index, tvb, offset, 2, ENC_BIG_ENDIAN);
543 offset += 2;
544 rpt_tree = proto_item_add_subtree(rpt_item, ett_4607_rpt);
545 }
546
547 if (SET(mask, D32_2)) {
548 rpt_item = proto_tree_add_item(rpt_tree, hf_4607_dwell_report_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
549 offset += 4;
550 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
551 offset += 4;
552 } else {
553 rpt_item = proto_tree_add_item(rpt_tree, hf_4607_dwell_report_delta_lat, tvb, offset, 2, ENC_BIG_ENDIAN);
554 offset += 2;
555 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_delta_lon, tvb, offset, 2, ENC_BIG_ENDIAN);
556 offset += 2;
557 }
558
559 /* If the report index wasn't set, then no subtree yet */
560 if (rpt_item && rpt_tree == seg_tree) {
561 rpt_tree = proto_item_add_subtree(rpt_item, ett_4607_rpt);
562 }
563 if (SET(mask, D32_6)) {
564 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_height, tvb, offset, 2, ENC_BIG_ENDIAN);
565 offset += 2;
566 }
567 if (SET(mask, D32_7)) {
568 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_radial, tvb, offset, 2, ENC_BIG_ENDIAN);
569 offset += 2;
570 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_wrap, tvb, offset, 2, ENC_BIG_ENDIAN);
571 offset += 2;
572 }
573 if (SET(mask, D32_9)) {
574 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_snr, tvb, offset, 1, ENC_BIG_ENDIAN);
575 offset += 1;
576 }
577 if (SET(mask, D32_10)) {
578 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_class, tvb, offset, 1, ENC_BIG_ENDIAN);
579 offset += 1;
580 }
581 if (SET(mask, D32_11)) {
582 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_prob, tvb, offset, 1, ENC_BIG_ENDIAN);
583 offset += 1;
584 }
585 if (SET(mask, D32_12)) {
586 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_slant, tvb, offset, 2, ENC_BIG_ENDIAN);
587 offset += 2;
588 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_cross, tvb, offset, 2, ENC_BIG_ENDIAN);
589 offset += 2;
590 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_height, tvb, offset, 1, ENC_BIG_ENDIAN);
591 offset += 1;
592 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_radial, tvb, offset, 2, ENC_BIG_ENDIAN);
593 offset += 2;
594 }
595 if (SET(mask, D32_16)) {
596 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_tag_app, tvb, offset, 1, ENC_BIG_ENDIAN);
597 offset += 1;
598 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_tag_entity, tvb, offset, 4, ENC_BIG_ENDIAN);
599 offset += 4;
600 }
601 if (SET(mask, D32_18)) {
602 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_section, tvb, offset, 1, ENC_BIG_ENDIAN);
603 offset += 1;
604 }
605
606 return offset;
607 }
608
609 /* Dwell Segment */
610 static gint
dissect_dwell(tvbuff_t * tvb,proto_tree * seg_tree,gint offset)611 dissect_dwell(tvbuff_t *tvb, proto_tree *seg_tree, gint offset)
612 {
613 guint64 mask;
614 guint32 count;
615
616 mask = tvb_get_ntoh64(tvb, offset);
617
618 proto_tree_add_item(seg_tree, hf_4607_dwell_mask, tvb, offset, 8, ENC_BIG_ENDIAN);
619 offset += 8;
620 proto_tree_add_item(seg_tree, hf_4607_dwell_revisit_index, tvb, offset, 2, ENC_BIG_ENDIAN);
621 offset += 2;
622 proto_tree_add_item(seg_tree, hf_4607_dwell_dwell_index, tvb, offset, 2, ENC_BIG_ENDIAN);
623 offset += 2;
624 proto_tree_add_item(seg_tree, hf_4607_dwell_last_dwell, tvb, offset, 1, ENC_BIG_ENDIAN);
625 offset += 1;
626
627 /* count of target reports */
628 count = tvb_get_ntohs(tvb, offset);
629 proto_tree_add_item(seg_tree, hf_4607_dwell_count, tvb, offset, 2, ENC_BIG_ENDIAN);
630 offset += 2;
631 proto_tree_add_item(seg_tree, hf_4607_dwell_time, tvb, offset, 4, ENC_BIG_ENDIAN);
632 offset += 4;
633 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
634 offset += 4;
635 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
636 offset += 4;
637 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_alt, tvb, offset, 4, ENC_BIG_ENDIAN);
638 offset += 4;
639
640 if (SET(mask, D10)) {
641 proto_tree_add_item(seg_tree, hf_4607_dwell_scale_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
642 offset += 4;
643 proto_tree_add_item(seg_tree, hf_4607_dwell_scale_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
644 offset += 4;
645 }
646 if (SET(mask, D12)) {
647 proto_tree_add_item(seg_tree, hf_4607_dwell_unc_along, tvb, offset, 4, ENC_BIG_ENDIAN);
648 offset += 4;
649 proto_tree_add_item(seg_tree, hf_4607_dwell_unc_cross, tvb, offset, 4, ENC_BIG_ENDIAN);
650 offset += 4;
651 proto_tree_add_item(seg_tree, hf_4607_dwell_unc_alt, tvb, offset, 2, ENC_BIG_ENDIAN);
652 offset += 2;
653 }
654 if (SET(mask, D15)) {
655 proto_tree_add_item(seg_tree, hf_4607_dwell_track, tvb, offset, 2, ENC_BIG_ENDIAN);
656 offset += 2;
657 proto_tree_add_item(seg_tree, hf_4607_dwell_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
658 offset += 4;
659 proto_tree_add_item(seg_tree, hf_4607_dwell_vert_velocity, tvb, offset, 1, ENC_BIG_ENDIAN);
660 offset += 1;
661 }
662 if (SET(mask, D18)) {
663 proto_tree_add_item(seg_tree, hf_4607_dwell_track_unc, tvb, offset, 1, ENC_BIG_ENDIAN);
664 offset += 1;
665 proto_tree_add_item(seg_tree, hf_4607_dwell_speed_unc, tvb, offset, 2, ENC_BIG_ENDIAN);
666 offset += 2;
667 proto_tree_add_item(seg_tree, hf_4607_dwell_vv_unc, tvb, offset, 2, ENC_BIG_ENDIAN);
668 offset += 2;
669 }
670 if (SET(mask, D21)) {
671 proto_tree_add_item(seg_tree, hf_4607_dwell_plat_heading, tvb, offset, 2, ENC_BIG_ENDIAN);
672 offset += 2;
673 proto_tree_add_item(seg_tree, hf_4607_dwell_plat_pitch, tvb, offset, 2, ENC_BIG_ENDIAN);
674 offset += 2;
675 proto_tree_add_item(seg_tree, hf_4607_dwell_plat_roll, tvb, offset, 2, ENC_BIG_ENDIAN);
676 offset += 2;
677 }
678
679 /* Mandatory Dwell Area */
680 proto_tree_add_item(seg_tree, hf_4607_dwell_da_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
681 offset += 4;
682 proto_tree_add_item(seg_tree, hf_4607_dwell_da_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
683 offset += 4;
684 proto_tree_add_item(seg_tree, hf_4607_dwell_da_range, tvb, offset, 2, ENC_BIG_ENDIAN);
685 offset += 2;
686 proto_tree_add_item(seg_tree, hf_4607_dwell_da_angle, tvb, offset, 2, ENC_BIG_ENDIAN);
687 offset += 2;
688
689 if (SET(mask, D28)) {
690 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_heading, tvb, offset, 2, ENC_BIG_ENDIAN);
691 offset += 2;
692 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_pitch, tvb, offset, 2, ENC_BIG_ENDIAN);
693 offset += 2;
694 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_roll, tvb, offset, 2, ENC_BIG_ENDIAN);
695 offset += 2;
696 }
697 if (SET(mask, D31)) {
698 proto_tree_add_item(seg_tree, hf_4607_dwell_mdv, tvb, offset, 1, ENC_BIG_ENDIAN);
699 offset += 1;
700 }
701
702 while (count--) {
703 offset = dissect_target(tvb, seg_tree, offset, mask);
704 }
705
706 return offset;
707 }
708
709 /* Job Definition */
710 static gint
dissect_jobdef(tvbuff_t * tvb,proto_tree * seg_tree,gint offset)711 dissect_jobdef(tvbuff_t *tvb, proto_tree *seg_tree, gint offset)
712 {
713 proto_tree_add_item(seg_tree, hf_4607_jobdef_job_id, tvb, offset, 4, ENC_BIG_ENDIAN);
714 offset += 4;
715 proto_tree_add_item(seg_tree, hf_4607_jobdef_sensor_type, tvb, offset, 1, ENC_BIG_ENDIAN);
716 offset += 1;
717 proto_tree_add_item(seg_tree, hf_4607_jobdef_sensor_model, tvb, offset, 6, ENC_ASCII|ENC_NA);
718 offset += 6;
719 proto_tree_add_item(seg_tree, hf_4607_jobdef_filter, tvb, offset, 1, ENC_BIG_ENDIAN);
720 offset += 1;
721 proto_tree_add_item(seg_tree, hf_4607_jobdef_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
722 offset += 1;
723 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_a, tvb, offset, 4, ENC_BIG_ENDIAN);
724 offset += 4;
725 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_a, tvb, offset, 4, ENC_BIG_ENDIAN);
726 offset += 4;
727 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_b, tvb, offset, 4, ENC_BIG_ENDIAN);
728 offset += 4;
729 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_b, tvb, offset, 4, ENC_BIG_ENDIAN);
730 offset += 4;
731 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_c, tvb, offset, 4, ENC_BIG_ENDIAN);
732 offset += 4;
733 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_c, tvb, offset, 4, ENC_BIG_ENDIAN);
734 offset += 4;
735 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_d, tvb, offset, 4, ENC_BIG_ENDIAN);
736 offset += 4;
737 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_d, tvb, offset, 4, ENC_BIG_ENDIAN);
738 offset += 4;
739 proto_tree_add_item(seg_tree, hf_4607_jobdef_radar_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
740 offset += 1;
741 proto_tree_add_item(seg_tree, hf_4607_jobdef_revisit_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
742 offset += 2;
743 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_along, tvb, offset, 2, ENC_BIG_ENDIAN);
744 offset += 2;
745 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_cross, tvb, offset, 2, ENC_BIG_ENDIAN);
746 offset += 2;
747 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_alt, tvb, offset, 2, ENC_BIG_ENDIAN);
748 offset += 2;
749 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_heading, tvb, offset, 1, ENC_BIG_ENDIAN);
750 offset += 1;
751 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
752 offset += 2;
753 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_slant, tvb, offset, 2, ENC_BIG_ENDIAN);
754 offset += 2;
755 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_cross, tvb, offset, 2, ENC_BIG_ENDIAN);
756 offset += 2;
757 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_vlos, tvb, offset, 2, ENC_BIG_ENDIAN);
758 offset += 2;
759 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_mdv, tvb, offset, 1, ENC_BIG_ENDIAN);
760 offset += 1;
761 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_prob, tvb, offset, 1, ENC_BIG_ENDIAN);
762 offset += 1;
763 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_alarm, tvb, offset, 1, ENC_BIG_ENDIAN);
764 offset += 1;
765 proto_tree_add_item(seg_tree, hf_4607_jobdef_terrain_model, tvb, offset, 1, ENC_BIG_ENDIAN);
766 offset += 1;
767 proto_tree_add_item(seg_tree, hf_4607_jobdef_geoid_model, tvb, offset, 1, ENC_BIG_ENDIAN);
768 offset += 1;
769
770 return offset;
771 }
772
773 static gint
dissect_platform_location(tvbuff_t * tvb,proto_tree * seg_tree,gint offset)774 dissect_platform_location(tvbuff_t *tvb, proto_tree *seg_tree, gint offset)
775 {
776 proto_tree_add_item(seg_tree, hf_4607_platloc_time, tvb, offset, 4, ENC_BIG_ENDIAN);
777 offset += 4;
778 proto_tree_add_item(seg_tree, hf_4607_platloc_latitude, tvb, offset, 4, ENC_BIG_ENDIAN);
779 offset += 4;
780 proto_tree_add_item(seg_tree, hf_4607_platloc_longitude, tvb, offset, 4, ENC_BIG_ENDIAN);
781 offset += 4;
782 proto_tree_add_item(seg_tree, hf_4607_platloc_altitude, tvb, offset, 4, ENC_BIG_ENDIAN);
783 offset += 4;
784 proto_tree_add_item(seg_tree, hf_4607_platloc_track, tvb, offset, 2, ENC_BIG_ENDIAN);
785 offset += 2;
786 proto_tree_add_item(seg_tree, hf_4607_platloc_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
787 offset += 4;
788 proto_tree_add_item(seg_tree, hf_4607_platloc_vertical_velocity, tvb, offset, 1, ENC_BIG_ENDIAN);
789 offset += 1;
790 return offset;
791 }
792
793 /* 32 == packet header, 5 == segment type and length */
794 #define STANAG4607_MIN_LENGTH (32+5)
795
796 #define MINIMUM_SEGMENT_SIZE 14
797 #define MISSION_SEGMENT_SIZE 44
798 #define JOB_DEFINITION_SEGMENT_SIZE 73
799 #define PLATFORM_LOCATION_SEGMENT_SIZE 28
800
801 /* Provide a basic sanity check on segment sizes; the fixed-length
802 * ones should be what they claim to be.
803 */
804 #define CHK_SIZE(SEG_TYPE) \
805 if (SEG_TYPE##_SIZE != seg_size) { \
806 col_append_str(pinfo->cinfo, COL_INFO, ", Error: Invalid segment size "); \
807 expert_add_info(pinfo, pi, &ei_bad_length); \
808 }
809
810 static int
dissect_stanag4607(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)811 dissect_stanag4607(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
812 {
813 guint32 offset = 0;
814 gint8 first_segment;
815
816 guint32 pkt_size = 0;
817 proto_item *ti = NULL;
818 proto_tree *hdr_tree = NULL;
819 proto_item *seg_type = NULL;
820 proto_tree *seg_tree = NULL;
821 guint8 seg_id = 0;
822
823 /* Basic length check */
824 if (tvb_captured_length(tvb) < STANAG4607_MIN_LENGTH)
825 return 0;
826
827 col_set_str(pinfo->cinfo, COL_PROTOCOL, "S4607");
828 /* Clear out stuff in the info column */
829 col_clear(pinfo->cinfo, COL_INFO);
830
831 /* Put type of first segment in the info column */
832 first_segment = tvb_get_guint8(tvb, 32);
833 col_add_str(pinfo->cinfo, COL_INFO,
834 val_to_str(first_segment, stanag4607_segment_vals, "Unknown (0x%02x)"));
835
836 /* Put the timestamp, if available in the time column */
837 if (PLATFORM_LOCATION_SEGMENT == first_segment) {
838 guint32 millisecs;
839 nstime_t ts;
840 millisecs = tvb_get_ntohl(tvb, 37);
841 ts.secs = millisecs / 1000;
842 ts.nsecs = (int)((millisecs - 1000 * ts.secs) * 1000000);
843 col_set_time(pinfo->cinfo, COL_REL_TIME, &ts, "s4607.ploc.time");
844 }
845
846 /* The generic packet header */
847 if (tree) {
848 ti = proto_tree_add_item(tree, proto_stanag4607, tvb, 0, -1, ENC_NA);
849 hdr_tree = proto_item_add_subtree(ti, ett_4607_hdr);
850 proto_tree_add_item(hdr_tree, hf_4607_version, tvb, 0, 2, ENC_ASCII|ENC_NA);
851 ti = proto_tree_add_item(hdr_tree, hf_4607_packet_size, tvb, 2, 4, ENC_BIG_ENDIAN);
852 proto_tree_add_item(hdr_tree, hf_4607_nationality, tvb, 6, 2, ENC_ASCII|ENC_NA);
853 proto_tree_add_item(hdr_tree, hf_4607_sec_class, tvb, 8, 1, ENC_BIG_ENDIAN);
854 proto_tree_add_item(hdr_tree, hf_4607_sec_system, tvb, 9, 2, ENC_ASCII|ENC_NA);
855 proto_tree_add_item(hdr_tree, hf_4607_sec_code, tvb, 11, 2, ENC_BIG_ENDIAN);
856 proto_tree_add_item(hdr_tree, hf_4607_exercise_indicator, tvb, 13, 1, ENC_BIG_ENDIAN);
857 proto_tree_add_item(hdr_tree, hf_4607_platform_id, tvb, 14, 10, ENC_ASCII|ENC_NA);
858 proto_tree_add_item(hdr_tree, hf_4607_mission_id, tvb, 24, 4, ENC_BIG_ENDIAN);
859 proto_tree_add_item(hdr_tree, hf_4607_job_id, tvb, 28, 4, ENC_BIG_ENDIAN);
860 }
861 offset = 32;
862
863 pkt_size = tvb_get_ntohl(tvb, 2);
864
865 /* Ruh ro. These should be equal... */
866 if (tvb_reported_length(tvb) != pkt_size) {
867 expert_add_info(pinfo, ti, &ei_bad_packet_size);
868 pkt_size = tvb_reported_length(tvb);
869 }
870
871 /* Loop over all segments in the packet */
872 while (offset < pkt_size) {
873 guint32 seg_size = 0;
874 guint32 saved_offset = offset;
875
876 proto_item * pi;
877 /* Segment header */
878 seg_type = proto_tree_add_item(hdr_tree, hf_4607_segment_type, tvb, offset, 1, ENC_BIG_ENDIAN);
879 seg_id = tvb_get_guint8(tvb, offset);
880 offset += 1;
881
882 seg_tree = proto_item_add_subtree(seg_type, ett_4607_seg);
883 pi = proto_tree_add_item(seg_tree, hf_4607_segment_size, tvb, offset, 4, ENC_BIG_ENDIAN);
884 seg_size = tvb_get_ntohl(tvb, offset);
885 offset += 4;
886 if (seg_size < MINIMUM_SEGMENT_SIZE) {
887 seg_size = MINIMUM_SEGMENT_SIZE;
888 col_append_str(pinfo->cinfo, COL_INFO, ", Error: Invalid segment size ");
889 expert_add_info(pinfo, pi, &ei_too_short);
890 }
891
892 switch (seg_id) {
893 case MISSION_SEGMENT:
894 CHK_SIZE(MISSION_SEGMENT);
895 offset = dissect_mission(tvb, seg_tree, offset);
896 break;
897 case DWELL_SEGMENT:
898 offset = dissect_dwell(tvb, seg_tree, offset);
899 break;
900 case JOB_DEFINITION_SEGMENT:
901 CHK_SIZE(JOB_DEFINITION_SEGMENT);
902 offset = dissect_jobdef(tvb, seg_tree, offset);
903 break;
904 case PLATFORM_LOCATION_SEGMENT:
905 CHK_SIZE(PLATFORM_LOCATION_SEGMENT);
906 offset = dissect_platform_location(tvb, seg_tree, offset);
907 break;
908 default:
909 offset += seg_size - 5;
910 break;
911 }
912
913 if (offset < saved_offset) {
914 /* overflow */
915 break;
916 }
917 }
918 return tvb_captured_length(tvb);
919 }
920
921 void
proto_register_stanag4607(void)922 proto_register_stanag4607(void)
923 {
924 static hf_register_info hf[] = {
925 /* ========================================== */
926 /* Packet header */
927 { &hf_4607_version,
928 { "Version ID", "s4607.version",
929 FT_STRING, BASE_NONE,
930 NULL, 0x0,
931 NULL, HFILL }
932 },
933 { &hf_4607_packet_size,
934 { "Packet Size", "s4607.size",
935 FT_UINT32, BASE_DEC,
936 NULL, 0x0,
937 NULL, HFILL }
938 },
939 { &hf_4607_nationality,
940 { "Nationality", "s4607.nationality",
941 FT_STRING, BASE_NONE,
942 NULL, 0x0,
943 NULL, HFILL }
944 },
945 { &hf_4607_sec_class,
946 { "Security Classification", "s4607.sec.class",
947 FT_UINT8, BASE_DEC,
948 VALS(stanag4607_class_vals), 0x0,
949 NULL, HFILL }
950 },
951 { &hf_4607_sec_system,
952 { "Security System", "s4607.sec.system",
953 FT_STRING, BASE_NONE,
954 NULL, 0x0,
955 NULL, HFILL }
956 },
957 { &hf_4607_sec_code,
958 { "Security Codes", "s4607.sec.codes",
959 FT_UINT16, BASE_HEX,
960 NULL, 0x0,
961 NULL, HFILL }
962 },
963 { &hf_4607_exercise_indicator,
964 { "Exercise Indicator", "s4607.exind",
965 FT_UINT8, BASE_DEC,
966 VALS(stanag4607_exind_vals), 0x0,
967 NULL, HFILL }
968 },
969 { &hf_4607_platform_id,
970 { "Platform ID", "s4607.platform",
971 FT_STRING, BASE_NONE,
972 NULL, 0x0,
973 NULL, HFILL }
974 },
975 { &hf_4607_mission_id,
976 { "Mission ID", "s4607.mission",
977 FT_UINT32, BASE_DEC,
978 NULL, 0x0,
979 NULL, HFILL }
980 },
981 { &hf_4607_job_id,
982 { "Job ID", "s4607.job",
983 FT_UINT32, BASE_DEC,
984 NULL, 0x0,
985 NULL, HFILL }
986 },
987
988 /* ========================================== */
989 /* Segment header */
990 { &hf_4607_segment_type,
991 { "Segment Type", "s4607.seg.type",
992 FT_UINT8, BASE_DEC,
993 VALS(stanag4607_segment_vals), 0x0,
994 NULL, HFILL }
995 },
996 { &hf_4607_segment_size,
997 { "Segment Size", "s4607.seg.size",
998 FT_UINT32, BASE_DEC,
999 NULL, 0x0,
1000 NULL, HFILL }
1001 },
1002
1003 /* ========================================== */
1004 /* Dwell Segment */
1005 { &hf_4607_dwell_mask,
1006 { "Existence Mask", "s4607.dwell.mask",
1007 FT_UINT64, BASE_HEX,
1008 NULL, 0x0,
1009 NULL, HFILL }
1010 },
1011 { &hf_4607_dwell_revisit_index,
1012 { "Revisit Index", "s4607.dwell.revisit",
1013 FT_UINT16, BASE_DEC,
1014 NULL, 0x0,
1015 NULL, HFILL }
1016 },
1017 { &hf_4607_dwell_dwell_index,
1018 { "Dwell Index", "s4607.dwell.dwell",
1019 FT_UINT16, BASE_DEC,
1020 NULL, 0x0,
1021 NULL, HFILL }
1022 },
1023 { &hf_4607_dwell_last_dwell,
1024 { "Last Dwell of Revisit", "s4607.dwell.last",
1025 FT_UINT8, BASE_DEC,
1026 NULL, 0x0,
1027 NULL, HFILL }
1028 },
1029 { &hf_4607_dwell_count,
1030 { "Target Report Count", "s4607.dwell.count",
1031 FT_UINT16, BASE_DEC,
1032 NULL, 0x0,
1033 NULL, HFILL }
1034 },
1035 { &hf_4607_dwell_time,
1036 { "Dwell Time", "s4607.dwell.time",
1037 FT_UINT32, BASE_CUSTOM,
1038 CF_FUNC(prt_millisec), 0x0,
1039 NULL, HFILL }
1040 },
1041 { &hf_4607_dwell_sensor_lat,
1042 { "Sensor Position Latitude", "s4607.dwell.sensor.lat",
1043 FT_INT32, BASE_CUSTOM,
1044 CF_FUNC(prt_sa32), 0x0,
1045 NULL, HFILL }
1046 },
1047 { &hf_4607_dwell_sensor_lon,
1048 { "Sensor Position Longitude", "s4607.dwell.sensor.lon",
1049 FT_UINT32, BASE_CUSTOM,
1050 CF_FUNC(prt_ba32), 0x0,
1051 NULL, HFILL }
1052 },
1053 { &hf_4607_dwell_sensor_alt,
1054 { "Sensor Position Altitude", "s4607.dwell.sensor.alt",
1055 FT_INT32, BASE_CUSTOM,
1056 CF_FUNC(prt_centimeters), 0x0,
1057 NULL, HFILL }
1058 },
1059 /* D10 */
1060 { &hf_4607_dwell_scale_lat,
1061 { "Scale Factor, Latitude", "s4607.dwell.scale.lat",
1062 FT_INT32, BASE_CUSTOM,
1063 CF_FUNC(prt_sa32), 0x0,
1064 NULL, HFILL }
1065 },
1066 { &hf_4607_dwell_scale_lon,
1067 { "Scale Factor, Longitude", "s4607.dwell.scale.lon",
1068 FT_UINT32, BASE_CUSTOM,
1069 CF_FUNC(prt_ba32), 0x0,
1070 NULL, HFILL }
1071 },
1072
1073 /* D12 */
1074 { &hf_4607_dwell_unc_along,
1075 { "Sensor Position Uncertainty Along Track", "s4607.dwell.unc.along",
1076 FT_UINT32, BASE_CUSTOM,
1077 CF_FUNC(prt_centimeters), 0x0,
1078 NULL, HFILL }
1079 },
1080 { &hf_4607_dwell_unc_cross,
1081 { "Sensor Position Uncertainty Cross Track", "s4607.dwell.unc.cross",
1082 FT_UINT32, BASE_CUSTOM,
1083 CF_FUNC(prt_centimeters), 0x0,
1084 NULL, HFILL }
1085 },
1086 { &hf_4607_dwell_unc_alt,
1087 { "Sensor Position Uncertainty Altitude", "s4607.dwell.unc.alt",
1088 FT_UINT16, BASE_CUSTOM,
1089 CF_FUNC(prt_centimeters), 0x0,
1090 NULL, HFILL }
1091 },
1092
1093 /* D15 */
1094 { &hf_4607_dwell_track,
1095 { "Sensor Track", "s4607.dwell.track",
1096 FT_UINT16, BASE_CUSTOM,
1097 CF_FUNC(prt_ba16), 0x0,
1098 NULL, HFILL }
1099 },
1100 { &hf_4607_dwell_speed,
1101 { "Sensor Speed", "s4607.dwell.speed",
1102 FT_UINT32, BASE_CUSTOM,
1103 CF_FUNC(prt_speed), 0x0,
1104 NULL, HFILL }
1105 },
1106 { &hf_4607_dwell_vert_velocity,
1107 { "Sensor Vertical Velocity", "s4607.dwell.vvel",
1108 FT_INT8, BASE_CUSTOM,
1109 CF_FUNC(prt_speed_deci), 0x0,
1110 NULL, HFILL }
1111 },
1112 { &hf_4607_dwell_track_unc,
1113 { "Sensor Track Uncertainty", "s4607.dwell.track.unc",
1114 FT_UINT8, BASE_DEC,
1115 NULL, 0x0,
1116 NULL, HFILL }
1117 },
1118 { &hf_4607_dwell_speed_unc,
1119 { "Sensor Speed Uncertainty", "s4607.dwell.speed.unc",
1120 FT_UINT16, BASE_CUSTOM,
1121 CF_FUNC(prt_speed), 0x0,
1122 NULL, HFILL }
1123 },
1124 { &hf_4607_dwell_vv_unc,
1125 { "Sensor Vertical Velocity Uncertainty", "s4607.dwell.vvel.unc",
1126 FT_UINT16, BASE_CUSTOM,
1127 CF_FUNC(prt_speed_centi), 0x0,
1128 NULL, HFILL }
1129 },
1130
1131 /* D21 */
1132 { &hf_4607_dwell_plat_heading,
1133 { "Platform Orientation Heading", "s4607.dwell.plat.heading",
1134 FT_UINT16, BASE_CUSTOM,
1135 CF_FUNC(prt_ba16), 0x0,
1136 NULL, HFILL }
1137 },
1138 { &hf_4607_dwell_plat_pitch,
1139 { "Platform Orientation Pitch", "s4607.dwell.plat.pitch",
1140 FT_INT16, BASE_CUSTOM,
1141 CF_FUNC(prt_sa16), 0x0,
1142 NULL, HFILL }
1143 },
1144 { &hf_4607_dwell_plat_roll,
1145 { "Platform Orientation Roll (Bank Angle)", "s4607.dwell.plat.roll",
1146 FT_INT16, BASE_CUSTOM,
1147 CF_FUNC(prt_sa16), 0x0,
1148 NULL, HFILL }
1149 },
1150
1151 /* D24 */
1152 { &hf_4607_dwell_da_lat,
1153 { "Dwell Area Center Latitude", "s4607.dwell.da.lat",
1154 FT_INT32, BASE_CUSTOM,
1155 CF_FUNC(prt_sa32), 0x0,
1156 NULL, HFILL }
1157 },
1158 { &hf_4607_dwell_da_lon,
1159 { "Dwell Area Center Longitude", "s4607.dwell.da.lon",
1160 FT_UINT32, BASE_CUSTOM,
1161 CF_FUNC(prt_ba32), 0x0,
1162 NULL, HFILL }
1163 },
1164 { &hf_4607_dwell_da_range,
1165 { "Dwell Area Range Half Extent", "s4607.dwell.da.range",
1166 FT_UINT16, BASE_CUSTOM,
1167 CF_FUNC(prt_kilo), 0x0,
1168 NULL, HFILL }
1169 },
1170 { &hf_4607_dwell_da_angle,
1171 { "Dwell Area Dwell Angle Half Extent", "s4607.dwell.da.angle",
1172 FT_UINT16, BASE_CUSTOM,
1173 CF_FUNC(prt_ba16), 0x0,
1174 NULL, HFILL }
1175 },
1176
1177 /* D28 */
1178 { &hf_4607_dwell_sensor_heading,
1179 { "Sensor Orientation Heading", "s4607.dwell.sensor.heading",
1180 FT_UINT16, BASE_CUSTOM,
1181 CF_FUNC(prt_ba16), 0x0,
1182 NULL, HFILL }
1183 },
1184 { &hf_4607_dwell_sensor_pitch,
1185 { "Sensor Orientation Pitch", "s4607.dwell.sensor.pitch",
1186 FT_INT16, BASE_CUSTOM,
1187 CF_FUNC(prt_sa16), 0x0,
1188 NULL, HFILL }
1189 },
1190 { &hf_4607_dwell_sensor_roll,
1191 { "Sensor Orientation Roll (Bank Angle)", "s4607.dwell.sensor.roll",
1192 FT_INT16, BASE_CUSTOM,
1193 CF_FUNC(prt_sa16), 0x0,
1194 NULL, HFILL }
1195 },
1196 { &hf_4607_dwell_mdv,
1197 { "Minimum Detectable Velocity (MDV)", "s4607.dwell.mdv",
1198 FT_UINT8, BASE_CUSTOM,
1199 CF_FUNC(prt_speed_deci), 0x0,
1200 NULL, HFILL }
1201 },
1202
1203 /* ========================================== */
1204 /* Target Report */
1205 { &hf_4607_dwell_report_index,
1206 { "MTI Report Index", "s4607.dwell.rpt.idx",
1207 FT_UINT16, BASE_DEC,
1208 NULL, 0x0,
1209 NULL, HFILL }
1210 },
1211
1212 /* D32.2 */
1213 { &hf_4607_dwell_report_lat,
1214 { "Target Location Hi-Res Latitude", "s4607.dwell.rpt.lat",
1215 FT_INT32, BASE_CUSTOM,
1216 CF_FUNC(prt_sa32), 0x0,
1217 NULL, HFILL }
1218 },
1219 { &hf_4607_dwell_report_lon,
1220 { "Target Location Hi-Res Longitude", "s4607.dwell.rpt.lon",
1221 FT_UINT32, BASE_CUSTOM,
1222 CF_FUNC(prt_ba32), 0x0,
1223 NULL, HFILL }
1224 },
1225
1226 /* D32.4 */
1227 { &hf_4607_dwell_report_delta_lat,
1228 { "Target Location Delta Latitude", "s4607.dwell.rpt.delta.lat",
1229 FT_INT16, BASE_DEC,
1230 NULL, 0x0,
1231 NULL, HFILL }
1232 },
1233 { &hf_4607_dwell_report_delta_lon,
1234 { "Target Location Delta Longitude", "s4607.dwell.rpt.delta.lon",
1235 FT_INT16, BASE_DEC,
1236 NULL, 0x0,
1237 NULL, HFILL }
1238 },
1239
1240 /* D32.6 */
1241 { &hf_4607_dwell_report_height,
1242 { "Target Location Geodetic Height", "s4607.dwell.rpt.height",
1243 FT_INT16, BASE_CUSTOM,
1244 CF_FUNC(prt_meters), 0x0,
1245 NULL, HFILL }
1246 },
1247
1248 /* D32.7 */
1249 { &hf_4607_dwell_report_radial,
1250 { "Target Velocity Line of Sight Component", "s4607.dwell.rpt.radial",
1251 FT_INT16, BASE_CUSTOM,
1252 CF_FUNC(prt_speed_centi), 0x0,
1253 NULL, HFILL }
1254 },
1255 { &hf_4607_dwell_report_wrap,
1256 { "Target Wrap Velocity", "s4607.dwell.rpt.wrap",
1257 FT_UINT16, BASE_CUSTOM,
1258 CF_FUNC(prt_speed_centi), 0x0,
1259 NULL, HFILL }
1260 },
1261 { &hf_4607_dwell_report_snr,
1262 { "Target SNR", "s4607.dwell.rpt.snr",
1263 FT_INT8, BASE_DEC,
1264 NULL, 0x0,
1265 NULL, HFILL }
1266 },
1267 { &hf_4607_dwell_report_class,
1268 { "Target Classification", "s4607.dwell.rpt.class",
1269 FT_UINT8, BASE_DEC,
1270 VALS(stanag4607_target_vals), 0x0,
1271 NULL, HFILL }
1272 },
1273 { &hf_4607_dwell_report_prob,
1274 { "Target Class Probability", "s4607.dwell.rpt.prob",
1275 FT_UINT8, BASE_DEC,
1276 NULL, 0x0,
1277 NULL, HFILL }
1278 },
1279
1280 /* D32.12 */
1281 { &hf_4607_dwell_report_unc_slant,
1282 { "Target Measurement Uncertainty Slant Range", "s4607.dwell.rpt.unc.slant",
1283 FT_UINT16, BASE_CUSTOM,
1284 CF_FUNC(prt_centimeters), 0x0,
1285 NULL, HFILL }
1286 },
1287 { &hf_4607_dwell_report_unc_cross,
1288 { "Target Measurement Uncertainty Cross Range", "s4607.dwell.rpt.unc.cross",
1289 FT_UINT16, BASE_CUSTOM,
1290 CF_FUNC(prt_decimeters), 0x0,
1291 NULL, HFILL }
1292 },
1293 { &hf_4607_dwell_report_unc_height,
1294 { "Target Measurement Uncertainty Height", "s4607.dwell.rpt.unc.height",
1295 FT_UINT8, BASE_CUSTOM,
1296 CF_FUNC(prt_meters), 0x0,
1297 NULL, HFILL }
1298 },
1299 { &hf_4607_dwell_report_unc_radial,
1300 { "Target Measurement Uncertainty Radial Velocity", "s4607.dwell.rpt.unc.radial",
1301 FT_UINT16, BASE_CUSTOM,
1302 CF_FUNC(prt_speed_centi), 0x0,
1303 NULL, HFILL }
1304 },
1305
1306 /* D32.16 */
1307 { &hf_4607_dwell_report_tag_app,
1308 { "Truth Tag Application", "s4607.dwell.rpt.tag.app",
1309 FT_UINT8, BASE_DEC,
1310 NULL, 0x0,
1311 NULL, HFILL }
1312 },
1313 { &hf_4607_dwell_report_tag_entity,
1314 { "Truth Tag Entity", "s4607.dwell.rpt.tag.entity",
1315 FT_UINT32, BASE_DEC,
1316 NULL, 0x0,
1317 NULL, HFILL }
1318 },
1319 { &hf_4607_dwell_report_section,
1320 { "Radar Cross Section", "s4607.dwell.rpt.section",
1321 FT_INT8, BASE_DEC,
1322 NULL, 0x0,
1323 NULL, HFILL }
1324 },
1325
1326
1327 /* ========================================== */
1328 /* Job Definition Segment */
1329 { &hf_4607_jobdef_job_id,
1330 { "Job ID", "s4607.job.id",
1331 FT_UINT32, BASE_DEC,
1332 NULL, 0x0,
1333 NULL, HFILL }
1334 },
1335 { &hf_4607_jobdef_sensor_type,
1336 { "Sensor Type", "s4607.job.type",
1337 FT_UINT8, BASE_DEC,
1338 VALS(stanag4607_sensor_vals), 0x0,
1339 NULL, HFILL }
1340 },
1341 { &hf_4607_jobdef_sensor_model,
1342 { "Sensor Model", "s4607.job.model",
1343 FT_STRING, BASE_NONE,
1344 NULL, 0x0,
1345 NULL, HFILL }
1346 },
1347 { &hf_4607_jobdef_filter,
1348 { "Target Filtering Flag", "s4607.job.filter",
1349 FT_UINT8, BASE_DEC,
1350 NULL, 0x0,
1351 NULL, HFILL }
1352 },
1353 { &hf_4607_jobdef_priority,
1354 { "Radar Priority", "s4607.job.priority",
1355 FT_UINT8, BASE_DEC,
1356 NULL, 0x0,
1357 NULL, HFILL }
1358 },
1359
1360 { &hf_4607_jobdef_ba_lat_a,
1361 { "Bounding Area Point A Latitude", "s4607.job.ba.lat.a",
1362 FT_INT32, BASE_CUSTOM,
1363 CF_FUNC(prt_sa32), 0x0,
1364 NULL, HFILL }
1365 },
1366 { &hf_4607_jobdef_ba_lon_a,
1367 { "Bounding Area Point A Longitude", "s4607.job.ba.lon.a",
1368 FT_UINT32, BASE_CUSTOM,
1369 CF_FUNC(prt_ba32), 0x0,
1370 NULL, HFILL }
1371 },
1372
1373 { &hf_4607_jobdef_ba_lat_b,
1374 { "Bounding Area Point B Latitude", "s4607.job.ba.lat.b",
1375 FT_INT32, BASE_CUSTOM,
1376 CF_FUNC(prt_sa32), 0x0,
1377 NULL, HFILL }
1378 },
1379 { &hf_4607_jobdef_ba_lon_b,
1380 { "Bounding Area Point B Longitude", "s4607.job.ba.lon.b",
1381 FT_UINT32, BASE_CUSTOM,
1382 CF_FUNC(prt_ba32), 0x0,
1383 NULL, HFILL }
1384 },
1385 { &hf_4607_jobdef_ba_lat_c,
1386 { "Bounding Area Point C Latitude", "s4607.job.ba.lat.c",
1387 FT_INT32, BASE_CUSTOM,
1388 CF_FUNC(prt_sa32), 0x0,
1389 NULL, HFILL }
1390 },
1391 { &hf_4607_jobdef_ba_lon_c,
1392 { "Bounding Area Point C Longitude", "s4607.job.ba.lon.c",
1393 FT_UINT32, BASE_CUSTOM,
1394 CF_FUNC(prt_ba32), 0x0,
1395 NULL, HFILL }
1396 },
1397 { &hf_4607_jobdef_ba_lat_d,
1398 { "Bounding Area Point D Latitude", "s4607.job.ba.lat.d",
1399 FT_INT32, BASE_CUSTOM,
1400 CF_FUNC(prt_sa32), 0x0,
1401 NULL, HFILL }
1402 },
1403 { &hf_4607_jobdef_ba_lon_d,
1404 { "Bounding Area Point D Longitude", "s4607.job.ba.lon.d",
1405 FT_UINT32, BASE_CUSTOM,
1406 CF_FUNC(prt_ba32), 0x0,
1407 NULL, HFILL }
1408 },
1409
1410 { &hf_4607_jobdef_radar_mode,
1411 { "Radar Mode", "s4607.job.mode",
1412 FT_UINT8, BASE_DEC,
1413 VALS(stanag4607_radar_mode_vals), 0x0,
1414 NULL, HFILL }
1415 },
1416
1417 { &hf_4607_jobdef_revisit_interval,
1418 { "Nominal Revisit Interval", "s4607.job.revisit",
1419 FT_UINT16, BASE_DEC,
1420 NULL, 0x0,
1421 NULL, HFILL }
1422 },
1423 { &hf_4607_jobdef_unc_along,
1424 { "Nominal Sensor Position Uncertainty Along Track", "s4607.job.unc.track",
1425 FT_UINT16, BASE_CUSTOM,
1426 CF_FUNC(prt_none16), 0x0,
1427 NULL, HFILL }
1428 },
1429 { &hf_4607_jobdef_unc_cross,
1430 { "Nominal Sensor Position Uncertainty Cross Track", "s4607.job.unc.cross",
1431 FT_UINT16, BASE_CUSTOM,
1432 CF_FUNC(prt_none16), 0x0,
1433 NULL, HFILL }
1434 },
1435 { &hf_4607_jobdef_unc_alt,
1436 { "Nominal Sensor Position Uncertainty Altitude", "s4607.job.unc.alt",
1437 FT_UINT16, BASE_CUSTOM,
1438 CF_FUNC(prt_none16), 0x0,
1439 NULL, HFILL }
1440 },
1441 { &hf_4607_jobdef_unc_heading,
1442 { "Nominal Sensor Position Uncertainty Track Heading", "s4607.job.unc.heading",
1443 FT_UINT8, BASE_CUSTOM,
1444 CF_FUNC(prt_none8), 0x0,
1445 NULL, HFILL }
1446 },
1447 { &hf_4607_jobdef_unc_speed,
1448 { "Nominal Sensor Position Uncertainty Speed", "s4607.job.unc.speed",
1449 FT_UINT16, BASE_CUSTOM,
1450 CF_FUNC(prt_none16), 0x0,
1451 NULL, HFILL }
1452 },
1453
1454 { &hf_4607_jobdef_sense_slant,
1455 { "Nominal Sensor Slant Range Standard Deviation", "s4607.job.sense.slant",
1456 FT_UINT16, BASE_CUSTOM,
1457 CF_FUNC(prt_none16), 0x0,
1458 NULL, HFILL }
1459 },
1460 { &hf_4607_jobdef_sense_cross,
1461 { "Nominal Sensor Cross Range Standard Deviation", "s4607.job.sense.cross",
1462 FT_UINT16, BASE_CUSTOM,
1463 CF_FUNC(prt_ba16_none), 0x0,
1464 NULL, HFILL }
1465 },
1466 { &hf_4607_jobdef_sense_vlos,
1467 { "Nominal Sensor Velocity Line-Of-Sight Std. Dev", "s4607.job.sense.vlos",
1468 FT_UINT16, BASE_CUSTOM,
1469 CF_FUNC(prt_none16), 0x0,
1470 NULL, HFILL }
1471 },
1472 { &hf_4607_jobdef_sense_mdv,
1473 { "Nominal Sensor Minimum Detectable Velocity (MDV)", "s4607.job.sense.mdv",
1474 FT_UINT8, BASE_CUSTOM,
1475 CF_FUNC(prt_none8), 0x0,
1476 NULL, HFILL }
1477 },
1478 { &hf_4607_jobdef_sense_prob,
1479 { "Nominal Sensor Detection Probability", "s4607.job.sense.prob",
1480 FT_UINT8, BASE_CUSTOM,
1481 CF_FUNC(prt_none8), 0x0,
1482 NULL, HFILL }
1483 },
1484 { &hf_4607_jobdef_sense_alarm,
1485 { "Nominal Sensor False Alarm Density", "s4607.job.sense.alarm",
1486 FT_UINT8, BASE_CUSTOM,
1487 CF_FUNC(prt_none8), 0x0,
1488 NULL, HFILL }
1489 },
1490 { &hf_4607_jobdef_terrain_model,
1491 { "Terrain Elevation Model Used", "s4607.job.terrain",
1492 FT_UINT8, BASE_DEC,
1493 VALS(stanag4607_terrain_vals), 0x0,
1494 NULL, HFILL }
1495 },
1496 { &hf_4607_jobdef_geoid_model,
1497 { "Geoid Model Used", "s4607.job.geoid",
1498 FT_UINT8, BASE_DEC,
1499 VALS(stanag4607_geoid_vals), 0x0,
1500 NULL, HFILL }
1501 },
1502
1503
1504 /* ========================================== */
1505 /* Mission segment */
1506 { &hf_4607_mission_plan,
1507 { "Mission Plan", "s4607.mission.plan",
1508 FT_STRING, BASE_NONE,
1509 NULL, 0x0,
1510 NULL, HFILL }
1511 },
1512 { &hf_4607_mission_flight_plan,
1513 { "Mission Flight Plan", "s4607.mission.flight",
1514 FT_STRING, BASE_NONE,
1515 NULL, 0x0,
1516 NULL, HFILL }
1517 },
1518 { &hf_4607_mission_platform,
1519 { "Mission Platform Type", "s4607.mission.platform",
1520 FT_UINT8, BASE_DEC,
1521 VALS(stanag4607_platform_vals), 0x0,
1522 NULL, HFILL }
1523 },
1524 { &hf_4607_mission_platform_config,
1525 { "Mission Platform Configuration", "s4607.mission.config",
1526 FT_STRING, BASE_NONE,
1527 NULL, 0x0,
1528 NULL, HFILL }
1529 },
1530 { &hf_4607_mission_time_year,
1531 { "Mission Reference Time Year", "s4607.mission.year",
1532 FT_UINT16, BASE_DEC,
1533 NULL, 0x0,
1534 NULL, HFILL }
1535 },
1536 { &hf_4607_mission_time_month,
1537 { "Mission Reference Time Month", "s4607.mission.month",
1538 FT_UINT8, BASE_DEC,
1539 NULL, 0x0,
1540 NULL, HFILL }
1541 },
1542 { &hf_4607_mission_time_day,
1543 { "Mission Reference Time Day", "s4607.mission.day",
1544 FT_UINT8, BASE_DEC,
1545 NULL, 0x0,
1546 NULL, HFILL }
1547 },
1548 /* ========================================== */
1549 { &hf_4607_platloc_time,
1550 { "Platform Location Time", "s4607.ploc.time",
1551 FT_UINT32, BASE_CUSTOM,
1552 CF_FUNC(prt_millisec), 0x0,
1553 NULL, HFILL }
1554 },
1555 { &hf_4607_platloc_latitude,
1556 { "Platform Position Latitude", "s4607.ploc.lat",
1557 FT_INT32, BASE_CUSTOM,
1558 CF_FUNC(prt_sa32), 0x0,
1559 NULL, HFILL }
1560 },
1561 { &hf_4607_platloc_longitude,
1562 { "Platform Position Longitude", "s4607.ploc.lon",
1563 FT_UINT32, BASE_CUSTOM,
1564 CF_FUNC(prt_ba32), 0x0,
1565 NULL, HFILL }
1566 },
1567 { &hf_4607_platloc_altitude,
1568 { "Platform Position Altitude", "s4607.ploc.alt",
1569 FT_INT32, BASE_CUSTOM,
1570 CF_FUNC(prt_centimeters), 0x0,
1571 NULL, HFILL }
1572 },
1573 { &hf_4607_platloc_track,
1574 { "Platform Track", "s4607.ploc.track",
1575 FT_UINT16, BASE_CUSTOM,
1576 CF_FUNC(prt_ba16), 0x0,
1577 NULL, HFILL }
1578 },
1579 { &hf_4607_platloc_speed,
1580 { "Platform Speed", "s4607.ploc.speed",
1581 FT_UINT32, BASE_CUSTOM,
1582 CF_FUNC(prt_speed), 0x0,
1583 NULL, HFILL }
1584 },
1585 { &hf_4607_platloc_vertical_velocity,
1586 { "Platform Vertical Velocity", "s4607.ploc.velocity",
1587 FT_INT8, BASE_CUSTOM,
1588 CF_FUNC(prt_speed_deci), 0x0,
1589 NULL, HFILL }
1590 },
1591
1592 };
1593
1594 /* Setup protocol subtree array */
1595 static gint *ett[] = {
1596 &ett_4607_hdr,
1597 &ett_4607_seg,
1598 &ett_4607_rpt,
1599 };
1600
1601 static ei_register_info ei[] = {
1602 { &ei_too_short,
1603 { "s4607.segment_too_short", PI_MALFORMED, PI_ERROR,
1604 "Segment size too small", EXPFILL }},
1605 { &ei_bad_length,
1606 { "s4607.segment_bad_length", PI_MALFORMED, PI_ERROR,
1607 "Bad segment size", EXPFILL }},
1608 { &ei_bad_packet_size,
1609 { "s4607.bad_packet_size", PI_MALFORMED, PI_ERROR,
1610 "Bad packet size field", EXPFILL }}
1611 };
1612
1613 expert_module_t* expert_4607;
1614
1615 proto_stanag4607 = proto_register_protocol (
1616 "STANAG 4607 (GMTI Format)", /* name */
1617 "STANAG 4607", /* short name */
1618 "s4607" /* abbrev */
1619 );
1620
1621 proto_register_field_array(proto_stanag4607, hf, array_length(hf));
1622 proto_register_subtree_array(ett, array_length(ett));
1623 expert_4607 = expert_register_protocol(proto_stanag4607);
1624 expert_register_field_array(expert_4607, ei, array_length(ei));
1625
1626 stanag4607_handle = register_dissector("STANAG 4607", dissect_stanag4607, proto_stanag4607);
1627 /* prefs_register_protocol(proto_stanag4607, proto_reg_handoff_stanag4607); */
1628 }
1629
1630 void
proto_reg_handoff_stanag4607(void)1631 proto_reg_handoff_stanag4607(void)
1632 {
1633 dissector_add_uint("wtap_encap", WTAP_ENCAP_STANAG_4607, stanag4607_handle);
1634 }
1635
1636 /*
1637 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1638 *
1639 * Local variables:
1640 * c-basic-offset: 8
1641 * tab-width: 8
1642 * indent-tabs-mode: t
1643 * End:
1644 *
1645 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1646 * :indentSize=8:tabSize=8:noTabs=false:
1647 */
1648