/src/wireshark/epan/dissectors/packet-psn.c
Line | Count | Source |
1 | | /* packet-psn.c |
2 | | * Routines for PSN packet disassembly |
3 | | * |
4 | | * Copyright (c) 2025 by Matt Morris <mattm.dev.1[AT]gmail.com> |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1999 Gerald Combs |
9 | | * |
10 | | * Specification: |
11 | | * https://github.com/vyv/psn-cpp/blob/master/doc/PosiStageNetprotocol_v2.03_2019_09_09.pdf |
12 | | * https://posistage.net/wp-content/uploads/2019/01/PosiStageNetprotocol_v2.02_2016_09_15.pdf |
13 | | * https://posistage.net/wp-content/uploads/2018/07/PosiStageNetprotocolv1.7.pdf |
14 | | * |
15 | | * SPDX-License-Identifier: GPL-2.0-or-later |
16 | | */ |
17 | | |
18 | | |
19 | | /* Include files */ |
20 | | #include "config.h" |
21 | | #include <epan/packet.h> |
22 | | #include <epan/unit_strings.h> |
23 | | #include <epan/tfs.h> |
24 | | #include <epan/expert.h> |
25 | | |
26 | | /* constants */ |
27 | 0 | #define PSN_INFO_PACKET 0x6756 |
28 | 0 | #define PSN_DATA_PACKET 0x6755 |
29 | 0 | #define PSN_V1_INFO_PACKET 0x503c |
30 | 0 | #define PSN_V1_DATA_PACKET 0x6754 |
31 | | |
32 | 0 | #define PSN_INFO_PACKET_HEADER 0x0000 |
33 | 0 | #define PSN_INFO_SYSTEM_NAME 0x0001 |
34 | 0 | #define PSN_INFO_TRACKER_LIST 0x0002 |
35 | | |
36 | 0 | #define PSN_INFO_TRACKER_NAME 0x0000 |
37 | | |
38 | 0 | #define PSN_DATA_PACKET_HEADER 0x0000 |
39 | 0 | #define PSN_DATA_TRACKER_LIST 0x0001 |
40 | | |
41 | 0 | #define PSN_DATA_TRACKER_POS 0x0000 |
42 | 0 | #define PSN_DATA_TRACKER_SPEED 0x0001 |
43 | 0 | #define PSN_DATA_TRACKER_ORI 0x0002 |
44 | 0 | #define PSN_DATA_TRACKER_STATUS 0x0003 |
45 | 0 | #define PSN_DATA_TRACKER_ACCEL 0x0004 |
46 | 0 | #define PSN_DATA_TRACKER_TRGTPOS 0x0005 |
47 | 0 | #define PSN_DATA_TRACKER_TIMESTAMP 0x0006 |
48 | | |
49 | | |
50 | | static int proto_psn; |
51 | | |
52 | | static dissector_handle_t psn_handle; |
53 | | |
54 | | static dissector_handle_t xml_dissector_handle; |
55 | | |
56 | | /* Open/Close trees */ |
57 | | static int ett_psn; |
58 | | |
59 | | static int ett_psn_info_chunk; |
60 | | static int ett_psn_data_chunk; |
61 | | static int ett_psn_tracker_chunk; |
62 | | static int ett_psn_tracker_info_chunk; |
63 | | static int ett_psn_tracker_data_chunk; |
64 | | |
65 | | static int ett_psn_chunk_data_field; |
66 | | |
67 | | static int ett_psn_v1_header; |
68 | | static int ett_psn_v1_tracker; |
69 | | |
70 | | /* Expert Info */ |
71 | | static expert_field ei_psn_chunk_id; |
72 | | static expert_field ei_psn_chunk_len; |
73 | | |
74 | | /* Register fields */ |
75 | | static int hf_psn_info_chunk; |
76 | | static int hf_psn_data_chunk; |
77 | | static int hf_psn_tracker_chunk; |
78 | | static int hf_psn_tracker_info_chunk; |
79 | | static int hf_psn_tracker_data_chunk; |
80 | | |
81 | | static int hf_psn_base_chunk_id; |
82 | | static int hf_psn_info_chunk_id; |
83 | | static int hf_psn_data_chunk_id; |
84 | | static int hf_psn_tracker_id; |
85 | | static int hf_psn_tracker_data_chunk_id; |
86 | | static int hf_psn_tracker_info_chunk_id; |
87 | | |
88 | | static int hf_psn_chunk_data_field; |
89 | | static int hf_psn_chunk_length; |
90 | | static int hf_psn_chunk_has_subchunks; |
91 | | |
92 | | static int hf_psn_packet_timestamp; |
93 | | static int hf_psn_version_high; |
94 | | static int hf_psn_version_low; |
95 | | static int hf_psn_frame_id; |
96 | | static int hf_psn_frame_packet_count; |
97 | | |
98 | | static int hf_psn_system_name; |
99 | | static int hf_psn_tracker_name; |
100 | | |
101 | | static int hf_psn_position_x; |
102 | | static int hf_psn_position_y; |
103 | | static int hf_psn_position_z; |
104 | | static int hf_psn_speed_x; |
105 | | static int hf_psn_speed_y; |
106 | | static int hf_psn_speed_z; |
107 | | static int hf_psn_ori_x; |
108 | | static int hf_psn_ori_y; |
109 | | static int hf_psn_ori_z; |
110 | | static int hf_psn_accel_x; |
111 | | static int hf_psn_accel_y; |
112 | | static int hf_psn_accel_z; |
113 | | static int hf_psn_trgtpos_x; |
114 | | static int hf_psn_trgtpos_y; |
115 | | static int hf_psn_trgtpos_z; |
116 | | |
117 | | static int hf_psn_validity; |
118 | | static int hf_psn_tracker_timestamp; |
119 | | |
120 | | /* V1 only fields */ |
121 | | static int hf_psn_v1_header; |
122 | | static int hf_psn_v1_identifier; |
123 | | static int hf_psn_v1_tracker; |
124 | | static int hf_psn_v1_position; |
125 | | static int hf_psn_v1_velocity; |
126 | | static int hf_psn_v1_packet_counter; |
127 | | static int hf_psn_v1_world_id; |
128 | | static int hf_psn_v1_tracker_count; |
129 | | static int hf_psn_v1_frame_index; |
130 | | static int hf_psn_v1_object_state; |
131 | | static int hf_psn_v1_info_xml; |
132 | | static int hf_psn_v1_reserved; |
133 | | |
134 | | static int * const chunk_data_fields[] = { |
135 | | &hf_psn_chunk_length, |
136 | | &hf_psn_chunk_has_subchunks, |
137 | | NULL |
138 | | }; |
139 | | |
140 | | |
141 | | static const value_string psn_base_chunk_id_names[] = { |
142 | | { PSN_INFO_PACKET, "Information Packet" }, |
143 | | { PSN_DATA_PACKET, "Data Packet" }, |
144 | | { PSN_V1_INFO_PACKET, "V1 Information Packet" }, |
145 | | { PSN_V1_DATA_PACKET, "V1 Data Packet" }, |
146 | | { 0, NULL }, |
147 | | }; |
148 | | |
149 | | static const value_string psn_info_chunk_id_names[] = { |
150 | | { PSN_INFO_PACKET_HEADER, "Packet Header" }, |
151 | | { PSN_INFO_SYSTEM_NAME, "System Name" }, |
152 | | { PSN_INFO_TRACKER_LIST, "Tracker List" }, |
153 | | { 0, NULL }, |
154 | | }; |
155 | | |
156 | | static const value_string psn_tracker_info_chunk_id_names[] = { |
157 | | { PSN_INFO_TRACKER_NAME, "Tracker Name" }, |
158 | | { 0, NULL }, |
159 | | }; |
160 | | |
161 | | static const value_string psn_data_chunk_id_names[] = { |
162 | | { PSN_DATA_PACKET_HEADER, "Packet Header" }, |
163 | | { PSN_DATA_TRACKER_LIST, "Tracker List" }, |
164 | | { 0, NULL }, |
165 | | }; |
166 | | |
167 | | static const value_string psn_tracker_data_chunk_id_names[] = { |
168 | | { PSN_DATA_TRACKER_POS, "Tracker Position" }, |
169 | | { PSN_DATA_TRACKER_SPEED, "Tracker Speed" }, |
170 | | { PSN_DATA_TRACKER_ORI, "Tracker Origin" }, |
171 | | { PSN_DATA_TRACKER_STATUS, "Tracker Status" }, |
172 | | { PSN_DATA_TRACKER_ACCEL, "Tracker Acceleration" }, |
173 | | { PSN_DATA_TRACKER_TRGTPOS, "Tracker Target Position" }, |
174 | | { PSN_DATA_TRACKER_TIMESTAMP, "Tracker Timestamp" }, |
175 | | { 0, NULL }, |
176 | | }; |
177 | | static const value_string psn_tracker_data_names[] = { |
178 | | { PSN_DATA_TRACKER_POS, "Position" }, |
179 | | { PSN_DATA_TRACKER_SPEED, "Speed" }, |
180 | | { PSN_DATA_TRACKER_ORI, "Origin" }, |
181 | | { PSN_DATA_TRACKER_STATUS, "Status" }, |
182 | | { PSN_DATA_TRACKER_ACCEL, "Acceleration" }, |
183 | | { PSN_DATA_TRACKER_TRGTPOS, "Target Position" }, |
184 | | { PSN_DATA_TRACKER_TIMESTAMP, "Timestamp" }, |
185 | | { 0, NULL }, |
186 | | }; |
187 | | |
188 | | static const value_string psn_v1_identifier[] = { |
189 | | { 0x6754, "Start of Packet" }, |
190 | | { 0x4576, "End of Packet" }, |
191 | | { 0, NULL }, |
192 | | }; |
193 | | |
194 | | |
195 | | |
196 | | /******************************************************************************/ |
197 | | /* Dissect protocol */ |
198 | | |
199 | 0 | static proto_tree* dissect_psn_chunk_header(tvbuff_t *tvb, proto_tree *tree, proto_item** ti, unsigned* offset, unsigned* chunk_end, uint32_t* chunk_id, uint16_t* chunk_data_len, const int hf_chunk, const int ett_chunk, const int hf_chunk_id) { |
200 | 0 | *ti = proto_tree_add_item(tree, hf_chunk, tvb, *offset, -1, ENC_NA); |
201 | 0 | proto_tree *chunk_tree = proto_item_add_subtree(*ti, ett_chunk); |
202 | | |
203 | | /* Chunk Header */ |
204 | 0 | proto_tree_add_item_ret_uint(chunk_tree, hf_chunk_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN, chunk_id); |
205 | 0 | *offset+=2; |
206 | |
|
207 | 0 | *chunk_data_len = tvb_get_uint16(tvb, *offset, ENC_LITTLE_ENDIAN) & 0x7FFF; |
208 | 0 | proto_item_set_len(*ti, (*chunk_data_len)+4); |
209 | 0 | proto_tree_add_bitmask_with_flags(chunk_tree, tvb, *offset, hf_psn_chunk_data_field, ett_psn_chunk_data_field, chunk_data_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
210 | 0 | *offset+=2; |
211 | 0 | *chunk_end = (*offset)+(*chunk_data_len); |
212 | |
|
213 | 0 | return chunk_tree; |
214 | 0 | } |
215 | | |
216 | 0 | static int dissect_psn_data_tracker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) { |
217 | 0 | unsigned chunk_end; |
218 | 0 | uint32_t track_id; |
219 | 0 | uint16_t track_data_len; |
220 | 0 | proto_item *track_item; |
221 | 0 | proto_tree *track_tree = dissect_psn_chunk_header(tvb, tree, &track_item, &offset, &chunk_end, |
222 | 0 | &track_id, &track_data_len, hf_psn_tracker_data_chunk, ett_psn_tracker_data_chunk, hf_psn_tracker_data_chunk_id); |
223 | |
|
224 | 0 | const char* tracker_name = val_to_str_const(track_id, psn_tracker_data_names, "Unknown"); |
225 | 0 | proto_item_append_text(track_item, ": %s", tracker_name); |
226 | |
|
227 | 0 | switch (track_id) { |
228 | 0 | case PSN_DATA_TRACKER_POS: |
229 | 0 | proto_tree_add_item(track_tree, hf_psn_position_x, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
230 | 0 | offset+=4; |
231 | 0 | proto_tree_add_item(track_tree, hf_psn_position_y, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
232 | 0 | offset+=4; |
233 | 0 | proto_tree_add_item(track_tree, hf_psn_position_z, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
234 | 0 | offset+=4; |
235 | 0 | break; |
236 | 0 | case PSN_DATA_TRACKER_SPEED: |
237 | 0 | proto_tree_add_item(track_tree, hf_psn_speed_x, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
238 | 0 | offset+=4; |
239 | 0 | proto_tree_add_item(track_tree, hf_psn_speed_y, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
240 | 0 | offset+=4; |
241 | 0 | proto_tree_add_item(track_tree, hf_psn_speed_z, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
242 | 0 | offset+=4; |
243 | 0 | break; |
244 | 0 | case PSN_DATA_TRACKER_ORI: |
245 | 0 | proto_tree_add_item(track_tree, hf_psn_ori_x, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
246 | 0 | offset+=4; |
247 | 0 | proto_tree_add_item(track_tree, hf_psn_ori_y, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
248 | 0 | offset+=4; |
249 | 0 | proto_tree_add_item(track_tree, hf_psn_ori_z, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
250 | 0 | offset+=4; |
251 | 0 | break; |
252 | 0 | case PSN_DATA_TRACKER_STATUS: |
253 | 0 | proto_tree_add_item(track_tree, hf_psn_validity, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
254 | 0 | offset+=4; |
255 | 0 | break; |
256 | 0 | case PSN_DATA_TRACKER_ACCEL: |
257 | 0 | proto_tree_add_item(track_tree, hf_psn_accel_x, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
258 | 0 | offset+=4; |
259 | 0 | proto_tree_add_item(track_tree, hf_psn_accel_y, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
260 | 0 | offset+=4; |
261 | 0 | proto_tree_add_item(track_tree, hf_psn_accel_z, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
262 | 0 | offset+=4; |
263 | 0 | break; |
264 | 0 | case PSN_DATA_TRACKER_TRGTPOS: |
265 | 0 | proto_tree_add_item(track_tree, hf_psn_trgtpos_x, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
266 | 0 | offset+=4; |
267 | 0 | proto_tree_add_item(track_tree, hf_psn_trgtpos_y, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
268 | 0 | offset+=4; |
269 | 0 | proto_tree_add_item(track_tree, hf_psn_trgtpos_z, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
270 | 0 | offset+=4; |
271 | 0 | break; |
272 | 0 | case PSN_DATA_TRACKER_TIMESTAMP: |
273 | 0 | proto_tree_add_item(track_tree, hf_psn_tracker_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN|ENC_TIME_USECS); |
274 | 0 | offset+=8; |
275 | 0 | break; |
276 | 0 | default: |
277 | | /* Unknown chunk type */ |
278 | 0 | expert_add_info(pinfo, track_tree, &ei_psn_chunk_id); |
279 | 0 | return chunk_end; |
280 | 0 | } |
281 | | |
282 | 0 | if (offset != chunk_end) |
283 | 0 | expert_add_info(pinfo, track_tree, &ei_psn_chunk_len); |
284 | 0 | return chunk_end; |
285 | 0 | } |
286 | | |
287 | 0 | static int dissect_psn_data_tracker_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) { |
288 | 0 | unsigned chunk_end; |
289 | 0 | uint32_t tracker_id; |
290 | 0 | uint16_t chunk_data_len; |
291 | 0 | proto_item *chunk_item; |
292 | 0 | proto_tree *chunk_tree = dissect_psn_chunk_header(tvb, tree, &chunk_item, &offset, &chunk_end, |
293 | 0 | &tracker_id, &chunk_data_len, hf_psn_tracker_chunk, ett_psn_tracker_chunk, hf_psn_tracker_id); |
294 | |
|
295 | 0 | proto_item_append_text(chunk_item, ", tracker ID: %u", tracker_id); |
296 | |
|
297 | 0 | while (offset < chunk_end) { |
298 | 0 | offset = dissect_psn_data_tracker(tvb, pinfo, chunk_tree, offset); |
299 | 0 | } |
300 | |
|
301 | 0 | if (offset != chunk_end) |
302 | 0 | expert_add_info(pinfo, chunk_tree, &ei_psn_chunk_len); |
303 | 0 | return chunk_end; |
304 | 0 | } |
305 | | |
306 | 0 | static int dissect_psn_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) { |
307 | 0 | unsigned chunk_end; |
308 | 0 | uint32_t chunk_id; |
309 | 0 | uint16_t chunk_data_len; |
310 | 0 | proto_item *chunk_item; |
311 | 0 | proto_tree *chunk_tree = dissect_psn_chunk_header(tvb, tree, &chunk_item, &offset, &chunk_end, |
312 | 0 | &chunk_id, &chunk_data_len, hf_psn_data_chunk, ett_psn_data_chunk, hf_psn_data_chunk_id); |
313 | |
|
314 | 0 | switch (chunk_id) { |
315 | 0 | case PSN_DATA_PACKET_HEADER: { |
316 | 0 | proto_tree_add_item(chunk_tree, hf_psn_packet_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN|ENC_TIME_USECS); |
317 | 0 | offset+=8; |
318 | 0 | proto_tree_add_item(chunk_tree, hf_psn_version_high, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
319 | 0 | offset+=1; |
320 | 0 | proto_tree_add_item(chunk_tree, hf_psn_version_low, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
321 | 0 | offset+=1; |
322 | 0 | uint32_t frame_id; |
323 | 0 | proto_tree_add_item_ret_uint(chunk_tree, hf_psn_frame_id, tvb, offset, 1, ENC_LITTLE_ENDIAN, &frame_id); |
324 | 0 | offset+=1; |
325 | 0 | proto_tree_add_item(chunk_tree, hf_psn_frame_packet_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
326 | 0 | offset+=1; |
327 | |
|
328 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Frame %3u", frame_id); |
329 | 0 | proto_item_append_text(chunk_item, ": Header"); |
330 | 0 | break; |
331 | 0 | } |
332 | 0 | case PSN_DATA_TRACKER_LIST: { |
333 | 0 | unsigned tracker_count = 0; |
334 | 0 | while (offset < chunk_end) { |
335 | 0 | offset = dissect_psn_data_tracker_list(tvb, pinfo, chunk_tree, offset); |
336 | 0 | tracker_count++; |
337 | 0 | } |
338 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %u Trackers", tracker_count); |
339 | 0 | proto_item_append_text(chunk_item, ": Tracker List, %u trackers", tracker_count); |
340 | 0 | break; |
341 | 0 | } |
342 | 0 | default: |
343 | | /* Unknown Chunk Type */ |
344 | 0 | expert_add_info(pinfo, chunk_tree, &ei_psn_chunk_id); |
345 | 0 | return chunk_end; |
346 | 0 | } |
347 | | |
348 | 0 | if (offset != chunk_end) |
349 | 0 | expert_add_info(pinfo, chunk_tree, &ei_psn_chunk_len); |
350 | 0 | return chunk_end; |
351 | 0 | } |
352 | | |
353 | 0 | static int dissect_psn_info_tracker_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) { |
354 | 0 | unsigned chunk_end; |
355 | 0 | uint32_t tracker_id; |
356 | 0 | uint16_t chunk_data_len; |
357 | 0 | proto_item *chunk_item; |
358 | 0 | proto_tree *chunk_tree = dissect_psn_chunk_header(tvb, tree, &chunk_item, &offset, &chunk_end, |
359 | 0 | &tracker_id, &chunk_data_len, hf_psn_tracker_chunk, ett_psn_tracker_chunk, hf_psn_tracker_id); |
360 | |
|
361 | 0 | proto_item_append_text(chunk_item, ", tracker ID: %u", tracker_id); |
362 | |
|
363 | 0 | while (offset < chunk_end) { |
364 | 0 | unsigned name_chunk_end; |
365 | 0 | uint32_t name_id; |
366 | 0 | uint16_t name_data_len; |
367 | 0 | proto_item *name_item; |
368 | 0 | proto_tree *name_tree = dissect_psn_chunk_header(tvb, chunk_tree, &name_item, &offset, &name_chunk_end, |
369 | 0 | &name_id, &name_data_len, hf_psn_tracker_info_chunk, ett_psn_tracker_info_chunk, hf_psn_tracker_info_chunk_id); |
370 | |
|
371 | 0 | if (name_id == PSN_INFO_TRACKER_NAME) { |
372 | 0 | const uint8_t* tracker_name; |
373 | 0 | proto_tree_add_item_ret_string(name_tree, hf_psn_tracker_name, tvb, offset, name_data_len, ENC_ASCII, pinfo->pool, &tracker_name); |
374 | |
|
375 | 0 | proto_item_append_text(name_item, ": Tracker Name, %s", tracker_name); |
376 | 0 | } |
377 | | /* Skip all the data, even if unknown chunk */ |
378 | 0 | offset+=name_data_len; |
379 | 0 | } |
380 | |
|
381 | 0 | if (offset != chunk_end) |
382 | 0 | expert_add_info(pinfo, chunk_tree, &ei_psn_chunk_len); |
383 | 0 | return chunk_end; |
384 | 0 | } |
385 | | |
386 | 0 | static int dissect_psn_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) { |
387 | 0 | unsigned chunk_end; |
388 | 0 | uint32_t chunk_id; |
389 | 0 | uint16_t chunk_data_len; |
390 | 0 | proto_item *chunk_item; |
391 | 0 | proto_tree *chunk_tree = dissect_psn_chunk_header(tvb, tree, &chunk_item, &offset, &chunk_end, |
392 | 0 | &chunk_id, &chunk_data_len, hf_psn_info_chunk, ett_psn_info_chunk, hf_psn_info_chunk_id); |
393 | |
|
394 | 0 | switch (chunk_id) { |
395 | 0 | case PSN_INFO_PACKET_HEADER: { |
396 | 0 | proto_tree_add_item(chunk_tree, hf_psn_packet_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN|ENC_TIME_USECS); |
397 | 0 | offset+=8; |
398 | 0 | proto_tree_add_item(chunk_tree, hf_psn_version_high, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
399 | 0 | offset+=1; |
400 | 0 | proto_tree_add_item(chunk_tree, hf_psn_version_low, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
401 | 0 | offset+=1; |
402 | 0 | uint32_t frame_id; |
403 | 0 | proto_tree_add_item_ret_uint(chunk_tree, hf_psn_frame_id, tvb, offset, 1, ENC_LITTLE_ENDIAN, &frame_id); |
404 | 0 | offset+=1; |
405 | 0 | proto_tree_add_item(chunk_tree, hf_psn_frame_packet_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
406 | 0 | offset+=1; |
407 | |
|
408 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Frame %3u", frame_id); |
409 | 0 | proto_item_append_text(chunk_item, ": Header"); |
410 | 0 | break; |
411 | 0 | } |
412 | 0 | case PSN_INFO_SYSTEM_NAME: { |
413 | 0 | const uint8_t* name; |
414 | 0 | proto_tree_add_item_ret_string(chunk_tree, hf_psn_system_name, tvb, offset, chunk_data_len, ENC_ASCII, pinfo->pool, &name); |
415 | 0 | offset+=chunk_data_len; |
416 | |
|
417 | 0 | proto_item_append_text(chunk_item, ": System Name, %s", name); |
418 | 0 | break; |
419 | 0 | } |
420 | 0 | case PSN_INFO_TRACKER_LIST: { |
421 | 0 | unsigned tracker_count = 0; |
422 | 0 | while (offset < chunk_end) { |
423 | 0 | offset = dissect_psn_info_tracker_list(tvb, pinfo, chunk_tree, offset); |
424 | 0 | tracker_count++; |
425 | 0 | } |
426 | 0 | proto_item_append_text(chunk_item, ": Tracker List, %u trackers", tracker_count); |
427 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %u Trackers", tracker_count); |
428 | 0 | break; |
429 | 0 | } |
430 | 0 | default: |
431 | | /* Unknown Chunk Type */ |
432 | 0 | expert_add_info(pinfo, chunk_tree, &ei_psn_chunk_id); |
433 | 0 | return chunk_end; |
434 | 0 | } |
435 | | |
436 | 0 | if (offset != chunk_end) |
437 | 0 | expert_add_info(pinfo, chunk_tree, &ei_psn_chunk_len); |
438 | 0 | return chunk_end; |
439 | 0 | } |
440 | | |
441 | 0 | static int dissect_psn_v1_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) { |
442 | 0 | proto_tree_add_item(tree, hf_psn_v1_identifier, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
443 | 0 | offset+=2; |
444 | |
|
445 | 0 | proto_item* header = proto_tree_add_item(tree, hf_psn_v1_header, tvb, offset, 16, ENC_NA); |
446 | 0 | proto_tree* header_tree = proto_item_add_subtree(header, ett_psn_v1_header); |
447 | |
|
448 | 0 | proto_tree_add_item(header_tree, hf_psn_v1_packet_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
449 | 0 | offset+=4; |
450 | 0 | proto_tree_add_item(header_tree, hf_psn_version_high, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
451 | 0 | offset+=1; |
452 | 0 | proto_tree_add_item(header_tree, hf_psn_version_low, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
453 | 0 | offset+=1; |
454 | 0 | proto_tree_add_item(header_tree, hf_psn_v1_world_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
455 | 0 | offset+=2; |
456 | 0 | uint32_t tracker_count; |
457 | 0 | proto_tree_add_item_ret_uint(header_tree, hf_psn_v1_tracker_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &tracker_count); |
458 | 0 | offset+=2; |
459 | 0 | uint32_t frame_id; |
460 | 0 | proto_tree_add_item_ret_uint(header_tree, hf_psn_frame_id, tvb, offset, 1, ENC_LITTLE_ENDIAN, &frame_id); |
461 | 0 | offset+=1; |
462 | 0 | proto_tree_add_item(header_tree, hf_psn_frame_packet_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
463 | 0 | offset+=1; |
464 | 0 | proto_tree_add_item(header_tree, hf_psn_v1_frame_index, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
465 | 0 | offset+=1; |
466 | | /* reserved */ |
467 | 0 | proto_tree_add_item(header_tree, hf_psn_v1_reserved, tvb, offset, 3, ENC_NA); |
468 | 0 | offset+=3; |
469 | |
|
470 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Frame %3u, %u Trackers", frame_id, tracker_count); |
471 | |
|
472 | 0 | for (unsigned int i = 0; i < tracker_count; i++) { |
473 | 0 | proto_item* tracker = proto_tree_add_item(tree, hf_psn_v1_tracker, tvb, offset, 32, ENC_NA); |
474 | 0 | proto_tree* tracker_tree = proto_item_add_subtree(tracker, ett_psn_v1_tracker); |
475 | |
|
476 | 0 | uint32_t tracker_id; |
477 | 0 | proto_tree_add_item_ret_uint(tracker_tree, hf_psn_tracker_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &tracker_id); |
478 | 0 | offset+=2; |
479 | 0 | proto_tree_add_item(tracker_tree, hf_psn_v1_object_state, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
480 | 0 | offset+=2; |
481 | | /* reserved */ |
482 | 0 | proto_tree_add_item(tracker_tree, hf_psn_v1_reserved, tvb, offset, 4, ENC_NA); |
483 | 0 | offset+=4; |
484 | 0 | proto_tree_add_item(tracker_tree, hf_psn_position_x, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
485 | 0 | offset+=4; |
486 | 0 | proto_tree_add_item(tracker_tree, hf_psn_position_y, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
487 | 0 | offset+=4; |
488 | 0 | proto_tree_add_item(tracker_tree, hf_psn_position_z, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
489 | 0 | offset+=4; |
490 | 0 | proto_item_prepend_text( |
491 | 0 | proto_tree_add_item(tracker_tree, hf_psn_speed_x, tvb, offset, 4, ENC_LITTLE_ENDIAN), |
492 | 0 | "Speed "); |
493 | 0 | offset+=4; |
494 | 0 | proto_item_prepend_text( |
495 | 0 | proto_tree_add_item(tracker_tree, hf_psn_speed_y, tvb, offset, 4, ENC_LITTLE_ENDIAN), |
496 | 0 | "Speed "); |
497 | 0 | offset+=4; |
498 | 0 | proto_item_prepend_text( |
499 | 0 | proto_tree_add_item(tracker_tree, hf_psn_speed_z, tvb, offset, 4, ENC_LITTLE_ENDIAN), |
500 | 0 | "Speed "); |
501 | 0 | offset+=4; |
502 | |
|
503 | 0 | proto_item_append_text(tracker, ", ID: %u", tracker_id); |
504 | 0 | } |
505 | 0 | proto_tree_add_item(tree, hf_psn_v1_identifier, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
506 | 0 | offset+=2; |
507 | |
|
508 | 0 | return offset; |
509 | 0 | } |
510 | | |
511 | | static int |
512 | | dissect_psn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
513 | 1 | { |
514 | | /* Check it's a PSN packet */ |
515 | 1 | if (tvb_captured_length(tvb) < 2) { |
516 | 0 | return 0; |
517 | 0 | } |
518 | | |
519 | 1 | uint16_t chunk_id = tvb_get_uint16(tvb, 0, ENC_LITTLE_ENDIAN); |
520 | 1 | if (try_val_to_str(chunk_id, psn_base_chunk_id_names) == NULL) { |
521 | 1 | return 0; |
522 | 1 | } |
523 | | |
524 | 0 | unsigned offset = 0; |
525 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PSN"); |
526 | | /* Clear the info column */ |
527 | 0 | col_clear(pinfo->cinfo,COL_INFO); |
528 | |
|
529 | 0 | proto_item *ti = proto_tree_add_item(tree, proto_psn, tvb, 0, -1, ENC_NA); |
530 | 0 | proto_tree *psn_tree = proto_item_add_subtree(ti, ett_psn); |
531 | | |
532 | | /* Chunk Header */ |
533 | 0 | switch (chunk_id) { |
534 | 0 | case PSN_INFO_PACKET: |
535 | 0 | case PSN_DATA_PACKET: { |
536 | 0 | proto_tree_add_item(psn_tree, hf_psn_base_chunk_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
537 | 0 | offset+=2; |
538 | |
|
539 | 0 | uint16_t chunk_data_len = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN) & 0x7FFF; |
540 | 0 | proto_item_set_len(ti, chunk_data_len+4); |
541 | 0 | proto_tree_add_bitmask_with_flags(psn_tree, tvb, offset, hf_psn_chunk_data_field, ett_psn_chunk_data_field, chunk_data_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
542 | 0 | offset+=2; |
543 | 0 | unsigned chunk_end = offset+chunk_data_len; |
544 | |
|
545 | 0 | if (chunk_id == PSN_INFO_PACKET) { |
546 | 0 | proto_item_append_text(ti, ", V2 Info Packet"); |
547 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "PSN V2 Info"); |
548 | 0 | while (offset < chunk_end) { |
549 | 0 | offset = dissect_psn_info(tvb, pinfo, psn_tree, offset); |
550 | 0 | } |
551 | 0 | } else { |
552 | 0 | proto_item_append_text(ti, ", V2 Data Packet"); |
553 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "PSN V2 Data"); |
554 | 0 | while (offset < chunk_end) { |
555 | 0 | offset = dissect_psn_data(tvb, pinfo, psn_tree, offset); |
556 | 0 | } |
557 | 0 | } |
558 | 0 | return chunk_end; |
559 | 0 | } |
560 | 0 | case PSN_V1_DATA_PACKET: |
561 | 0 | proto_item_append_text(ti, ", V1 Data Packet"); |
562 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "PSN V1 Data"); |
563 | 0 | offset = dissect_psn_v1_data(tvb, pinfo, psn_tree, offset); |
564 | 0 | proto_item_set_len(ti, offset); |
565 | 0 | return offset; |
566 | 0 | case PSN_V1_INFO_PACKET: |
567 | 0 | if (tvb_strneql(tvb, 0, "<PSN>", 5) == 0) { |
568 | 0 | proto_item_append_text(ti, ", V1 Info Packet"); |
569 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "PSN V1 Info"); |
570 | 0 | } else if (tvb_strneql(tvb, 0, "<PSN_config>", 12) == 0) { |
571 | 0 | proto_item_append_text(ti, ", V1 Config Packet"); |
572 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "PSN V1 Config"); |
573 | 0 | } else if (tvb_strneql(tvb, 0, "<PSN_config_ACK>", 16) == 0) { |
574 | 0 | proto_item_append_text(ti, ", V1 Config Ack Packet"); |
575 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "PSN V1 Config Ack"); |
576 | 0 | } else { |
577 | 0 | proto_item_append_text(ti, ", V1 XML Packet"); |
578 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "PSN V1 XML"); |
579 | 0 | } |
580 | 0 | return call_dissector(xml_dissector_handle, tvb, pinfo, tree); |
581 | 0 | default: |
582 | | /* UNREACHABLE */ |
583 | 0 | return 0; |
584 | 0 | } |
585 | 0 | } |
586 | | |
587 | | /******************************************************************************/ |
588 | | /* Register protocol */ |
589 | | void |
590 | 15 | proto_register_psn(void) { |
591 | 15 | static hf_register_info hf[] = { |
592 | 15 | { &hf_psn_info_chunk, |
593 | 15 | { "Info Chunk", "psn.info", |
594 | 15 | FT_NONE, BASE_NONE, |
595 | 15 | NULL, 0x0, |
596 | 15 | NULL, HFILL } |
597 | 15 | }, |
598 | 15 | { &hf_psn_data_chunk, |
599 | 15 | { "Data Chunk", "psn.data", |
600 | 15 | FT_NONE, BASE_NONE, |
601 | 15 | NULL, 0x0, |
602 | 15 | NULL, HFILL } |
603 | 15 | }, |
604 | 15 | { &hf_psn_tracker_chunk, |
605 | 15 | { "Tracker Chunk", "psn.tracker", |
606 | 15 | FT_NONE, BASE_NONE, |
607 | 15 | NULL, 0x0, |
608 | 15 | NULL, HFILL } |
609 | 15 | }, |
610 | 15 | { &hf_psn_tracker_data_chunk, |
611 | 15 | { "Tracker Data Chunk", "psn.tracker.data", |
612 | 15 | FT_NONE, BASE_NONE, |
613 | 15 | NULL, 0x0, |
614 | 15 | NULL, HFILL } |
615 | 15 | }, |
616 | 15 | { &hf_psn_tracker_info_chunk, |
617 | 15 | { "Tracker Info Chunk", "psn.tracker.info", |
618 | 15 | FT_NONE, BASE_NONE, |
619 | 15 | NULL, 0x0, |
620 | 15 | NULL, HFILL } |
621 | 15 | }, |
622 | | |
623 | 15 | { &hf_psn_base_chunk_id, |
624 | 15 | { "Chunk ID", "psn.chunk_id", |
625 | 15 | FT_UINT16, BASE_HEX, |
626 | 15 | VALS(psn_base_chunk_id_names), 0x0, |
627 | 15 | NULL, HFILL } |
628 | 15 | }, |
629 | 15 | { &hf_psn_info_chunk_id, |
630 | 15 | { "Chunk ID", "psn.info.chunk_id", |
631 | 15 | FT_UINT16, BASE_HEX, |
632 | 15 | VALS(psn_info_chunk_id_names), 0x0, |
633 | 15 | NULL, HFILL } |
634 | 15 | }, |
635 | 15 | { &hf_psn_data_chunk_id, |
636 | 15 | { "Chunk ID", "psn.data.chunk_id", |
637 | 15 | FT_UINT16, BASE_HEX, |
638 | 15 | VALS(psn_data_chunk_id_names), 0x0, |
639 | 15 | NULL, HFILL } |
640 | 15 | }, |
641 | 15 | { &hf_psn_tracker_id, |
642 | 15 | { "Tracker ID", "psn.tracker.id", |
643 | 15 | FT_UINT16, BASE_DEC, |
644 | 15 | NULL, 0x0, |
645 | 15 | NULL, HFILL } |
646 | 15 | }, |
647 | 15 | { &hf_psn_tracker_data_chunk_id, |
648 | 15 | { "Chunk ID", "psn.tracker.data.chunk_id", |
649 | 15 | FT_UINT16, BASE_HEX, |
650 | 15 | VALS(psn_tracker_data_chunk_id_names), 0x0, |
651 | 15 | NULL, HFILL } |
652 | 15 | }, |
653 | 15 | { &hf_psn_tracker_info_chunk_id, |
654 | 15 | { "Chunk ID", "psn.tracker.info.chunk_id", |
655 | 15 | FT_UINT16, BASE_HEX, |
656 | 15 | VALS(psn_tracker_info_chunk_id_names), 0x0, |
657 | 15 | NULL, HFILL } |
658 | 15 | }, |
659 | | |
660 | 15 | { &hf_psn_chunk_data_field, |
661 | 15 | { "Chunk Header", "psn.chunk.header", |
662 | 15 | FT_UINT16, BASE_HEX, |
663 | 15 | NULL, 0x0, |
664 | 15 | NULL, HFILL } |
665 | 15 | }, |
666 | 15 | { &hf_psn_chunk_length, |
667 | 15 | { "Length", "psn.chunk.len", |
668 | 15 | FT_UINT16, BASE_DEC, |
669 | 15 | NULL, 0x7FFF, |
670 | 15 | NULL, HFILL } |
671 | 15 | }, |
672 | 15 | { &hf_psn_chunk_has_subchunks, |
673 | 15 | { "Has Sub Chunks", "psn.chunk.has_subchunks", |
674 | 15 | FT_BOOLEAN, 16, |
675 | 15 | TFS(&tfs_yes_no), 0x8000, |
676 | 15 | NULL, HFILL } |
677 | 15 | }, |
678 | | |
679 | 15 | { &hf_psn_packet_timestamp, |
680 | 15 | { "Timestamp", "psn.timestamp", |
681 | 15 | FT_RELATIVE_TIME, BASE_NONE, |
682 | 15 | NULL, 0x0, |
683 | 15 | NULL, HFILL } |
684 | 15 | }, |
685 | 15 | { &hf_psn_version_high, |
686 | 15 | { "Version High", "psn.version_high", |
687 | 15 | FT_UINT8, BASE_DEC, |
688 | 15 | NULL, 0x0, |
689 | 15 | NULL, HFILL } |
690 | 15 | }, |
691 | 15 | { &hf_psn_version_low, |
692 | 15 | { "Version Low", "psn.version_low", |
693 | 15 | FT_UINT8, BASE_DEC, |
694 | 15 | NULL, 0x0, |
695 | 15 | NULL, HFILL } |
696 | 15 | }, |
697 | 15 | { &hf_psn_frame_id, |
698 | 15 | { "Frame ID", "psn.frame_id", |
699 | 15 | FT_UINT8, BASE_DEC, |
700 | 15 | NULL, 0x0, |
701 | 15 | NULL, HFILL } |
702 | 15 | }, |
703 | 15 | { &hf_psn_frame_packet_count, |
704 | 15 | { "Frame Packet Count", "psn.frame_packet_count", |
705 | 15 | FT_UINT8, BASE_DEC, |
706 | 15 | NULL, 0x0, |
707 | 15 | NULL, HFILL } |
708 | 15 | }, |
709 | | |
710 | | |
711 | 15 | { &hf_psn_system_name, |
712 | 15 | { "System Name", "psn.info.system_name", |
713 | 15 | FT_STRING, BASE_NONE, |
714 | 15 | NULL, 0x0, |
715 | 15 | NULL, HFILL } |
716 | 15 | }, |
717 | 15 | { &hf_psn_tracker_name, |
718 | 15 | { "Tracker Name", "psn.tracker.info.name", |
719 | 15 | FT_STRING, BASE_NONE, |
720 | 15 | NULL, 0x0, |
721 | 15 | NULL, HFILL } |
722 | 15 | }, |
723 | | |
724 | 15 | { &hf_psn_position_x, |
725 | 15 | { "X", "psn.position.x", |
726 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
727 | 15 | UNS(&units_meters), 0x0, |
728 | 15 | NULL, HFILL } |
729 | 15 | }, |
730 | 15 | { &hf_psn_position_y, |
731 | 15 | { "Y", "psn.position.y", |
732 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
733 | 15 | UNS(&units_meters), 0x0, |
734 | 15 | NULL, HFILL } |
735 | 15 | }, |
736 | 15 | { &hf_psn_position_z, |
737 | 15 | { "Z", "psn.position.z", |
738 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
739 | 15 | UNS(&units_meters), 0x0, |
740 | 15 | NULL, HFILL } |
741 | 15 | }, |
742 | 15 | { &hf_psn_speed_x, |
743 | 15 | { "X", "psn.speed.x", |
744 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
745 | 15 | UNS(&units_m_s), 0x0, |
746 | 15 | NULL, HFILL } |
747 | 15 | }, |
748 | 15 | { &hf_psn_speed_y, |
749 | 15 | { "Y", "psn.speed.y", |
750 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
751 | 15 | UNS(&units_m_s), 0x0, |
752 | 15 | NULL, HFILL } |
753 | 15 | }, |
754 | 15 | { &hf_psn_speed_z, |
755 | 15 | { "Z", "psn.speed.z", |
756 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
757 | 15 | UNS(&units_m_s), 0x0, |
758 | 15 | NULL, HFILL } |
759 | 15 | }, |
760 | 15 | { &hf_psn_ori_x, |
761 | 15 | { "X", "psn.origin.x", |
762 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
763 | 15 | UNS(&units_meters), 0x0, |
764 | 15 | NULL, HFILL } |
765 | 15 | }, |
766 | 15 | { &hf_psn_ori_y, |
767 | 15 | { "Y", "psn.origin.y", |
768 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
769 | 15 | UNS(&units_meters), 0x0, |
770 | 15 | NULL, HFILL } |
771 | 15 | }, |
772 | 15 | { &hf_psn_ori_z, |
773 | 15 | { "Z", "psn.origin.z", |
774 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
775 | 15 | UNS(&units_meters), 0x0, |
776 | 15 | NULL, HFILL } |
777 | 15 | }, |
778 | 15 | { &hf_psn_accel_x, |
779 | 15 | { "X", "psn.acceleration.x", |
780 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
781 | 15 | UNS(&units_meter_sec_squared), 0x0, |
782 | 15 | NULL, HFILL } |
783 | 15 | }, |
784 | 15 | { &hf_psn_accel_y, |
785 | 15 | { "Y", "psn.acceleration.y", |
786 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
787 | 15 | UNS(&units_meter_sec_squared), 0x0, |
788 | 15 | NULL, HFILL } |
789 | 15 | }, |
790 | 15 | { &hf_psn_accel_z, |
791 | 15 | { "Z", "psn.acceleration.z", |
792 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
793 | 15 | UNS(&units_meter_sec_squared), 0x0, |
794 | 15 | NULL, HFILL } |
795 | 15 | }, |
796 | 15 | { &hf_psn_trgtpos_x, |
797 | 15 | { "X", "psn.target_pos.x", |
798 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
799 | 15 | UNS(&units_meters), 0x0, |
800 | 15 | NULL, HFILL } |
801 | 15 | }, |
802 | 15 | { &hf_psn_trgtpos_y, |
803 | 15 | { "Y", "psn.target_pos.y", |
804 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
805 | 15 | UNS(&units_meters), 0x0, |
806 | 15 | NULL, HFILL } |
807 | 15 | }, |
808 | 15 | { &hf_psn_trgtpos_z, |
809 | 15 | { "Z", "psn.target_pos.z", |
810 | 15 | FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, |
811 | 15 | UNS(&units_meters), 0x0, |
812 | 15 | NULL, HFILL } |
813 | 15 | }, |
814 | 15 | { &hf_psn_validity, |
815 | 15 | { "Validity", "psn.tracker.data.validity", |
816 | 15 | FT_FLOAT, BASE_NONE, |
817 | 15 | NULL, 0x0, |
818 | 15 | NULL, HFILL } |
819 | 15 | }, |
820 | 15 | { &hf_psn_tracker_timestamp, |
821 | 15 | { "Timestamp", "psn.tracker.data.timestamp", |
822 | 15 | FT_RELATIVE_TIME, BASE_NONE, |
823 | 15 | NULL, 0x0, |
824 | 15 | NULL, HFILL } |
825 | 15 | }, |
826 | | |
827 | 15 | { &hf_psn_v1_header, |
828 | 15 | { "Header", "psn.v1.header", |
829 | 15 | FT_NONE, BASE_NONE, |
830 | 15 | NULL, 0x0, |
831 | 15 | NULL, HFILL } |
832 | 15 | }, |
833 | 15 | { &hf_psn_v1_identifier, |
834 | 15 | { "Identifier", "psn.v1.identifier", |
835 | 15 | FT_UINT16, BASE_HEX, |
836 | 15 | VALS(psn_v1_identifier), 0x0, |
837 | 15 | NULL, HFILL } |
838 | 15 | }, |
839 | 15 | { &hf_psn_v1_tracker, |
840 | 15 | { "Tracker", "psn.v1.tracker", |
841 | 15 | FT_NONE, BASE_NONE, |
842 | 15 | NULL, 0x0, |
843 | 15 | NULL, HFILL } |
844 | 15 | }, |
845 | 15 | { &hf_psn_v1_position, |
846 | 15 | { "Position", "psn.v1.position", |
847 | 15 | FT_NONE, BASE_NONE, |
848 | 15 | NULL, 0x0, |
849 | 15 | NULL, HFILL } |
850 | 15 | }, |
851 | 15 | { &hf_psn_v1_velocity, |
852 | 15 | { "Velocity", "psn.v1.velocity", |
853 | 15 | FT_NONE, BASE_NONE, |
854 | 15 | NULL, 0x0, |
855 | 15 | NULL, HFILL } |
856 | 15 | }, |
857 | 15 | { &hf_psn_v1_packet_counter, |
858 | 15 | { "Packet Counter", "psn.v1.packet_counter", |
859 | 15 | FT_UINT32, BASE_DEC, |
860 | 15 | NULL, 0x0, |
861 | 15 | NULL, HFILL } |
862 | 15 | }, |
863 | 15 | { &hf_psn_v1_world_id, |
864 | 15 | { "World ID", "psn.v1.world_id", |
865 | 15 | FT_UINT32, BASE_DEC, |
866 | 15 | NULL, 0x0, |
867 | 15 | NULL, HFILL } |
868 | 15 | }, |
869 | 15 | { &hf_psn_v1_tracker_count, |
870 | 15 | { "Tracker Count", "psn.v1.tracker_count", |
871 | 15 | FT_UINT16, BASE_DEC, |
872 | 15 | NULL, 0x0, |
873 | 15 | NULL, HFILL } |
874 | 15 | }, |
875 | 15 | { &hf_psn_v1_frame_index, |
876 | 15 | { "Frame Index", "psn.v1.frame_index", |
877 | 15 | FT_UINT8, BASE_DEC, |
878 | 15 | NULL, 0x0, |
879 | 15 | NULL, HFILL } |
880 | 15 | }, |
881 | 15 | { &hf_psn_v1_object_state, |
882 | 15 | { "Object State", "psn.v1.object_state", |
883 | 15 | FT_UINT16, BASE_DEC, |
884 | 15 | NULL, 0x0, |
885 | 15 | NULL, HFILL } |
886 | 15 | }, |
887 | 15 | { &hf_psn_v1_info_xml, |
888 | 15 | { "V1 Info XML", "psn.v1.info_xml", |
889 | 15 | FT_STRING, BASE_NONE, |
890 | 15 | NULL, 0x0, |
891 | 15 | NULL, HFILL } |
892 | 15 | }, |
893 | 15 | { &hf_psn_v1_reserved, |
894 | 15 | { "Reserved", "psn.v1.reserved", |
895 | 15 | FT_BYTES, BASE_NONE, |
896 | 15 | NULL, 0x0, |
897 | 15 | NULL, HFILL } |
898 | 15 | }, |
899 | 15 | }; |
900 | | |
901 | | /* Setup protocol subtree array */ |
902 | 15 | static int *ett[] = { |
903 | 15 | &ett_psn, |
904 | | |
905 | 15 | &ett_psn_info_chunk, |
906 | 15 | &ett_psn_data_chunk, |
907 | 15 | &ett_psn_tracker_chunk, |
908 | 15 | &ett_psn_tracker_info_chunk, |
909 | 15 | &ett_psn_tracker_data_chunk, |
910 | | |
911 | 15 | &ett_psn_chunk_data_field, |
912 | | |
913 | 15 | &ett_psn_v1_header, |
914 | 15 | &ett_psn_v1_tracker, |
915 | 15 | }; |
916 | | |
917 | 15 | static ei_register_info ei[] = { |
918 | 15 | { &ei_psn_chunk_id, { "psn.chunk_id.unknown", PI_PROTOCOL, PI_ERROR, "Unknown chunk ID for this location", EXPFILL }}, |
919 | 15 | { &ei_psn_chunk_len, { "psn.chunk.len.mismatch", PI_PROTOCOL, PI_WARN, "Mismatch between reported chunk length and consumed data", EXPFILL }}, |
920 | 15 | }; |
921 | | |
922 | 15 | proto_psn = proto_register_protocol("PosiStageNet", "PSN", "psn"); |
923 | | |
924 | 15 | proto_register_field_array(proto_psn, hf, array_length(hf)); |
925 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
926 | 15 | expert_module_t* expert_psn = expert_register_protocol(proto_psn); |
927 | 15 | expert_register_field_array(expert_psn, ei, array_length(ei)); |
928 | | |
929 | 15 | psn_handle = register_dissector_with_description ( |
930 | 15 | "psn", /* dissector name */ |
931 | 15 | "PSN", /* dissector description */ |
932 | 15 | dissect_psn, /* dissector function */ |
933 | 15 | proto_psn /* protocol being dissected */ |
934 | 15 | ); |
935 | 15 | } |
936 | | |
937 | | /******************************************************************************/ |
938 | | /* Register handoff */ |
939 | | void |
940 | | proto_reg_handoff_psn(void) |
941 | 15 | { |
942 | 15 | dissector_add_uint_with_preference("udp.port", 56565, psn_handle); |
943 | | |
944 | 15 | xml_dissector_handle = find_dissector_add_dependency("xml", proto_psn); |
945 | 15 | } |
946 | | |
947 | | /* |
948 | | * Editor modelines |
949 | | * |
950 | | * Local Variables: |
951 | | * c-basic-offset: 4 |
952 | | * tab-width: 8 |
953 | | * indent-tabs-mode: nil |
954 | | * End: |
955 | | * |
956 | | * ex: set shiftwidth=4 tabstop=8 expandtab: |
957 | | * :indentSize=4:tabSize=8:noTabs=true: |
958 | | */ |