Initialize Tizen 2.3
[framework/connectivity/bluez.git] / wearable / monitor / packet.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2011-2012  Intel Corporation
6  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program 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
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; 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 <errno.h>
31 #include <ctype.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdbool.h>
36 #include <time.h>
37 #include <sys/time.h>
38
39 #include <bluetooth/bluetooth.h>
40 #include <bluetooth/hci.h>
41 #include <bluetooth/hci_lib.h>
42
43 #include "control.h"
44 #include "btsnoop.h"
45 #include "packet.h"
46
47 static unsigned long filter_mask = 0;
48
49 void packet_set_filter(unsigned long filter)
50 {
51         filter_mask = filter;
52 }
53
54 static void print_channel_header(struct timeval *tv, uint16_t index,
55                                                         uint16_t channel)
56 {
57         if (filter_mask & PACKET_FILTER_SHOW_INDEX) {
58                 switch (channel) {
59                 case HCI_CHANNEL_CONTROL:
60                         printf("{hci%d} ", index);
61                         break;
62                 case HCI_CHANNEL_MONITOR:
63                         printf("[hci%d] ", index);
64                         break;
65                 }
66         }
67
68         if (tv) {
69                 time_t t = tv->tv_sec;
70                 struct tm tm;
71
72                 localtime_r(&t, &tm);
73
74                 if (filter_mask & PACKET_FILTER_SHOW_DATE)
75                         printf("%04d-%02d-%02d ", tm.tm_year + 1900,
76                                                 tm.tm_mon + 1, tm.tm_mday);
77
78                 if (filter_mask & PACKET_FILTER_SHOW_TIME)
79                         printf("%02d:%02d:%02d.%06lu ", tm.tm_hour,
80                                         tm.tm_min, tm.tm_sec, tv->tv_usec);
81         }
82 }
83
84 static void print_header(struct timeval *tv, uint16_t index)
85 {
86         print_channel_header(tv, index, HCI_CHANNEL_MONITOR);
87 }
88
89 void packet_hexdump(const unsigned char *buf, uint16_t len)
90 {
91         static const char hexdigits[] = "0123456789abcdef";
92         char str[68];
93         uint16_t i;
94
95         if (!len)
96                 return;
97
98         for (i = 0; i < len; i++) {
99                 str[((i % 16) * 3) + 0] = hexdigits[buf[i] >> 4];
100                 str[((i % 16) * 3) + 1] = hexdigits[buf[i] & 0xf];
101                 str[((i % 16) * 3) + 2] = ' ';
102                 str[(i % 16) + 49] = isprint(buf[i]) ? buf[i] : '.';
103
104                 if ((i + 1) % 16 == 0) {
105                         str[47] = ' ';
106                         str[48] = ' ';
107                         str[65] = '\0';
108                         printf("%-12c%s\n", ' ', str);
109                         str[0] = ' ';
110                 }
111         }
112
113         if (i % 16 > 0) {
114                 uint16_t j;
115                 for (j = (i % 16); j < 16; j++) {
116                         str[(j * 3) + 0] = ' ';
117                         str[(j * 3) + 1] = ' ';
118                         str[(j * 3) + 2] = ' ';
119                         str[j + 49] = ' ';
120                 }
121                 str[47] = ' ';
122                 str[48] = ' ';
123                 str[65] = '\0';
124                 printf("%-12c%s\n", ' ', str);
125         }
126 }
127
128 void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode,
129                                         const void *data, uint16_t size)
130 {
131         print_channel_header(tv, index, HCI_CHANNEL_CONTROL);
132
133         control_message(opcode, data, size);
134 }
135
136 #define MONITOR_NEW_INDEX       0
137 #define MONITOR_DEL_INDEX       1
138 #define MONITOR_COMMAND_PKT     2
139 #define MONITOR_EVENT_PKT       3
140 #define MONITOR_ACL_TX_PKT      4
141 #define MONITOR_ACL_RX_PKT      5
142 #define MONITOR_SCO_TX_PKT      6
143 #define MONITOR_SCO_RX_PKT      7
144
145 struct monitor_new_index {
146         uint8_t  type;
147         uint8_t  bus;
148         bdaddr_t bdaddr;
149         char     name[8];
150 } __attribute__((packed));
151
152 #define MONITOR_NEW_INDEX_SIZE 16
153
154 #define MONITOR_DEL_INDEX_SIZE 0
155
156 #define MAX_INDEX 16
157
158 static struct monitor_new_index index_list[MAX_INDEX];
159
160 void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode,
161                                         const void *data, uint16_t size)
162 {
163         const struct monitor_new_index *ni;
164         char str[18];
165
166         switch (opcode) {
167         case MONITOR_NEW_INDEX:
168                 ni = data;
169
170                 if (index < MAX_INDEX)
171                         memcpy(&index_list[index], ni, MONITOR_NEW_INDEX_SIZE);
172
173                 ba2str(&ni->bdaddr, str);
174                 packet_new_index(tv, index, str, ni->type, ni->bus, ni->name);
175                 break;
176         case MONITOR_DEL_INDEX:
177                 if (index < MAX_INDEX)
178                         ba2str(&index_list[index].bdaddr, str);
179                 else
180                         ba2str(BDADDR_ANY, str);
181
182                 packet_del_index(tv, index, str);
183                 break;
184         case MONITOR_COMMAND_PKT:
185                 packet_hci_command(tv, index, data, size);
186                 break;
187         case MONITOR_EVENT_PKT:
188                 packet_hci_event(tv, index, data, size);
189                 break;
190         case MONITOR_ACL_TX_PKT:
191                 packet_hci_acldata(tv, index, false, data, size);
192                 break;
193         case MONITOR_ACL_RX_PKT:
194                 packet_hci_acldata(tv, index, true, data, size);
195                 break;
196         case MONITOR_SCO_TX_PKT:
197                 packet_hci_scodata(tv, index, false, data, size);
198                 break;
199         case MONITOR_SCO_RX_PKT:
200                 packet_hci_scodata(tv, index, true, data, size);
201                 break;
202         default:
203                 print_header(tv, index);
204                 printf("* Unknown packet (code %d len %d)\n", opcode, size);
205                 packet_hexdump(data, size);
206                 break;
207         }
208 }
209
210 static const struct {
211         uint16_t opcode;
212         const char *str;
213 } opcode2str_table[] = {
214         /* OGF 1 - Link Control */
215         { 0x0401, "Inquiry"                             },
216         { 0x0402, "Inquiry Cancel"                      },
217         { 0x0403, "Periodic Inquiry Mode"               },
218         { 0x0404, "Exit Periodic Inquiry Mode"          },
219         { 0x0405, "Create Connection"                   },
220         { 0x0406, "Disconnect"                          },
221         { 0x0407, "Add SCO Connection"                  },
222         { 0x0408, "Create Connection Cancel"            },
223         { 0x0409, "Accept Connection Request"           },
224         { 0x040a, "Reject Connection Request"           },
225         { 0x040b, "Link Key Request Reply"              },
226         { 0x040c, "Link Key Request Negative Reply"     },
227         { 0x040d, "PIN Code Request Reply"              },
228         { 0x040e, "PIN Code Request Negative Reply"     },
229         { 0x040f, "Change Connection Packet Type"       },
230         /* reserved command */
231         { 0x0411, "Authentication Requested"            },
232         /* reserved command */
233         { 0x0413, "Set Connection Encryption"           },
234         /* reserved command */
235         { 0x0415, "Change Connection Link Key"          },
236         /* reserved command */
237         { 0x0417, "Master Link Key"                     },
238         /* reserved command */
239         { 0x0419, "Remote Name Request"                 },
240         { 0x041a, "Remote Name Request Cancel"          },
241         { 0x041b, "Read Remote Supported Features"      },
242         { 0x041c, "Read Remote Extended Features"       },
243         { 0x041d, "Read Remote Version Information"     },
244         /* reserved command */
245         { 0x041f, "Read Clock Offset"                   },
246         { 0x0420, "Read LMP Handle"                     },
247         /* reserved commands */
248         { 0x0428, "Setup Synchronous Connection"        },
249         { 0x0429, "Accept Synchronous Connection"       },
250         { 0x042a, "Reject Synchronous Connection"       },
251         { 0x042b, "IO Capability Request Reply"         },
252         { 0x042c, "User Confirmation Request Reply"     },
253         { 0x042d, "User Confirmation Request Neg Reply" },
254         { 0x042e, "User Passkey Request Reply"          },
255         { 0x042f, "User Passkey Request Negative Reply" },
256         { 0x0430, "Remote OOB Data Request Reply"       },
257         /* reserved commands */
258         { 0x0433, "Remote OOB Data Request Neg Reply"   },
259         { 0x0434, "IO Capability Request Negative Reply"},
260         { 0x0435, "Create Physical Link"                },
261         { 0x0436, "Accept Physical Link"                },
262         { 0x0437, "Disconnect Physical Link"            },
263         { 0x0438, "Create Logical Link"                 },
264         { 0x0439, "Accept Logical Link"                 },
265         { 0x043a, "Disconnect Logical Link"             },
266         { 0x043b, "Logical Link Cancel"                 },
267         { 0x043c, "Flow Specifcation Modify"            },
268
269         /* OGF 2 - Link Policy */
270         { 0x0801, "Holde Mode"                          },
271         /* reserved command */
272         { 0x0803, "Sniff Mode"                          },
273         { 0x0804, "Exit Sniff Mode"                     },
274         { 0x0805, "Park State"                          },
275         { 0x0806, "Exit Park State"                     },
276         { 0x0807, "QoS Setup"                           },
277         /* reserved command */
278         { 0x0809, "Role Discovery"                      },
279         /* reserved command */
280         { 0x080b, "Switch Role"                         },
281         { 0x080c, "Read Link Policy Settings"           },
282         { 0x080d, "Write Link Policy Settings"          },
283         { 0x080e, "Read Default Link Policy Settings"   },
284         { 0x080f, "Write Default Link Policy Settings"  },
285         { 0x0810, "Flow Specification"                  },
286         { 0x0811, "Sniff Subrating"                     },
287
288         /* OGF 3 - Host Control */
289         { 0x0c01, "Set Event Mask"                      },
290         /* reserved command */
291         { 0x0c03, "Reset"                               },
292         /* reserved command */
293         { 0x0c05, "Set Event Filter"                    },
294         /* reserved commands */
295         { 0x0c08, "Flush"                               },
296         { 0x0c09, "Read PIN Type"                       },
297         { 0x0c0a, "Write PIN Type"                      },
298         { 0x0c0b, "Create New Unit Key"                 },
299         /* reserved command */
300         { 0x0c0d, "Read Stored Link Key"                },
301         /* reserved commands */
302         { 0x0c11, "Write Stored Link Key"               },
303         { 0x0c12, "Delete Stored Link Key"              },
304         { 0x0c13, "Write Local Name"                    },
305         { 0x0c14, "Read Local Name"                     },
306         { 0x0c15, "Read Connection Accept Timeout"      },
307         { 0x0c16, "Write Connection Accept Timeout"     },
308         { 0x0c17, "Read Page Timeout"                   },
309         { 0x0c18, "Write Page Timeout"                  },
310         { 0x0c19, "Read Scan Enable"                    },
311         { 0x0c1a, "Write Scan Enable"                   },
312         { 0x0c1b, "Read Page Scan Activity"             },
313         { 0x0c1c, "Write Page Scan Activity"            },
314         { 0x0c1d, "Read Inquiry Scan Activity"          },
315         { 0x0c1e, "Write Inquiry Scan Activity"         },
316         { 0x0c1f, "Read Authentication Enable"          },
317         { 0x0c20, "Write Authentication Enable"         },
318         { 0x0c21, "Read Encryption Mode"                },
319         { 0x0c22, "Write Encryption Mode"               },
320         { 0x0c23, "Read Class of Device"                },
321         { 0x0c24, "Write Class of Device"               },
322         { 0x0c25, "Read Voice Setting"                  },
323         { 0x0c26, "Write Voice Setting"                 },
324         { 0x0c27, "Read Automatic Flush Timeout"        },
325         { 0x0c28, "Write Automatic Flush Timeout"       },
326         { 0x0c29, "Read Num Broadcast Retransmissions"  },
327         { 0x0c2a, "Write Num Broadcast Retransmissions" },
328         { 0x0c2b, "Read Hold Mode Activity"             },
329         { 0x0c2c, "Write Hold Mode Activity"            },
330         { 0x0c2d, "Read Transmit Power Level"           },
331         { 0x0c2e, "Read Sync Flow Control Enable"       },
332         { 0x0c2f, "Write Sync Flow Control Enable"      },
333         /* reserved command */
334         { 0x0c31, "Set Host Controller To Host Flow"    },
335         /* reserved command */
336         { 0x0c33, "Host Buffer Size"                    },
337         /* reserved command */
338         { 0x0c35, "Host Number of Completed Packets"    },
339         { 0x0c36, "Read Link Supervision Timeout"       },
340         { 0x0c37, "Write Link Supervision Timeout"      },
341         { 0x0c38, "Read Number of Supported IAC"        },
342         { 0x0c39, "Read Current IAC LAP"                },
343         { 0x0c3a, "Write Current IAC LAP"               },
344         { 0x0c3b, "Read Page Scan Period Mode"          },
345         { 0x0c3c, "Write Page Scan Period Mode"         },
346         { 0x0c3d, "Read Page Scan Mode"                 },
347         { 0x0c3e, "Write Page Scan Mode"                },
348         { 0x0c3f, "Set AFH Host Channel Classification" },
349         /* reserved commands */
350         { 0x0c42, "Read Inquiry Scan Type"              },
351         { 0x0c43, "Write Inquiry Scan Type"             },
352         { 0x0c44, "Read Inquiry Mode"                   },
353         { 0x0c45, "Write Inquiry Mode"                  },
354         { 0x0c46, "Read Page Scan Type"                 },
355         { 0x0c47, "Write Page Scan Type"                },
356         { 0x0c48, "Read AFH Channel Assessment Mode"    },
357         { 0x0c49, "Write AFH Channel Assessment Mode"   },
358         /* reserved commands */
359         { 0x0c51, "Read Extended Inquiry Response"      },
360         { 0x0c52, "Write Extended Inquiry Response"     },
361         { 0x0c53, "Refresh Encryption Key"              },
362         /* reserved command */
363         { 0x0c55, "Read Simple Pairing Mode"            },
364         { 0x0c56, "Write Simple Pairing Mode"           },
365         { 0x0c57, "Read Local OOB Data"                 },
366         { 0x0c58, "Read Inquiry Response TX Power Level"},
367         { 0x0c59, "Write Inquiry Transmit Power Level"  },
368         { 0x0c5a, "Read Default Erroneous Reporting"    },
369         { 0x0c5b, "Write Default Erroneous Reporting"   },
370         /* reserved commands */
371         { 0x0c5f, "Enhanced Flush"                      },
372         /* reserved command */
373         { 0x0c61, "Read Logical Link Accept Timeout"    },
374         { 0x0c62, "Write Logical Link Accept Timeout"   },
375         { 0x0c63, "Set Event Mask Page 2"               },
376         { 0x0c64, "Read Location Data"                  },
377         { 0x0c65, "Write Location Data"                 },
378         { 0x0c66, "Read Flow Control Mode"              },
379         { 0x0c67, "Write Flow Control Mode"             },
380         { 0x0c68, "Read Enhanced Transmit Power Level"  },
381         { 0x0c69, "Read Best Effort Flush Timeout"      },
382         { 0x0c6a, "Write Best Effort Flush Timeout"     },
383         { 0x0c6b, "Short Range Mode"                    },
384         { 0x0c6c, "Read LE Host Supported"              },
385         { 0x0c6d, "Write LE Host Supported"             },
386
387         /* OGF 4 - Information Parameter */
388         { 0x1001, "Read Local Version Information"      },
389         { 0x1002, "Read Local Supported Commands"       },
390         { 0x1003, "Read Local Supported Features"       },
391         { 0x1004, "Read Local Extended Features"        },
392         { 0x1005, "Read Buffer Size"                    },
393         /* reserved command */
394         { 0x1007, "Read Country Code"                   },
395         /* reserved command */
396         { 0x1009, "Read BD ADDR"                        },
397         { 0x100a, "Read Data Block Size"                },
398
399         /* OGF 5 - Status Parameter */
400         { 0x1401, "Read Failed Contact Counter"         },
401         { 0x1402, "Reset Failed Contact Counter"        },
402         { 0x1403, "Read Link Quality"                   },
403         /* reserved command */
404         { 0x1405, "Read RSSI"                           },
405         { 0x1406, "Read AFH Channel Map"                },
406         { 0x1407, "Read Clock"                          },
407         { 0x1408, "Read Encryption Key Size"            },
408         { 0x1409, "Read Local AMP Info"                 },
409         { 0x140a, "Read Local AMP ASSOC"                },
410         { 0x140b, "Write Remote AMP ASSOC"              },
411
412         /* OGF 8 - LE Control */
413         { 0x2001, "LE Set Event Mask"                   },
414         { 0x2002, "LE Read Buffer Size"                 },
415         { 0x2003, "LE Read Local Supported Features"    },
416         /* reserved command */
417         { 0x2005, "LE Set Random Address"               },
418         { 0x2006, "LE Set Advertising Parameters"       },
419         { 0x2007, "LE Read Advertising Channel TX Power"},
420         { 0x2008, "LE Set Advertising Data"             },
421         { 0x2009, "LE Set Scan Response Data"           },
422         { 0x200a, "LE Set Advertise Enable"             },
423         { 0x200b, "LE Set Scan Parameters"              },
424         { 0x200c, "LE Set Scan Enable"                  },
425         { 0x200d, "LE Create Connection"                },
426         { 0x200e, "LE Create Connection Cancel"         },
427         { 0x200f, "LE Read White List Size"             },
428         { 0x2010, "LE Clear White List"                 },
429         { 0x2011, "LE Add Device To White List"         },
430         { 0x2012, "LE Remove Device From White List"    },
431         { 0x2013, "LE Connection Update"                },
432         { 0x2014, "LE Set Host Channel Classification"  },
433         { 0x2015, "LE Read Channel Map"                 },
434         { 0x2016, "LE Read Remote Used Features"        },
435         { 0x2017, "LE Encrypt"                          },
436         { 0x2018, "LE Rand"                             },
437         { 0x2019, "LE Start Encryption"                 },
438         { 0x201a, "LE Long Term Key Request Reply"      },
439         { 0x201b, "LE Long Term Key Request Neg Reply"  },
440         { 0x201c, "LE Read Supported States"            },
441         { 0x201d, "LE Receiver Test"                    },
442         { 0x201e, "LE Transmitter Test"                 },
443         { 0x201f, "LE Test End"                         },
444         { }
445 };
446
447 static const char *opcode2str(uint16_t opcode)
448 {
449         int i;
450
451         for (i = 0; opcode2str_table[i].str; i++) {
452                 if (opcode2str_table[i].opcode == opcode)
453                         return opcode2str_table[i].str;
454         }
455
456         return "Unknown";
457 }
458
459 static const struct {
460         uint8_t event;
461         const char *str;
462 } event2str_table[] = {
463         { 0x01, "Inquiry Complete"                      },
464         { 0x02, "Inquiry Result"                        },
465         { 0x03, "Connect Complete"                      },
466         { 0x04, "Connect Request"                       },
467         { 0x05, "Disconn Complete"                      },
468         { 0x06, "Auth Complete"                         },
469         { 0x07, "Remote Name Req Complete"              },
470         { 0x08, "Encrypt Change"                        },
471         { 0x09, "Change Connection Link Key Complete"   },
472         { 0x0a, "Master Link Key Complete"              },
473         { 0x0b, "Read Remote Supported Features"        },
474         { 0x0c, "Read Remote Version Complete"          },
475         { 0x0d, "QoS Setup Complete"                    },
476         { 0x0e, "Command Complete"                      },
477         { 0x0f, "Command Status"                        },
478         { 0x10, "Hardware Error"                        },
479         { 0x11, "Flush Occurred"                        },
480         { 0x12, "Role Change"                           },
481         { 0x13, "Number of Completed Packets"           },
482         { 0x14, "Mode Change"                           },
483         { 0x15, "Return Link Keys"                      },
484         { 0x16, "PIN Code Request"                      },
485         { 0x17, "Link Key Request"                      },
486         { 0x18, "Link Key Notification"                 },
487         { 0x19, "Loopback Command"                      },
488         { 0x1a, "Data Buffer Overflow"                  },
489         { 0x1b, "Max Slots Change"                      },
490         { 0x1c, "Read Clock Offset Complete"            },
491         { 0x1d, "Connection Packet Type Changed"        },
492         { 0x1e, "QoS Violation"                         },
493         { 0x1f, "Page Scan Mode Change"                 },
494         { 0x20, "Page Scan Repetition Mode Change"      },
495         { 0x21, "Flow Specification Complete"           },
496         { 0x22, "Inquiry Result with RSSI"              },
497         { 0x23, "Read Remote Extended Features"         },
498         /* reserved events */
499         { 0x2c, "Synchronous Connect Complete"          },
500         { 0x2d, "Synchronous Connect Changed"           },
501         { 0x2e, "Sniff Subrate"                         },
502         { 0x2f, "Extended Inquiry Result"               },
503         { 0x30, "Encryption Key Refresh Complete"       },
504         { 0x31, "IO Capability Request"                 },
505         { 0x32, "IO Capability Response"                },
506         { 0x33, "User Confirmation Request"             },
507         { 0x34, "User Passkey Request"                  },
508         { 0x35, "Remote OOB Data Request"               },
509         { 0x36, "Simple Pairing Complete"               },
510         /* reserved event */
511         { 0x38, "Link Supervision Timeout Change"       },
512         { 0x39, "Enhanced Flush Complete"               },
513         /* reserved event */
514         { 0x3b, "User Passkey Notification"             },
515         { 0x3c, "Keypress Notification"                 },
516         { 0x3d, "Remote Host Supported Features"        },
517         { 0x3e, "LE Meta Event"                         },
518         /* reserved event */
519         { 0x40, "Physical Link Complete"                },
520         { 0x41, "Channel Selected"                      },
521         { 0x42, "Disconn Physical Link Complete"        },
522         { 0x43, "Physical Link Loss Early Warning"      },
523         { 0x44, "Physical Link Recovery"                },
524         { 0x45, "Logical Link Complete"                 },
525         { 0x46, "Disconn Logical Link Complete"         },
526         { 0x47, "Flow Spec Modify Complete"             },
527         { 0x48, "Number Of Completed Data Blocks"       },
528         { 0x49, "AMP Start Test"                        },
529         { 0x4a, "AMP Test End"                          },
530         { 0x4b, "AMP Receiver Report"                   },
531         { 0x4c, "Short Range Mode Change Complete"      },
532         { 0x4d, "AMP Status Change"                     },
533         { 0xfe, "Testing"                               },
534         { 0xff, "Vendor"                                },
535         { }
536 };
537
538 static const char *event2str(uint8_t event)
539 {
540         int i;
541
542         for (i = 0; event2str_table[i].str; i++) {
543                 if (event2str_table[i].event == event)
544                         return event2str_table[i].str;
545         }
546
547         return "Unknown";
548 }
549
550 void packet_new_index(struct timeval *tv, uint16_t index, const char *label,
551                                 uint8_t type, uint8_t bus, const char *name)
552 {
553         print_header(tv, index);
554
555         printf("= New Index: %s (%s,%s,%s)\n", label,
556                                 hci_typetostr(type), hci_bustostr(bus), name);
557 }
558
559 void packet_del_index(struct timeval *tv, uint16_t index, const char *label)
560 {
561         print_header(tv, index);
562
563         printf("= Delete Index: %s\n", label);
564 }
565
566 void packet_hci_command(struct timeval *tv, uint16_t index,
567                                         const void *data, uint16_t size)
568 {
569         const hci_command_hdr *hdr = data;
570         uint16_t opcode = btohs(hdr->opcode);
571         uint16_t ogf = cmd_opcode_ogf(opcode);
572         uint16_t ocf = cmd_opcode_ocf(opcode);
573
574         btsnoop_write(tv, index, 0x02, data, size);
575
576         print_header(tv, index);
577
578         if (size < HCI_COMMAND_HDR_SIZE) {
579                 printf("* Malformed HCI Command packet\n");
580                 return;
581         }
582
583         printf("< HCI Command: %s (0x%2.2x|0x%4.4x) plen %d\n",
584                                 opcode2str(opcode), ogf, ocf, hdr->plen);
585
586         data += HCI_COMMAND_HDR_SIZE;
587         size -= HCI_COMMAND_HDR_SIZE;
588
589         packet_hexdump(data, size);
590 }
591
592 void packet_hci_event(struct timeval *tv, uint16_t index,
593                                         const void *data, uint16_t size)
594 {
595         const hci_event_hdr *hdr = data;
596
597         btsnoop_write(tv, index, 0x03, data, size);
598
599         print_header(tv, index);
600
601         if (size < HCI_EVENT_HDR_SIZE) {
602                 printf("* Malformed HCI Event packet\n");
603                 return;
604         }
605
606         printf("> HCI Event: %s (0x%2.2x) plen %d\n",
607                                 event2str(hdr->evt), hdr->evt, hdr->plen);
608
609         data += HCI_EVENT_HDR_SIZE;
610         size -= HCI_EVENT_HDR_SIZE;
611
612         packet_hexdump(data, size);
613 }
614
615 void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in,
616                                         const void *data, uint16_t size)
617 {
618         const hci_acl_hdr *hdr = data;
619         uint16_t handle = btohs(hdr->handle);
620         uint16_t dlen = btohs(hdr->dlen);
621         uint8_t flags = acl_flags(handle);
622
623         btsnoop_write(tv, index, in ? 0x01 : 0x00, data, size);
624
625         print_header(tv, index);
626
627         if (size < HCI_ACL_HDR_SIZE) {
628                 printf("* Malformed ACL Data %s packet\n", in ? "RX" : "TX");
629                 return;
630         }
631
632         printf("%c ACL Data: handle %d flags 0x%2.2x dlen %d\n",
633                         in ? '>' : '<', acl_handle(handle), flags, dlen);
634
635         data += HCI_ACL_HDR_SIZE;
636         size -= HCI_ACL_HDR_SIZE;
637
638         if (filter_mask & PACKET_FILTER_SHOW_ACL_DATA)
639                 packet_hexdump(data, size);
640 }
641
642 void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in,
643                                         const void *data, uint16_t size)
644 {
645         const hci_sco_hdr *hdr = data;
646         uint16_t handle = btohs(hdr->handle);
647         uint8_t flags = acl_flags(handle);
648
649         print_header(tv, index);
650
651         if (size < HCI_SCO_HDR_SIZE) {
652                 printf("* Malformed SCO Data %s packet\n", in ? "RX" : "TX");
653                 return;
654         }
655
656         printf("%c SCO Data: handle %d flags 0x%2.2x dlen %d\n",
657                         in ? '>' : '<', acl_handle(handle), flags, hdr->dlen);
658
659         data += HCI_SCO_HDR_SIZE;
660         size -= HCI_SCO_HDR_SIZE;
661
662         if (filter_mask & PACKET_FILTER_SHOW_SCO_DATA)
663                 packet_hexdump(data, size);
664 }