device: Set disconnect timer to zero for fast disconnection
[platform/upstream/bluez.git] / monitor / analyze.c
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3  *
4  *  BlueZ - Bluetooth protocol stack for Linux
5  *
6  *  Copyright (C) 2011-2014  Intel Corporation
7  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
8  *
9  *
10  */
11
12 #ifdef HAVE_CONFIG_H
13 #include <config.h>
14 #endif
15
16 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
17 #define _GNU_SOURCE
18 #endif
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/time.h>
22 #include <unistd.h>
23
24 #include "lib/bluetooth.h"
25
26 #include "src/shared/util.h"
27 #include "src/shared/queue.h"
28 #include "src/shared/btsnoop.h"
29 #include "monitor/bt.h"
30 #include "monitor/display.h"
31 #include "monitor/packet.h"
32 #include "monitor/analyze.h"
33
34 #define TIMEVAL_MSEC(_tv) \
35         (long long)((_tv)->tv_sec * 1000 + (_tv)->tv_usec / 1000)
36
37 struct hci_dev {
38         uint16_t index;
39         uint8_t type;
40         uint8_t bdaddr[6];
41         struct timeval time_added;
42         struct timeval time_removed;
43         unsigned long num_hci;
44         unsigned long num_cmd;
45         unsigned long num_evt;
46         unsigned long num_acl;
47         unsigned long num_sco;
48         unsigned long num_iso;
49         unsigned long vendor_diag;
50         unsigned long system_note;
51         unsigned long user_log;
52         unsigned long ctrl_msg;
53         unsigned long unknown;
54         uint16_t manufacturer;
55         struct queue *conn_list;
56 };
57
58 #define CONN_BR_ACL     0x01
59 #define CONN_BR_SCO     0x02
60 #define CONN_BR_ESCO    0x03
61 #define CONN_LE_ACL     0x04
62 #define CONN_LE_ISO     0x05
63
64 struct hci_stats {
65         size_t bytes;
66         size_t num;
67         size_t num_comp;
68         struct packet_latency latency;
69         struct queue *plot;
70         uint16_t min;
71         uint16_t max;
72 };
73
74 struct hci_conn {
75         uint16_t handle;
76         uint16_t link;
77         uint8_t type;
78         uint8_t bdaddr[6];
79         bool setup_seen;
80         bool terminated;
81         struct queue *tx_queue;
82         struct timeval last_rx;
83         struct queue *chan_list;
84         struct hci_stats rx;
85         struct hci_stats tx;
86 };
87
88 struct hci_conn_tx {
89         struct timeval tv;
90         struct l2cap_chan *chan;
91 };
92
93 struct plot {
94         long long x_msec;
95         size_t y_count;
96 };
97
98 struct l2cap_chan {
99         uint16_t cid;
100         uint16_t psm;
101         bool out;
102         struct timeval last_rx;
103         struct hci_stats rx;
104         struct hci_stats tx;
105 };
106
107 static struct queue *dev_list;
108
109 static void tmp_write(void *data, void *user_data)
110 {
111         struct plot *plot = data;
112         FILE *tmp = user_data;
113
114         fprintf(tmp, "%lld %zu\n", plot->x_msec, plot->y_count);
115 }
116
117 static void plot_draw(struct queue *queue, const char *tittle)
118 {
119         FILE *gplot;
120
121         if (queue_length(queue) < 2)
122                 return;
123
124         gplot = popen("gnuplot", "w");
125         if (!gplot)
126                 return;
127
128         fprintf(gplot, "$data << EOD\n");
129         queue_foreach(queue, tmp_write, gplot);
130         fprintf(gplot, "EOD\n");
131
132         fprintf(gplot, "set terminal dumb enhanced ansi\n");
133         fprintf(gplot, "set xlabel 'Latency (ms)'\n");
134         fprintf(gplot, "set tics out nomirror\n");
135         fprintf(gplot, "set log y\n");
136         fprintf(gplot, "set yrange [0.5:*]\n");
137         fprintf(gplot, "plot $data using 1:2 t '%s' w impulses\n", tittle);
138         fflush(gplot);
139
140         pclose(gplot);
141 }
142
143 static void print_stats(struct hci_stats *stats, const char *label)
144 {
145         if (!stats->num)
146                 return;
147
148         print_field("%s packets: %zu/%zu", label, stats->num, stats->num_comp);
149         print_field("%s Latency: %lld-%lld msec (~%lld msec)", label,
150                         TV_MSEC(stats->latency.min),
151                         TV_MSEC(stats->latency.max),
152                         TV_MSEC(stats->latency.med));
153         print_field("%s size: %u-%u octets (~%zd octets)", label,
154                         stats->min, stats->max, stats->bytes / stats->num);
155
156         if (TV_MSEC(stats->latency.total))
157                 print_field("%s speed: ~%lld Kb/s", label,
158                         stats->bytes * 8 / TV_MSEC(stats->latency.total));
159
160         plot_draw(stats->plot, label);
161 }
162
163 static void chan_destroy(void *data)
164 {
165         struct l2cap_chan *chan = data;
166
167         if (!chan->rx.num && !chan->tx.num)
168                 goto done;
169
170         printf("  Found %s L2CAP channel with CID %u\n",
171                                         chan->out ? "TX" : "RX", chan->cid);
172         if (chan->psm)
173                 print_field("PSM %u", chan->psm);
174
175         print_stats(&chan->rx, "RX");
176         print_stats(&chan->tx, "TX");
177
178 done:
179         free(chan);
180 }
181
182 static struct l2cap_chan *chan_alloc(struct hci_conn *conn, uint16_t cid,
183                                                                 bool out)
184 {
185         struct l2cap_chan *chan;
186
187         chan = new0(struct l2cap_chan, 1);
188
189         chan->cid = cid;
190         chan->out = out;
191         chan->rx.plot = queue_new();
192         chan->tx.plot = queue_new();
193
194         return chan;
195 }
196
197 static bool chan_match_cid(const void *a, const void *b)
198 {
199         const struct l2cap_chan *chan = a;
200         uint32_t val = PTR_TO_UINT(b);
201         uint16_t cid = val & 0xffff;
202         bool out = val & 0x10000;
203
204         return chan->cid == cid && chan->out == out;
205 }
206
207 static struct l2cap_chan *chan_lookup(struct hci_conn *conn, uint16_t cid,
208                                                                 bool out)
209 {
210         struct l2cap_chan *chan;
211         uint32_t val = cid | (out ? 0x10000 : 0);
212
213         chan = queue_find(conn->chan_list, chan_match_cid, UINT_TO_PTR(val));
214         if (!chan) {
215                 chan = chan_alloc(conn, cid, out);
216                 queue_push_tail(conn->chan_list, chan);
217         }
218
219         return chan;
220 }
221
222 static void conn_destroy(void *data)
223 {
224         struct hci_conn *conn = data;
225         const char *str;
226
227         switch (conn->type) {
228         case CONN_BR_ACL:
229                 str = "BR-ACL";
230                 break;
231         case CONN_BR_SCO:
232                 str = "BR-SCO";
233                 break;
234         case CONN_BR_ESCO:
235                 str = "BR-ESCO";
236                 break;
237         case CONN_LE_ACL:
238                 str = "LE-ACL";
239                 break;
240         case CONN_LE_ISO:
241                 str = "LE-ISO";
242                 break;
243         default:
244                 str = "unknown";
245                 break;
246         }
247
248         printf("  Found %s connection with handle %u\n", str, conn->handle);
249         /* TODO: Store address type */
250         packet_print_addr("Address", conn->bdaddr, 0x00);
251         if (!conn->setup_seen)
252                 print_field("Connection setup missing");
253         print_stats(&conn->rx, "RX");
254         print_stats(&conn->tx, "TX");
255
256         queue_destroy(conn->rx.plot, free);
257         queue_destroy(conn->tx.plot, free);
258         queue_destroy(conn->chan_list, chan_destroy);
259
260         queue_destroy(conn->tx_queue, free);
261         free(conn);
262 }
263
264 static struct hci_conn *conn_alloc(struct hci_dev *dev, uint16_t handle,
265                                                                 uint8_t type)
266 {
267         struct hci_conn *conn;
268
269         conn = new0(struct hci_conn, 1);
270
271         conn->handle = handle;
272         conn->type = type;
273         conn->tx_queue = queue_new();
274         conn->tx.plot = queue_new();
275         conn->rx.plot = queue_new();
276
277         conn->chan_list = queue_new();
278
279         return conn;
280 }
281
282 static bool conn_match_handle(const void *a, const void *b)
283 {
284         const struct hci_conn *conn = a;
285         uint16_t handle = PTR_TO_UINT(b);
286
287         return (conn->handle == handle && !conn->terminated);
288 }
289
290 static struct hci_conn *conn_lookup(struct hci_dev *dev, uint16_t handle)
291 {
292         return queue_find(dev->conn_list, conn_match_handle,
293                                                 UINT_TO_PTR(handle));
294 }
295
296 static bool link_match_handle(const void *a, const void *b)
297 {
298         const struct hci_conn *conn = a;
299         uint16_t handle = PTR_TO_UINT(b);
300
301         return (conn->link == handle && !conn->terminated);
302 }
303
304 static struct hci_conn *link_lookup(struct hci_dev *dev, uint16_t handle)
305 {
306         return queue_find(dev->conn_list, link_match_handle,
307                                                 UINT_TO_PTR(handle));
308 }
309
310 static struct hci_conn *conn_lookup_type(struct hci_dev *dev, uint16_t handle,
311                                                                 uint8_t type)
312 {
313         struct hci_conn *conn;
314
315         conn = queue_find(dev->conn_list, conn_match_handle,
316                                                 UINT_TO_PTR(handle));
317         if (!conn || (type && conn->type != type)) {
318                 conn = conn_alloc(dev, handle, type);
319                 queue_push_tail(dev->conn_list, conn);
320         }
321
322         return conn;
323 }
324
325 static void dev_destroy(void *data)
326 {
327         struct hci_dev *dev = data;
328         const char *str;
329
330         switch (dev->type) {
331         case 0x00:
332                 str = "BR/EDR";
333                 break;
334         case 0x01:
335                 str = "AMP";
336                 break;
337         default:
338                 str = "unknown";
339                 break;
340         }
341
342         printf("Found %s controller with index %u\n", str, dev->index);
343         printf("  BD_ADDR %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
344                         dev->bdaddr[5], dev->bdaddr[4], dev->bdaddr[3],
345                         dev->bdaddr[2], dev->bdaddr[1], dev->bdaddr[0]);
346         if (dev->manufacturer != 0xffff)
347                 printf(" (%s)", bt_compidtostr(dev->manufacturer));
348         printf("\n");
349
350
351         printf("  %lu commands\n", dev->num_cmd);
352         printf("  %lu events\n", dev->num_evt);
353         printf("  %lu ACL packets\n", dev->num_acl);
354         printf("  %lu SCO packets\n", dev->num_sco);
355         printf("  %lu ISO packets\n", dev->num_iso);
356         printf("  %lu vendor diagnostics\n", dev->vendor_diag);
357         printf("  %lu system notes\n", dev->system_note);
358         printf("  %lu user logs\n", dev->user_log);
359         printf("  %lu control messages \n", dev->ctrl_msg);
360         printf("  %lu unknown opcodes\n", dev->unknown);
361         queue_destroy(dev->conn_list, conn_destroy);
362         printf("\n");
363
364         free(dev);
365 }
366
367 static struct hci_dev *dev_alloc(uint16_t index)
368 {
369         struct hci_dev *dev;
370
371         dev = new0(struct hci_dev, 1);
372
373         dev->index = index;
374         dev->manufacturer = 0xffff;
375
376         dev->conn_list = queue_new();
377
378         return dev;
379 }
380
381 static bool dev_match_index(const void *a, const void *b)
382 {
383         const struct hci_dev *dev = a;
384         uint16_t index = PTR_TO_UINT(b);
385
386         return dev->index == index;
387 }
388
389 static struct hci_dev *dev_lookup(uint16_t index)
390 {
391         struct hci_dev *dev;
392
393         dev = queue_find(dev_list, dev_match_index, UINT_TO_PTR(index));
394         if (!dev) {
395                 dev = dev_alloc(index);
396                 queue_push_tail(dev_list, dev);
397         }
398
399         return dev;
400 }
401
402 static void l2cap_sig(struct hci_conn *conn, bool out,
403                                         const void *data, uint16_t size)
404 {
405         const struct bt_l2cap_hdr_sig *hdr = data;
406         struct l2cap_chan *chan;
407         uint16_t psm, scid, dcid;
408
409         switch (hdr->code) {
410         case BT_L2CAP_PDU_CONN_REQ:
411                 psm = get_le16(data + 4);
412                 scid = get_le16(data + 6);
413                 chan = chan_lookup(conn, scid, out);
414                 if (chan)
415                         chan->psm = psm;
416                 break;
417         case BT_L2CAP_PDU_CONN_RSP:
418                 dcid = get_le16(data + 4);
419                 scid = get_le16(data + 6);
420                 chan = chan_lookup(conn, scid, !out);
421                 if (chan) {
422                         psm = chan->psm;
423                         chan = chan_lookup(conn, dcid, out);
424                         if (chan)
425                                 chan->psm = psm;
426                 }
427                 break;
428         }
429 }
430
431 static void new_index(struct timeval *tv, uint16_t index,
432                                         const void *data, uint16_t size)
433 {
434         const struct btsnoop_opcode_new_index *ni = data;
435         struct hci_dev *dev;
436
437         dev = dev_alloc(index);
438
439         dev->type = ni->type;
440         memcpy(dev->bdaddr, ni->bdaddr, 6);
441
442         queue_push_tail(dev_list, dev);
443 }
444
445 static void del_index(struct timeval *tv, uint16_t index,
446                                         const void *data, uint16_t size)
447 {
448         struct hci_dev *dev;
449
450         dev = queue_remove_if(dev_list, dev_match_index, UINT_TO_PTR(index));
451         if (!dev) {
452                 fprintf(stderr, "Remove for an unexisting device\n");
453                 return;
454         }
455
456         dev_destroy(dev);
457 }
458
459 static void command_pkt(struct timeval *tv, uint16_t index,
460                                         const void *data, uint16_t size)
461 {
462         struct hci_dev *dev;
463
464         dev = dev_lookup(index);
465         if (!dev)
466                 return;
467
468         dev->num_hci++;
469         dev->num_cmd++;
470 }
471
472 static void evt_conn_complete(struct hci_dev *dev, struct timeval *tv,
473                                         const void *data, uint16_t size)
474 {
475         const struct bt_hci_evt_conn_complete *evt = data;
476         struct hci_conn *conn;
477
478         if (evt->status)
479                 return;
480
481         conn = conn_lookup_type(dev, le16_to_cpu(evt->handle), CONN_BR_ACL);
482         if (!conn)
483                 return;
484
485         memcpy(conn->bdaddr, evt->bdaddr, 6);
486         conn->setup_seen = true;
487 }
488
489 static void evt_disconnect_complete(struct hci_dev *dev, struct timeval *tv,
490                                         const void *data, uint16_t size)
491 {
492         const struct bt_hci_evt_disconnect_complete *evt = data;
493         struct hci_conn *conn;
494
495         if (evt->status)
496                 return;
497
498         conn = conn_lookup(dev, le16_to_cpu(evt->handle));
499         if (!conn)
500                 return;
501
502         conn->terminated = true;
503 }
504
505 static void rsp_read_bd_addr(struct hci_dev *dev, struct timeval *tv,
506                                         const void *data, uint16_t size)
507 {
508         const struct bt_hci_rsp_read_bd_addr *rsp = data;
509
510         if (rsp->status)
511                 return;
512
513         memcpy(dev->bdaddr, rsp->bdaddr, 6);
514 }
515
516 static void evt_cmd_complete(struct hci_dev *dev, struct timeval *tv,
517                                         const void *data, uint16_t size)
518 {
519         const struct bt_hci_evt_cmd_complete *evt = data;
520         uint16_t opcode;
521
522         data += sizeof(*evt);
523         size -= sizeof(*evt);
524
525         opcode = le16_to_cpu(evt->opcode);
526
527         switch (opcode) {
528         case BT_HCI_CMD_READ_BD_ADDR:
529                 rsp_read_bd_addr(dev, tv, data, size);
530                 break;
531         }
532 }
533
534 static bool match_plot_latency(const void *data, const void *user_data)
535 {
536         const struct plot *plot = data;
537         const struct timeval *latency = user_data;
538
539         return TIMEVAL_MSEC(latency) == plot->x_msec;
540 }
541
542 static void plot_add(struct queue *queue, struct timeval *latency,
543                                                 uint16_t count)
544 {
545         struct plot *plot;
546
547         /* Use LRU ordering */
548         plot = queue_remove_if(queue, match_plot_latency, latency);
549         if (plot) {
550                 plot->y_count += count;
551                 queue_push_head(queue, plot);
552                 return;
553         }
554
555         plot = new0(struct plot, 1);
556         plot->x_msec = TIMEVAL_MSEC(latency);
557         plot->y_count = count;
558
559         queue_push_tail(queue, plot);
560 }
561
562 static void evt_le_conn_complete(struct hci_dev *dev, struct timeval *tv,
563                                         struct iovec *iov)
564 {
565         const struct bt_hci_evt_le_conn_complete *evt;
566         struct hci_conn *conn;
567
568         evt = util_iov_pull_mem(iov, sizeof(*evt));
569         if (!evt || evt->status)
570                 return;
571
572         conn = conn_lookup_type(dev, le16_to_cpu(evt->handle), CONN_LE_ACL);
573         if (!conn)
574                 return;
575
576         memcpy(conn->bdaddr, evt->peer_addr, 6);
577         conn->setup_seen = true;
578 }
579
580 static void evt_le_enh_conn_complete(struct hci_dev *dev, struct timeval *tv,
581                                         struct iovec *iov)
582 {
583         const struct bt_hci_evt_le_enhanced_conn_complete *evt;
584         struct hci_conn *conn;
585
586         evt = util_iov_pull_mem(iov, sizeof(*evt));
587         if (!evt || evt->status)
588                 return;
589
590         conn = conn_lookup_type(dev, le16_to_cpu(evt->handle), CONN_LE_ACL);
591         if (!conn)
592                 return;
593
594         memcpy(conn->bdaddr, evt->peer_addr, 6);
595         conn->setup_seen = true;
596 }
597
598 static void evt_num_completed_packets(struct hci_dev *dev, struct timeval *tv,
599                                         const void *data, uint16_t size)
600 {
601         uint8_t num_handles = get_u8(data);
602         int i;
603
604         data += sizeof(num_handles);
605         size -= sizeof(num_handles);
606
607         for (i = 0; i < num_handles; i++) {
608                 uint16_t handle = get_le16(data);
609                 uint16_t count = get_le16(data + 2);
610                 struct hci_conn *conn;
611                 struct timeval res;
612                 struct hci_conn_tx *last_tx;
613                 int j;
614
615                 data += 4;
616                 size -= 4;
617
618                 conn = conn_lookup(dev, handle);
619                 if (!conn)
620                         continue;
621
622                 conn->tx.num_comp += count;
623
624                 for (j = 0; j < count; j++) {
625                         last_tx = queue_pop_head(conn->tx_queue);
626                         if (last_tx) {
627                                 struct l2cap_chan *chan = last_tx->chan;
628
629                                 timersub(tv, &last_tx->tv, &res);
630
631                                 packet_latency_add(&conn->tx.latency, &res);
632                                 plot_add(conn->tx.plot, &res, 1);
633
634                                 if (chan) {
635                                         chan->tx.num_comp += count;
636                                         packet_latency_add(&chan->tx.latency,
637                                                                         &res);
638                                         plot_add(chan->tx.plot, &res, 1);
639                                 }
640
641                                 free(last_tx);
642                         }
643                 }
644         }
645 }
646
647 static void evt_sync_conn_complete(struct hci_dev *dev, struct timeval *tv,
648                                         const void *data, uint16_t size)
649 {
650         const struct bt_hci_evt_sync_conn_complete *evt = data;
651         struct hci_conn *conn;
652
653         if (evt->status)
654                 return;
655
656         conn = conn_lookup_type(dev, le16_to_cpu(evt->handle), evt->link_type);
657         if (!conn)
658                 return;
659
660         memcpy(conn->bdaddr, evt->bdaddr, 6);
661         conn->setup_seen = true;
662 }
663
664 static void evt_le_cis_established(struct hci_dev *dev, struct timeval *tv,
665                                         struct iovec *iov)
666 {
667         const struct bt_hci_evt_le_cis_established *evt;
668         struct hci_conn *conn, *link;
669
670         evt = util_iov_pull_mem(iov, sizeof(*evt));
671         if (!evt || evt->status)
672                 return;
673
674         conn = conn_lookup_type(dev, le16_to_cpu(evt->conn_handle),
675                                                 CONN_LE_ISO);
676         if (!conn)
677                 return;
678
679         conn->setup_seen = true;
680
681         link = link_lookup(dev, conn->handle);
682         if (link)
683                 memcpy(conn->bdaddr, link->bdaddr, 6);
684 }
685
686 static void evt_le_cis_req(struct hci_dev *dev, struct timeval *tv,
687                                         struct iovec *iov)
688 {
689         const struct bt_hci_evt_le_cis_req *evt;
690         struct hci_conn *conn;
691
692         evt = util_iov_pull_mem(iov, sizeof(*evt));
693         if (!evt)
694                 return;
695
696         conn = conn_lookup(dev, le16_to_cpu(evt->acl_handle));
697         if (!conn)
698                 return;
699
700         conn->link = le16_to_cpu(evt->cis_handle);
701 }
702
703 static void evt_le_big_complete(struct hci_dev *dev, struct timeval *tv,
704                                         struct iovec *iov)
705 {
706         const struct bt_hci_evt_le_big_complete *evt;
707         int i;
708
709         evt = util_iov_pull_mem(iov, sizeof(*evt));
710         if (!evt || evt->status)
711                 return;
712
713         for (i = 0; i < evt->num_bis; i++) {
714                 struct hci_conn *conn;
715                 uint16_t handle;
716
717                 if (!util_iov_pull_le16(iov, &handle))
718                         return;
719
720                 conn = conn_lookup_type(dev, handle, CONN_LE_ISO);
721                 if (conn)
722                         conn->setup_seen = true;
723         }
724 }
725
726 static void evt_le_big_sync_established(struct hci_dev *dev, struct timeval *tv,
727                                         struct iovec *iov)
728 {
729         const struct bt_hci_evt_le_big_sync_estabilished *evt;
730         int i;
731
732         evt = util_iov_pull_mem(iov, sizeof(*evt));
733         if (!evt || evt->status)
734                 return;
735
736         for (i = 0; i < evt->num_bis; i++) {
737                 struct hci_conn *conn;
738                 uint16_t handle;
739
740                 if (!util_iov_pull_le16(iov, &handle))
741                         return;
742
743                 conn = conn_lookup_type(dev, handle, CONN_LE_ISO);
744                 if (conn)
745                         conn->setup_seen = true;
746         }
747 }
748
749 static void evt_le_meta_event(struct hci_dev *dev, struct timeval *tv,
750                                         const void *data, uint16_t size)
751 {
752         struct iovec iov = {
753                 .iov_base = (void *)data,
754                 .iov_len = size,
755         };
756         uint8_t subevt;
757
758         if (!util_iov_pull_u8(&iov, &subevt))
759                 return;
760
761         switch (subevt) {
762         case BT_HCI_EVT_LE_CONN_COMPLETE:
763                 evt_le_conn_complete(dev, tv, &iov);
764                 break;
765         case BT_HCI_EVT_LE_ENHANCED_CONN_COMPLETE:
766                 evt_le_enh_conn_complete(dev, tv, &iov);
767                 break;
768         case BT_HCI_EVT_LE_CIS_ESTABLISHED:
769                 evt_le_cis_established(dev, tv, &iov);
770                 break;
771         case BT_HCI_EVT_LE_CIS_REQ:
772                 evt_le_cis_req(dev, tv, &iov);
773                 break;
774         case BT_HCI_EVT_LE_BIG_COMPLETE:
775                 evt_le_big_complete(dev, tv, &iov);
776                 break;
777         case BT_HCI_EVT_LE_BIG_SYNC_ESTABILISHED:
778                 evt_le_big_sync_established(dev, tv, &iov);
779                 break;
780         }
781 }
782
783 static void event_pkt(struct timeval *tv, uint16_t index,
784                                         const void *data, uint16_t size)
785 {
786         const struct bt_hci_evt_hdr *hdr = data;
787         struct hci_dev *dev;
788
789         data += sizeof(*hdr);
790         size -= sizeof(*hdr);
791
792         dev = dev_lookup(index);
793         if (!dev)
794                 return;
795
796         dev->num_hci++;
797         dev->num_evt++;
798
799         switch (hdr->evt) {
800         case BT_HCI_EVT_CONN_COMPLETE:
801                 evt_conn_complete(dev, tv, data, size);
802                 break;
803         case BT_HCI_EVT_DISCONNECT_COMPLETE:
804                 evt_disconnect_complete(dev, tv, data, size);
805                 break;
806         case BT_HCI_EVT_CMD_COMPLETE:
807                 evt_cmd_complete(dev, tv, data, size);
808                 break;
809         case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
810                 evt_num_completed_packets(dev, tv, data, size);
811                 break;
812         case BT_HCI_EVT_SYNC_CONN_COMPLETE:
813                 evt_sync_conn_complete(dev, tv, data, size);
814                 break;
815         case BT_HCI_EVT_LE_META_EVENT:
816                 evt_le_meta_event(dev, tv, data, size);
817                 break;
818         }
819 }
820
821 static void stats_add(struct hci_stats *stats, uint16_t size)
822 {
823         stats->num++;
824         stats->bytes += size;
825
826         if (!stats->min || size < stats->min)
827                 stats->min = size;
828         if (!stats->max || size > stats->max)
829                 stats->max = size;
830 }
831
832 static void conn_pkt_tx(struct hci_conn *conn, struct timeval *tv,
833                                 uint16_t size, struct l2cap_chan *chan)
834 {
835         struct hci_conn_tx *last_tx;
836
837         last_tx = new0(struct hci_conn_tx, 1);
838         memcpy(last_tx, tv, sizeof(*tv));
839         last_tx->chan = chan;
840         queue_push_tail(conn->tx_queue, last_tx);
841
842         stats_add(&conn->tx, size);
843
844         if (chan)
845                 stats_add(&chan->tx, size);
846 }
847
848 static void conn_pkt_rx(struct hci_conn *conn, struct timeval *tv,
849                                 uint16_t size, struct l2cap_chan *chan)
850 {
851         struct timeval res;
852
853         if (timerisset(&conn->last_rx)) {
854                 timersub(tv, &conn->last_rx, &res);
855                 packet_latency_add(&conn->rx.latency, &res);
856                 plot_add(conn->rx.plot, &res, 1);
857         }
858
859         conn->last_rx = *tv;
860
861         stats_add(&conn->rx, size);
862         conn->rx.num_comp++;
863
864         if (chan) {
865                 if (timerisset(&chan->last_rx)) {
866                         timersub(tv, &chan->last_rx, &res);
867                         packet_latency_add(&chan->rx.latency, &res);
868                         plot_add(chan->rx.plot, &res, 1);
869                 }
870
871                 chan->last_rx = *tv;
872
873                 stats_add(&chan->rx, size);
874                 chan->rx.num_comp++;
875         }
876 }
877
878 static void acl_pkt(struct timeval *tv, uint16_t index, bool out,
879                                         const void *data, uint16_t size)
880 {
881         const struct bt_hci_acl_hdr *hdr = data;
882         struct hci_dev *dev;
883         struct hci_conn *conn;
884         struct l2cap_chan *chan = NULL;
885         uint16_t cid;
886
887         data += sizeof(*hdr);
888         size -= sizeof(*hdr);
889
890         dev = dev_lookup(index);
891         if (!dev)
892                 return;
893
894         dev->num_hci++;
895         dev->num_acl++;
896
897         conn = conn_lookup_type(dev, le16_to_cpu(hdr->handle) & 0x0fff, 0x00);
898         if (!conn)
899                 return;
900
901         switch (le16_to_cpu(hdr->handle) >> 12) {
902         case 0x00:
903         case 0x02:
904                 cid = get_le16(data + 2);
905                 chan = chan_lookup(conn, cid, out);
906                 if (cid == 1)
907                         l2cap_sig(conn, out, data + 4, size - 4);
908                 break;
909         }
910
911         if (out) {
912                 conn_pkt_tx(conn, tv, size, chan);
913         } else {
914                 conn_pkt_rx(conn, tv, size, chan);
915         }
916 }
917
918 static void sco_pkt(struct timeval *tv, uint16_t index, bool out,
919                                         const void *data, uint16_t size)
920 {
921         const struct bt_hci_acl_hdr *hdr = data;
922         struct hci_dev *dev;
923         struct hci_conn *conn;
924
925         dev = dev_lookup(index);
926         if (!dev)
927                 return;
928
929         dev->num_hci++;
930         dev->num_sco++;
931
932         conn = conn_lookup_type(dev, le16_to_cpu(hdr->handle) & 0x0fff,
933                                                                 CONN_BR_SCO);
934         if (!conn)
935                 return;
936
937         if (out) {
938                 conn_pkt_tx(conn, tv, size - sizeof(*hdr), NULL);
939         } else {
940                 conn_pkt_rx(conn, tv, size - sizeof(*hdr), NULL);
941         }
942 }
943
944 static void info_index(struct timeval *tv, uint16_t index,
945                                         const void *data, uint16_t size)
946 {
947         const struct btsnoop_opcode_index_info *hdr = data;
948         struct hci_dev *dev;
949
950         dev = dev_lookup(index);
951         if (!dev)
952                 return;
953
954         dev->manufacturer = hdr->manufacturer;
955 }
956
957 static void vendor_diag(struct timeval *tv, uint16_t index,
958                                         const void *data, uint16_t size)
959 {
960         struct hci_dev *dev;
961
962         dev = dev_lookup(index);
963         if (!dev)
964                 return;
965
966         dev->vendor_diag++;
967 }
968
969 static void system_note(struct timeval *tv, uint16_t index,
970                                         const void *data, uint16_t size)
971 {
972         struct hci_dev *dev;
973
974         dev = dev_lookup(index);
975         if (!dev)
976                 return;
977
978         dev->system_note++;
979 }
980
981 static void user_log(struct timeval *tv, uint16_t index,
982                                         const void *data, uint16_t size)
983 {
984         struct hci_dev *dev;
985
986         dev = dev_lookup(index);
987         if (!dev)
988                 return;
989
990         dev->user_log++;
991 }
992
993 static void ctrl_msg(struct timeval *tv, uint16_t index,
994                                         const void *data, uint16_t size)
995 {
996         struct hci_dev *dev;
997
998         dev = dev_lookup(index);
999         if (!dev)
1000                 return;
1001
1002         dev->ctrl_msg++;
1003 }
1004
1005 static void iso_pkt(struct timeval *tv, uint16_t index, bool out,
1006                                         const void *data, uint16_t size)
1007 {
1008         const struct bt_hci_iso_hdr *hdr = data;
1009         struct hci_conn *conn;
1010         struct hci_dev *dev;
1011
1012         dev = dev_lookup(index);
1013         if (!dev)
1014                 return;
1015
1016         dev->num_hci++;
1017         dev->num_iso++;
1018
1019         conn = conn_lookup_type(dev, le16_to_cpu(hdr->handle) & 0x0fff,
1020                                                                 CONN_LE_ISO);
1021         if (!conn)
1022                 return;
1023
1024         if (out) {
1025                 conn_pkt_tx(conn, tv, size - sizeof(*hdr), NULL);
1026         } else {
1027                 conn_pkt_rx(conn, tv, size - sizeof(*hdr), NULL);
1028         }
1029 }
1030
1031 static void unknown_opcode(struct timeval *tv, uint16_t index,
1032                                         const void *data, uint16_t size)
1033 {
1034         struct hci_dev *dev;
1035
1036         dev = dev_lookup(index);
1037         if (!dev)
1038                 return;
1039
1040         dev->unknown++;
1041 }
1042
1043 void analyze_trace(const char *path)
1044 {
1045         struct btsnoop *btsnoop_file;
1046         unsigned long num_packets = 0;
1047         uint32_t format;
1048
1049         btsnoop_file = btsnoop_open(path, BTSNOOP_FLAG_PKLG_SUPPORT);
1050         if (!btsnoop_file)
1051                 return;
1052
1053         format = btsnoop_get_format(btsnoop_file);
1054
1055         switch (format) {
1056         case BTSNOOP_FORMAT_HCI:
1057         case BTSNOOP_FORMAT_UART:
1058         case BTSNOOP_FORMAT_MONITOR:
1059                 break;
1060         default:
1061                 fprintf(stderr, "Unsupported packet format\n");
1062                 goto done;
1063         }
1064
1065         dev_list = queue_new();
1066
1067         while (1) {
1068                 unsigned char buf[BTSNOOP_MAX_PACKET_SIZE];
1069                 struct timeval tv;
1070                 uint16_t index, opcode, pktlen;
1071
1072                 if (!btsnoop_read_hci(btsnoop_file, &tv, &index, &opcode,
1073                                                                 buf, &pktlen))
1074                         break;
1075
1076                 switch (opcode) {
1077                 case BTSNOOP_OPCODE_NEW_INDEX:
1078                         new_index(&tv, index, buf, pktlen);
1079                         break;
1080                 case BTSNOOP_OPCODE_DEL_INDEX:
1081                         del_index(&tv, index, buf, pktlen);
1082                         break;
1083                 case BTSNOOP_OPCODE_COMMAND_PKT:
1084                         command_pkt(&tv, index, buf, pktlen);
1085                         break;
1086                 case BTSNOOP_OPCODE_EVENT_PKT:
1087                         event_pkt(&tv, index, buf, pktlen);
1088                         break;
1089                 case BTSNOOP_OPCODE_ACL_TX_PKT:
1090                         acl_pkt(&tv, index, true, buf, pktlen);
1091                         break;
1092                 case BTSNOOP_OPCODE_ACL_RX_PKT:
1093                         acl_pkt(&tv, index, false, buf, pktlen);
1094                         break;
1095                 case BTSNOOP_OPCODE_SCO_TX_PKT:
1096                         sco_pkt(&tv, index, true, buf, pktlen);
1097                         break;
1098                 case BTSNOOP_OPCODE_SCO_RX_PKT:
1099                         sco_pkt(&tv, index, false, buf, pktlen);
1100                         break;
1101                 case BTSNOOP_OPCODE_OPEN_INDEX:
1102                 case BTSNOOP_OPCODE_CLOSE_INDEX:
1103                         break;
1104                 case BTSNOOP_OPCODE_INDEX_INFO:
1105                         info_index(&tv, index, buf, pktlen);
1106                         break;
1107                 case BTSNOOP_OPCODE_VENDOR_DIAG:
1108                         vendor_diag(&tv, index, buf, pktlen);
1109                         break;
1110                 case BTSNOOP_OPCODE_SYSTEM_NOTE:
1111                         system_note(&tv, index, buf, pktlen);
1112                         break;
1113                 case BTSNOOP_OPCODE_USER_LOGGING:
1114                         user_log(&tv, index, buf, pktlen);
1115                         break;
1116                 case BTSNOOP_OPCODE_CTRL_OPEN:
1117                 case BTSNOOP_OPCODE_CTRL_CLOSE:
1118                 case BTSNOOP_OPCODE_CTRL_COMMAND:
1119                 case BTSNOOP_OPCODE_CTRL_EVENT:
1120                         ctrl_msg(&tv, index, buf, pktlen);
1121                         break;
1122                 case BTSNOOP_OPCODE_ISO_TX_PKT:
1123                         iso_pkt(&tv, index, true, buf, pktlen);
1124                         break;
1125                 case BTSNOOP_OPCODE_ISO_RX_PKT:
1126                         iso_pkt(&tv, index, false, buf, pktlen);
1127                         break;
1128                 default:
1129                         unknown_opcode(&tv, index, buf, pktlen);
1130                         break;
1131                 }
1132
1133                 num_packets++;
1134         }
1135
1136         printf("Trace contains %lu packets\n\n", num_packets);
1137
1138         queue_destroy(dev_list, dev_destroy);
1139
1140 done:
1141         btsnoop_unref(btsnoop_file);
1142 }