Home | History | Annotate | Download | only in src
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2004-2007  Marcel Holtmann <marcel (at) holtmann.org>
      6  *
      7  *
      8  *  This program is free software; you can redistribute it and/or modify
      9  *  it under the terms of the GNU General Public License as published by
     10  *  the Free Software Foundation; either version 2 of the License, or
     11  *  (at your option) any later version.
     12  *
     13  *  This program is distributed in the hope that it will be useful,
     14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  *  GNU General Public License for more details.
     17  *
     18  *  You should have received a copy of the GNU General Public License
     19  *  along with this program; if not, write to the Free Software
     20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     21  *
     22  */
     23 
     24 #ifdef HAVE_CONFIG_H
     25 #include <config.h>
     26 #endif
     27 
     28 #include <stdio.h>
     29 #include <errno.h>
     30 #include <unistd.h>
     31 #include <stdlib.h>
     32 #include <getopt.h>
     33 #include <signal.h>
     34 #include <sys/ioctl.h>
     35 #include <sys/socket.h>
     36 
     37 #include <bluetooth/bluetooth.h>
     38 #include <bluetooth/hci.h>
     39 #include <bluetooth/hci_lib.h>
     40 
     41 static volatile sig_atomic_t __io_canceled = 0;
     42 
     43 static void sig_hup(int sig)
     44 {
     45 }
     46 
     47 static void sig_term(int sig)
     48 {
     49 	__io_canceled = 1;
     50 }
     51 
     52 static struct {
     53 	uint16_t id;
     54 	uint16_t ver;
     55 	char *date;
     56 } firmware_map[] = {
     57 	{  195,  1, "2001-11-27"	},
     58 	{  220,  2, "2002-01-03"	},
     59 	{  269,  3, "2002-02-22"	},
     60 	{  270,  4, "2002-02-26"	},
     61 	{  284,  5, "2002-03-12"	},
     62 	{  292,  6, "2002-03-20"	},
     63 	{  305,  7, "2002-04-12"	},
     64 	{  306,  8, "2002-04-12"	},
     65 	{  343,  9, "2002-05-02"	},
     66 	{  346, 10, "2002-05-03"	},
     67 	{  355, 11, "2002-05-16"	},
     68 	{  256, 11, "2002-05-16"	},
     69 	{  390, 12, "2002-06-26"	},
     70 	{  450, 13, "2002-08-16"	},
     71 	{  451, 13, "2002-08-16"	},
     72 	{  533, 14, "2002-10-11"	},
     73 	{  580, 15, "2002-11-14"	},
     74 	{  623, 16, "2002-12-12"	},
     75 	{  678, 17, "2003-01-29"	},
     76 	{  847, 18, "2003-04-17"	},
     77 	{  876, 19, "2003-06-10"	},
     78 	{  997, 22, "2003-09-05"	},
     79 	{ 1027, 23, "2003-10-03"	},
     80 	{ 1029, 24, "2003-10-03"	},
     81 	{ 1112, 25, "2003-12-03"	},
     82 	{ 1113, 25, "2003-12-03"	},
     83 	{ 1133, 26, "2003-12-18"	},
     84 	{ 1134, 26, "2003-12-18"	},
     85 	{ 1223, 27, "2004-03-08"	},
     86 	{ 1224, 27, "2004-03-08"	},
     87 	{ 1319, 31, "2004-04-22"	},
     88 	{ 1320, 31, "2004-04-22"	},
     89 	{ 1427, 34, "2004-06-16"	},
     90 	{ 1508, 35, "2004-07-19"	},
     91 	{ 1509, 35, "2004-07-19"	},
     92 	{ 1587, 36, "2004-08-18"	},
     93 	{ 1588, 36, "2004-08-18"	},
     94 	{ 1641, 37, "2004-09-16"	},
     95 	{ 1642, 37, "2004-09-16"	},
     96 	{ 1699, 38, "2004-10-07"	},
     97 	{ 1700, 38, "2004-10-07"	},
     98 	{ 1752, 39, "2004-11-02"	},
     99 	{ 1753, 39, "2004-11-02"	},
    100 	{ 1759, 40, "2004-11-03"	},
    101 	{ 1760, 40, "2004-11-03"	},
    102 	{ 1761, 40, "2004-11-03"	},
    103 	{ 2009, 41, "2005-04-06"	},
    104 	{ 2010, 41, "2005-04-06"	},
    105 	{ 2011, 41, "2005-04-06"	},
    106 	{ 2016, 42, "2005-04-11"	},
    107 	{ 2017, 42, "2005-04-11"	},
    108 	{ 2018, 42, "2005-04-11"	},
    109 	{ 2023, 43, "2005-04-14"	},
    110 	{ 2024, 43, "2005-04-14"	},
    111 	{ 2025, 43, "2005-04-14"	},
    112 	{ 2032, 44, "2005-04-18"	},
    113 	{ 2033, 44, "2005-04-18"	},
    114 	{ 2034, 44, "2005-04-18"	},
    115 	{ 2288, 45, "2005-07-08"	},
    116 	{ 2289, 45, "2005-07-08"	},
    117 	{ 2290, 45, "2005-07-08"	},
    118 	{ 2388, 46, "2005-08-17"	},
    119 	{ 2389, 46, "2005-08-17"	},
    120 	{ 2390, 46, "2005-08-17"	},
    121 	{ 2869, 47, "2006-02-15"	},
    122 	{ 2870, 47, "2006-02-15"	},
    123 	{ 2871, 47, "2006-02-15"	},
    124 	{ 3214, 48, "2006-02-16"	},
    125 	{ 3215, 48, "2006-02-16"	},
    126 	{ 3216, 48, "2006-02-16"	},
    127 	{    0, }
    128 };
    129 
    130 static int id2ver(uint16_t id)
    131 {
    132 	int i;
    133 
    134 	for (i = 0; firmware_map[i].id; i++)
    135 		if (firmware_map[i].id == id)
    136 			return firmware_map[i].ver;
    137 
    138 	return -1;
    139 }
    140 
    141 static void usage(void)
    142 {
    143 	printf("csrsniff - Utility for the CSR BlueCore sniffers\n\n");
    144 	printf("Usage:\n"
    145 		"\tcsrsniff [-i <dev>] <master-bdaddr> [slave-bdaddr]\n");
    146 }
    147 
    148 static struct option main_options[] = {
    149 	{ "help",	0, 0, 'h' },
    150 	{ "device",	1, 0, 'i' },
    151 	{ 0, 0, 0, 0}
    152 };
    153 
    154 int main(int argc, char *argv[])
    155 {
    156 	struct sigaction sa;
    157 	struct hci_dev_info di;
    158 	struct hci_version ver;
    159 	struct hci_filter flt;
    160 	bdaddr_t bdaddr, master, slave;
    161 	int need_raw;
    162 	int dd, opt, dev = 0;
    163 
    164 	bacpy(&slave, BDADDR_ANY);
    165 
    166 	while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
    167 		switch (opt) {
    168 		case 'i':
    169 			dev = hci_devid(optarg);
    170 			if (dev < 0) {
    171 				perror("Invalid device");
    172 				exit(1);
    173 			}
    174 			break;
    175 
    176 		case 'h':
    177 		default:
    178 			usage();
    179 			exit(0);
    180 		}
    181 	}
    182 
    183 	argc -= optind;
    184 	argv += optind;
    185 	optind = 0;
    186 
    187 	if (argc < 1) {
    188 		usage();
    189 		exit(1);
    190 	}
    191 
    192 	str2ba(argv[0], &master);
    193 
    194 	if (argc > 1)
    195 		str2ba(argv[1], &slave);
    196 
    197 	dd = hci_open_dev(dev);
    198 	if (dd < 0) {
    199 		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
    200 						dev, strerror(errno), errno);
    201 		exit(1);
    202 	}
    203 
    204 	if (hci_devinfo(dev, &di) < 0) {
    205 		fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n",
    206 						dev, strerror(errno), errno);
    207 		hci_close_dev(dd);
    208 		exit(1);
    209 	}
    210 
    211 	if (hci_read_local_version(dd, &ver, 1000) < 0) {
    212 		fprintf(stderr, "Can't read version for hci%d: %s (%d)\n",
    213 						dev, strerror(errno), errno);
    214 		hci_close_dev(dd);
    215 		exit(1);
    216 	}
    217 
    218 	if (ver.manufacturer != 10 || id2ver(ver.hci_rev) < 0) {
    219 		fprintf(stderr, "Can't find sniffer at hci%d: %s (%d)\n",
    220 						dev, strerror(ENOSYS), ENOSYS);
    221 		hci_close_dev(dd);
    222 		exit(1);
    223 	}
    224 
    225 	if (!bacmp(&di.bdaddr, BDADDR_ANY)) {
    226 		if (hci_read_bd_addr(dd, &bdaddr, 1000) < 0) {
    227 			fprintf(stderr, "Can't read address for hci%d: %s (%d)\n",
    228 						dev, strerror(errno), errno);
    229 			hci_close_dev(dd);
    230 			exit(1);
    231 		}
    232 	} else
    233 		bacpy(&bdaddr, &di.bdaddr);
    234 
    235 	need_raw = !hci_test_bit(HCI_RAW, &di.flags);
    236 
    237 	hci_filter_clear(&flt);
    238 	hci_filter_set_ptype(HCI_ACLDATA_PKT, &flt);
    239 	hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
    240 	hci_filter_set_event(EVT_VENDOR, &flt);
    241 
    242 	if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
    243 		fprintf(stderr, "Can't set filter for hci%d: %s (%d)\n",
    244 						dev, strerror(errno), errno);
    245 		hci_close_dev(dd);
    246 		exit(1);
    247 	}
    248 
    249 	memset(&sa, 0, sizeof(sa));
    250 	sa.sa_flags   = SA_NOCLDSTOP;
    251 	sa.sa_handler = SIG_IGN;
    252 	sigaction(SIGCHLD, &sa, NULL);
    253 	sigaction(SIGPIPE, &sa, NULL);
    254 
    255 	sa.sa_handler = sig_term;
    256 	sigaction(SIGTERM, &sa, NULL);
    257 	sigaction(SIGINT,  &sa, NULL);
    258 
    259 	sa.sa_handler = sig_hup;
    260 	sigaction(SIGHUP, &sa, NULL);
    261 
    262 	if (need_raw) {
    263 		if (ioctl(dd, HCISETRAW, 1) < 0) {
    264 			fprintf(stderr, "Can't set raw mode on hci%d: %s (%d)\n",
    265 						dev, strerror(errno), errno);
    266 			hci_close_dev(dd);
    267 			exit(1);
    268 		}
    269 	}
    270 
    271 	printf("CSR sniffer - Bluetooth packet analyzer ver %s\n", VERSION);
    272 
    273 	if (need_raw) {
    274 		if (ioctl(dd, HCISETRAW, 0) < 0)
    275 			fprintf(stderr, "Can't clear raw mode on hci%d: %s (%d)\n",
    276 						dev, strerror(errno), errno);
    277 	}
    278 
    279 	hci_close_dev(dd);
    280 
    281 	return 0;
    282 }
    283