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