1 /* packet-ar_drone.c
2 * Routines for AR ar_drone protocol packet disassembly
3 * By Paul Hoisington <hoisingtonp@bit-sys.com>,
4 * Tom Hildesheim <hildesheimt@bit-sys.com>,
5 * and Claire Brantley <brantleyc@bit-sys.com>
6 * Copyright 2012 BIT Systems
7 *
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15 #include "config.h"
16
17 #include <epan/packet.h>
18 #include <epan/expert.h>
19
20 void proto_register_ar_drone(void);
21 void proto_reg_handoff_ar_drone(void);
22
23 /* ************************************************ */
24 /* Begin static variable declaration/initialization */
25 /* ************************************************ */
26
27 /* ar_drone Protocol */
28 static int proto_ar_drone = -1;
29
30 /* Headers */
31 static int hf_command = -1;
32 static int hf_PCMD_id = -1;
33 static int hf_PCMD_flag = -1;
34 static int hf_PCMD_roll = -1;
35 static int hf_PCMD_pitch = -1;
36 static int hf_PCMD_gaz = -1;
37 static int hf_PCMD_yaw = -1;
38 static int hf_REF_id = -1;
39 static int hf_REF_ctrl = -1;
40 static int hf_FTRIM_seq = -1;
41 static int hf_CONFIG_seq = -1;
42 static int hf_CONFIG_name = -1;
43 static int hf_CONFIG_val = -1;
44 static int hf_CONFIG_ID_seq = -1;
45 static int hf_CONFIG_ID_session = -1;
46 static int hf_CONFIG_ID_user = -1;
47 static int hf_CONFIG_ID_app = -1;
48 static int hf_COMWDG = -1;
49 static int hf_LED_seq = -1;
50 static int hf_LED_anim = -1;
51 static int hf_LED_freq = -1;
52 static int hf_LED_sec = -1;
53 static int hf_ANIM_seq = -1;
54 static int hf_ANIM_anim = -1;
55 static int hf_ANIM_sec = -1;
56 static int hf_CTRL_seq = -1;
57 static int hf_CTRL_mode = -1;
58 static int hf_CTRL_fsize = -1;
59
60 /**Subtrees */
61 static gint ett_FTRIM = -1;
62 static gint ett_ar_drone = -1;
63 static gint ett_PCMD = -1;
64 static gint ett_REF = -1;
65 static gint ett_CONFIG = -1;
66 static gint ett_CONFIG_ID = -1;
67 static gint ett_COMWDG = -1;
68 static gint ett_LED = -1;
69 static gint ett_ANIM = -1;
70 static gint ett_CTRL = -1;
71
72 static expert_field ei_NO_COMMA = EI_INIT;
73 static expert_field ei_NO_CR = EI_INIT;
74
75 /* Value String */
76 #if 0 /* TODO: Delete these? Or make use of them? */
77 static const value_string REF_types_vs[] = {
78 { 0x38323038, "FLYING MODE" },
79 { 0x37393532, "EMERGENCY LANDING" },
80 { 0x37363936, "LANDING MODE" },
81 { 0, NULL }
82 };
83 static const value_string PCMD_flag_vs[] = {
84 { 0x30 , "DO NOT ALLOW ROLL/PITCH" },
85 { 0x31 , "ALLOW ROLL/PITCH" },
86 { 0 , NULL }
87 };
88 #endif
89
90 static const string_string CTRL_mode_vs[] = {
91 { "4" , " (CFG_GET_CONTROL_MODE)" },
92 { "5" , " (ACK_CONTROL_MODE)" },
93 { "6" , " (CUSTOM_CFG_GET_CONTROL_MODE)" },
94 { 0, NULL }
95 };
96
97 /* ********************************************** */
98 /* End static variable declaration/initialization */
99 /* ********************************************** */
100 static int
dissect_ar_drone(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)101 dissect_ar_drone(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
102 {
103 gint offset, length;
104 gint master_offset = 0;
105 proto_item *ti, *sub_item;
106 proto_tree *ar_tree, *sub_tree;
107 char *command;
108 guint8 *complete_str;
109 guint32 dword;
110
111 if (tvb_captured_length(tvb) < 4)
112 return 0;
113
114 /* Make sure the packet we're dissecting is a ar_drone packet
115 * Cheap string check for 'AT*'
116 */
117 dword = tvb_get_ntoh24(tvb, 0);
118 if (dword != 0x41542a)
119 return 0;
120
121 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ar_drone");
122 col_set_str(pinfo->cinfo, COL_INFO, "AR Drone Packet");
123
124 /* Initialize ar_drone Packet tree with subtrees */
125 ti = proto_tree_add_item(tree, proto_ar_drone, tvb, 0, -1, ENC_NA);
126 ar_tree = proto_item_add_subtree(ti, ett_ar_drone);
127
128 while (tvb_reported_length_remaining(tvb, master_offset) > 3)
129 {
130 /* Get a string to compare our command strings (aka "AT*PCMD", etc.) to */
131 offset = tvb_find_guint8(tvb, master_offset, -1, '=');
132 if (offset < master_offset)
133 return master_offset;
134
135 command = tvb_get_string_enc(pinfo->pool, tvb, master_offset, offset-master_offset, ENC_ASCII|ENC_NA);
136 complete_str = tvb_get_string_enc(pinfo->pool, tvb, master_offset+3, offset-master_offset-3, ENC_ASCII|ENC_NA);
137 sub_item = proto_tree_add_string(ar_tree, hf_command, tvb, master_offset, -1, complete_str);
138
139 if (!strncmp(command, "AT*PCMD", 7))
140 {
141 /** Parse according the PCMD layout: */
142 guint8 PCMD_byte;
143 const char *PCMD_str;
144
145 sub_tree = proto_item_add_subtree(sub_item, ett_PCMD);
146
147 offset = master_offset + 8;
148
149 /* Add PCMD ID */
150 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
151 if (length < 0) {
152 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
153 return offset;
154 }
155 proto_tree_add_item(sub_tree, hf_PCMD_id, tvb, offset, length, ENC_ASCII|ENC_NA);
156 offset += (length + 1);
157
158 /* Add PCMD Flag */
159 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
160 if (length < 0) {
161 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
162 return offset;
163 }
164 proto_tree_add_item(sub_tree, hf_PCMD_flag, tvb, offset, length, ENC_ASCII|ENC_NA);
165 offset += (length + 1);
166
167 /* Add PCMD Roll */
168 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
169 if (length < 0) {
170 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
171 return offset;
172 }
173 ti = proto_tree_add_item(sub_tree, hf_PCMD_roll, tvb, offset, length, ENC_ASCII|ENC_NA);
174
175 PCMD_byte = tvb_get_guint8(tvb, offset);
176 if (PCMD_byte == 0x30)
177 {
178 PCMD_str = " (NO CHANGE)";
179 }
180 else if (PCMD_byte == 0x2d)
181 {
182 PCMD_byte = tvb_get_guint8(tvb, offset + 1);
183 if (PCMD_byte == 0x30)
184 {
185 PCMD_str = " (NO CHANGE)";
186 }
187 else
188 {
189 PCMD_str = " (ROLL LEFT)";
190 }
191 }
192 else
193 {
194 PCMD_str = " (ROLL RIGHT)";
195 }
196 proto_item_append_text(ti, "%s", PCMD_str);
197 offset += (length + 1);
198
199 /* Add PCMD Pitch */
200 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
201 if (length < 0) {
202 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
203 return offset;
204 }
205 ti = proto_tree_add_item(sub_tree, hf_PCMD_pitch, tvb, offset, length, ENC_ASCII|ENC_NA);
206
207 PCMD_byte = tvb_get_guint8(tvb, offset);
208 if (PCMD_byte == 0x30)
209 {
210 PCMD_str = " (NO CHANGE)";
211 }
212 else if (PCMD_byte == 0x2d)
213 {
214 PCMD_byte = tvb_get_guint8(tvb, offset + 1);
215 if (PCMD_byte == 0x30)
216 {
217 PCMD_str = " (NO CHANGE)";
218 }
219 else
220 {
221 PCMD_str = " (PITCH FORWARD)";
222 }
223 }
224 else
225 {
226 PCMD_str = " (PITCH BACKWARD)";
227 }
228 proto_item_append_text(ti, "%s", PCMD_str);
229 offset += (length + 1);
230
231 /* Add PCMD Gaz */
232 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
233 if (length < 0) {
234 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
235 return offset;
236 }
237 ti = proto_tree_add_item(sub_tree, hf_PCMD_gaz, tvb, offset, length, ENC_ASCII|ENC_NA);
238
239 PCMD_byte = tvb_get_guint8(tvb, offset);
240 if (PCMD_byte == 0x30)
241 {
242 PCMD_str = " (NO CHANGE)";
243 }
244 else if (PCMD_byte == 0x2d)
245 {
246 PCMD_byte = tvb_get_guint8(tvb, offset + 1);
247 if (PCMD_byte == 0x30)
248 {
249 PCMD_str = " (NO CHANGE)";
250 }
251 else
252 {
253 PCMD_str = " (DECREASE VERT SPEED)";
254 }
255 }
256 else
257 {
258 PCMD_str = " (INCREASE VERT SPEED)";
259 }
260 proto_item_append_text(ti, "%s", PCMD_str);
261 offset += (length + 1);
262
263 /* Add PCMD Yaw */
264 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
265 if (length < 0) {
266 expert_add_info(pinfo, sub_item, &ei_NO_CR);
267 return offset;
268 }
269 ti = proto_tree_add_item(sub_tree, hf_PCMD_yaw, tvb, offset, length, ENC_ASCII|ENC_NA);
270
271 PCMD_byte = tvb_get_guint8(tvb, offset);
272 if (PCMD_byte == 0x30)
273 {
274 PCMD_str = " (NO CHANGE)";
275 }
276 else if (PCMD_byte == 0x2d)
277 {
278 PCMD_byte = tvb_get_guint8(tvb, offset + 1);
279 if (PCMD_byte == 0x30)
280 {
281 PCMD_str = " (NO CHANGE)";
282 }
283 else
284 {
285 PCMD_str = " (ROTATE LEFT)";
286 }
287 }
288 else
289 {
290 PCMD_str = " (ROTATE RIGHT)";
291 }
292 proto_item_append_text(ti, "%s", PCMD_str);
293 offset += (length + 1);
294 }
295 else if (!strncmp(command, "AT*REF", 6))
296 {
297 /** Parse according to the REF layout: */
298 sub_tree = proto_item_add_subtree(sub_item, ett_REF);
299
300 offset = master_offset + 7;
301
302 /* Add REF ID */
303 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
304 if (length < 0) {
305 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
306 return offset;
307 }
308 proto_tree_add_item(sub_tree, hf_REF_id, tvb, offset, length, ENC_ASCII|ENC_NA);
309 offset += (length + 1);
310
311 /* Add REF ctrl */
312 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
313 if (length < 0) {
314 expert_add_info(pinfo, sub_item, &ei_NO_CR);
315 return offset;
316 }
317 proto_tree_add_item(sub_tree, hf_REF_ctrl, tvb, offset, length, ENC_ASCII|ENC_NA);
318 offset += (length + 1);
319
320 } else if (!strncmp(command, "AT*CONFIG_IDS", 13))
321 {
322 /** Parse according to the CONFIG_ID layout: */
323 sub_tree = proto_item_add_subtree(sub_item, ett_CONFIG_ID);
324
325 offset = master_offset + 14;
326
327 /* Add Sequence Number */
328 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
329 if (length < 0) {
330 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
331 return offset;
332 }
333 proto_tree_add_item(sub_tree, hf_CONFIG_ID_seq, tvb, offset, length, ENC_ASCII|ENC_NA);
334 offset += (length + 1);
335
336 /* Add Session ID */
337 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
338 if (length < 0) {
339 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
340 return offset;
341 }
342 proto_tree_add_item(sub_tree, hf_CONFIG_ID_session, tvb, offset, length, ENC_ASCII|ENC_NA);
343 offset += (length + 1);
344
345 /* Add User ID */
346 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
347 if (length < 0) {
348 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
349 return offset;
350 }
351 proto_tree_add_item(sub_tree, hf_CONFIG_ID_user, tvb, offset, length, ENC_ASCII|ENC_NA);
352 offset += (length + 1);
353
354 /* Add Application ID */
355 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
356 if (length < 0) {
357 expert_add_info(pinfo, sub_item, &ei_NO_CR);
358 return offset;
359 }
360 proto_tree_add_item(sub_tree, hf_CONFIG_ID_app, tvb, offset, length, ENC_ASCII|ENC_NA);
361 offset += (length + 1);
362
363 } else if (!strncmp(command, "AT*ANIM", 7))
364 {
365 /** Parse according to the ANIM layout: */
366 sub_tree = proto_item_add_subtree(sub_item, ett_ANIM);
367
368 offset = master_offset + 8;
369
370 /* Add sequence */
371 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
372 if (length < 0) {
373 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
374 return offset;
375 }
376 proto_tree_add_item(sub_tree, hf_ANIM_seq, tvb, offset, length, ENC_ASCII|ENC_NA);
377 offset += (length + 1);
378
379 /* Add Animation */
380 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
381 if (length < 0) {
382 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
383 return offset;
384 }
385 proto_tree_add_item(sub_tree, hf_ANIM_anim, tvb, offset, length, ENC_ASCII|ENC_NA);
386 offset += (length + 1);
387
388 /* Add animation time(sec) */
389 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
390 if (length < 0) {
391 expert_add_info(pinfo, sub_item, &ei_NO_CR);
392 return offset;
393 }
394 proto_tree_add_item(sub_tree, hf_ANIM_sec, tvb, offset, length, ENC_ASCII|ENC_NA);
395 offset += (length + 1);
396
397 } else if (!strncmp(command, "AT*FTRIM", 8))
398 {
399 /** Parse according to the FTRIM layout: */
400 sub_tree = proto_item_add_subtree(sub_item, ett_FTRIM);
401
402 offset = master_offset + 9;
403
404 /* Add sequence number */
405 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
406 if (length < 0) {
407 expert_add_info(pinfo, sub_item, &ei_NO_CR);
408 return offset;
409 }
410 proto_item_append_text(sub_item, " (Sets the reference for the horizontal plane)");
411 proto_tree_add_item(sub_tree, hf_FTRIM_seq, tvb, offset, length, ENC_ASCII|ENC_NA);
412 offset += (length + 1);
413 } else if (!strncmp(command, "AT*CONFIG", 9))
414 {
415 /** Parse according to the CONFIG layout: */
416 sub_tree = proto_item_add_subtree(sub_item, ett_CONFIG);
417
418 offset = master_offset + 10;
419
420 /* Add sequence */
421 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
422 if (length < 0) {
423 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
424 return offset;
425 }
426 proto_tree_add_item(sub_tree, hf_CONFIG_seq, tvb, offset, length, ENC_ASCII|ENC_NA);
427 offset += (length + 1);
428
429 /* Add Name */
430 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
431 if (length < 0) {
432 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
433 return offset;
434 }
435 proto_tree_add_item(sub_tree, hf_CONFIG_name, tvb, offset, length, ENC_ASCII|ENC_NA);
436 offset += (length + 1);
437
438 /* Add Value */
439 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
440 if (length < 0) {
441 expert_add_info(pinfo, sub_item, &ei_NO_CR);
442 return offset;
443 }
444 proto_tree_add_item(sub_tree, hf_CONFIG_val, tvb, offset, length, ENC_ASCII|ENC_NA);
445 offset += (length + 1);
446
447 } else if (!strncmp(command, "AT*LED", 6))
448 {
449 /** Parse according to the LED layout: */
450 sub_tree = proto_item_add_subtree(sub_item, ett_LED);
451
452 offset = master_offset + 7;
453
454 /* Add sequence */
455 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
456 if (length < 0) {
457 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
458 return offset;
459 }
460 proto_tree_add_item(sub_tree, hf_LED_seq, tvb, offset, length, ENC_ASCII|ENC_NA);
461 offset += (length + 1);
462
463 /* Add animation to play */
464 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
465 if (length < 0) {
466 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
467 return offset;
468 }
469 proto_tree_add_item(sub_tree, hf_LED_anim, tvb, offset, length, ENC_ASCII|ENC_NA);
470 offset += (length + 1);
471
472 /* Add frequency */
473 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
474 if (length < 0) {
475 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
476 return offset;
477 }
478 proto_tree_add_item(sub_tree, hf_LED_freq, tvb, offset, length, ENC_ASCII|ENC_NA);
479 offset += (length + 1);
480
481 /* Add Time to play in sec */
482 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
483 if (length < 0) {
484 expert_add_info(pinfo, sub_item, &ei_NO_CR);
485 return offset;
486 }
487 proto_tree_add_item(sub_tree, hf_LED_sec, tvb, offset, length, ENC_ASCII|ENC_NA);
488 offset += (length + 1);
489
490 } else if (!strncmp(command, "AT*COMWDG", 9))
491 {
492 /** Parse according to the COMWDG layout: */
493 sub_tree = proto_item_add_subtree(sub_item, ett_COMWDG);
494
495 offset = master_offset + 10;
496
497 /* Add sequence number */
498 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
499 if (length < 0) {
500 expert_add_info(pinfo, sub_item, &ei_NO_CR);
501 return offset;
502 }
503 proto_tree_add_item(sub_tree, hf_COMWDG, tvb, offset, length, ENC_ASCII|ENC_NA);
504 offset += (length + 1);
505
506 }else if (!strncmp(command, "AT*CTRL", 7))
507 {
508 const guint8* CTRL_mode_str;
509
510 /** Parse according to the CTRL layout: */
511 sub_tree = proto_item_add_subtree(sub_item, ett_CTRL);
512
513 offset = master_offset + 8;
514
515 /* Add sequence */
516 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
517 if (length < 0) {
518 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
519 return offset;
520 }
521 proto_tree_add_item(sub_tree, hf_CTRL_seq, tvb, offset, length, ENC_ASCII|ENC_NA);
522 offset += (length + 1);
523
524 /* Add Mode */
525 length = tvb_find_guint8(tvb, offset, -1, ',') - offset;
526 if (length < 0) {
527 expert_add_info(pinfo, sub_item, &ei_NO_COMMA);
528 return offset;
529 }
530 ti = proto_tree_add_item_ret_string(sub_tree, hf_CTRL_mode, tvb, offset, length, ENC_ASCII|ENC_NA, pinfo->pool, &CTRL_mode_str);
531 proto_item_append_text(ti, "%s", str_to_str(CTRL_mode_str, CTRL_mode_vs, " (Unknown Mode)"));
532 offset += (length + 1);
533
534 /* Add File Size */
535 length = tvb_find_guint8(tvb, offset, -1, 0x0d) - offset;
536 if (length < 0) {
537 expert_add_info(pinfo, sub_item, &ei_NO_CR);
538 return offset;
539 }
540 proto_tree_add_item(sub_tree, hf_CTRL_fsize, tvb, offset, length, ENC_ASCII|ENC_NA);
541 offset += (length + 1);
542 }
543 else
544 {
545 /* Unknown command, just abort */
546 return master_offset;
547 }
548
549 proto_item_set_len(sub_item, offset-master_offset);
550 master_offset = offset;
551 }
552
553 return master_offset;
554 }
555
556 void
proto_register_ar_drone(void)557 proto_register_ar_drone(void)
558 {
559 /* Setup protocol header array */
560 static hf_register_info hf[] = {
561 { &hf_command,
562 { "Command", "ar_drone.command",
563 FT_STRING, BASE_NONE,
564 NULL, 0x0,
565 NULL, HFILL }
566 },
567 { &hf_PCMD_id,
568 { "Sequence Number", "ar_drone.pcmd.id",
569 FT_STRING, BASE_NONE,
570 NULL, 0x0,
571 "Progressive Command ID", HFILL }
572 },
573 { &hf_PCMD_flag,
574 { "Flag", "ar_drone.pcmd.flag",
575 FT_STRING, BASE_NONE,
576 NULL/*VALS(PCMD_flag_vs)*/, 0x0,
577 "Progressive Command Flag", HFILL }
578 },
579 { &hf_PCMD_roll,
580 { "Roll", "ar_drone.pcmd.roll",
581 FT_STRING, BASE_NONE,
582 NULL, 0x0,
583 "Progressive Command Roll", HFILL }
584 },
585 { &hf_PCMD_pitch,
586 { "Pitch", "ar_drone.pcmd.pitch",
587 FT_STRING, BASE_NONE,
588 NULL, 0x0,
589 "Progressive Command Pitch", HFILL }
590 },
591 { &hf_PCMD_gaz,
592 { "Gaz", "ar_drone.pcmd.gaz",
593 FT_STRING, BASE_NONE,
594 NULL, 0x0,
595 "Progressive Command Gaz", HFILL }
596 },
597 { &hf_PCMD_yaw,
598 { "Yaw", "ar_drone.pcmd.yaw",
599 FT_STRING, BASE_NONE,
600 NULL, 0x0,
601 "Progressive Command Yaw", HFILL }
602 },
603 { &hf_REF_id,
604 { "Sequence Number", "ar_drone.ref.id",
605 FT_STRING, BASE_NONE,
606 NULL, 0x0,
607 "Reference ID", HFILL }
608 },
609 { &hf_REF_ctrl,
610 { "Control Command", "ar_drone.ref.ctrl",
611 FT_STRING, BASE_NONE,
612 NULL/*VALS(REF_types_vs)*/, 0x0,
613 NULL, HFILL }
614 },
615 { &hf_FTRIM_seq,
616 { "Sequence Number", "ar_drone.ftrim.seq",
617 FT_STRING, BASE_NONE,
618 NULL, 0x0,
619 "Flap Trim / Horizontal Plane Reference", HFILL }
620 },
621 { &hf_CONFIG_ID_seq,
622 { "Sequence Number", "ar_drone.configids.seq",
623 FT_STRING, BASE_NONE,
624 NULL, 0x0,
625 "Configuration ID sequence number", HFILL }
626 },
627 { &hf_CONFIG_ID_session,
628 { "Current Session ID", "ar_drone.configids.session",
629 FT_STRING, BASE_NONE,
630 NULL, 0x0,
631 "Configuration ID current session ID", HFILL }
632 },
633 { &hf_CONFIG_ID_user,
634 { "Current User ID", "ar_drone.configids.user",
635 FT_STRING, BASE_NONE,
636 NULL, 0x0,
637 "Configuration ID current user ID", HFILL }
638 },
639 { &hf_CONFIG_ID_app,
640 { "Current Application ID", "ar_drone.configids.app",
641 FT_STRING, BASE_NONE,
642 NULL, 0x0,
643 "Configuration ID current application ID", HFILL }
644 },
645 { &hf_COMWDG,
646 { "Command WatchDog Request", "ar_drone.comwdg",
647 FT_STRING, BASE_NONE,
648 NULL, 0x0,
649 "Command WatchDog Reset request", HFILL }
650 },
651 { &hf_CONFIG_seq,
652 { "Sequence Number", "ar_drone.config.seq",
653 FT_STRING, BASE_NONE,
654 NULL, 0x0,
655 "Configuration Seq Num", HFILL }
656 },
657 { &hf_CONFIG_name,
658 { "Option Name", "ar_drone.config.name",
659 FT_STRING, BASE_NONE,
660 NULL, 0x0,
661 NULL, HFILL }
662 },
663 { &hf_CONFIG_val,
664 { "Option Parameter", "ar_drone.config.val",
665 FT_STRING, BASE_NONE,
666 NULL, 0x0,
667 NULL, HFILL }
668 },
669 { &hf_LED_seq,
670 { "Sequence Number", "ar_drone.led.seq",
671 FT_STRING, BASE_NONE,
672 NULL, 0x0,
673 "LED Sequence Number", HFILL }
674 },
675 { &hf_LED_anim,
676 { "Selected Animation", "ar_drone.led.anim",
677 FT_STRING, BASE_NONE,
678 NULL, 0x0,
679 "Selected LED Animation", HFILL }
680 },
681 { &hf_LED_freq,
682 { "Animation Frequency", "ar_drone.led.freq",
683 FT_STRING, BASE_NONE,
684 NULL, 0x0,
685 "LED Animation Frequency", HFILL }
686 },
687 { &hf_LED_sec,
688 { "LED Animation Length (Seconds)", "ar_drone.led.sec",
689 FT_STRING, BASE_NONE,
690 NULL, 0x0,
691 "LED Anim Length", HFILL }
692 },
693 { &hf_ANIM_seq,
694 { "Animation Sequence Number", "ar_drone.anim.seq",
695 FT_STRING, BASE_NONE,
696 NULL, 0x0,
697 "Movement(Animation) Sequence #", HFILL }
698 },
699 { &hf_ANIM_anim,
700 { "Selected Animation Number", "ar_drone.anim.num",
701 FT_STRING, BASE_NONE,
702 NULL, 0x0,
703 "Movement(Animation) to Play", HFILL }
704 },
705 { &hf_ANIM_sec,
706 { "Animation Duration (seconds)", "ar_drone.anim.sec",
707 FT_STRING, BASE_NONE,
708 NULL, 0x0,
709 "Movement(Animation) Time in Seconds", HFILL }
710 },
711 { &hf_CTRL_seq,
712 { "Sequence Number", "ar_drone.ctrl.seq",
713 FT_STRING, BASE_NONE,
714 NULL, 0x0,
715 NULL, HFILL }
716 },
717 { &hf_CTRL_mode,
718 { "Control Mode", "ar_drone.ctrl.mode",
719 FT_STRING, BASE_NONE,
720 NULL, 0x0,
721 NULL, HFILL }
722 },
723 { &hf_CTRL_fsize,
724 { "Firmware Update File Size (0 for no update)", "ar_drone.ctrl.filesize",
725 FT_STRING, BASE_NONE,
726 NULL, 0x0,
727 NULL, HFILL }
728 }
729 };
730
731 /* Setup protocol subtree array */
732 static gint *ett[] = {
733 &ett_ar_drone,
734 &ett_PCMD,
735 &ett_REF,
736 &ett_FTRIM,
737 &ett_CONFIG,
738 &ett_CONFIG_ID,
739 &ett_COMWDG,
740 &ett_LED,
741 &ett_ANIM,
742 &ett_CTRL
743 };
744
745 static ei_register_info ei[] = {
746 { &ei_NO_COMMA, { "ar_drone.no_comma", PI_MALFORMED, PI_ERROR, "Comma delimiter not found", EXPFILL }},
747 { &ei_NO_CR, { "ar_drone.no_cr", PI_MALFORMED, PI_ERROR, "Carriage return delimiter (0x0d) not found", EXPFILL }},
748 };
749
750 expert_module_t* expert_drone;
751
752 /* Setup protocol info */
753 proto_ar_drone = proto_register_protocol("AR Drone Packet", "AR Drone", "ar_drone");
754
755 proto_register_field_array(proto_ar_drone, hf, array_length(hf));
756 proto_register_subtree_array(ett, array_length(ett));
757
758 expert_drone = expert_register_protocol(proto_ar_drone);
759 expert_register_field_array(expert_drone, ei, array_length(ei));
760 }
761
762 void
proto_reg_handoff_ar_drone(void)763 proto_reg_handoff_ar_drone(void)
764 {
765 dissector_handle_t ar_drone_handle;
766
767 ar_drone_handle = create_dissector_handle(dissect_ar_drone, proto_ar_drone);
768
769 heur_dissector_add("udp", dissect_ar_drone, "AR Drone over UDP", "ar_drone_udp", proto_ar_drone, HEURISTIC_ENABLE);
770 dissector_add_for_decode_as_with_preference("udp.port", ar_drone_handle);
771 }
772
773 /*
774 * Editor modelines - https://www.wireshark.org/tools/modelines.html
775 *
776 * Local variables:
777 * c-basic-offset: 4
778 * tab-width: 8
779 * indent-tabs-mode: nil
780 * End:
781 *
782 * vi: set shiftwidth=4 tabstop=8 expandtab:
783 * :indentSize=4:tabSize=8:noTabs=true:
784 */
785