Coverage Report

Created: 2026-06-30 07:22

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