Merge branch 'bluez_upgrade_5.52' of https://review.tizen.org/gerrit/p/platform/upstr...
[platform/upstream/bluez.git] / monitor / intel.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2011-2014  Intel Corporation
6  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2.1 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdio.h>
30 #include <inttypes.h>
31
32 #include "lib/bluetooth.h"
33 #include "lib/hci.h"
34
35 #include "src/shared/util.h"
36 #include "display.h"
37 #include "packet.h"
38 #include "lmp.h"
39 #include "ll.h"
40 #include "vendor.h"
41 #include "intel.h"
42
43 #define COLOR_UNKNOWN_EVENT_MASK        COLOR_WHITE_BG
44 #define COLOR_UNKNOWN_SCAN_STATUS       COLOR_WHITE_BG
45
46 static void print_status(uint8_t status)
47 {
48         packet_print_error("Status", status);
49 }
50
51 static void print_module(uint8_t module)
52 {
53         const char *str;
54
55         switch (module) {
56         case 0x01:
57                 str = "BC";
58                 break;
59         case 0x02:
60                 str = "HCI";
61                 break;
62         case 0x03:
63                 str = "LLC";
64                 break;
65         case 0x04:
66                 str = "OS";
67                 break;
68         case 0x05:
69                 str = "LM";
70                 break;
71         case 0x06:
72                 str = "SC";
73                 break;
74         case 0x07:
75                 str = "SP";
76                 break;
77         case 0x08:
78                 str = "OSAL";
79                 break;
80         case 0x09:
81                 str = "LC";
82                 break;
83         case 0x0a:
84                 str = "APP";
85                 break;
86         case 0x0b:
87                 str = "TLD";
88                 break;
89         case 0xf0:
90                 str = "Debug";
91                 break;
92         default:
93                 str = "Reserved";
94                 break;
95         }
96
97         print_field("Module: %s (0x%2.2x)", str, module);
98 }
99
100 static void null_cmd(const void *data, uint8_t size)
101 {
102 }
103
104 static void status_rsp(const void *data, uint8_t size)
105 {
106         uint8_t status = get_u8(data);
107
108         print_status(status);
109 }
110
111 static void reset_cmd(const void *data, uint8_t size)
112 {
113         uint8_t reset_type = get_u8(data);
114         uint8_t patch_enable = get_u8(data + 1);
115         uint8_t ddc_reload = get_u8(data + 2);
116         uint8_t boot_option = get_u8(data + 3);
117         uint32_t boot_addr = get_le32(data + 4);
118         const char *str;
119
120         switch (reset_type) {
121         case 0x00:
122                 str = "Soft software reset";
123                 break;
124         case 0x01:
125                 str = "Hard software reset";
126                 break;
127         default:
128                 str = "Reserved";
129                 break;
130         }
131
132         print_field("Reset type: %s (0x%2.2x)", str, reset_type);
133
134         switch (patch_enable) {
135         case 0x00:
136                 str = "Do not enable";
137                 break;
138         case 0x01:
139                 str = "Enable";
140                 break;
141         default:
142                 str = "Reserved";
143                 break;
144         }
145
146         print_field("Patch vectors: %s (0x%2.2x)", str, patch_enable);
147
148         switch (ddc_reload) {
149         case 0x00:
150                 str = "Do not reload";
151                 break;
152         case 0x01:
153                 str = "Reload from OTP";
154                 break;
155         default:
156                 str = "Reserved";
157                 break;
158         }
159
160         print_field("DDC parameters: %s (0x%2.2x)", str, ddc_reload);
161
162         switch (boot_option) {
163         case 0x00:
164                 str = "Current image";
165                 break;
166         case 0x01:
167                 str = "Specified address";
168                 break;
169         default:
170                 str = "Reserved";
171                 break;
172         }
173
174         print_field("Boot option: %s (0x%2.2x)", str, boot_option);
175         print_field("Boot address: 0x%8.8x", boot_addr);
176 }
177
178 static void read_version_rsp(const void *data, uint8_t size)
179 {
180         uint8_t status = get_u8(data);
181         uint8_t hw_platform = get_u8(data + 1);
182         uint8_t hw_variant = get_u8(data + 2);
183         uint8_t hw_revision = get_u8(data + 3);
184         uint8_t fw_variant = get_u8(data + 4);
185         uint8_t fw_revision = get_u8(data + 5);
186         uint8_t fw_build_nn = get_u8(data + 6);
187         uint8_t fw_build_cw = get_u8(data + 7);
188         uint8_t fw_build_yy = get_u8(data + 8);
189         uint8_t fw_patch = get_u8(data + 9);
190
191         print_status(status);
192         print_field("Hardware platform: 0x%2.2x", hw_platform);
193         print_field("Hardware variant: 0x%2.2x", hw_variant);
194         print_field("Hardware revision: %u.%u", hw_revision >> 4,
195                                                 hw_revision & 0x0f);
196         print_field("Firmware variant: 0x%2.2x", fw_variant);
197         print_field("Firmware revision: %u.%u", fw_revision >> 4,
198                                                 fw_revision & 0x0f);
199
200         print_field("Firmware build: %u-%u.%u", fw_build_nn,
201                                         fw_build_cw, 2000 + fw_build_yy);
202         print_field("Firmware patch: %u", fw_patch);
203 }
204
205 static void set_uart_baudrate_cmd(const void *data, uint8_t size)
206 {
207         uint8_t baudrate = get_u8(data);
208         const char *str;
209
210         switch (baudrate) {
211         case 0x00:
212                 str = "9600 Baud";
213                 break;
214         case 0x01:
215                 str = "19200 Baud";
216                 break;
217         case 0x02:
218                 str = "38400 Baud";
219                 break;
220         case 0x03:
221                 str = "57600 Baud";
222                 break;
223         case 0x04:
224                 str = "115200 Baud";
225                 break;
226         case 0x05:
227                 str = "230400 Baud";
228                 break;
229         case 0x06:
230                 str = "460800 Baud";
231                 break;
232         case 0x07:
233                 str = "921600 Baud";
234                 break;
235         case 0x08:
236                 str = "1843200 Baud";
237                 break;
238         case 0x09:
239                 str = "3250000 baud";
240                 break;
241         case 0x0a:
242                 str = "2000000 baud";
243                 break;
244         case 0x0b:
245                 str = "3000000 baud";
246                 break;
247         case 0x0c:
248                 str = "3714286 baud";
249                 break;
250         case 0x0d:
251                 str = "4333333 baud";
252                 break;
253         case 0x0e:
254                 str = "6500000 baud";
255                 break;
256         default:
257                 str = "Reserved";
258                 break;
259         }
260
261         print_field("Baudrate: %s (0x%2.2x)", str, baudrate);
262 }
263
264 static void secure_send_cmd(const void *data, uint8_t size)
265 {
266         uint8_t type = get_u8(data);
267         const char *str;
268
269         switch (type) {
270         case 0x00:
271                 str = "Init";
272                 break;
273         case 0x01:
274                 str = "Data";
275                 break;
276         case 0x02:
277                 str = "Sign";
278                 break;
279         case 0x03:
280                 str = "PKey";
281                 break;
282         default:
283                 str = "Reserved";
284                 break;
285         }
286
287         print_field("Type: %s fragment (0x%2.2x)", str, type);
288
289         packet_hexdump(data + 1, size - 1);
290 }
291
292 static void manufacturer_mode_cmd(const void *data, uint8_t size)
293 {
294         uint8_t mode = get_u8(data);
295         uint8_t reset = get_u8(data + 1);
296         const char *str;
297
298         switch (mode) {
299         case 0x00:
300                 str = "Disabled";
301                 break;
302         case 0x01:
303                 str = "Enabled";
304                 break;
305         default:
306                 str = "Reserved";
307                 break;
308         }
309
310         print_field("Mode switch: %s (0x%2.2x)", str, mode);
311
312         switch (reset) {
313         case 0x00:
314                 str = "No reset";
315                 break;
316         case 0x01:
317                 str = "Reset and deactivate patches";
318                 break;
319         case 0x02:
320                 str = "Reset and activate patches";
321                 break;
322         default:
323                 str = "Reserved";
324                 break;
325         }
326
327         print_field("Reset behavior: %s (0x%2.2x)", str, reset);
328 }
329
330 static void write_bd_data_cmd(const void *data, uint8_t size)
331 {
332         uint8_t features[8];
333
334         packet_print_addr("Address", data, false);
335         packet_hexdump(data + 6, 6);
336
337         memcpy(features, data + 12, 8);
338         packet_print_features_lmp(features, 0);
339
340         memcpy(features, data + 20, 1);
341         memset(features + 1, 0, 7);
342         packet_print_features_ll(features);
343
344         packet_hexdump(data + 21, size - 21);
345 }
346
347 static void read_bd_data_rsp(const void *data, uint8_t size)
348 {
349         uint8_t status = get_u8(data);
350
351         print_status(status);
352         packet_print_addr("Address", data + 1, false);
353         packet_hexdump(data + 7, size - 7);
354 }
355
356 static void write_bd_address_cmd(const void *data, uint8_t size)
357 {
358         packet_print_addr("Address", data, false);
359 }
360
361 static void act_deact_traces_cmd(const void *data, uint8_t size)
362 {
363         uint8_t tx = get_u8(data);
364         uint8_t tx_arq = get_u8(data + 1);
365         uint8_t rx = get_u8(data + 2);
366
367         print_field("Transmit traces: 0x%2.2x", tx);
368         print_field("Transmit ARQ: 0x%2.2x", tx_arq);
369         print_field("Receive traces: 0x%2.2x", rx);
370 }
371
372 static void stimulate_exception_cmd(const void *data, uint8_t size)
373 {
374         uint8_t type = get_u8(data);
375         const char *str;
376
377         switch (type) {
378         case 0x00:
379                 str = "Fatal Exception";
380                 break;
381         case 0x01:
382                 str = "Debug Exception";
383                 break;
384         default:
385                 str = "Reserved";
386                 break;
387         }
388
389         print_field("Type: %s (0x%2.2x)", str, type);
390 }
391
392 static const struct {
393         uint8_t bit;
394         const char *str;
395 } events_table[] = {
396         {  0, "Bootup"                  },
397         {  1, "SCO Rejected via LMP"    },
398         {  2, "PTT Switch Notification" },
399         {  7, "Scan Status"             },
400         {  9, "Debug Exception"         },
401         { 10, "Fatal Exception"         },
402         { 11, "System Exception"        },
403         { 13, "LE Link Established"     },
404         { 14, "FW Trace String"         },
405         { }
406 };
407
408 static void set_event_mask_cmd(const void *data, uint8_t size)
409 {
410         const uint8_t *events_array = data;
411         uint64_t mask, events = 0;
412         int i;
413
414         for (i = 0; i < 8; i++)
415                 events |= ((uint64_t) events_array[i]) << (i * 8);
416
417         print_field("Mask: 0x%16.16" PRIx64, events);
418
419         mask = events;
420
421         for (i = 0; events_table[i].str; i++) {
422                 if (events & (((uint64_t) 1) << events_table[i].bit)) {
423                         print_field("  %s", events_table[i].str);
424                         mask &= ~(((uint64_t) 1) << events_table[i].bit);
425                 }
426         }
427
428         if (mask)
429                 print_text(COLOR_UNKNOWN_EVENT_MASK, "  Unknown mask "
430                                                 "(0x%16.16" PRIx64 ")", mask);
431 }
432
433 static void ddc_config_write_cmd(const void *data, uint8_t size)
434 {
435         while (size > 0) {
436                 uint8_t param_len = get_u8(data);
437                 uint16_t param_id = get_le16(data + 1);
438
439                 print_field("Identifier: 0x%4.4x", param_id);
440                 packet_hexdump(data + 3, param_len - 2);
441
442                 data += param_len + 1;
443                 size -= param_len + 1;
444         }
445 }
446
447 static void ddc_config_write_rsp(const void *data, uint8_t size)
448 {
449         uint8_t status = get_u8(data);
450         uint16_t param_id = get_le16(data + 1);
451
452         print_status(status);
453         print_field("Identifier: 0x%4.4x", param_id);
454 }
455
456 static void memory_write_cmd(const void *data, uint8_t size)
457 {
458         uint32_t addr = get_le32(data);
459         uint8_t mode = get_u8(data + 4);
460         uint8_t length = get_u8(data + 5);
461         const char *str;
462
463         print_field("Address: 0x%8.8x", addr);
464
465         switch (mode) {
466         case 0x00:
467                 str = "Byte access";
468                 break;
469         case 0x01:
470                 str = "Half word access";
471                 break;
472         case 0x02:
473                 str = "Word access";
474                 break;
475         default:
476                 str = "Reserved";
477                 break;
478         }
479
480         print_field("Mode: %s (0x%2.2x)", str, mode);
481         print_field("Length: %u", length);
482
483         packet_hexdump(data + 6, size - 6);
484 }
485
486 static const struct vendor_ocf vendor_ocf_table[] = {
487         { 0x001, "Reset",
488                         reset_cmd, 8, true,
489                         status_rsp, 1, true },
490         { 0x002, "No Operation" },
491         { 0x005, "Read Version",
492                         null_cmd, 0, true,
493                         read_version_rsp, 10, true },
494         { 0x006, "Set UART Baudrate",
495                         set_uart_baudrate_cmd, 1, true,
496                         status_rsp, 1, true },
497         { 0x007, "Enable LPM" },
498         { 0x008, "PCM Write Configuration" },
499         { 0x009, "Secure Send",
500                         secure_send_cmd, 1, false,
501                         status_rsp, 1, true },
502         { 0x00d, "Read Secure Boot Params",
503                         null_cmd, 0, true },
504         { 0x00e, "Write Secure Boot Params" },
505         { 0x00f, "Unlock" },
506         { 0x010, "Change UART Baudrate" },
507         { 0x011, "Manufacturer Mode",
508                         manufacturer_mode_cmd, 2, true,
509                         status_rsp, 1, true },
510         { 0x012, "Read Link RSSI" },
511         { 0x022, "Get Exception Info" },
512         { 0x024, "Clear Exception Info" },
513         { 0x02f, "Write BD Data",
514                         write_bd_data_cmd, 6, false },
515         { 0x030, "Read BD Data",
516                         null_cmd, 0, true,
517                         read_bd_data_rsp, 7, false },
518         { 0x031, "Write BD Address",
519                         write_bd_address_cmd, 6, true,
520                         status_rsp, 1, true },
521         { 0x032, "Flow Specification" },
522         { 0x034, "Read Secure ID" },
523         { 0x038, "Set Synchronous USB Interface Type" },
524         { 0x039, "Config Synchronous Interface" },
525         { 0x03f, "SW RF Kill",
526                         null_cmd, 0, true,
527                         status_rsp, 1, true },
528         { 0x043, "Activate Deactivate Traces",
529                         act_deact_traces_cmd, 3, true },
530         { 0x04d, "Stimulate Exception",
531                         stimulate_exception_cmd, 1, true,
532                         status_rsp, 1, true },
533         { 0x050, "Read HW Version" },
534         { 0x052, "Set Event Mask",
535                         set_event_mask_cmd, 8, true,
536                         status_rsp, 1, true },
537         { 0x053, "Config_Link_Controller" },
538         { 0x089, "DDC Write" },
539         { 0x08a, "DDC Read" },
540         { 0x08b, "DDC Config Write",
541                         ddc_config_write_cmd, 3, false,
542                         ddc_config_write_rsp, 3, true },
543         { 0x08c, "DDC Config Read" },
544         { 0x08d, "Memory Read" },
545         { 0x08e, "Memory Write",
546                         memory_write_cmd, 6, false,
547                         status_rsp, 1, true },
548         { }
549 };
550
551 const struct vendor_ocf *intel_vendor_ocf(uint16_t ocf)
552 {
553         int i;
554
555         for (i = 0; vendor_ocf_table[i].str; i++) {
556                 if (vendor_ocf_table[i].ocf == ocf)
557                         return &vendor_ocf_table[i];
558         }
559
560         return NULL;
561 }
562
563 static void startup_evt(const void *data, uint8_t size)
564 {
565 }
566
567 static void fatal_exception_evt(const void *data, uint8_t size)
568 {
569         uint16_t line = get_le16(data);
570         uint8_t module = get_u8(data + 2);
571         uint8_t reason = get_u8(data + 3);
572
573         print_field("Line: %u", line);
574         print_module(module);
575         print_field("Reason: 0x%2.2x", reason);
576 }
577
578 static void bootup_evt(const void *data, uint8_t size)
579 {
580         uint8_t zero = get_u8(data);
581         uint8_t num_packets = get_u8(data + 1);
582         uint8_t source = get_u8(data + 2);
583         uint8_t reset_type = get_u8(data + 3);
584         uint8_t reset_reason = get_u8(data + 4);
585         uint8_t ddc_status = get_u8(data + 5);
586         const char *str;
587
588         print_field("Zero: 0x%2.2x", zero);
589         print_field("Number of packets: %d", num_packets);
590
591         switch (source) {
592         case 0x00:
593                 str = "Bootloader";
594                 break;
595         case 0x01:
596                 str = "Operational firmware";
597                 break;
598         case 0x02:
599                 str = "Self test firmware";
600                 break;
601         default:
602                 str = "Reserved";
603                 break;
604         }
605
606         print_field("Source: %s (0x%2.2x)", str, source);
607
608         switch (reset_type) {
609         case 0x00:
610                 str = "Hardware reset";
611                 break;
612         case 0x01:
613                 str = "Soft watchdog reset";
614                 break;
615         case 0x02:
616                 str = "Soft software reset";
617                 break;
618         case 0x03:
619                 str = "Hard watchdog reset";
620                 break;
621         case 0x04:
622                 str = "Hard software reset";
623                 break;
624         default:
625                 str = "Reserved";
626                 break;
627         }
628
629         print_field("Reset type: %s (0x%2.2x)", str, reset_type);
630
631         switch (reset_reason) {
632         case 0x00:
633                 str = "Power on";
634                 break;
635         case 0x01:
636                 str = "Reset command";
637                 break;
638         case 0x02:
639                 str = "Intel reset command";
640                 break;
641         case 0x03:
642                 str = "Watchdog";
643                 break;
644         case 0x04:
645                 str = "Fatal exception";
646                 break;
647         case 0x05:
648                 str = "System exception";
649                 break;
650         case 0xff:
651                 str = "Unknown";
652                 break;
653         default:
654                 str = "Reserved";
655                 break;
656         }
657
658         print_field("Reset reason: %s (0x%2.2x)", str, reset_reason);
659
660         switch (ddc_status) {
661         case 0x00:
662                 str = "Firmware default";
663                 break;
664         case 0x01:
665                 str = "Firmware default plus OTP";
666                 break;
667         case 0x02:
668                 str = "Persistent RAM";
669                 break;
670         case 0x03:
671                 str = "Not used";
672                 break;
673         default:
674                 str = "Reserved";
675                 break;
676         }
677
678         print_field("DDC status: %s (0x%2.2x)", str, ddc_status);
679 }
680
681 static void default_bd_data_evt(const void *data, uint8_t size)
682 {
683         uint8_t mem_status = get_u8(data);
684         const char *str;
685
686         switch (mem_status) {
687         case 0x02:
688                 str = "Invalid manufacturing data";
689                 break;
690         default:
691                 str = "Reserved";
692                 break;
693         }
694
695         print_field("Memory status: %s (0x%2.2x)", str, mem_status);
696 }
697
698 static void secure_send_commands_result_evt(const void *data, uint8_t size)
699 {
700         uint8_t result = get_u8(data);
701         uint16_t opcode = get_le16(data + 1);
702         uint16_t ogf = cmd_opcode_ogf(opcode);
703         uint16_t ocf = cmd_opcode_ocf(opcode);
704         uint8_t status = get_u8(data + 3);
705         const char *str;
706
707         switch (result) {
708         case 0x00:
709                 str = "Success";
710                 break;
711         case 0x01:
712                 str = "General failure";
713                 break;
714         case 0x02:
715                 str = "Hardware failure";
716                 break;
717         case 0x03:
718                 str = "Signature verification failed";
719                 break;
720         case 0x04:
721                 str = "Parsing error of command buffer";
722                 break;
723         case 0x05:
724                 str = "Command execution failure";
725                 break;
726         case 0x06:
727                 str = "Command parameters error";
728                 break;
729         case 0x07:
730                 str = "Command missing";
731                 break;
732         default:
733                 str = "Reserved";
734                 break;
735         }
736
737         print_field("Result: %s (0x%2.2x)", str, result);
738         print_field("Opcode: 0x%4.4x (0x%2.2x|0x%4.4x)", opcode, ogf, ocf);
739         print_status(status);
740 }
741
742 static void debug_exception_evt(const void *data, uint8_t size)
743 {
744         uint16_t line = get_le16(data);
745         uint8_t module = get_u8(data + 2);
746         uint8_t reason = get_u8(data + 3);
747
748         print_field("Line: %u", line);
749         print_module(module);
750         print_field("Reason: 0x%2.2x", reason);
751 }
752
753 static void le_link_established_evt(const void *data, uint8_t size)
754 {
755         uint16_t handle = get_le16(data);
756         uint32_t access_addr = get_le32(data + 10);
757
758         print_field("Handle: %u", handle);
759
760         packet_hexdump(data + 2, 8);
761
762         print_field("Access address: 0x%8.8x", access_addr);
763
764         packet_hexdump(data + 14, size - 14);
765 }
766
767 static void scan_status_evt(const void *data, uint8_t size)
768 {
769         uint8_t enable = get_u8(data);
770
771         print_field("Inquiry scan: %s",
772                                 (enable & 0x01) ? "Enabled" : "Disabled");
773         print_field("Page scan: %s",
774                                 (enable & 0x02) ? "Enabled" : "Disabled");
775
776         if (enable & 0xfc)
777                 print_text(COLOR_UNKNOWN_SCAN_STATUS,
778                                 "  Unknown status (0x%2.2x)", enable & 0xfc);
779
780 }
781
782 static void act_deact_traces_complete_evt(const void *data, uint8_t size)
783 {
784         uint8_t status = get_u8(data);
785
786         print_status(status);
787 }
788
789 static void lmp_pdu_trace_evt(const void *data, uint8_t size)
790 {
791         uint8_t type, len, id;
792         uint16_t handle, count;
793         uint32_t clock;
794         const char *str;
795
796         type = get_u8(data);
797         handle = get_le16(data + 1);
798
799         switch (type) {
800         case 0x00:
801                 str = "RX LMP";
802                 break;
803         case 0x01:
804                 str = "TX LMP";
805                 break;
806         case 0x02:
807                 str = "ACK LMP";
808                 break;
809         case 0x03:
810                 str = "RX LL";
811                 break;
812         case 0x04:
813                 str = "TX LL";
814                 break;
815         case 0x05:
816                 str = "ACK LL";
817                 break;
818         default:
819                 str = "Unknown";
820                 break;
821         }
822
823         print_field("Type: %s (0x%2.2x)", str, type);
824         print_field("Handle: %u", handle);
825
826         switch (type) {
827         case 0x00:
828                 len = size - 8;
829                 clock = get_le32(data + 4 + len);
830
831                 packet_hexdump(data + 3, 1);
832                 lmp_packet(data + 4, len, false);
833                 print_field("Clock: 0x%8.8x", clock);
834                 break;
835         case 0x01:
836                 len = size - 9;
837                 clock = get_le32(data + 4 + len);
838                 id = get_u8(data + 4 + len + 4);
839
840                 packet_hexdump(data + 3, 1);
841                 lmp_packet(data + 4, len, false);
842                 print_field("Clock: 0x%8.8x", clock);
843                 print_field("ID: 0x%2.2x", id);
844                 break;
845         case 0x02:
846                 clock = get_le32(data + 3);
847                 id = get_u8(data + 3 + 4);
848
849                 print_field("Clock: 0x%8.8x", clock);
850                 print_field("ID: 0x%2.2x", id);
851                 break;
852         case 0x03:
853                 len = size - 8;
854                 count = get_le16(data + 3);
855
856                 print_field("Count: 0x%4.4x", count);
857                 packet_hexdump(data + 3 + 2 + 1, 2);
858                 llcp_packet(data + 8, len, false);
859                 break;
860         case 0x04:
861                 len = size - 8;
862                 count = get_le16(data + 3);
863                 id = get_u8(data + 3 + 2);
864
865                 print_field("Count: 0x%4.4x", count);
866                 print_field("ID: 0x%2.2x", id);
867                 packet_hexdump(data + 3 + 2 + 1, 2);
868                 llcp_packet(data + 8, len, false);
869                 break;
870         case 0x05:
871                 count = get_le16(data + 3);
872                 id = get_u8(data + 3 + 2);
873
874                 print_field("Count: 0x%4.4x", count);
875                 print_field("ID: 0x%2.2x", id);
876                 break;
877         default:
878                 packet_hexdump(data + 3, size - 3);
879                 break;
880         }
881 }
882
883 static void write_bd_data_complete_evt(const void *data, uint8_t size)
884 {
885         uint8_t status = get_u8(data);
886
887         print_status(status);
888 }
889
890 static void sco_rejected_via_lmp_evt(const void *data, uint8_t size)
891 {
892         uint8_t reason = get_u8(data + 6);
893
894         packet_print_addr("Address", data, false);
895         packet_print_error("Reason", reason);
896 }
897
898 static void ptt_switch_notification_evt(const void *data, uint8_t size)
899 {
900         uint16_t handle = get_le16(data);
901         uint8_t table = get_u8(data + 2);
902         const char *str;
903
904         print_field("Handle: %u", handle);
905
906         switch (table) {
907         case 0x00:
908                 str = "Basic rate";
909                 break;
910         case 0x01:
911                 str = "Enhanced data rate";
912                 break;
913         default:
914                 str = "Reserved";
915                 break;
916         }
917
918         print_field("Packet type table: %s (0x%2.2x)", str, table);
919 }
920
921 static void system_exception_evt(const void *data, uint8_t size)
922 {
923         uint8_t type = get_u8(data);
924         const char *str;
925
926         switch (type) {
927         case 0x00:
928                 str = "No Exception";
929                 break;
930         case 0x01:
931                 str = "Undefined Instruction";
932                 break;
933         case 0x02:
934                 str = "Prefetch abort";
935                 break;
936         case 0x03:
937                 str = "Data abort";
938                 break;
939         default:
940                 str = "Reserved";
941                 break;
942         }
943
944         print_field("Type: %s (0x%2.2x)", str, type);
945
946         packet_hexdump(data + 1, size - 1);
947 }
948
949 static const struct vendor_evt vendor_evt_table[] = {
950         { 0x00, "Startup",
951                         startup_evt, 0, true },
952         { 0x01, "Fatal Exception",
953                         fatal_exception_evt, 4, true },
954         { 0x02, "Bootup",
955                         bootup_evt, 6, true },
956         { 0x05, "Default BD Data",
957                         default_bd_data_evt, 1, true },
958         { 0x06, "Secure Send Commands Result",
959                         secure_send_commands_result_evt, 4, true },
960         { 0x08, "Debug Exception",
961                         debug_exception_evt, 4, true },
962         { 0x0f, "LE Link Established",
963                         le_link_established_evt, 26, true },
964         { 0x11, "Scan Status",
965                         scan_status_evt, 1, true },
966         { 0x16, "Activate Deactivate Traces Complete",
967                         act_deact_traces_complete_evt, 1, true },
968         { 0x17, "LMP PDU Trace",
969                         lmp_pdu_trace_evt, 3, false },
970         { 0x19, "Write BD Data Complete",
971                         write_bd_data_complete_evt, 1, true },
972         { 0x25, "SCO Rejected via LMP",
973                         sco_rejected_via_lmp_evt, 7, true },
974         { 0x26, "PTT Switch Notification",
975                         ptt_switch_notification_evt, 3, true },
976         { 0x29, "System Exception",
977                         system_exception_evt, 133, true },
978         { 0x2c, "FW Trace String" },
979         { 0x2e, "FW Trace Binary" },
980         { }
981 };
982
983 const struct vendor_evt *intel_vendor_evt(uint8_t evt)
984 {
985         int i;
986
987         for (i = 0; vendor_evt_table[i].str; i++) {
988                 if (vendor_evt_table[i].evt == evt)
989                         return &vendor_evt_table[i];
990         }
991
992         return NULL;
993 }