Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-stanag4607.c
blob854059c5995d2aae8ee581c34373a93ed16773ec
1 /* packet-stanag4607.c
2 * Routines for STANAG 4607 dissection
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 #include "config.h"
8 #include <math.h>
9 #include <epan/packet.h>
10 #include <epan/expert.h>
12 #include <wiretap/stanag4607.h>
14 void proto_register_stanag4607(void);
15 void proto_reg_handoff_stanag4607(void);
17 static int proto_stanag4607;
19 static int hf_4607_version;
20 static int hf_4607_version_edition;
21 static int hf_4607_version_version;
22 static int hf_4607_packet_size;
23 static int hf_4607_nationality;
24 static int hf_4607_sec_class;
25 static int hf_4607_sec_system;
26 static int hf_4607_sec_code;
27 static int hf_4607_exercise_indicator;
28 static int hf_4607_platform_id;
29 static int hf_4607_mission_id;
30 static int hf_4607_job_id;
32 static int hf_4607_segment_type;
33 static int hf_4607_segment_size;
35 /* Mission Segment */
36 static int hf_4607_mission_plan;
37 static int hf_4607_mission_flight_plan;
38 static int hf_4607_mission_platform;
39 static int hf_4607_mission_platform_config;
40 static int hf_4607_mission_time_year;
41 static int hf_4607_mission_time_month;
42 static int hf_4607_mission_time_day;
44 /* Dwell Segment */
45 static int hf_4607_dwell_mask;
46 static int hf_4607_dwell_mask_7_7;
47 static int hf_4607_dwell_mask_7_6;
48 static int hf_4607_dwell_mask_7_5;
49 static int hf_4607_dwell_mask_7_4;
50 static int hf_4607_dwell_mask_7_3;
51 static int hf_4607_dwell_mask_7_2;
52 static int hf_4607_dwell_mask_7_1;
53 static int hf_4607_dwell_mask_7_0;
54 static int hf_4607_dwell_mask_6_7;
55 static int hf_4607_dwell_mask_6_6;
56 static int hf_4607_dwell_mask_6_5;
57 static int hf_4607_dwell_mask_6_4;
58 static int hf_4607_dwell_mask_6_3;
59 static int hf_4607_dwell_mask_6_2;
60 static int hf_4607_dwell_mask_6_1;
61 static int hf_4607_dwell_mask_6_0;
62 static int hf_4607_dwell_mask_5_7;
63 static int hf_4607_dwell_mask_5_6;
64 static int hf_4607_dwell_mask_5_5;
65 static int hf_4607_dwell_mask_5_4;
66 static int hf_4607_dwell_mask_5_3;
67 static int hf_4607_dwell_mask_5_2;
68 static int hf_4607_dwell_mask_5_1;
69 static int hf_4607_dwell_mask_5_0;
70 static int hf_4607_dwell_mask_4_7;
71 static int hf_4607_dwell_mask_4_6;
72 static int hf_4607_dwell_mask_4_5;
73 static int hf_4607_dwell_mask_4_4;
74 static int hf_4607_dwell_mask_4_3;
75 static int hf_4607_dwell_mask_4_2;
76 static int hf_4607_dwell_mask_4_1;
77 static int hf_4607_dwell_mask_4_0;
78 static int hf_4607_dwell_mask_3_7;
79 static int hf_4607_dwell_mask_3_6;
80 static int hf_4607_dwell_mask_3_5;
81 static int hf_4607_dwell_mask_3_4;
82 static int hf_4607_dwell_mask_3_3;
83 static int hf_4607_dwell_mask_3_2;
84 static int hf_4607_dwell_mask_3_1;
85 static int hf_4607_dwell_mask_3_0;
86 static int hf_4607_dwell_mask_2_7;
87 static int hf_4607_dwell_mask_2_6;
88 static int hf_4607_dwell_mask_2_5;
89 static int hf_4607_dwell_mask_2_4;
90 static int hf_4607_dwell_mask_2_3;
91 static int hf_4607_dwell_mask_2_2;
92 static int hf_4607_dwell_mask_2_1;
93 static int hf_4607_dwell_mask_2_0;
94 static int hf_4607_dwell_mask_spare;
96 static int hf_4607_dwell_revisit_index;
97 static int hf_4607_dwell_dwell_index;
98 static int hf_4607_dwell_last_dwell;
99 static int hf_4607_dwell_count;
100 static int hf_4607_dwell_time;
101 static int hf_4607_dwell_sensor_lat;
102 static int hf_4607_dwell_sensor_lon;
103 static int hf_4607_dwell_sensor_alt;
104 static int hf_4607_dwell_scale_lat;
105 static int hf_4607_dwell_scale_lon;
106 static int hf_4607_dwell_unc_along;
107 static int hf_4607_dwell_unc_cross;
108 static int hf_4607_dwell_unc_alt;
109 static int hf_4607_dwell_track;
110 static int hf_4607_dwell_speed;
111 static int hf_4607_dwell_vert_velocity;
112 static int hf_4607_dwell_track_unc;
113 static int hf_4607_dwell_speed_unc;
114 static int hf_4607_dwell_vv_unc;
116 static int hf_4607_dwell_plat_heading;
117 static int hf_4607_dwell_plat_pitch;
118 static int hf_4607_dwell_plat_roll;
119 static int hf_4607_dwell_da_lat;
120 static int hf_4607_dwell_da_lon;
121 static int hf_4607_dwell_da_range;
122 static int hf_4607_dwell_da_angle;
123 static int hf_4607_dwell_sensor_heading;
124 static int hf_4607_dwell_sensor_pitch;
125 static int hf_4607_dwell_sensor_roll;
126 static int hf_4607_dwell_mdv;
128 /* Target Report */
129 static int hf_4607_dwell_report_index;
130 static int hf_4607_dwell_report_lat;
131 static int hf_4607_dwell_report_lon;
132 static int hf_4607_dwell_report_delta_lat;
133 static int hf_4607_dwell_report_delta_lon;
134 static int hf_4607_dwell_report_height;
135 static int hf_4607_dwell_report_radial;
136 static int hf_4607_dwell_report_wrap;
137 static int hf_4607_dwell_report_snr;
138 static int hf_4607_dwell_report_class;
139 static int hf_4607_dwell_report_prob;
140 static int hf_4607_dwell_report_unc_slant;
141 static int hf_4607_dwell_report_unc_cross;
142 static int hf_4607_dwell_report_unc_height;
143 static int hf_4607_dwell_report_unc_radial;
144 static int hf_4607_dwell_report_tag_app;
145 static int hf_4607_dwell_report_tag_entity;
146 static int hf_4607_dwell_report_section;
148 /* Job Definition Segment */
149 static int hf_4607_jobdef_job_id;
150 static int hf_4607_jobdef_sensor_type;
151 static int hf_4607_jobdef_sensor_model;
152 static int hf_4607_jobdef_filter;
153 static int hf_4607_jobdef_priority;
154 static int hf_4607_jobdef_ba_lat_a;
155 static int hf_4607_jobdef_ba_lon_a;
156 static int hf_4607_jobdef_ba_lat_b;
157 static int hf_4607_jobdef_ba_lon_b;
158 static int hf_4607_jobdef_ba_lat_c;
159 static int hf_4607_jobdef_ba_lon_c;
160 static int hf_4607_jobdef_ba_lat_d;
161 static int hf_4607_jobdef_ba_lon_d;
162 static int hf_4607_jobdef_radar_mode;
163 static int hf_4607_jobdef_revisit_interval;
164 static int hf_4607_jobdef_unc_along;
165 static int hf_4607_jobdef_unc_cross;
166 static int hf_4607_jobdef_unc_alt;
167 static int hf_4607_jobdef_unc_heading;
168 static int hf_4607_jobdef_unc_speed;
169 static int hf_4607_jobdef_sense_slant;
170 static int hf_4607_jobdef_sense_cross;
171 static int hf_4607_jobdef_sense_vlos;
172 static int hf_4607_jobdef_sense_mdv;
173 static int hf_4607_jobdef_sense_prob;
174 static int hf_4607_jobdef_sense_alarm;
175 static int hf_4607_jobdef_terrain_model;
176 static int hf_4607_jobdef_geoid_model;
178 /* Platform Location Segment */
179 static int hf_4607_platloc_time;
180 static int hf_4607_platloc_latitude;
181 static int hf_4607_platloc_longitude;
182 static int hf_4607_platloc_altitude;
183 static int hf_4607_platloc_track;
184 static int hf_4607_platloc_speed;
185 static int hf_4607_platloc_vertical_velocity;
187 /* Subtree pointers */
188 static int ett_4607_hdr;
189 static int ett_4607_seg;
190 static int ett_4607_rpt;
191 static int ett_4607_mask;
192 static int ett_4607_ver;
194 /* Error pointers */
195 static expert_field ei_bad_length;
196 static expert_field ei_too_short;
197 static expert_field ei_bad_packet_size;
198 static expert_field ei_job_id_zero;
200 static dissector_handle_t stanag4607_handle;
203 static const value_string stanag4607_class_vals[] = {
204 { 1, "TOP SECRET" },
205 { 2, "SECRET" },
206 { 3, "CONFIDENTIAL" },
207 { 4, "RESTRICTED" },
208 { 5, "UNCLASSIFIED" },
209 { 0, NULL }
212 static const value_string stanag4607_security_codes_vals[] = {
213 { 0x0000, "NONE (NO-STATEMENT VALUE)" },
214 { 0x0001, "EU (Releasable To European Commission)" },
215 { 0x0002, "EUFOR (Releasable To European Union Force)" },
216 { 0x0004, "ISAF (Releasable To International Security Assistance Force)" },
217 { 0x0008, "KFOR (Releasable To Kosovo Force)" },
218 { 0x0010, "NATO RESPONSE FORCE (Releaseable to NRF)" },
219 { 0x0020, "NMI (Releasable To NATO Mission Iraq)" },
220 { 0x0040, "PFP (Releasable To Partnership for Peace)" },
221 { 0x0080, "RESOLUTE SUPPORT (Releasable To RS)" },
222 { 0x0100, "THE PUBLIC (Releasable To The Public)" },
223 { 0x0200, "UNDEFINED. FOR FUTURE USE" },
224 { 0x0400, "UNDEFINED. FOR FUTURE USE" },
225 { 0x0800, "UNDEFINED. FOR FUTURE USE" },
226 { 0x1000, "UNDEFINED. FOR FUTURE USE" },
227 { 0x2000, "UNDEFINED. FOR FUTURE USE" },
228 { 0x4000, "UNDEFINED. FOR FUTURE USE" },
229 { 0x8000, "UNDEFINED. FOR FUTURE USE" },
230 { 0, NULL }
233 static const value_string stanag4607_exind_vals[] = {
234 { 0, "Operation, Real Data" },
235 { 1, "Operation, Simulated Data" },
236 { 2, "Operation, Synthesized Data" },
237 { 128, "Exercise, Real Data" },
238 { 129, "Exercise, Simulated Data" },
239 { 130, "Exercise, Synthesized Data" },
240 { 0, NULL }
243 #define MISSION_SEGMENT 1
244 #define DWELL_SEGMENT 2
245 #define JOB_DEFINITION_SEGMENT 5
246 #define PLATFORM_LOCATION_SEGMENT 13
248 static const value_string stanag4607_segment_vals[] = {
249 { 1, "Mission Segment" },
250 { 2, "Dwell Segment" },
251 { 3, "HRR Segment" },
252 { 5, "Job Definition Segment" },
253 { 6, "Free Text Segment" },
254 { 7, "Low Reflectivity Index Segment" },
255 { 8, "Group Segment" },
256 { 9, "Attached Target Segment" },
257 { 10, "Test and Status Segment" },
258 { 11, "System-Specific Segment" },
259 { 12, "Processing History Segment" },
260 { 13, "Platform Location Segment" },
261 { 101, "Job Request Segment" },
262 { 102, "Job Acknowledgment Segment" },
263 { 0, NULL }
266 static const value_string stanag4607_sensor_vals[] = {
267 { 0, "Unidentified" },
268 { 1, "Other" },
269 { 2, "HiSAR" },
270 { 3, "ASTOR" },
271 { 4, "Rotary Wing Radar" },
272 { 5, "Global Hawk Sensor" },
273 { 6, "HORIZON" },
274 { 7, "APY-3" },
275 { 8, "APY-6" },
276 { 9, "APY-8 (Lynx I)" },
277 { 10, "RADARSAT2" },
278 { 11, "ASARS-2A" },
279 { 12, "TESAR" },
280 { 13, "MP-RTIP" },
281 { 14, "APG-77" },
282 { 15, "APG-79" },
283 { 16, "APG-81" },
284 { 17, "APY-6v1" },
285 { 18, "SPY-I (Lynx II)" },
286 { 19, "SIDM" },
287 { 20, "LIMIT" },
288 { 21, "TCAR (AGS A321)" },
289 { 22, "LSRS Sensor" },
290 { 23, "UGS Single Sensor" },
291 { 24, "UGS Cluster Sensor" },
292 { 25, "IMASTER GMTI" },
293 { 26, "AN/ZPY-1 (STARLite)" },
294 { 27, "VADER" },
295 { 255, "No Statement" },
296 { 0, NULL }
299 static const value_string stanag4607_radar_mode_vals[] = {
300 { 0, "Unspecified Mode" },
301 { 1, "MTI (Moving Target Indicator)" },
302 { 2, "HRR (High Range Resolution)" },
303 { 3, "UHRR (Ultra High Range Resolution)" },
304 { 4, "HUR (High Update Rate)" },
305 { 5, "FTI" },
306 /* TODO: and many many more ... */
307 { 0, NULL }
310 static const value_string stanag4607_terrain_vals[] = {
311 { 0, "None Specified" },
312 { 1, "DTED0 (Digital Terrain Elevation Data, Level 0)" },
313 { 2, "DTED1 (Digital Terrain Elevation Data, Level 1)" },
314 { 3, "DTED2 (Digital Terrain Elevation Data, Level 2)" },
315 { 4, "DTED3 (Digital Terrain Elevation Data, Level 3)" },
316 { 5, "DTED4 (Digital Terrain Elevation Data, Level 4)" },
317 { 6, "DTED5 (Digital Terrain Elevation Data, Level 5)" },
318 { 7, "SRTM1 (Shuttle Radar Topography Mission, Level 1)" },
319 { 8, "SRTM2 (Shuttle Radar Topography Mission, Level 2)" },
320 { 9, "DGM50 M745 (Digitales Gelandemodell 1:50 000)" },
321 { 10, "DGM250 (Digitales Gelandemodell 1:250 000)" },
322 { 11, "ITHD (Interferometric Terrain Data Height)" },
323 { 12, "STHD (Stereometric Terrain Data Height)" },
324 { 13, "SEDRIS (SEDRIS Reference Model ISO/IEC 18026)" },
325 { 0, NULL }
328 static const value_string stanag4607_geoid_vals[] = {
329 { 0, "None Specified" },
330 { 1, "EGM96 (Earth Gravitational Model, Version 1996)" },
331 { 2, "GEO96 (Geoid Gravitational Model, Version 1996)" },
332 { 3, "Flat Earth" },
333 { 0, NULL }
336 static const value_string stanag4607_target_vals[] = {
337 { 0, "No Information, Live Target" },
338 { 1, "Tracked Vehicle, Live Target" },
339 { 2, "Wheeled Vehicle, Live Target" },
340 { 3, "Rotary Wing Aircraft, Live Target" },
341 { 4, "Fixed Wing Aircraft, Live Target" },
342 { 5, "Stationary Rotator, Live Target" },
343 { 6, "Maritime, Live Target" },
344 { 7, "Beacon, Live Target" },
345 { 8, "Amphibious, Live Target" },
346 { 9, "Person, Live Target" },
347 { 10, "Vehicle, Live Target" },
348 { 11, "Animal, Live Target" },
349 { 12, "Large Multiple-Return, Live Land Target" },
350 { 13, "Large Multiple-Return, Live Maritime Target" },
352 { 126, "Other, Live Target" },
353 { 127, "Unknown, Live Target" },
354 { 128, "No Information, Simulated Target" },
355 { 129, "Tracked Vehicle, Simulated Target" },
356 { 130, "Wheeled Vehicle, Simulated Target" },
357 { 131, "Rotary Wing Aircraft, Simulated Target" },
358 { 132, "Fixed Wing Aircraft, Simulated Target" },
359 { 133, "Stationary Rotator, Simulated Target" },
360 { 134, "Maritime, Simulated Target" },
361 { 135, "Beacon, Simulated Target" },
362 { 136, "Amphibious, Simulated Target" },
363 { 137, "Person, Simulated Target" },
364 { 138, "Vehicle, Simulated Target" },
365 { 139, "Animal, Simulated Target" },
366 { 140, "Large Multiple-Return, Simulated Land Target" },
367 { 141, "Large Multiple-Return, Simulated Maritime Target" },
369 { 143, "Tagging Device" },
371 { 254, "Other, Simulated Target" },
372 { 255, "Unknown, Simulated Target" },
373 { 0, NULL }
376 static const value_string stanag4607_platform_vals[] = {
377 { 0, "Unidentified" },
378 { 1, "ACS" },
379 { 2, "ARL-M" },
380 { 3, "Sentinel" },
381 { 4, "Rotary Wing Radar" },
382 { 5, "Global Hawk-Navy" },
383 { 6, "HORIZON" },
384 { 7, "E-8C (Joint STARS)" },
385 { 8, "P-3C" },
386 { 9, "Predator" },
387 { 10, "RADARSAT2" },
388 { 11, "U-2" },
389 { 12, "E-10" },
390 { 13, "UGS - Single" },
391 { 14, "UGS - Cluster" },
392 { 15, "Ground Based" },
393 { 16, "UAV-Army" },
394 { 17, "UAV-Marines" },
395 { 18, "UAV-Navy" },
396 { 19, "UAV-Air Force" },
397 { 20, "Global Hawk-Air Force" },
398 { 21, "Global Hawk-Australia" },
399 { 22, "Global Hawk-Germany" },
400 { 23, "Paul Revere" },
401 { 24, "Mariner UAV" },
402 { 25, "BAC-111" },
403 { 26, "Coyote" },
404 { 27, "King Air" },
405 { 28, "LIMIT" },
406 { 29, "NRL NP-3B" },
407 { 30, "SOSTAR-X" },
408 { 31, "WatchKeeper" },
409 { 32, "Alliance Ground Surveillance (AGS) (A321)" },
410 { 33, "Stryker" },
411 { 34, "AGS (HALE UAV)" },
412 { 35, "SIDM" },
413 { 36, "MQ-9 Reaper" },
414 { 37, "Warrior A" },
415 { 38, "Warrior" },
416 { 39, "Twin Otter" },
417 { 40, "LEMV" },
418 { 41, "P8A Poseidon" },
419 { 42, "A160" },
420 { 43, "MQ-1C Gray Eagle" },
421 { 44, "RQ-7C Shadow" },
422 { 45, "PGSS" },
423 { 46, "PTDS" },
424 { 47, "LRAS 3" },
425 { 48, "RAID Tower" },
426 { 49, "Heron" },
427 { 50, "Scan Eagle" },
428 { 51, "Fire Scout" },
429 { 52, "F35 Joint Strike Fighter" },
430 { 53, "F-61 Sea King (SKASac)" },
431 { 54, "Lynx Wildcat" },
432 { 55, "Merlin" },
433 { 56, "SDT (Système de Drone Tactique)" },
434 { 255, "Other" },
435 { 0, NULL }
438 static void
439 prt_sa32(char *buff, uint32_t val)
441 double deg, min, sec;
442 double x = (double) ((int32_t) val);
443 x /= (double) (1UL<<30);
444 x *= 45.0;
445 deg = floor(x);
446 min = floor(60.0 * (x - deg));
447 sec = 60.0 * (60.0 * (x - deg) - min);
448 /* checkAPI.pl doesn't like the unicode degree symbol, I don't know what to do... */
449 snprintf(buff, ITEM_LABEL_LENGTH, "%.8f degrees (%.0f %.0f\' %.2f\")", x, deg, min, sec);
452 static void
453 prt_ba32(char *buff, uint32_t val)
455 double deg, min, sec;
456 double x = (double) val;
457 x /= (double) (1UL<<30);
458 x *= 90.0;
459 deg = floor(x);
460 min = floor(60.0 * (x - deg));
461 sec = 60.0 * (60.0 * (x - deg) - min);
462 /* checkAPI.pl doesn't like the unicode degree symbol, I don't know what to do... */
463 snprintf(buff, ITEM_LABEL_LENGTH, "%.8f degrees (%.0f %.0f\' %.2f\")", x, deg, min, sec);
466 static void
467 prt_sa16(char *buff, uint32_t val)
469 double x = (double) ((int32_t) val);
470 x /= (double) (1<<14);
471 x *= 90.0;
472 snprintf(buff, ITEM_LABEL_LENGTH, "%.3f degrees", x);
475 static void
476 prt_ba16(char *buff, uint32_t val)
478 double x = (double) val;
479 x /= (double) (1<<14);
480 x *= 90.0;
481 snprintf(buff, ITEM_LABEL_LENGTH, "%.3f degrees", x);
484 static void
485 prt_ba16_none(char *buff, uint32_t val)
487 double x = (double) val;
488 x /= (double) (1<<14);
489 x *= 90.0;
490 if (val <= 65536)
491 snprintf(buff, ITEM_LABEL_LENGTH, "No Statement");
492 else
493 snprintf(buff, ITEM_LABEL_LENGTH, "%.3f degrees", x);
496 static void
497 prt_kilo(char *buff, uint32_t val)
499 double x = (double) ((int32_t) val);
500 x /= 128.0;
501 snprintf(buff, ITEM_LABEL_LENGTH, "%.2f kilometers", x);
504 static void
505 prt_meters(char *buff, uint32_t val)
507 double x = (double) ((int32_t) val);
508 snprintf(buff, ITEM_LABEL_LENGTH, "%.0f meters", x);
511 static void
512 prt_decimeters(char *buff, uint32_t val)
514 double x = (double) ((int32_t) val);
515 x /= 10.0;
516 snprintf(buff, ITEM_LABEL_LENGTH, "%.1f meters", x);
519 static void
520 prt_centimeters(char *buff, uint32_t val)
522 double x = (double) ((int32_t) val);
523 x /= 100.0;
524 snprintf(buff, ITEM_LABEL_LENGTH, "%.2f meters", x);
527 static void
528 prt_speed(char *buff, uint32_t val)
530 double x = (double) val;
531 x /= 1000.0;
532 snprintf(buff, ITEM_LABEL_LENGTH, "%.3f meters/second", x);
535 static void
536 prt_speed_centi(char *buff, uint32_t val)
538 double x = (double) ((int32_t) val);
539 x /= 100.0;
540 snprintf(buff, ITEM_LABEL_LENGTH, "%.2f meters/second", x);
543 static void
544 prt_speed_deci(char *buff, uint32_t val)
546 /* Usually 8-bit, signed */
547 double x = (double) ((int32_t) val);
548 x /= 10.0;
549 snprintf(buff, ITEM_LABEL_LENGTH, "%.1f meters/second", x);
552 static void
553 prt_millisec(char *buff, uint32_t val)
555 double x = (double) val;
556 x /= 1000.0;
557 snprintf(buff, ITEM_LABEL_LENGTH, "%.3f seconds", x);
560 static void
561 prt_none8(char *buff, uint32_t val)
563 if (0xff == val)
564 snprintf(buff, ITEM_LABEL_LENGTH, "No Statement");
565 else
566 snprintf(buff, ITEM_LABEL_LENGTH, "%d", val);
569 static void
570 prt_none16(char *buff, uint32_t val)
572 if (0xffff == val)
573 snprintf(buff, ITEM_LABEL_LENGTH, "No Statement");
574 else
575 snprintf(buff, ITEM_LABEL_LENGTH, "%d", val);
579 static int
580 dissect_mission(tvbuff_t *tvb, proto_tree *seg_tree, int offset)
582 proto_tree_add_item(seg_tree, hf_4607_mission_plan, tvb, offset, 12, ENC_ASCII);
583 offset += 12;
584 proto_tree_add_item(seg_tree, hf_4607_mission_flight_plan, tvb, offset, 12, ENC_ASCII);
585 offset += 12;
586 proto_tree_add_item(seg_tree, hf_4607_mission_platform, tvb, offset, 1, ENC_BIG_ENDIAN);
587 offset += 1;
588 proto_tree_add_item(seg_tree, hf_4607_mission_platform_config, tvb, offset, 10, ENC_ASCII);
589 offset += 10;
590 proto_tree_add_item(seg_tree, hf_4607_mission_time_year, tvb, offset, 2, ENC_BIG_ENDIAN);
591 offset += 2;
592 proto_tree_add_item(seg_tree, hf_4607_mission_time_month, tvb, offset, 1, ENC_BIG_ENDIAN);
593 offset += 1;
594 proto_tree_add_item(seg_tree, hf_4607_mission_time_day, tvb, offset, 1, ENC_BIG_ENDIAN);
595 offset += 1;
597 return offset;
600 /* Dwell Segment Existence Mask */
601 /* The Dxx fields are NOT bit locations! They are the field numbers
602 * as specified in Table 2-4 Dwell Segment. These field numbers DO NOT
603 * count bit locations in the existence mask (even though they come
604 * close to this). The m and n values of the m*8+n offset below are
605 * given in Figure 2-1 titled "Dwell Segment Existence Mask Mapping."
607 #define SET(MASK,OFF) (((MASK)>>(OFF)) & INT64_C(1))
608 #define D2 7*8+7
609 #define D3 7*8+6
610 #define D4 7*8+5
611 #define D5 7*8+4
612 #define D6 7*8+3
613 #define D7 7*8+2
614 #define D8 7*8+1
615 #define D9 7*8+0
616 #define D10 6*8+7
617 #define D11 6*8+6
618 #define D12 6*8+5
619 #define D13 6*8+4
620 #define D14 6*8+3
621 #define D15 6*8+2
622 #define D16 6*8+1
623 #define D17 6*8+0
624 #define D18 5*8+7
625 #define D19 5*8+6
626 #define D20 5*8+5
627 #define D21 5*8+4
628 #define D22 5*8+3
629 #define D23 5*8+2
630 #define D24 5*8+1
631 #define D25 5*8+0
632 #define D26 4*8+7
633 #define D27 4*8+6
634 #define D28 4*8+5
635 #define D29 4*8+4
636 #define D30 4*8+3
637 #define D31 4*8+2
638 #define D32_1 4*8+1
639 #define D32_2 4*8+0
640 #define D32_3 3*8+7
641 #define D32_4 3*8+6
642 #define D32_5 3*8+5
643 #define D32_6 3*8+4
644 #define D32_7 3*8+3
645 #define D32_8 3*8+2
646 #define D32_9 3*8+1
647 #define D32_10 3*8+0
648 #define D32_11 2*8+7
649 #define D32_12 2*8+6
650 #define D32_13 2*8+5
651 #define D32_14 2*8+4
652 #define D32_15 2*8+3
653 #define D32_16 2*8+2
654 #define D32_17 2*8+1
655 #define D32_18 2*8+0
657 /* Target Report */
658 static int
659 dissect_target(tvbuff_t *tvb, proto_tree *seg_tree, int offset, uint64_t mask)
661 proto_item *rpt_item = NULL;
662 proto_tree *rpt_tree = seg_tree;
664 if (SET(mask, D32_1)) {
665 rpt_item = proto_tree_add_item(rpt_tree, hf_4607_dwell_report_index, tvb, offset, 2, ENC_BIG_ENDIAN);
666 offset += 2;
667 rpt_tree = proto_item_add_subtree(rpt_item, ett_4607_rpt);
670 if (SET(mask, D32_2)) {
671 rpt_item = proto_tree_add_item(rpt_tree, hf_4607_dwell_report_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
672 offset += 4;
674 if (SET(mask, D32_3)) {
675 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
676 offset += 4;
678 if (SET(mask, D32_4)) {
679 rpt_item = proto_tree_add_item(rpt_tree, hf_4607_dwell_report_delta_lat, tvb, offset, 2, ENC_BIG_ENDIAN);
680 offset += 2;
682 if (SET(mask, D32_5)) {
683 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_delta_lon, tvb, offset, 2, ENC_BIG_ENDIAN);
684 offset += 2;
687 /* If the report index wasn't set, then no subtree yet */
688 if (rpt_item && rpt_tree == seg_tree) {
689 rpt_tree = proto_item_add_subtree(rpt_item, ett_4607_rpt);
691 if (SET(mask, D32_6)) {
692 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_height, tvb, offset, 2, ENC_BIG_ENDIAN);
693 offset += 2;
695 if (SET(mask, D32_7)) {
696 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_radial, tvb, offset, 2, ENC_BIG_ENDIAN);
697 offset += 2;
699 if (SET(mask, D32_8)) {
700 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_wrap, tvb, offset, 2, ENC_BIG_ENDIAN);
701 offset += 2;
703 if (SET(mask, D32_9)) {
704 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_snr, tvb, offset, 1, ENC_BIG_ENDIAN);
705 offset += 1;
707 if (SET(mask, D32_10)) {
708 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_class, tvb, offset, 1, ENC_BIG_ENDIAN);
709 offset += 1;
711 if (SET(mask, D32_11)) {
712 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_prob, tvb, offset, 1, ENC_BIG_ENDIAN);
713 offset += 1;
715 if (SET(mask, D32_12)) {
716 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_slant, tvb, offset, 2, ENC_BIG_ENDIAN);
717 offset += 2;
719 if (SET(mask, D32_13)) {
720 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_cross, tvb, offset, 2, ENC_BIG_ENDIAN);
721 offset += 2;
723 if (SET(mask, D32_14)) {
724 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_height, tvb, offset, 1, ENC_BIG_ENDIAN);
725 offset += 1;
727 if (SET(mask, D32_15)) {
728 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_unc_radial, tvb, offset, 2, ENC_BIG_ENDIAN);
729 offset += 2;
731 if (SET(mask, D32_16)) {
732 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_tag_app, tvb, offset, 1, ENC_BIG_ENDIAN);
733 offset += 1;
735 if (SET(mask, D32_17)) {
736 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_tag_entity, tvb, offset, 4, ENC_BIG_ENDIAN);
737 offset += 4;
739 if (SET(mask, D32_18)) {
740 proto_tree_add_item(rpt_tree, hf_4607_dwell_report_section, tvb, offset, 1, ENC_BIG_ENDIAN);
741 offset += 1;
744 return offset;
747 /* Dwell Segment */
748 static int
749 dissect_dwell(tvbuff_t *tvb, proto_tree *seg_tree, int offset)
751 uint64_t mask;
752 uint32_t count;
754 mask = tvb_get_ntoh64(tvb, offset);
756 static int* const mask_bits[] = {
757 &hf_4607_dwell_mask_7_7,
758 &hf_4607_dwell_mask_7_6,
759 &hf_4607_dwell_mask_7_5,
760 &hf_4607_dwell_mask_7_4,
761 &hf_4607_dwell_mask_7_3,
762 &hf_4607_dwell_mask_7_2,
763 &hf_4607_dwell_mask_7_1,
764 &hf_4607_dwell_mask_7_0,
765 &hf_4607_dwell_mask_6_7,
766 &hf_4607_dwell_mask_6_6,
767 &hf_4607_dwell_mask_6_5,
768 &hf_4607_dwell_mask_6_4,
769 &hf_4607_dwell_mask_6_3,
770 &hf_4607_dwell_mask_6_2,
771 &hf_4607_dwell_mask_6_1,
772 &hf_4607_dwell_mask_6_0,
773 &hf_4607_dwell_mask_5_7,
774 &hf_4607_dwell_mask_5_6,
775 &hf_4607_dwell_mask_5_5,
776 &hf_4607_dwell_mask_5_4,
777 &hf_4607_dwell_mask_5_3,
778 &hf_4607_dwell_mask_5_2,
779 &hf_4607_dwell_mask_5_1,
780 &hf_4607_dwell_mask_5_0,
781 &hf_4607_dwell_mask_4_7,
782 &hf_4607_dwell_mask_4_6,
783 &hf_4607_dwell_mask_4_5,
784 &hf_4607_dwell_mask_4_4,
785 &hf_4607_dwell_mask_4_3,
786 &hf_4607_dwell_mask_4_2,
787 &hf_4607_dwell_mask_4_1,
788 &hf_4607_dwell_mask_4_0,
789 &hf_4607_dwell_mask_3_7,
790 &hf_4607_dwell_mask_3_6,
791 &hf_4607_dwell_mask_3_5,
792 &hf_4607_dwell_mask_3_4,
793 &hf_4607_dwell_mask_3_3,
794 &hf_4607_dwell_mask_3_2,
795 &hf_4607_dwell_mask_3_1,
796 &hf_4607_dwell_mask_3_0,
797 &hf_4607_dwell_mask_2_7,
798 &hf_4607_dwell_mask_2_6,
799 &hf_4607_dwell_mask_2_5,
800 &hf_4607_dwell_mask_2_4,
801 &hf_4607_dwell_mask_2_3,
802 &hf_4607_dwell_mask_2_2,
803 &hf_4607_dwell_mask_2_1,
804 &hf_4607_dwell_mask_2_0,
805 &hf_4607_dwell_mask_spare,
806 NULL
808 proto_tree_add_bitmask(seg_tree, tvb, offset, hf_4607_dwell_mask, ett_4607_mask, mask_bits, ENC_BIG_ENDIAN);
809 offset += 8;
811 /* Mandatory fields, existence mask irrelevant */
812 proto_tree_add_item(seg_tree, hf_4607_dwell_revisit_index, tvb, offset, 2, ENC_BIG_ENDIAN);
813 offset += 2;
815 proto_tree_add_item(seg_tree, hf_4607_dwell_dwell_index, tvb, offset, 2, ENC_BIG_ENDIAN);
816 offset += 2;
818 proto_tree_add_item(seg_tree, hf_4607_dwell_last_dwell, tvb, offset, 1, ENC_BIG_ENDIAN);
819 offset += 1;
821 /* count of target reports */
822 count = tvb_get_ntohs(tvb, offset);
823 proto_tree_add_item(seg_tree, hf_4607_dwell_count, tvb, offset, 2, ENC_BIG_ENDIAN);
824 offset += 2;
826 proto_tree_add_item(seg_tree, hf_4607_dwell_time, tvb, offset, 4, ENC_BIG_ENDIAN);
827 offset += 4;
829 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
830 offset += 4;
832 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
833 offset += 4;
835 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_alt, tvb, offset, 4, ENC_BIG_ENDIAN);
836 offset += 4;
838 /* Optional or conditional fields, in accordance to presence mask */
839 if (SET(mask, D10)) {
840 proto_tree_add_item(seg_tree, hf_4607_dwell_scale_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
841 offset += 4;
843 if (SET(mask, D11)) {
844 proto_tree_add_item(seg_tree, hf_4607_dwell_scale_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
845 offset += 4;
847 if (SET(mask, D12)) {
848 proto_tree_add_item(seg_tree, hf_4607_dwell_unc_along, tvb, offset, 4, ENC_BIG_ENDIAN);
849 offset += 4;
851 if (SET(mask, D13)) {
852 proto_tree_add_item(seg_tree, hf_4607_dwell_unc_cross, tvb, offset, 4, ENC_BIG_ENDIAN);
853 offset += 4;
855 if (SET(mask, D14)) {
856 proto_tree_add_item(seg_tree, hf_4607_dwell_unc_alt, tvb, offset, 2, ENC_BIG_ENDIAN);
857 offset += 2;
859 if (SET(mask, D15)) {
860 proto_tree_add_item(seg_tree, hf_4607_dwell_track, tvb, offset, 2, ENC_BIG_ENDIAN);
861 offset += 2;
863 if (SET(mask, D16)) {
864 proto_tree_add_item(seg_tree, hf_4607_dwell_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
865 offset += 4;
867 if (SET(mask, D17)) {
868 proto_tree_add_item(seg_tree, hf_4607_dwell_vert_velocity, tvb, offset, 1, ENC_BIG_ENDIAN);
869 offset += 1;
871 if (SET(mask, D18)) {
872 proto_tree_add_item(seg_tree, hf_4607_dwell_track_unc, tvb, offset, 1, ENC_BIG_ENDIAN);
873 offset += 1;
875 if (SET(mask, D19)) {
876 proto_tree_add_item(seg_tree, hf_4607_dwell_speed_unc, tvb, offset, 2, ENC_BIG_ENDIAN);
877 offset += 2;
879 if (SET(mask, D20)) {
880 proto_tree_add_item(seg_tree, hf_4607_dwell_vv_unc, tvb, offset, 2, ENC_BIG_ENDIAN);
881 offset += 2;
883 if (SET(mask, D21)) {
884 proto_tree_add_item(seg_tree, hf_4607_dwell_plat_heading, tvb, offset, 2, ENC_BIG_ENDIAN);
885 offset += 2;
887 if (SET(mask, D22)) {
888 proto_tree_add_item(seg_tree, hf_4607_dwell_plat_pitch, tvb, offset, 2, ENC_BIG_ENDIAN);
889 offset += 2;
891 if (SET(mask, D23)) {
892 proto_tree_add_item(seg_tree, hf_4607_dwell_plat_roll, tvb, offset, 2, ENC_BIG_ENDIAN);
893 offset += 2;
896 /* Dwell Area */
897 /* Mandatory fields, existence mask irrelevant */
898 proto_tree_add_item(seg_tree, hf_4607_dwell_da_lat, tvb, offset, 4, ENC_BIG_ENDIAN);
899 offset += 4;
901 proto_tree_add_item(seg_tree, hf_4607_dwell_da_lon, tvb, offset, 4, ENC_BIG_ENDIAN);
902 offset += 4;
904 proto_tree_add_item(seg_tree, hf_4607_dwell_da_range, tvb, offset, 2, ENC_BIG_ENDIAN);
905 offset += 2;
907 proto_tree_add_item(seg_tree, hf_4607_dwell_da_angle, tvb, offset, 2, ENC_BIG_ENDIAN);
908 offset += 2;
910 /* Optional or conditional fields, in accordance to presence mask */
911 if (SET(mask, D28)) {
912 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_heading, tvb, offset, 2, ENC_BIG_ENDIAN);
914 if (SET(mask, D29)) {
915 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_pitch, tvb, offset, 2, ENC_BIG_ENDIAN);
916 offset += 2;
918 if (SET(mask, D30)) {
919 proto_tree_add_item(seg_tree, hf_4607_dwell_sensor_roll, tvb, offset, 2, ENC_BIG_ENDIAN);
920 offset += 2;
922 if (SET(mask, D31)) {
923 proto_tree_add_item(seg_tree, hf_4607_dwell_mdv, tvb, offset, 1, ENC_BIG_ENDIAN);
924 offset += 1;
927 while (count--) {
928 offset = dissect_target(tvb, seg_tree, offset, mask);
931 return offset;
934 /* Job Definition */
935 static int
936 dissect_jobdef(tvbuff_t *tvb, proto_tree *seg_tree, int offset)
938 proto_tree_add_item(seg_tree, hf_4607_jobdef_job_id, tvb, offset, 4, ENC_BIG_ENDIAN);
939 offset += 4;
940 proto_tree_add_item(seg_tree, hf_4607_jobdef_sensor_type, tvb, offset, 1, ENC_BIG_ENDIAN);
941 offset += 1;
942 proto_tree_add_item(seg_tree, hf_4607_jobdef_sensor_model, tvb, offset, 6, ENC_ASCII);
943 offset += 6;
944 proto_tree_add_item(seg_tree, hf_4607_jobdef_filter, tvb, offset, 1, ENC_BIG_ENDIAN);
945 offset += 1;
946 proto_tree_add_item(seg_tree, hf_4607_jobdef_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
947 offset += 1;
948 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_a, tvb, offset, 4, ENC_BIG_ENDIAN);
949 offset += 4;
950 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_a, tvb, offset, 4, ENC_BIG_ENDIAN);
951 offset += 4;
952 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_b, tvb, offset, 4, ENC_BIG_ENDIAN);
953 offset += 4;
954 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_b, tvb, offset, 4, ENC_BIG_ENDIAN);
955 offset += 4;
956 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_c, tvb, offset, 4, ENC_BIG_ENDIAN);
957 offset += 4;
958 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_c, tvb, offset, 4, ENC_BIG_ENDIAN);
959 offset += 4;
960 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lat_d, tvb, offset, 4, ENC_BIG_ENDIAN);
961 offset += 4;
962 proto_tree_add_item(seg_tree, hf_4607_jobdef_ba_lon_d, tvb, offset, 4, ENC_BIG_ENDIAN);
963 offset += 4;
964 proto_tree_add_item(seg_tree, hf_4607_jobdef_radar_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
965 offset += 1;
966 proto_tree_add_item(seg_tree, hf_4607_jobdef_revisit_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
967 offset += 2;
968 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_along, tvb, offset, 2, ENC_BIG_ENDIAN);
969 offset += 2;
970 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_cross, tvb, offset, 2, ENC_BIG_ENDIAN);
971 offset += 2;
972 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_alt, tvb, offset, 2, ENC_BIG_ENDIAN);
973 offset += 2;
974 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_heading, tvb, offset, 1, ENC_BIG_ENDIAN);
975 offset += 1;
976 proto_tree_add_item(seg_tree, hf_4607_jobdef_unc_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
977 offset += 2;
978 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_slant, tvb, offset, 2, ENC_BIG_ENDIAN);
979 offset += 2;
980 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_cross, tvb, offset, 2, ENC_BIG_ENDIAN);
981 offset += 2;
982 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_vlos, tvb, offset, 2, ENC_BIG_ENDIAN);
983 offset += 2;
984 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_mdv, tvb, offset, 1, ENC_BIG_ENDIAN);
985 offset += 1;
986 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_prob, tvb, offset, 1, ENC_BIG_ENDIAN);
987 offset += 1;
988 proto_tree_add_item(seg_tree, hf_4607_jobdef_sense_alarm, tvb, offset, 1, ENC_BIG_ENDIAN);
989 offset += 1;
990 proto_tree_add_item(seg_tree, hf_4607_jobdef_terrain_model, tvb, offset, 1, ENC_BIG_ENDIAN);
991 offset += 1;
992 proto_tree_add_item(seg_tree, hf_4607_jobdef_geoid_model, tvb, offset, 1, ENC_BIG_ENDIAN);
993 offset += 1;
995 return offset;
998 static int
999 dissect_platform_location(tvbuff_t *tvb, proto_tree *seg_tree, int offset)
1001 proto_tree_add_item(seg_tree, hf_4607_platloc_time, tvb, offset, 4, ENC_BIG_ENDIAN);
1002 offset += 4;
1003 proto_tree_add_item(seg_tree, hf_4607_platloc_latitude, tvb, offset, 4, ENC_BIG_ENDIAN);
1004 offset += 4;
1005 proto_tree_add_item(seg_tree, hf_4607_platloc_longitude, tvb, offset, 4, ENC_BIG_ENDIAN);
1006 offset += 4;
1007 proto_tree_add_item(seg_tree, hf_4607_platloc_altitude, tvb, offset, 4, ENC_BIG_ENDIAN);
1008 offset += 4;
1009 proto_tree_add_item(seg_tree, hf_4607_platloc_track, tvb, offset, 2, ENC_BIG_ENDIAN);
1010 offset += 2;
1011 proto_tree_add_item(seg_tree, hf_4607_platloc_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
1012 offset += 4;
1013 proto_tree_add_item(seg_tree, hf_4607_platloc_vertical_velocity, tvb, offset, 1, ENC_BIG_ENDIAN);
1014 offset += 1;
1015 return offset;
1018 /* 32 == packet header, 5 == segment type and length */
1019 #define STANAG4607_MIN_LENGTH (32+5)
1021 #define MINIMUM_SEGMENT_SIZE 14
1022 #define MISSION_SEGMENT_SIZE 44
1023 #define JOB_DEFINITION_SEGMENT_SIZE 73
1024 #define PLATFORM_LOCATION_SEGMENT_SIZE 28
1026 /* Provide a basic sanity check on segment sizes; the fixed-length
1027 * ones should be what they claim to be.
1029 #define CHK_SIZE(SEG_TYPE) \
1030 if (SEG_TYPE##_SIZE != seg_size) { \
1031 col_append_str(pinfo->cinfo, COL_INFO, ", Error: Invalid segment size "); \
1032 expert_add_info(pinfo, pi, &ei_bad_length); \
1035 static int
1036 dissect_stanag4607(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1038 uint32_t offset = 0;
1039 int8_t first_segment;
1041 uint32_t pkt_size = 0, job_id;
1042 proto_item *ti, *seg_type, *pver, *pedition;
1043 proto_tree *hdr_tree, *seg_tree, *ver_tree;
1044 uint8_t seg_id = 0;
1046 /* Basic length check */
1047 if (tvb_captured_length(tvb) < STANAG4607_MIN_LENGTH)
1048 return 0;
1050 col_set_str(pinfo->cinfo, COL_PROTOCOL, "S4607");
1051 /* Clear out stuff in the info column */
1052 col_clear(pinfo->cinfo, COL_INFO);
1054 /* Put type of first segment in the info column */
1055 first_segment = tvb_get_uint8(tvb, 32);
1056 col_add_str(pinfo->cinfo, COL_INFO,
1057 val_to_str(first_segment, stanag4607_segment_vals, "Unknown (0x%02x)"));
1059 /* Put the timestamp, if available in the time column */
1060 if (PLATFORM_LOCATION_SEGMENT == first_segment) {
1061 uint32_t millisecs;
1062 nstime_t ts;
1063 millisecs = tvb_get_ntohl(tvb, 37);
1064 ts.secs = millisecs / 1000;
1065 ts.nsecs = (int)((millisecs - 1000 * ts.secs) * 1000000);
1066 col_set_time(pinfo->cinfo, COL_REL_TIME, &ts, "s4607.ploc.time");
1069 /* The generic packet header */
1070 ti = proto_tree_add_item(tree, proto_stanag4607, tvb, 0, -1, ENC_NA);
1071 hdr_tree = proto_item_add_subtree(ti, ett_4607_hdr);
1073 /* Version is in format mn (ASCII) where m reflects edition and n version
1075 m="4" equates to A, m="5" equates to B, and so on
1076 n is the direct alphanumeric representation
1078 Note: STANAG 4607 has numbers up to 3 (Edition 3 Rev. 0 => "30").
1079 This changed with the transition to AEDP-4607.
1081 pver = proto_tree_add_item(hdr_tree, hf_4607_version, tvb, 0, 2, ENC_ASCII);
1082 ver_tree = proto_item_add_subtree(pver, ett_4607_ver);
1083 pedition = proto_tree_add_item(ver_tree, hf_4607_version_edition, tvb, 0, 1, ENC_ASCII);
1084 uint8_t edition = tvb_get_uint8(tvb, 0);
1085 if(edition >= 48 && edition <= 51) {
1086 /* ASCII char 48-51 (0-3) */
1087 proto_item_append_text(pedition, " (STANAG 4607 Edition %c)", edition);
1088 } else if(edition >= 52 && edition <= 57) {
1089 /* ASCII char 52-57 (0-9) -> ASCII table offset 13 -> 52 (4) + 13 = 65 (A) */
1090 proto_item_append_text(pedition, " (AEDP-4607 Edition %c)", edition + 13);
1092 proto_tree_add_item(ver_tree, hf_4607_version_version, tvb, 1, 1, ENC_ASCII);
1094 ti = proto_tree_add_item(hdr_tree, hf_4607_packet_size, tvb, 2, 4, ENC_BIG_ENDIAN);
1095 proto_tree_add_item(hdr_tree, hf_4607_nationality, tvb, 6, 2, ENC_ASCII);
1096 proto_tree_add_item(hdr_tree, hf_4607_sec_class, tvb, 8, 1, ENC_BIG_ENDIAN);
1097 proto_tree_add_item(hdr_tree, hf_4607_sec_system, tvb, 9, 2, ENC_ASCII);
1098 proto_tree_add_item(hdr_tree, hf_4607_sec_code, tvb, 11, 2, ENC_BIG_ENDIAN);
1099 proto_tree_add_item(hdr_tree, hf_4607_exercise_indicator, tvb, 13, 1, ENC_BIG_ENDIAN);
1100 proto_tree_add_item(hdr_tree, hf_4607_platform_id, tvb, 14, 10, ENC_ASCII);
1101 proto_tree_add_item(hdr_tree, hf_4607_mission_id, tvb, 24, 4, ENC_BIG_ENDIAN);
1102 proto_tree_add_item(hdr_tree, hf_4607_job_id, tvb, 28, 4, ENC_BIG_ENDIAN);
1103 job_id = tvb_get_uint32(tvb, 28, ENC_BIG_ENDIAN);
1104 offset = 32;
1106 pkt_size = tvb_get_ntohl(tvb, 2);
1108 /* Ruh ro. These should be equal... */
1109 if (tvb_reported_length(tvb) != pkt_size) {
1110 expert_add_info(pinfo, ti, &ei_bad_packet_size);
1111 pkt_size = tvb_reported_length(tvb);
1114 /* Loop over all segments in the packet */
1115 while (offset < pkt_size) {
1116 uint32_t seg_size = 0;
1117 uint32_t saved_offset = offset;
1119 proto_item * pi;
1120 /* Segment header */
1121 seg_type = proto_tree_add_item(hdr_tree, hf_4607_segment_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1122 seg_id = tvb_get_uint8(tvb, offset);
1123 offset += 1;
1125 seg_tree = proto_item_add_subtree(seg_type, ett_4607_seg);
1126 pi = proto_tree_add_item(seg_tree, hf_4607_segment_size, tvb, offset, 4, ENC_BIG_ENDIAN);
1127 seg_size = tvb_get_ntohl(tvb, offset);
1128 offset += 4;
1129 if (seg_size < MINIMUM_SEGMENT_SIZE) {
1130 seg_size = MINIMUM_SEGMENT_SIZE;
1131 col_append_str(pinfo->cinfo, COL_INFO, ", Error: Invalid segment size ");
1132 expert_add_info(pinfo, pi, &ei_too_short);
1135 switch (seg_id) {
1136 case MISSION_SEGMENT:
1137 CHK_SIZE(MISSION_SEGMENT);
1138 offset = dissect_mission(tvb, seg_tree, offset);
1139 break;
1140 case DWELL_SEGMENT:
1141 if(job_id == 0)
1142 proto_tree_add_expert(seg_tree, pinfo, &ei_job_id_zero, tvb, 0, 0);
1143 offset = dissect_dwell(tvb, seg_tree, offset);
1144 break;
1145 case JOB_DEFINITION_SEGMENT:
1146 CHK_SIZE(JOB_DEFINITION_SEGMENT);
1147 offset = dissect_jobdef(tvb, seg_tree, offset);
1148 break;
1149 case PLATFORM_LOCATION_SEGMENT:
1150 CHK_SIZE(PLATFORM_LOCATION_SEGMENT);
1151 offset = dissect_platform_location(tvb, seg_tree, offset);
1152 break;
1153 default:
1154 offset += seg_size - 5;
1155 break;
1158 if (offset < saved_offset) {
1159 /* overflow */
1160 break;
1163 return tvb_captured_length(tvb);
1166 void
1167 proto_register_stanag4607(void)
1169 static hf_register_info hf[] = {
1170 /* ========================================== */
1171 /* Packet header */
1172 { &hf_4607_version,
1173 { "Version ID", "s4607.version",
1174 FT_STRING, BASE_NONE,
1175 NULL, 0x0,
1176 NULL, HFILL }
1178 { &hf_4607_version_edition,
1179 { "Edition", "s4607.version.edition",
1180 FT_STRING, BASE_NONE,
1181 NULL, 0x0,
1182 NULL, HFILL }
1184 { &hf_4607_version_version,
1185 { "Version", "s4607.version.version",
1186 FT_STRING, BASE_NONE,
1187 NULL, 0x0,
1188 NULL, HFILL }
1190 { &hf_4607_packet_size,
1191 { "Packet Size", "s4607.size",
1192 FT_UINT32, BASE_DEC,
1193 NULL, 0x0,
1194 NULL, HFILL }
1196 { &hf_4607_nationality,
1197 { "Nationality", "s4607.nationality",
1198 FT_STRING, BASE_NONE,
1199 NULL, 0x0,
1200 NULL, HFILL }
1202 { &hf_4607_sec_class,
1203 { "Security Classification", "s4607.sec.class",
1204 FT_UINT8, BASE_DEC,
1205 VALS(stanag4607_class_vals), 0x0,
1206 NULL, HFILL }
1208 { &hf_4607_sec_system,
1209 { "Security System", "s4607.sec.system",
1210 FT_STRING, BASE_NONE,
1211 NULL, 0x0,
1212 NULL, HFILL }
1214 { &hf_4607_sec_code,
1215 { "Security Codes", "s4607.sec.codes",
1216 FT_UINT16, BASE_HEX,
1217 VALS(stanag4607_security_codes_vals), 0x0,
1218 NULL, HFILL }
1220 { &hf_4607_exercise_indicator,
1221 { "Exercise Indicator", "s4607.exind",
1222 FT_UINT8, BASE_DEC,
1223 VALS(stanag4607_exind_vals), 0x0,
1224 NULL, HFILL }
1226 { &hf_4607_platform_id,
1227 { "Platform ID", "s4607.platform",
1228 FT_STRING, BASE_NONE,
1229 NULL, 0x0,
1230 NULL, HFILL }
1232 { &hf_4607_mission_id,
1233 { "Mission ID", "s4607.mission",
1234 FT_UINT32, BASE_DEC,
1235 NULL, 0x0,
1236 NULL, HFILL }
1238 { &hf_4607_job_id,
1239 { "Job ID", "s4607.job",
1240 FT_UINT32, BASE_DEC,
1241 NULL, 0x0,
1242 NULL, HFILL }
1245 /* ========================================== */
1246 /* Segment header */
1247 { &hf_4607_segment_type,
1248 { "Segment Type", "s4607.seg.type",
1249 FT_UINT8, BASE_DEC,
1250 VALS(stanag4607_segment_vals), 0x0,
1251 NULL, HFILL }
1253 { &hf_4607_segment_size,
1254 { "Segment Size", "s4607.seg.size",
1255 FT_UINT32, BASE_DEC,
1256 NULL, 0x0,
1257 NULL, HFILL }
1260 /* ========================================== */
1261 /* Dwell Segment */
1262 { &hf_4607_dwell_mask,
1263 { "Existence Mask", "s4607.dwell.mask",
1264 FT_UINT64, BASE_HEX,
1265 NULL, 0x0,
1266 NULL, HFILL }
1268 { &hf_4607_dwell_mask_7_7,
1269 { "Revisit Index (D2)", "s4607.dwell.mask.d2",
1270 FT_BOOLEAN, 64,
1271 NULL, 0x8000000000000000,
1272 NULL, HFILL }
1274 { &hf_4607_dwell_mask_7_6,
1275 { "Dwell Index (D3)", "s4607.dwell.mask.d3",
1276 FT_BOOLEAN, 64,
1277 NULL, 0x4000000000000000,
1278 NULL, HFILL }
1280 { &hf_4607_dwell_mask_7_5,
1281 { "Last Dwell of Revisit (D4)", "s4607.dwell.mask.d4",
1282 FT_BOOLEAN, 64,
1283 NULL, 0x2000000000000000,
1284 NULL, HFILL }
1286 { &hf_4607_dwell_mask_7_4,
1287 { "Target Report Count (D5)", "s4607.dwell.mask.d5",
1288 FT_BOOLEAN, 64,
1289 NULL, 0x1000000000000000,
1290 NULL, HFILL }
1292 { &hf_4607_dwell_mask_7_3,
1293 { "Dwell Time (D6)", "s4607.dwell.mask.d6",
1294 FT_BOOLEAN, 64,
1295 NULL, 0x0800000000000000,
1296 NULL, HFILL }
1298 { &hf_4607_dwell_mask_7_2,
1299 { "Sensor Position (Latitude) (D7)", "s4607.dwell.mask.d7",
1300 FT_BOOLEAN, 64,
1301 NULL, 0x0400000000000000,
1302 NULL, HFILL }
1304 { &hf_4607_dwell_mask_7_1,
1305 { "Sensor Position (Longitude) (D8)", "s4607.dwell.mask.d8",
1306 FT_BOOLEAN, 64,
1307 NULL, 0x0200000000000000,
1308 NULL, HFILL }
1310 { &hf_4607_dwell_mask_7_0,
1311 { "Sensor Position (Altitude) (D9)", "s4607.dwell.mask.d9",
1312 FT_BOOLEAN, 64,
1313 NULL, 0x0100000000000000,
1314 NULL, HFILL }
1316 { &hf_4607_dwell_mask_6_7,
1317 { "Scale Factor (Latitude Scale) (D10)", "s4607.dwell.mask.d10",
1318 FT_BOOLEAN, 64,
1319 NULL, 0x0080000000000000,
1320 NULL, HFILL }
1322 { &hf_4607_dwell_mask_6_6,
1323 { "Scale Factor (Longitude Scale) (D11)", "s4607.dwell.mask.d11",
1324 FT_BOOLEAN, 64,
1325 NULL, 0x0040000000000000,
1326 NULL, HFILL }
1328 { &hf_4607_dwell_mask_6_5,
1329 { "Sensor Position Uncertainty (Along Track) (D12)", "s4607.dwell.mask.d12",
1330 FT_BOOLEAN, 64,
1331 NULL, 0x0020000000000000,
1332 NULL, HFILL }
1334 { &hf_4607_dwell_mask_6_4,
1335 { "Sensor Position Uncertainty (Cross-Track) (D13)", "s4607.dwell.mask.d13",
1336 FT_BOOLEAN, 64,
1337 NULL, 0x0010000000000000,
1338 NULL, HFILL }
1340 { &hf_4607_dwell_mask_6_3,
1341 { "Sensor Position Uncertainty (Altitude) (D14)", "s4607.dwell.mask.d14",
1342 FT_BOOLEAN, 64,
1343 NULL, 0x0008000000000000,
1344 NULL, HFILL }
1346 { &hf_4607_dwell_mask_6_2,
1347 { "Sensor Track (D15)", "s4607.dwell.mask.d15",
1348 FT_BOOLEAN, 64,
1349 NULL, 0x0004000000000000,
1350 NULL, HFILL }
1352 { &hf_4607_dwell_mask_6_1,
1353 { "Sensor Speed (D16)", "s4607.dwell.mask.d16",
1354 FT_BOOLEAN, 64,
1355 NULL, 0x0002000000000000,
1356 NULL, HFILL }
1358 { &hf_4607_dwell_mask_6_0,
1359 { "Sensor Vertical Velocity (D17)", "s4607.dwell.mask.d17",
1360 FT_BOOLEAN, 64,
1361 NULL, 0x0001000000000000,
1362 NULL, HFILL }
1364 { &hf_4607_dwell_mask_5_7,
1365 { "Sensor Track Uncertainty (D18)", "s4607.dwell.mask.d18",
1366 FT_BOOLEAN, 64,
1367 NULL, 0x0000800000000000,
1368 NULL, HFILL }
1370 { &hf_4607_dwell_mask_5_6,
1371 { "Sensor Speed Uncertainty (D19)", "s4607.dwell.mask.d19",
1372 FT_BOOLEAN, 64,
1373 NULL, 0x0000400000000000,
1374 NULL, HFILL }
1376 { &hf_4607_dwell_mask_5_5,
1377 { "Sensor Vertical Velocity Uncertainty (D20)", "s4607.dwell.mask.d20",
1378 FT_BOOLEAN, 64,
1379 NULL, 0x0000200000000000,
1380 NULL, HFILL }
1382 { &hf_4607_dwell_mask_5_4,
1383 { "Platform Orientation (Heading) (D21)", "s4607.dwell.mask.d21",
1384 FT_BOOLEAN, 64,
1385 NULL, 0x0000100000000000,
1386 NULL, HFILL }
1388 { &hf_4607_dwell_mask_5_3,
1389 { "Platform Orientation (Pitch) (D22)", "s4607.dwell.mask.d22",
1390 FT_BOOLEAN, 64,
1391 NULL, 0x0000080000000000,
1392 NULL, HFILL }
1394 { &hf_4607_dwell_mask_5_2,
1395 { "Platform Orientation (Roll) (D23)", "s4607.dwell.mask.d23",
1396 FT_BOOLEAN, 64,
1397 NULL, 0x0000040000000000,
1398 NULL, HFILL }
1400 { &hf_4607_dwell_mask_5_1,
1401 { "Dwell Area (Center Latitude) (D24)", "s4607.dwell.mask.d24",
1402 FT_BOOLEAN, 64,
1403 NULL, 0x0000020000000000,
1404 NULL, HFILL }
1406 { &hf_4607_dwell_mask_5_0,
1407 { "Dwell Area (Center Longitude) (D25)", "s4607.dwell.mask.d25",
1408 FT_BOOLEAN, 64,
1409 NULL, 0x0000010000000000,
1410 NULL, HFILL }
1412 { &hf_4607_dwell_mask_4_7,
1413 { "Dwell Area (Range Half Extent) (D26)", "s4607.dwell.mask.d26",
1414 FT_BOOLEAN, 64,
1415 NULL, 0x0000008000000000,
1416 NULL, HFILL }
1418 { &hf_4607_dwell_mask_4_6,
1419 { "Dwell Area (Dwell Angle Half Extent) (D27)", "s4607.dwell.mask.d27",
1420 FT_BOOLEAN, 64,
1421 NULL, 0x0000004000000000,
1422 NULL, HFILL }
1424 { &hf_4607_dwell_mask_4_5,
1425 { "Sensor Orientation (Heading) (D28)", "s4607.dwell.mask.d28",
1426 FT_BOOLEAN, 64,
1427 NULL, 0x0000002000000000,
1428 NULL, HFILL }
1430 { &hf_4607_dwell_mask_4_4,
1431 { "Sensor Orientation (Pitch) (D29)", "s4607.dwell.mask.d29",
1432 FT_BOOLEAN, 64,
1433 NULL, 0x0000001000000000,
1434 NULL, HFILL }
1436 { &hf_4607_dwell_mask_4_3,
1437 { "Sensor Orientation (Roll) (D30)", "s4607.dwell.mask.d30",
1438 FT_BOOLEAN, 64,
1439 NULL, 0x0000000800000000,
1440 NULL, HFILL }
1442 { &hf_4607_dwell_mask_4_2,
1443 { "Minimum Detectable Velocity, MDV (D31)", "s4607.dwell.mask.d31",
1444 FT_BOOLEAN, 64,
1445 NULL, 0x0000000400000000,
1446 NULL, HFILL }
1448 { &hf_4607_dwell_mask_4_1,
1449 { "MTI Report Index (D32.1)", "s4607.dwell.mask.d32_1",
1450 FT_BOOLEAN, 64,
1451 NULL, 0x0000000200000000,
1452 NULL, HFILL }
1454 { &hf_4607_dwell_mask_4_0,
1455 { "Target Location (Hi-Res Latitude) (D32.2)", "s4607.dwell.mask.d32_2",
1456 FT_BOOLEAN, 64,
1457 NULL, 0x0000000100000000,
1458 NULL, HFILL }
1460 { &hf_4607_dwell_mask_3_7,
1461 { "Target Location (Hi-Res Longitude) (D32.3)", "s4607.dwell.mask.d32_3",
1462 FT_BOOLEAN, 64,
1463 NULL, 0x0000000080000000,
1464 NULL, HFILL }
1466 { &hf_4607_dwell_mask_3_6,
1467 { "Target Location (Delta Latitude) (D32.4)", "s4607.dwell.mask.d32_4",
1468 FT_BOOLEAN, 64,
1469 NULL, 0x0000000040000000,
1470 NULL, HFILL }
1472 { &hf_4607_dwell_mask_3_5,
1473 { "Target Location (Delta Longitude) (D32.5)", "s4607.dwell.mask.d32_5",
1474 FT_BOOLEAN, 64,
1475 NULL, 0x0000000020000000,
1476 NULL, HFILL }
1478 { &hf_4607_dwell_mask_3_4,
1479 { "Target Location (Geodetic Height) (D32.6)", "s4607.dwell.mask.d32_6",
1480 FT_BOOLEAN, 64,
1481 NULL, 0x0000000010000000,
1482 NULL, HFILL }
1484 { &hf_4607_dwell_mask_3_3,
1485 { "Target Velocity Line-of-Sight Component (D32.7)", "s4607.dwell.mask.d32_7",
1486 FT_BOOLEAN, 64,
1487 NULL, 0x0000000008000000,
1488 NULL, HFILL }
1490 { &hf_4607_dwell_mask_3_2,
1491 { "Target Wrap Velocity (D32.8)", "s4607.dwell.mask.d32_8",
1492 FT_BOOLEAN, 64,
1493 NULL, 0x0000000004000000,
1494 NULL, HFILL }
1496 { &hf_4607_dwell_mask_3_1,
1497 { "Target SNR (D32.9)", "s4607.dwell.mask.d32_9",
1498 FT_BOOLEAN, 64,
1499 NULL, 0x0000000002000000,
1500 NULL, HFILL }
1502 { &hf_4607_dwell_mask_3_0,
1503 { "Target Classification (D32.10)", "s4607.dwell.mask.d32_10",
1504 FT_BOOLEAN, 64,
1505 NULL, 0x0000000001000000,
1506 NULL, HFILL }
1508 { &hf_4607_dwell_mask_2_7,
1509 { "Target Class. Probability (D32.11)", "s4607.dwell.mask.d32_11",
1510 FT_BOOLEAN, 64,
1511 NULL, 0x0000000000800000,
1512 NULL, HFILL }
1514 { &hf_4607_dwell_mask_2_6,
1515 { "Target Measurement Uncertainty (Slant Range) (D32.12)", "s4607.dwell.mask.d32_12",
1516 FT_BOOLEAN, 64,
1517 NULL, 0x0000000000400000,
1518 NULL, HFILL }
1520 { &hf_4607_dwell_mask_2_5,
1521 { "Target Measurement Uncertainty (Cross Range) (D32.13)", "s4607.dwell.mask.d32_13",
1522 FT_BOOLEAN, 64,
1523 NULL, 0x0000000000200000,
1524 NULL, HFILL }
1526 { &hf_4607_dwell_mask_2_4,
1527 { "Target Measurement Uncertainty (Height) (D32.14)", "s4607.dwell.mask.d32_14",
1528 FT_BOOLEAN, 64,
1529 NULL, 0x0000000000100000,
1530 NULL, HFILL }
1532 { &hf_4607_dwell_mask_2_3,
1533 { "Target Measurement Uncertainty (Target Radial Velocity) (D32.15)", "s4607.dwell.mask.d32_15",
1534 FT_BOOLEAN, 64,
1535 NULL, 0x0000000000080000,
1536 NULL, HFILL }
1538 { &hf_4607_dwell_mask_2_2,
1539 { "Truth Tag (Application) (D32.16)", "s4607.dwell.mask.d32_16",
1540 FT_BOOLEAN, 64,
1541 NULL, 0x0000000000040000,
1542 NULL, HFILL }
1544 { &hf_4607_dwell_mask_2_1,
1545 { "Truth Tag (Entity) (D32.17)", "s4607.dwell.mask.d32_17",
1546 FT_BOOLEAN, 64,
1547 NULL, 0x0000000000020000,
1548 NULL, HFILL }
1550 { &hf_4607_dwell_mask_2_0,
1551 { "Target Radar Cross Section (D32.18)", "s4607.dwell.mask.d32_18",
1552 FT_BOOLEAN, 64,
1553 NULL, 0x0000000000010000,
1554 NULL, HFILL }
1556 { &hf_4607_dwell_mask_spare,
1557 { "Spare", "s4607.dwell.mask.spare",
1558 FT_UINT64, BASE_HEX,
1559 NULL, 0x000000000000FFFF,
1560 NULL, HFILL }
1562 { &hf_4607_dwell_revisit_index,
1563 { "Revisit Index", "s4607.dwell.revisit",
1564 FT_UINT16, BASE_DEC,
1565 NULL, 0x0,
1566 NULL, HFILL }
1568 { &hf_4607_dwell_dwell_index,
1569 { "Dwell Index", "s4607.dwell.dwell",
1570 FT_UINT16, BASE_DEC,
1571 NULL, 0x0,
1572 NULL, HFILL }
1574 { &hf_4607_dwell_last_dwell,
1575 { "Last Dwell of Revisit", "s4607.dwell.last",
1576 FT_UINT8, BASE_DEC,
1577 NULL, 0x0,
1578 NULL, HFILL }
1580 { &hf_4607_dwell_count,
1581 { "Target Report Count", "s4607.dwell.count",
1582 FT_UINT16, BASE_DEC,
1583 NULL, 0x0,
1584 NULL, HFILL }
1586 { &hf_4607_dwell_time,
1587 { "Dwell Time", "s4607.dwell.time",
1588 FT_UINT32, BASE_CUSTOM,
1589 CF_FUNC(prt_millisec), 0x0,
1590 NULL, HFILL }
1592 { &hf_4607_dwell_sensor_lat,
1593 { "Sensor Position Latitude", "s4607.dwell.sensor.lat",
1594 FT_INT32, BASE_CUSTOM,
1595 CF_FUNC(prt_sa32), 0x0,
1596 NULL, HFILL }
1598 { &hf_4607_dwell_sensor_lon,
1599 { "Sensor Position Longitude", "s4607.dwell.sensor.lon",
1600 FT_UINT32, BASE_CUSTOM,
1601 CF_FUNC(prt_ba32), 0x0,
1602 NULL, HFILL }
1604 { &hf_4607_dwell_sensor_alt,
1605 { "Sensor Position Altitude", "s4607.dwell.sensor.alt",
1606 FT_INT32, BASE_CUSTOM,
1607 CF_FUNC(prt_centimeters), 0x0,
1608 NULL, HFILL }
1610 /* D10 */
1611 { &hf_4607_dwell_scale_lat,
1612 { "Scale Factor, Latitude", "s4607.dwell.scale.lat",
1613 FT_INT32, BASE_CUSTOM,
1614 CF_FUNC(prt_sa32), 0x0,
1615 NULL, HFILL }
1617 { &hf_4607_dwell_scale_lon,
1618 { "Scale Factor, Longitude", "s4607.dwell.scale.lon",
1619 FT_UINT32, BASE_CUSTOM,
1620 CF_FUNC(prt_ba32), 0x0,
1621 NULL, HFILL }
1624 /* D12 */
1625 { &hf_4607_dwell_unc_along,
1626 { "Sensor Position Uncertainty Along Track", "s4607.dwell.unc.along",
1627 FT_UINT32, BASE_CUSTOM,
1628 CF_FUNC(prt_centimeters), 0x0,
1629 NULL, HFILL }
1631 { &hf_4607_dwell_unc_cross,
1632 { "Sensor Position Uncertainty Cross Track", "s4607.dwell.unc.cross",
1633 FT_UINT32, BASE_CUSTOM,
1634 CF_FUNC(prt_centimeters), 0x0,
1635 NULL, HFILL }
1637 { &hf_4607_dwell_unc_alt,
1638 { "Sensor Position Uncertainty Altitude", "s4607.dwell.unc.alt",
1639 FT_UINT16, BASE_CUSTOM,
1640 CF_FUNC(prt_centimeters), 0x0,
1641 NULL, HFILL }
1644 /* D15 */
1645 { &hf_4607_dwell_track,
1646 { "Sensor Track", "s4607.dwell.track",
1647 FT_UINT16, BASE_CUSTOM,
1648 CF_FUNC(prt_ba16), 0x0,
1649 NULL, HFILL }
1651 { &hf_4607_dwell_speed,
1652 { "Sensor Speed", "s4607.dwell.speed",
1653 FT_UINT32, BASE_CUSTOM,
1654 CF_FUNC(prt_speed), 0x0,
1655 NULL, HFILL }
1657 { &hf_4607_dwell_vert_velocity,
1658 { "Sensor Vertical Velocity", "s4607.dwell.vvel",
1659 FT_INT8, BASE_CUSTOM,
1660 CF_FUNC(prt_speed_deci), 0x0,
1661 NULL, HFILL }
1663 { &hf_4607_dwell_track_unc,
1664 { "Sensor Track Uncertainty", "s4607.dwell.track.unc",
1665 FT_UINT8, BASE_DEC,
1666 NULL, 0x0,
1667 NULL, HFILL }
1669 { &hf_4607_dwell_speed_unc,
1670 { "Sensor Speed Uncertainty", "s4607.dwell.speed.unc",
1671 FT_UINT16, BASE_CUSTOM,
1672 CF_FUNC(prt_speed), 0x0,
1673 NULL, HFILL }
1675 { &hf_4607_dwell_vv_unc,
1676 { "Sensor Vertical Velocity Uncertainty", "s4607.dwell.vvel.unc",
1677 FT_UINT16, BASE_CUSTOM,
1678 CF_FUNC(prt_speed_centi), 0x0,
1679 NULL, HFILL }
1682 /* D21 */
1683 { &hf_4607_dwell_plat_heading,
1684 { "Platform Orientation Heading", "s4607.dwell.plat.heading",
1685 FT_UINT16, BASE_CUSTOM,
1686 CF_FUNC(prt_ba16), 0x0,
1687 NULL, HFILL }
1689 { &hf_4607_dwell_plat_pitch,
1690 { "Platform Orientation Pitch", "s4607.dwell.plat.pitch",
1691 FT_INT16, BASE_CUSTOM,
1692 CF_FUNC(prt_sa16), 0x0,
1693 NULL, HFILL }
1695 { &hf_4607_dwell_plat_roll,
1696 { "Platform Orientation Roll (Bank Angle)", "s4607.dwell.plat.roll",
1697 FT_INT16, BASE_CUSTOM,
1698 CF_FUNC(prt_sa16), 0x0,
1699 NULL, HFILL }
1702 /* D24 */
1703 { &hf_4607_dwell_da_lat,
1704 { "Dwell Area Center Latitude", "s4607.dwell.da.lat",
1705 FT_INT32, BASE_CUSTOM,
1706 CF_FUNC(prt_sa32), 0x0,
1707 NULL, HFILL }
1709 { &hf_4607_dwell_da_lon,
1710 { "Dwell Area Center Longitude", "s4607.dwell.da.lon",
1711 FT_UINT32, BASE_CUSTOM,
1712 CF_FUNC(prt_ba32), 0x0,
1713 NULL, HFILL }
1715 { &hf_4607_dwell_da_range,
1716 { "Dwell Area Range Half Extent", "s4607.dwell.da.range",
1717 FT_UINT16, BASE_CUSTOM,
1718 CF_FUNC(prt_kilo), 0x0,
1719 NULL, HFILL }
1721 { &hf_4607_dwell_da_angle,
1722 { "Dwell Area Dwell Angle Half Extent", "s4607.dwell.da.angle",
1723 FT_UINT16, BASE_CUSTOM,
1724 CF_FUNC(prt_ba16), 0x0,
1725 NULL, HFILL }
1728 /* D28 */
1729 { &hf_4607_dwell_sensor_heading,
1730 { "Sensor Orientation Heading", "s4607.dwell.sensor.heading",
1731 FT_UINT16, BASE_CUSTOM,
1732 CF_FUNC(prt_ba16), 0x0,
1733 NULL, HFILL }
1735 { &hf_4607_dwell_sensor_pitch,
1736 { "Sensor Orientation Pitch", "s4607.dwell.sensor.pitch",
1737 FT_INT16, BASE_CUSTOM,
1738 CF_FUNC(prt_sa16), 0x0,
1739 NULL, HFILL }
1741 { &hf_4607_dwell_sensor_roll,
1742 { "Sensor Orientation Roll (Bank Angle)", "s4607.dwell.sensor.roll",
1743 FT_INT16, BASE_CUSTOM,
1744 CF_FUNC(prt_sa16), 0x0,
1745 NULL, HFILL }
1747 { &hf_4607_dwell_mdv,
1748 { "Minimum Detectable Velocity (MDV)", "s4607.dwell.mdv",
1749 FT_UINT8, BASE_CUSTOM,
1750 CF_FUNC(prt_speed_deci), 0x0,
1751 NULL, HFILL }
1754 /* ========================================== */
1755 /* Target Report */
1756 { &hf_4607_dwell_report_index,
1757 { "MTI Report Index", "s4607.dwell.rpt.idx",
1758 FT_UINT16, BASE_DEC,
1759 NULL, 0x0,
1760 NULL, HFILL }
1763 /* D32.2 */
1764 { &hf_4607_dwell_report_lat,
1765 { "Target Location Hi-Res Latitude", "s4607.dwell.rpt.lat",
1766 FT_INT32, BASE_CUSTOM,
1767 CF_FUNC(prt_sa32), 0x0,
1768 NULL, HFILL }
1770 { &hf_4607_dwell_report_lon,
1771 { "Target Location Hi-Res Longitude", "s4607.dwell.rpt.lon",
1772 FT_UINT32, BASE_CUSTOM,
1773 CF_FUNC(prt_ba32), 0x0,
1774 NULL, HFILL }
1777 /* D32.4 */
1778 { &hf_4607_dwell_report_delta_lat,
1779 { "Target Location Delta Latitude", "s4607.dwell.rpt.delta.lat",
1780 FT_INT16, BASE_DEC,
1781 NULL, 0x0,
1782 NULL, HFILL }
1784 { &hf_4607_dwell_report_delta_lon,
1785 { "Target Location Delta Longitude", "s4607.dwell.rpt.delta.lon",
1786 FT_INT16, BASE_DEC,
1787 NULL, 0x0,
1788 NULL, HFILL }
1791 /* D32.6 */
1792 { &hf_4607_dwell_report_height,
1793 { "Target Location Geodetic Height", "s4607.dwell.rpt.height",
1794 FT_INT16, BASE_CUSTOM,
1795 CF_FUNC(prt_meters), 0x0,
1796 NULL, HFILL }
1799 /* D32.7 */
1800 { &hf_4607_dwell_report_radial,
1801 { "Target Velocity Line of Sight Component", "s4607.dwell.rpt.radial",
1802 FT_INT16, BASE_CUSTOM,
1803 CF_FUNC(prt_speed_centi), 0x0,
1804 NULL, HFILL }
1806 { &hf_4607_dwell_report_wrap,
1807 { "Target Wrap Velocity", "s4607.dwell.rpt.wrap",
1808 FT_UINT16, BASE_CUSTOM,
1809 CF_FUNC(prt_speed_centi), 0x0,
1810 NULL, HFILL }
1812 { &hf_4607_dwell_report_snr,
1813 { "Target SNR", "s4607.dwell.rpt.snr",
1814 FT_INT8, BASE_DEC,
1815 NULL, 0x0,
1816 NULL, HFILL }
1818 { &hf_4607_dwell_report_class,
1819 { "Target Classification", "s4607.dwell.rpt.class",
1820 FT_UINT8, BASE_DEC,
1821 VALS(stanag4607_target_vals), 0x0,
1822 NULL, HFILL }
1824 { &hf_4607_dwell_report_prob,
1825 { "Target Class Probability", "s4607.dwell.rpt.prob",
1826 FT_UINT8, BASE_DEC,
1827 NULL, 0x0,
1828 NULL, HFILL }
1831 /* D32.12 */
1832 { &hf_4607_dwell_report_unc_slant,
1833 { "Target Measurement Uncertainty Slant Range", "s4607.dwell.rpt.unc.slant",
1834 FT_UINT16, BASE_CUSTOM,
1835 CF_FUNC(prt_centimeters), 0x0,
1836 NULL, HFILL }
1838 { &hf_4607_dwell_report_unc_cross,
1839 { "Target Measurement Uncertainty Cross Range", "s4607.dwell.rpt.unc.cross",
1840 FT_UINT16, BASE_CUSTOM,
1841 CF_FUNC(prt_decimeters), 0x0,
1842 NULL, HFILL }
1844 { &hf_4607_dwell_report_unc_height,
1845 { "Target Measurement Uncertainty Height", "s4607.dwell.rpt.unc.height",
1846 FT_UINT8, BASE_CUSTOM,
1847 CF_FUNC(prt_meters), 0x0,
1848 NULL, HFILL }
1850 { &hf_4607_dwell_report_unc_radial,
1851 { "Target Measurement Uncertainty Radial Velocity", "s4607.dwell.rpt.unc.radial",
1852 FT_UINT16, BASE_CUSTOM,
1853 CF_FUNC(prt_speed_centi), 0x0,
1854 NULL, HFILL }
1857 /* D32.16 */
1858 { &hf_4607_dwell_report_tag_app,
1859 { "Truth Tag Application", "s4607.dwell.rpt.tag.app",
1860 FT_UINT8, BASE_DEC,
1861 NULL, 0x0,
1862 NULL, HFILL }
1864 { &hf_4607_dwell_report_tag_entity,
1865 { "Truth Tag Entity", "s4607.dwell.rpt.tag.entity",
1866 FT_UINT32, BASE_DEC,
1867 NULL, 0x0,
1868 NULL, HFILL }
1870 { &hf_4607_dwell_report_section,
1871 { "Radar Cross Section", "s4607.dwell.rpt.section",
1872 FT_INT8, BASE_DEC,
1873 NULL, 0x0,
1874 NULL, HFILL }
1878 /* ========================================== */
1879 /* Job Definition Segment */
1880 { &hf_4607_jobdef_job_id,
1881 { "Job ID", "s4607.job.id",
1882 FT_UINT32, BASE_DEC,
1883 NULL, 0x0,
1884 NULL, HFILL }
1886 { &hf_4607_jobdef_sensor_type,
1887 { "Sensor Type", "s4607.job.type",
1888 FT_UINT8, BASE_DEC,
1889 VALS(stanag4607_sensor_vals), 0x0,
1890 NULL, HFILL }
1892 { &hf_4607_jobdef_sensor_model,
1893 { "Sensor Model", "s4607.job.model",
1894 FT_STRING, BASE_NONE,
1895 NULL, 0x0,
1896 NULL, HFILL }
1898 { &hf_4607_jobdef_filter,
1899 { "Target Filtering Flag", "s4607.job.filter",
1900 FT_UINT8, BASE_DEC,
1901 NULL, 0x0,
1902 NULL, HFILL }
1904 { &hf_4607_jobdef_priority,
1905 { "Radar Priority", "s4607.job.priority",
1906 FT_UINT8, BASE_DEC,
1907 NULL, 0x0,
1908 NULL, HFILL }
1911 { &hf_4607_jobdef_ba_lat_a,
1912 { "Bounding Area Point A Latitude", "s4607.job.ba.lat.a",
1913 FT_INT32, BASE_CUSTOM,
1914 CF_FUNC(prt_sa32), 0x0,
1915 NULL, HFILL }
1917 { &hf_4607_jobdef_ba_lon_a,
1918 { "Bounding Area Point A Longitude", "s4607.job.ba.lon.a",
1919 FT_UINT32, BASE_CUSTOM,
1920 CF_FUNC(prt_ba32), 0x0,
1921 NULL, HFILL }
1924 { &hf_4607_jobdef_ba_lat_b,
1925 { "Bounding Area Point B Latitude", "s4607.job.ba.lat.b",
1926 FT_INT32, BASE_CUSTOM,
1927 CF_FUNC(prt_sa32), 0x0,
1928 NULL, HFILL }
1930 { &hf_4607_jobdef_ba_lon_b,
1931 { "Bounding Area Point B Longitude", "s4607.job.ba.lon.b",
1932 FT_UINT32, BASE_CUSTOM,
1933 CF_FUNC(prt_ba32), 0x0,
1934 NULL, HFILL }
1936 { &hf_4607_jobdef_ba_lat_c,
1937 { "Bounding Area Point C Latitude", "s4607.job.ba.lat.c",
1938 FT_INT32, BASE_CUSTOM,
1939 CF_FUNC(prt_sa32), 0x0,
1940 NULL, HFILL }
1942 { &hf_4607_jobdef_ba_lon_c,
1943 { "Bounding Area Point C Longitude", "s4607.job.ba.lon.c",
1944 FT_UINT32, BASE_CUSTOM,
1945 CF_FUNC(prt_ba32), 0x0,
1946 NULL, HFILL }
1948 { &hf_4607_jobdef_ba_lat_d,
1949 { "Bounding Area Point D Latitude", "s4607.job.ba.lat.d",
1950 FT_INT32, BASE_CUSTOM,
1951 CF_FUNC(prt_sa32), 0x0,
1952 NULL, HFILL }
1954 { &hf_4607_jobdef_ba_lon_d,
1955 { "Bounding Area Point D Longitude", "s4607.job.ba.lon.d",
1956 FT_UINT32, BASE_CUSTOM,
1957 CF_FUNC(prt_ba32), 0x0,
1958 NULL, HFILL }
1961 { &hf_4607_jobdef_radar_mode,
1962 { "Radar Mode", "s4607.job.mode",
1963 FT_UINT8, BASE_DEC,
1964 VALS(stanag4607_radar_mode_vals), 0x0,
1965 NULL, HFILL }
1968 { &hf_4607_jobdef_revisit_interval,
1969 { "Nominal Revisit Interval", "s4607.job.revisit",
1970 FT_UINT16, BASE_DEC,
1971 NULL, 0x0,
1972 NULL, HFILL }
1974 { &hf_4607_jobdef_unc_along,
1975 { "Nominal Sensor Position Uncertainty Along Track", "s4607.job.unc.track",
1976 FT_UINT16, BASE_CUSTOM,
1977 CF_FUNC(prt_none16), 0x0,
1978 NULL, HFILL }
1980 { &hf_4607_jobdef_unc_cross,
1981 { "Nominal Sensor Position Uncertainty Cross Track", "s4607.job.unc.cross",
1982 FT_UINT16, BASE_CUSTOM,
1983 CF_FUNC(prt_none16), 0x0,
1984 NULL, HFILL }
1986 { &hf_4607_jobdef_unc_alt,
1987 { "Nominal Sensor Position Uncertainty Altitude", "s4607.job.unc.alt",
1988 FT_UINT16, BASE_CUSTOM,
1989 CF_FUNC(prt_none16), 0x0,
1990 NULL, HFILL }
1992 { &hf_4607_jobdef_unc_heading,
1993 { "Nominal Sensor Position Uncertainty Track Heading", "s4607.job.unc.heading",
1994 FT_UINT8, BASE_CUSTOM,
1995 CF_FUNC(prt_none8), 0x0,
1996 NULL, HFILL }
1998 { &hf_4607_jobdef_unc_speed,
1999 { "Nominal Sensor Position Uncertainty Speed", "s4607.job.unc.speed",
2000 FT_UINT16, BASE_CUSTOM,
2001 CF_FUNC(prt_none16), 0x0,
2002 NULL, HFILL }
2005 { &hf_4607_jobdef_sense_slant,
2006 { "Nominal Sensor Slant Range Standard Deviation", "s4607.job.sense.slant",
2007 FT_UINT16, BASE_CUSTOM,
2008 CF_FUNC(prt_none16), 0x0,
2009 NULL, HFILL }
2011 { &hf_4607_jobdef_sense_cross,
2012 { "Nominal Sensor Cross Range Standard Deviation", "s4607.job.sense.cross",
2013 FT_UINT16, BASE_CUSTOM,
2014 CF_FUNC(prt_ba16_none), 0x0,
2015 NULL, HFILL }
2017 { &hf_4607_jobdef_sense_vlos,
2018 { "Nominal Sensor Velocity Line-Of-Sight Std. Dev", "s4607.job.sense.vlos",
2019 FT_UINT16, BASE_CUSTOM,
2020 CF_FUNC(prt_none16), 0x0,
2021 NULL, HFILL }
2023 { &hf_4607_jobdef_sense_mdv,
2024 { "Nominal Sensor Minimum Detectable Velocity (MDV)", "s4607.job.sense.mdv",
2025 FT_UINT8, BASE_CUSTOM,
2026 CF_FUNC(prt_none8), 0x0,
2027 NULL, HFILL }
2029 { &hf_4607_jobdef_sense_prob,
2030 { "Nominal Sensor Detection Probability", "s4607.job.sense.prob",
2031 FT_UINT8, BASE_CUSTOM,
2032 CF_FUNC(prt_none8), 0x0,
2033 NULL, HFILL }
2035 { &hf_4607_jobdef_sense_alarm,
2036 { "Nominal Sensor False Alarm Density", "s4607.job.sense.alarm",
2037 FT_UINT8, BASE_CUSTOM,
2038 CF_FUNC(prt_none8), 0x0,
2039 NULL, HFILL }
2041 { &hf_4607_jobdef_terrain_model,
2042 { "Terrain Elevation Model Used", "s4607.job.terrain",
2043 FT_UINT8, BASE_DEC,
2044 VALS(stanag4607_terrain_vals), 0x0,
2045 NULL, HFILL }
2047 { &hf_4607_jobdef_geoid_model,
2048 { "Geoid Model Used", "s4607.job.geoid",
2049 FT_UINT8, BASE_DEC,
2050 VALS(stanag4607_geoid_vals), 0x0,
2051 NULL, HFILL }
2055 /* ========================================== */
2056 /* Mission segment */
2057 { &hf_4607_mission_plan,
2058 { "Mission Plan", "s4607.mission.plan",
2059 FT_STRING, BASE_NONE,
2060 NULL, 0x0,
2061 NULL, HFILL }
2063 { &hf_4607_mission_flight_plan,
2064 { "Mission Flight Plan", "s4607.mission.flight",
2065 FT_STRING, BASE_NONE,
2066 NULL, 0x0,
2067 NULL, HFILL }
2069 { &hf_4607_mission_platform,
2070 { "Mission Platform Type", "s4607.mission.platform",
2071 FT_UINT8, BASE_DEC,
2072 VALS(stanag4607_platform_vals), 0x0,
2073 NULL, HFILL }
2075 { &hf_4607_mission_platform_config,
2076 { "Mission Platform Configuration", "s4607.mission.config",
2077 FT_STRING, BASE_NONE,
2078 NULL, 0x0,
2079 NULL, HFILL }
2081 { &hf_4607_mission_time_year,
2082 { "Mission Reference Time Year", "s4607.mission.year",
2083 FT_UINT16, BASE_DEC,
2084 NULL, 0x0,
2085 NULL, HFILL }
2087 { &hf_4607_mission_time_month,
2088 { "Mission Reference Time Month", "s4607.mission.month",
2089 FT_UINT8, BASE_DEC,
2090 NULL, 0x0,
2091 NULL, HFILL }
2093 { &hf_4607_mission_time_day,
2094 { "Mission Reference Time Day", "s4607.mission.day",
2095 FT_UINT8, BASE_DEC,
2096 NULL, 0x0,
2097 NULL, HFILL }
2099 /* ========================================== */
2100 { &hf_4607_platloc_time,
2101 { "Platform Location Time", "s4607.ploc.time",
2102 FT_UINT32, BASE_CUSTOM,
2103 CF_FUNC(prt_millisec), 0x0,
2104 NULL, HFILL }
2106 { &hf_4607_platloc_latitude,
2107 { "Platform Position Latitude", "s4607.ploc.lat",
2108 FT_INT32, BASE_CUSTOM,
2109 CF_FUNC(prt_sa32), 0x0,
2110 NULL, HFILL }
2112 { &hf_4607_platloc_longitude,
2113 { "Platform Position Longitude", "s4607.ploc.lon",
2114 FT_UINT32, BASE_CUSTOM,
2115 CF_FUNC(prt_ba32), 0x0,
2116 NULL, HFILL }
2118 { &hf_4607_platloc_altitude,
2119 { "Platform Position Altitude", "s4607.ploc.alt",
2120 FT_INT32, BASE_CUSTOM,
2121 CF_FUNC(prt_centimeters), 0x0,
2122 NULL, HFILL }
2124 { &hf_4607_platloc_track,
2125 { "Platform Track", "s4607.ploc.track",
2126 FT_UINT16, BASE_CUSTOM,
2127 CF_FUNC(prt_ba16), 0x0,
2128 NULL, HFILL }
2130 { &hf_4607_platloc_speed,
2131 { "Platform Speed", "s4607.ploc.speed",
2132 FT_UINT32, BASE_CUSTOM,
2133 CF_FUNC(prt_speed), 0x0,
2134 NULL, HFILL }
2136 { &hf_4607_platloc_vertical_velocity,
2137 { "Platform Vertical Velocity", "s4607.ploc.velocity",
2138 FT_INT8, BASE_CUSTOM,
2139 CF_FUNC(prt_speed_deci), 0x0,
2140 NULL, HFILL }
2145 /* Setup protocol subtree array */
2146 static int *ett[] = {
2147 &ett_4607_hdr,
2148 &ett_4607_seg,
2149 &ett_4607_rpt,
2150 &ett_4607_mask,
2151 &ett_4607_ver,
2154 static ei_register_info ei[] = {
2155 { &ei_too_short,
2156 { "s4607.segment_too_short", PI_MALFORMED, PI_ERROR,
2157 "Segment size too small", EXPFILL }},
2158 { &ei_bad_length,
2159 { "s4607.segment_bad_length", PI_MALFORMED, PI_ERROR,
2160 "Bad segment size", EXPFILL }},
2161 { &ei_bad_packet_size,
2162 { "s4607.bad_packet_size", PI_MALFORMED, PI_ERROR,
2163 "Bad packet size field", EXPFILL }},
2164 { &ei_job_id_zero,
2165 { "s4607.job_id_zero", PI_MALFORMED, PI_WARN,
2166 "Segment present without valid Job ID", EXPFILL }}
2169 expert_module_t* expert_4607;
2171 proto_stanag4607 = proto_register_protocol (
2172 "STANAG 4607 (GMTI Format)", /* name */
2173 "STANAG 4607", /* short name */
2174 "s4607" /* abbrev */
2177 proto_register_field_array(proto_stanag4607, hf, array_length(hf));
2178 proto_register_subtree_array(ett, array_length(ett));
2179 expert_4607 = expert_register_protocol(proto_stanag4607);
2180 expert_register_field_array(expert_4607, ei, array_length(ei));
2182 stanag4607_handle = register_dissector("stanag4607", dissect_stanag4607, proto_stanag4607);
2183 /* prefs_register_protocol(proto_stanag4607, proto_reg_handoff_stanag4607); */
2186 void
2187 proto_reg_handoff_stanag4607(void)
2189 dissector_add_for_decode_as("tcp.port", stanag4607_handle);
2190 dissector_add_for_decode_as("udp.port", stanag4607_handle);
2191 dissector_add_uint("wtap_encap", WTAP_ENCAP_STANAG_4607, stanag4607_handle);
2195 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2197 * Local variables:
2198 * c-basic-offset: 8
2199 * tab-width: 8
2200 * indent-tabs-mode: t
2201 * End:
2203 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2204 * :indentSize=8:tabSize=8:noTabs=false: