1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2000-2001  Qualcomm Incorporated
6 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
7 *  Copyright (C) 2002-2009  Marcel Holtmann <marcel@holtmann.org>
8 *
9 *
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License as published by
12 *  the Free Software Foundation; either version 2 of the License, or
13 *  (at your option) any later version.
14 *
15 *  This program is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this program; if not, write to the Free Software
22 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23 *
24 */
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29
30#include <stdio.h>
31#include <errno.h>
32#include <ctype.h>
33#include <unistd.h>
34#include <stdlib.h>
35#include <string.h>
36#include <getopt.h>
37#include <sys/param.h>
38#include <sys/ioctl.h>
39#include <sys/socket.h>
40
41#include <bluetooth/bluetooth.h>
42#include <bluetooth/hci.h>
43#include <bluetooth/hci_lib.h>
44
45#include "textfile.h"
46#include "csr.h"
47
48static struct hci_dev_info di;
49static int all;
50
51static void print_dev_hdr(struct hci_dev_info *di);
52static void print_dev_info(int ctl, struct hci_dev_info *di);
53
54static void print_dev_list(int ctl, int flags)
55{
56	struct hci_dev_list_req *dl;
57	struct hci_dev_req *dr;
58	int i;
59
60	if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) {
61		perror("Can't allocate memory");
62		exit(1);
63	}
64	dl->dev_num = HCI_MAX_DEV;
65	dr = dl->dev_req;
66
67	if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) {
68		perror("Can't get device list");
69		exit(1);
70	}
71
72	for (i = 0; i< dl->dev_num; i++) {
73		di.dev_id = (dr+i)->dev_id;
74		if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0)
75			continue;
76		if (hci_test_bit(HCI_RAW, &di.flags) &&
77				!bacmp(&di.bdaddr, BDADDR_ANY)) {
78			int dd = hci_open_dev(di.dev_id);
79			hci_read_bd_addr(dd, &di.bdaddr, 1000);
80			hci_close_dev(dd);
81		}
82		print_dev_info(ctl, &di);
83	}
84}
85
86static void print_pkt_type(struct hci_dev_info *di)
87{
88	char *str;
89	str = hci_ptypetostr(di->pkt_type);
90	printf("\tPacket type: %s\n", str);
91	bt_free(str);
92}
93
94static void print_link_policy(struct hci_dev_info *di)
95{
96	printf("\tLink policy: %s\n", hci_lptostr(di->link_policy));
97}
98
99static void print_link_mode(struct hci_dev_info *di)
100{
101	char *str;
102	str =  hci_lmtostr(di->link_mode);
103	printf("\tLink mode: %s\n", str);
104	bt_free(str);
105}
106
107static void print_dev_features(struct hci_dev_info *di, int format)
108{
109	printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
110				"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
111		di->features[0], di->features[1], di->features[2],
112		di->features[3], di->features[4], di->features[5],
113		di->features[6], di->features[7]);
114
115	if (format) {
116		char *tmp = lmp_featurestostr(di->features, "\t\t", 63);
117		printf("%s\n", tmp);
118		bt_free(tmp);
119	}
120}
121
122static void cmd_rstat(int ctl, int hdev, char *opt)
123{
124	/* Reset HCI device stat counters */
125	if (ioctl(ctl, HCIDEVRESTAT, hdev) < 0) {
126		fprintf(stderr, "Can't reset stats counters hci%d: %s (%d)\n",
127						hdev, strerror(errno), errno);
128		exit(1);
129	}
130}
131
132static void cmd_scan(int ctl, int hdev, char *opt)
133{
134	struct hci_dev_req dr;
135
136	dr.dev_id  = hdev;
137	dr.dev_opt = SCAN_DISABLED;
138	if (!strcmp(opt, "iscan"))
139		dr.dev_opt = SCAN_INQUIRY;
140	else if (!strcmp(opt, "pscan"))
141		dr.dev_opt = SCAN_PAGE;
142	else if (!strcmp(opt, "piscan"))
143		dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
144
145	if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) {
146		fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n",
147						hdev, strerror(errno), errno);
148		exit(1);
149	}
150}
151
152static void cmd_iac(int ctl, int hdev, char *opt)
153{
154	int s = hci_open_dev(hdev);
155
156	if (s < 0) {
157		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
158						hdev, strerror(errno), errno);
159		exit(1);
160	}
161	if (opt) {
162		int l = strtoul(opt, 0, 16);
163		uint8_t lap[3];
164		if (!strcasecmp(opt, "giac")) {
165			l = 0x9e8b33;
166		} else if (!strcasecmp(opt, "liac")) {
167			l = 0x9e8b00;
168		} else if (l < 0x9e8b00 || l > 0x9e8b3f) {
169			printf("Invalid access code 0x%x\n", l);
170			exit(1);
171		}
172		lap[0] = (l & 0xff);
173		lap[1] = (l >> 8) & 0xff;
174		lap[2] = (l >> 16) & 0xff;
175		if (hci_write_current_iac_lap(s, 1, lap, 1000) < 0) {
176			printf("Failed to set IAC on hci%d: %s\n", hdev, strerror(errno));
177			exit(1);
178		}
179	} else {
180		uint8_t lap[3 * MAX_IAC_LAP];
181		int i, j;
182		uint8_t n;
183		if (hci_read_current_iac_lap(s, &n, lap, 1000) < 0) {
184			printf("Failed to read IAC from hci%d: %s\n", hdev, strerror(errno));
185			exit(1);
186		}
187		print_dev_hdr(&di);
188		printf("\tIAC: ");
189		for (i = 0; i < n; i++) {
190			printf("0x");
191			for (j = 3; j--; )
192				printf("%02x", lap[j + 3 * i]);
193			if (i < n - 1)
194				printf(", ");
195		}
196		printf("\n");
197	}
198	close(s);
199}
200
201static void cmd_auth(int ctl, int hdev, char *opt)
202{
203	struct hci_dev_req dr;
204
205	dr.dev_id = hdev;
206	if (!strcmp(opt, "auth"))
207		dr.dev_opt = AUTH_ENABLED;
208	else
209		dr.dev_opt = AUTH_DISABLED;
210
211	if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) {
212		fprintf(stderr, "Can't set auth on hci%d: %s (%d)\n",
213						hdev, strerror(errno), errno);
214		exit(1);
215	}
216}
217
218static void cmd_encrypt(int ctl, int hdev, char *opt)
219{
220	struct hci_dev_req dr;
221
222	dr.dev_id = hdev;
223	if (!strcmp(opt, "encrypt"))
224		dr.dev_opt = ENCRYPT_P2P;
225	else
226		dr.dev_opt = ENCRYPT_DISABLED;
227
228	if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) {
229		fprintf(stderr, "Can't set encrypt on hci%d: %s (%d)\n",
230						hdev, strerror(errno), errno);
231		exit(1);
232	}
233}
234
235static void cmd_up(int ctl, int hdev, char *opt)
236{
237	/* Start HCI device */
238	if (ioctl(ctl, HCIDEVUP, hdev) < 0) {
239		if (errno == EALREADY)
240			return;
241		fprintf(stderr, "Can't init device hci%d: %s (%d)\n",
242						hdev, strerror(errno), errno);
243		exit(1);
244	}
245}
246
247static void cmd_down(int ctl, int hdev, char *opt)
248{
249	/* Stop HCI device */
250	if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) {
251		fprintf(stderr, "Can't down device hci%d: %s (%d)\n",
252						hdev, strerror(errno), errno);
253		exit(1);
254	}
255}
256
257static void cmd_reset(int ctl, int hdev, char *opt)
258{
259	/* Reset HCI device */
260#if 0
261	if (ioctl(ctl, HCIDEVRESET, hdev) < 0 ){
262		fprintf(stderr, "Reset failed for device hci%d: %s (%d)\n",
263						hdev, strerror(errno), errno);
264		exit(1);
265	}
266#endif
267	cmd_down(ctl, hdev, "down");
268	cmd_up(ctl, hdev, "up");
269}
270
271static void cmd_ptype(int ctl, int hdev, char *opt)
272{
273	struct hci_dev_req dr;
274
275	dr.dev_id = hdev;
276
277	if (hci_strtoptype(opt, &dr.dev_opt)) {
278		if (ioctl(ctl, HCISETPTYPE, (unsigned long) &dr) < 0) {
279			fprintf(stderr, "Can't set pkttype on hci%d: %s (%d)\n",
280						hdev, strerror(errno), errno);
281			exit(1);
282		}
283	} else {
284		print_dev_hdr(&di);
285		print_pkt_type(&di);
286	}
287}
288
289static void cmd_lp(int ctl, int hdev, char *opt)
290{
291	struct hci_dev_req dr;
292
293	dr.dev_id = hdev;
294
295	if (hci_strtolp(opt, &dr.dev_opt)) {
296		if (ioctl(ctl, HCISETLINKPOL, (unsigned long) &dr) < 0) {
297			fprintf(stderr, "Can't set link policy on hci%d: %s (%d)\n",
298						hdev, strerror(errno), errno);
299			exit(1);
300		}
301	} else {
302		print_dev_hdr(&di);
303		print_link_policy(&di);
304	}
305}
306
307static void cmd_lm(int ctl, int hdev, char *opt)
308{
309	struct hci_dev_req dr;
310
311	dr.dev_id = hdev;
312
313	if (hci_strtolm(opt, &dr.dev_opt)) {
314		if (ioctl(ctl, HCISETLINKMODE, (unsigned long) &dr) < 0) {
315			fprintf(stderr, "Can't set default link mode on hci%d: %s (%d)\n",
316						hdev, strerror(errno), errno);
317			exit(1);
318		}
319	} else {
320		print_dev_hdr(&di);
321		print_link_mode(&di);
322	}
323}
324
325static void cmd_aclmtu(int ctl, int hdev, char *opt)
326{
327	struct hci_dev_req dr = { dev_id: hdev };
328	uint16_t mtu, mpkt;
329
330	if (!opt)
331		return;
332
333	if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2)
334		return;
335
336	dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16));
337
338	if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) {
339		fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n",
340						hdev, strerror(errno), errno);
341		exit(1);
342	}
343}
344
345static void cmd_scomtu(int ctl, int hdev, char *opt)
346{
347	struct hci_dev_req dr = { dev_id: hdev };
348	uint16_t mtu, mpkt;
349
350	if (!opt)
351		return;
352
353	if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2)
354		return;
355
356	dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16));
357
358	if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) {
359		fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n",
360						hdev, strerror(errno), errno);
361		exit(1);
362	}
363}
364
365static void cmd_features(int ctl, int hdev, char *opt)
366{
367	uint8_t features[8], max_page = 0;
368	char *tmp;
369	int i, dd;
370
371	if (!(di.features[7] & LMP_EXT_FEAT)) {
372		print_dev_hdr(&di);
373		print_dev_features(&di, 1);
374		return;
375	}
376
377	dd = hci_open_dev(hdev);
378	if (dd < 0) {
379		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
380						hdev, strerror(errno), errno);
381		exit(1);
382	}
383
384	if (hci_read_local_ext_features(dd, 0, &max_page, features, 1000) < 0) {
385		fprintf(stderr, "Can't read extended features hci%d: %s (%d)\n",
386						hdev, strerror(errno), errno);
387		exit(1);
388	}
389
390	print_dev_hdr(&di);
391	printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
392				"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
393		(max_page > 0) ? " page 0" : "",
394		features[0], features[1], features[2], features[3],
395		features[4], features[5], features[6], features[7]);
396
397	tmp = lmp_featurestostr(di.features, "\t\t", 63);
398	printf("%s\n", tmp);
399	bt_free(tmp);
400
401	for (i = 1; i <= max_page; i++) {
402		if (hci_read_local_ext_features(dd, i, NULL,
403							features, 1000) < 0)
404			continue;
405
406		printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
407					"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i,
408			features[0], features[1], features[2], features[3],
409			features[4], features[5], features[6], features[7]);
410	}
411
412	hci_close_dev(dd);
413}
414
415static void cmd_name(int ctl, int hdev, char *opt)
416{
417	int dd;
418
419	dd = hci_open_dev(hdev);
420	if (dd < 0) {
421		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
422						hdev, strerror(errno), errno);
423		exit(1);
424	}
425
426	if (opt) {
427		if (hci_write_local_name(dd, opt, 2000) < 0) {
428			fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n",
429						hdev, strerror(errno), errno);
430			exit(1);
431		}
432	} else {
433		char name[249];
434		int i;
435
436		if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) {
437			fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n",
438						hdev, strerror(errno), errno);
439			exit(1);
440		}
441
442		for (i = 0; i < 248 && name[i]; i++) {
443			if ((unsigned char) name[i] < 32 || name[i] == 127)
444				name[i] = '.';
445		}
446
447		name[248] = '\0';
448
449		print_dev_hdr(&di);
450		printf("\tName: '%s'\n", name);
451	}
452
453	hci_close_dev(dd);
454}
455
456/*
457 * see http://www.bluetooth.org/assigned-numbers/baseband.htm --- all
458 * strings are reproduced verbatim
459 */
460static char *get_minor_device_name(int major, int minor)
461{
462	switch (major) {
463	case 0:	/* misc */
464		return "";
465	case 1:	/* computer */
466		switch(minor) {
467		case 0:
468			return "Uncategorized";
469		case 1:
470			return "Desktop workstation";
471		case 2:
472			return "Server";
473		case 3:
474			return "Laptop";
475		case 4:
476			return "Handheld";
477		case 5:
478			return "Palm";
479		case 6:
480			return "Wearable";
481		}
482		break;
483	case 2:	/* phone */
484		switch(minor) {
485		case 0:
486			return "Uncategorized";
487		case 1:
488			return "Cellular";
489		case 2:
490			return "Cordless";
491		case 3:
492			return "Smart phone";
493		case 4:
494			return "Wired modem or voice gateway";
495		case 5:
496			return "Common ISDN Access";
497		case 6:
498			return "Sim Card Reader";
499		}
500		break;
501	case 3:	/* lan access */
502		if (minor == 0)
503			return "Uncategorized";
504		switch(minor / 8) {
505		case 0:
506			return "Fully available";
507		case 1:
508			return "1-17% utilized";
509		case 2:
510			return "17-33% utilized";
511		case 3:
512			return "33-50% utilized";
513		case 4:
514			return "50-67% utilized";
515		case 5:
516			return "67-83% utilized";
517		case 6:
518			return "83-99% utilized";
519		case 7:
520			return "No service available";
521		}
522		break;
523	case 4:	/* audio/video */
524		switch(minor) {
525		case 0:
526			return "Uncategorized";
527		case 1:
528			return "Device conforms to the Headset profile";
529		case 2:
530			return "Hands-free";
531			/* 3 is reserved */
532		case 4:
533			return "Microphone";
534		case 5:
535			return "Loudspeaker";
536		case 6:
537			return "Headphones";
538		case 7:
539			return "Portable Audio";
540		case 8:
541			return "Car Audio";
542		case 9:
543			return "Set-top box";
544		case 10:
545			return "HiFi Audio Device";
546		case 11:
547			return "VCR";
548		case 12:
549			return "Video Camera";
550		case 13:
551			return "Camcorder";
552		case 14:
553			return "Video Monitor";
554		case 15:
555			return "Video Display and Loudspeaker";
556		case 16:
557			return "Video Conferencing";
558			/* 17 is reserved */
559		case 18:
560			return "Gaming/Toy";
561		}
562		break;
563	case 5:	/* peripheral */ {
564		static char cls_str[48];
565
566		cls_str[0] = '\0';
567
568		switch(minor & 48) {
569		case 16:
570			strncpy(cls_str, "Keyboard", sizeof(cls_str));
571			break;
572		case 32:
573			strncpy(cls_str, "Pointing device", sizeof(cls_str));
574			break;
575		case 48:
576			strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str));
577			break;
578		}
579		if((minor & 15) && (strlen(cls_str) > 0))
580			strcat(cls_str, "/");
581
582		switch(minor & 15) {
583		case 0:
584			break;
585		case 1:
586			strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str));
587			break;
588		case 2:
589			strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str));
590			break;
591		case 3:
592			strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str));
593			break;
594		case 4:
595			strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str));
596			break;
597		case 5:
598			strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str));
599			break;
600		case 6:
601			strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str));
602			break;
603		default:
604			strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str));
605			break;
606		}
607		if(strlen(cls_str) > 0)
608			return cls_str;
609	}
610	case 6:	/* imaging */
611		if (minor & 4)
612			return "Display";
613		if (minor & 8)
614			return "Camera";
615		if (minor & 16)
616			return "Scanner";
617		if (minor & 32)
618			return "Printer";
619		break;
620	case 7: /* wearable */
621		switch(minor) {
622		case 1:
623			return "Wrist Watch";
624		case 2:
625			return "Pager";
626		case 3:
627			return "Jacket";
628		case 4:
629			return "Helmet";
630		case 5:
631			return "Glasses";
632		}
633		break;
634	case 8: /* toy */
635		switch(minor) {
636		case 1:
637			return "Robot";
638		case 2:
639			return "Vehicle";
640		case 3:
641			return "Doll / Action Figure";
642		case 4:
643			return "Controller";
644		case 5:
645			return "Game";
646		}
647		break;
648	case 63:	/* uncategorised */
649		return "";
650	}
651	return "Unknown (reserved) minor device class";
652}
653
654static void cmd_class(int ctl, int hdev, char *opt)
655{
656	static const char *services[] = { "Positioning",
657					"Networking",
658					"Rendering",
659					"Capturing",
660					"Object Transfer",
661					"Audio",
662					"Telephony",
663					"Information" };
664	static const char *major_devices[] = { "Miscellaneous",
665					"Computer",
666					"Phone",
667					"LAN Access",
668					"Audio/Video",
669					"Peripheral",
670					"Imaging",
671					"Uncategorized" };
672	int s = hci_open_dev(hdev);
673
674	if (s < 0) {
675		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
676						hdev, strerror(errno), errno);
677		exit(1);
678	}
679	if (opt) {
680		uint32_t cod = strtoul(opt, NULL, 16);
681		if (hci_write_class_of_dev(s, cod, 2000) < 0) {
682			fprintf(stderr, "Can't write local class of device on hci%d: %s (%d)\n",
683						hdev, strerror(errno), errno);
684			exit(1);
685		}
686	} else {
687		uint8_t cls[3];
688		if (hci_read_class_of_dev(s, cls, 1000) < 0) {
689			fprintf(stderr, "Can't read class of device on hci%d: %s (%d)\n",
690						hdev, strerror(errno), errno);
691			exit(1);
692		}
693		print_dev_hdr(&di);
694		printf("\tClass: 0x%02x%02x%02x\n", cls[2], cls[1], cls[0]);
695		printf("\tService Classes: ");
696		if (cls[2]) {
697			unsigned int i;
698			int first = 1;
699			for (i = 0; i < (sizeof(services) / sizeof(*services)); i++)
700				if (cls[2] & (1 << i)) {
701					if (!first)
702						printf(", ");
703					printf("%s", services[i]);
704					first = 0;
705				}
706		} else
707			printf("Unspecified");
708		printf("\n\tDevice Class: ");
709		if ((cls[1] & 0x1f) >= sizeof(major_devices) / sizeof(*major_devices))
710			printf("Invalid Device Class!\n");
711		else
712			printf("%s, %s\n", major_devices[cls[1] & 0x1f],
713				get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2));
714	}
715}
716
717static void cmd_voice(int ctl, int hdev, char *opt)
718{
719	static char *icf[] = { "Linear", "u-Law", "A-Law", "Reserved" };
720	static char *idf[] = { "1's complement", "2's complement", "Sign-Magnitude", "Reserved" };
721	static char *iss[] = { "8 bit", "16 bit" };
722	static char *acf[] = { "CVSD", "u-Law", "A-Law", "Reserved" };
723	int s = hci_open_dev(hdev);
724
725	if (s < 0) {
726		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
727						hdev, strerror(errno), errno);
728		exit(1);
729	}
730	if (opt) {
731		uint16_t vs = htobs(strtoul(opt, NULL, 16));
732		if (hci_write_voice_setting(s, vs, 2000) < 0) {
733			fprintf(stderr, "Can't write voice setting on hci%d: %s (%d)\n",
734						hdev, strerror(errno), errno);
735			exit(1);
736		}
737	} else {
738		uint16_t vs;
739		uint8_t ic;
740		if (hci_read_voice_setting(s, &vs, 1000) < 0) {
741			fprintf(stderr, "Can't read voice setting on hci%d: %s (%d)\n",
742						hdev, strerror(errno), errno);
743			exit(1);
744		}
745		vs = htobs(vs);
746		ic = (vs & 0x0300) >> 8;
747		print_dev_hdr(&di);
748		printf("\tVoice setting: 0x%04x%s\n", vs,
749			((vs & 0x03fc) == 0x0060) ? " (Default Condition)" : "");
750		printf("\tInput Coding: %s\n", icf[ic]);
751		printf("\tInput Data Format: %s\n", idf[(vs & 0xc0) >> 6]);
752		if (!ic) {
753			printf("\tInput Sample Size: %s\n", iss[(vs & 0x20) >> 5]);
754			printf("\t# of bits padding at MSB: %d\n", (vs & 0x1c) >> 2);
755		}
756		printf("\tAir Coding Format: %s\n", acf[vs & 0x03]);
757	}
758}
759
760static int get_link_key(const bdaddr_t *local, const bdaddr_t *peer, uint8_t *key)
761{
762	char filename[PATH_MAX + 1], addr[18], tmp[3], *str;
763	int i;
764
765	ba2str(local, addr);
766	create_name(filename, PATH_MAX, STORAGEDIR, addr, "linkkeys");
767
768	ba2str(peer, addr);
769	str = textfile_get(filename, addr);
770	if (!str)
771		return -EIO;
772
773	memset(tmp, 0, sizeof(tmp));
774	for (i = 0; i < 16; i++) {
775		memcpy(tmp, str + (i * 2), 2);
776		key[i] = (uint8_t) strtol(tmp, NULL, 16);
777	}
778
779	free(str);
780
781	return 0;
782}
783
784static void cmd_putkey(int ctl, int hdev, char *opt)
785{
786	struct hci_dev_info di;
787	bdaddr_t bdaddr;
788	uint8_t key[16];
789	int dd;
790
791	if (!opt)
792		return;
793
794	dd = hci_open_dev(hdev);
795	if (dd < 0) {
796		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
797						hdev, strerror(errno), errno);
798		exit(1);
799	}
800
801	if (hci_devinfo(hdev, &di) < 0) {
802		fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n",
803						hdev, strerror(errno), errno);
804		exit(1);
805	}
806
807	str2ba(opt, &bdaddr);
808	if (get_link_key(&di.bdaddr, &bdaddr, key) < 0) {
809		fprintf(stderr, "Can't find link key for %s on hci%d\n", opt, hdev);
810		exit(1);
811	}
812
813	if (hci_write_stored_link_key(dd, &bdaddr, key, 1000) < 0) {
814		fprintf(stderr, "Can't write stored link key on hci%d: %s (%d)\n",
815						hdev, strerror(errno), errno);
816		exit(1);
817	}
818
819	hci_close_dev(dd);
820}
821
822static void cmd_delkey(int ctl, int hdev, char *opt)
823{
824	bdaddr_t bdaddr;
825	uint8_t all;
826	int dd;
827
828	if (!opt)
829		return;
830
831	dd = hci_open_dev(hdev);
832	if (dd < 0) {
833		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
834						hdev, strerror(errno), errno);
835		exit(1);
836	}
837
838	if (!strcasecmp(opt, "all")) {
839		bacpy(&bdaddr, BDADDR_ANY);
840		all = 1;
841	} else {
842		str2ba(opt, &bdaddr);
843		all = 0;
844	}
845
846	if (hci_delete_stored_link_key(dd, &bdaddr, all, 1000) < 0) {
847		fprintf(stderr, "Can't delete stored link key on hci%d: %s (%d)\n",
848						hdev, strerror(errno), errno);
849		exit(1);
850	}
851
852	hci_close_dev(dd);
853}
854
855static void cmd_oob_data(int ctl, int hdev, char *opt)
856{
857	uint8_t hash[16], randomizer[16];
858	int i, dd;
859
860	dd = hci_open_dev(hdev);
861	if (dd < 0) {
862		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
863						hdev, strerror(errno), errno);
864		exit(1);
865	}
866
867	if (hci_read_local_oob_data(dd, hash, randomizer, 1000) < 0) {
868		fprintf(stderr, "Can't read local OOB data on hci%d: %s (%d)\n",
869						hdev, strerror(errno), errno);
870		exit(1);
871	}
872
873	print_dev_hdr(&di);
874	printf("\tOOB Hash:  ");
875	for (i = 0; i < 16; i++)
876		printf(" %02x", hash[i]);
877	printf("\n\tRandomizer:");
878	for (i = 0; i < 16; i++)
879		printf(" %02x", randomizer[i]);
880	printf("\n");
881
882	hci_close_dev(dd);
883}
884
885static void cmd_commands(int ctl, int hdev, char *opt)
886{
887	uint8_t cmds[64];
888	char *str;
889	int i, n, dd;
890
891	dd = hci_open_dev(hdev);
892	if (dd < 0) {
893		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
894						hdev, strerror(errno), errno);
895		exit(1);
896	}
897
898	if (hci_read_local_commands(dd, cmds, 1000) < 0) {
899		fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n",
900						hdev, strerror(errno), errno);
901		exit(1);
902	}
903
904	print_dev_hdr(&di);
905	for (i = 0; i < 64; i++) {
906		if (!cmds[i])
907			continue;
908
909		printf("%s Octet %-2d = 0x%02x (Bit",
910			i ? "\t\t ": "\tCommands:", i, cmds[i]);
911		for (n = 0; n < 8; n++)
912			if (cmds[i] & (1 << n))
913				printf(" %d", n);
914		printf(")\n");
915	}
916
917	str = hci_commandstostr(cmds, "\t", 71);
918	printf("%s\n", str);
919	bt_free(str);
920
921	hci_close_dev(dd);
922}
923
924static void cmd_version(int ctl, int hdev, char *opt)
925{
926	struct hci_version ver;
927	char *hciver, *lmpver;
928	int dd;
929
930	dd = hci_open_dev(hdev);
931	if (dd < 0) {
932		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
933						hdev, strerror(errno), errno);
934		exit(1);
935	}
936
937	if (hci_read_local_version(dd, &ver, 1000) < 0) {
938		fprintf(stderr, "Can't read version info hci%d: %s (%d)\n",
939						hdev, strerror(errno), errno);
940		exit(1);
941	}
942
943	hciver = hci_vertostr(ver.hci_ver);
944	lmpver = lmp_vertostr(ver.hci_ver);
945
946	print_dev_hdr(&di);
947	printf("\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n"
948		"\tManufacturer: %s (%d)\n",
949		hciver ? hciver : "n/a", ver.hci_ver, ver.hci_rev,
950		lmpver ? lmpver : "n/a", ver.lmp_ver, ver.lmp_subver,
951		bt_compidtostr(ver.manufacturer), ver.manufacturer);
952
953	if (hciver)
954		bt_free(hciver);
955	if (lmpver)
956		bt_free(lmpver);
957
958	hci_close_dev(dd);
959}
960
961static void cmd_inq_tpl(int ctl, int hdev, char *opt)
962{
963	int dd;
964
965	dd = hci_open_dev(hdev);
966	if (dd < 0) {
967		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
968						hdev, strerror(errno), errno);
969		exit(1);
970	}
971
972	if (opt) {
973		int8_t level = atoi(opt);
974
975		if (hci_write_inquiry_transmit_power_level(dd, level, 2000) < 0) {
976			fprintf(stderr, "Can't set inquiry transmit power level on hci%d: %s (%d)\n",
977						hdev, strerror(errno), errno);
978			exit(1);
979		}
980	} else {
981		int8_t level;
982
983		if (hci_read_inquiry_transmit_power_level(dd, &level, 1000) < 0) {
984			fprintf(stderr, "Can't read inquiry transmit power level on hci%d: %s (%d)\n",
985						hdev, strerror(errno), errno);
986			exit(1);
987		}
988
989		print_dev_hdr(&di);
990		printf("\tInquiry transmit power level: %d\n", level);
991	}
992
993	hci_close_dev(dd);
994}
995
996static void cmd_inq_mode(int ctl, int hdev, char *opt)
997{
998	int dd;
999
1000	dd = hci_open_dev(hdev);
1001	if (dd < 0) {
1002		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1003						hdev, strerror(errno), errno);
1004		exit(1);
1005	}
1006
1007	if (opt) {
1008		uint8_t mode = atoi(opt);
1009
1010		if (hci_write_inquiry_mode(dd, mode, 2000) < 0) {
1011			fprintf(stderr, "Can't set inquiry mode on hci%d: %s (%d)\n",
1012						hdev, strerror(errno), errno);
1013			exit(1);
1014		}
1015	} else {
1016		uint8_t mode;
1017
1018		if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) {
1019			fprintf(stderr, "Can't read inquiry mode on hci%d: %s (%d)\n",
1020						hdev, strerror(errno), errno);
1021			exit(1);
1022		}
1023
1024		print_dev_hdr(&di);
1025		printf("\tInquiry mode: ");
1026		switch (mode) {
1027		case 0:
1028			printf("Standard Inquiry\n");
1029			break;
1030		case 1:
1031			printf("Inquiry with RSSI\n");
1032			break;
1033		case 2:
1034			printf("Inquiry with RSSI or Extended Inquiry\n");
1035			break;
1036		default:
1037			printf("Unknown (0x%02x)\n", mode);
1038			break;
1039		}
1040	}
1041
1042	hci_close_dev(dd);
1043}
1044
1045static void cmd_inq_data(int ctl, int hdev, char *opt)
1046{
1047	int i, dd;
1048
1049	dd = hci_open_dev(hdev);
1050	if (dd < 0) {
1051		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1052						hdev, strerror(errno), errno);
1053		exit(1);
1054	}
1055
1056	if (opt) {
1057		uint8_t fec = 0, data[240];
1058		char tmp[3];
1059		int i, size;
1060
1061		memset(data, 0, sizeof(data));
1062
1063		memset(tmp, 0, sizeof(tmp));
1064		size = (strlen(opt) + 1) / 2;
1065		if (size > 240)
1066			size = 240;
1067
1068		for (i = 0; i < size; i++) {
1069			memcpy(tmp, opt + (i * 2), 2);
1070			data[i] = strtol(tmp, NULL, 16);
1071		}
1072
1073		if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) {
1074			fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n",
1075						hdev, strerror(errno), errno);
1076			exit(1);
1077		}
1078	} else {
1079		uint8_t fec, data[240], len, type, *ptr;
1080		char *str;
1081
1082		if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) {
1083			fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n",
1084						hdev, strerror(errno), errno);
1085			exit(1);
1086		}
1087
1088		print_dev_hdr(&di);
1089		printf("\tFEC %s\n\t\t", fec ? "enabled" : "disabled");
1090		for (i = 0; i < 240; i++)
1091			printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ",
1092				(i + 1) % 16 ? " " : (i < 239 ? "\n\t\t" : "\n"));
1093
1094		ptr = data;
1095		while (*ptr) {
1096			len = *ptr++;
1097			type = *ptr++;
1098			switch (type) {
1099			case 0x01:
1100				printf("\tFlags:");
1101				for (i = 0; i < len - 1; i++)
1102					printf(" 0x%2.2x", *((uint8_t *) (ptr + i)));
1103				printf("\n");
1104				break;
1105			case 0x02:
1106			case 0x03:
1107				printf("\t%s service classes:",
1108					type == 0x02 ? "Shortened" : "Complete");
1109				for (i = 0; i < (len - 1) / 2; i++) {
1110					uint16_t val = btohs(bt_get_unaligned((uint16_t *) (ptr + (i * 2))));
1111					printf(" 0x%4.4x", val);
1112				}
1113				printf("\n");
1114				break;
1115			case 0x08:
1116			case 0x09:
1117				str = malloc(len);
1118				if (str) {
1119					snprintf(str, len, "%s", ptr);
1120					for (i = 0; i < len - 1; i++) {
1121						if ((unsigned char) str[i] < 32 || str[i] == 127)
1122							str[i] = '.';
1123					}
1124					printf("\t%s local name: \'%s\'\n",
1125						type == 0x08 ? "Shortened" : "Complete", str);
1126					free(str);
1127				}
1128				break;
1129			case 0x0a:
1130				printf("\tTX power level: %d\n", *((uint8_t *) ptr));
1131				break;
1132			default:
1133				printf("\tUnknown type 0x%02x with %d bytes data\n",
1134								type, len - 1);
1135				break;
1136			}
1137
1138			ptr += (len - 1);
1139		}
1140
1141		printf("\n");
1142	}
1143
1144	hci_close_dev(dd);
1145}
1146
1147static void cmd_inq_type(int ctl, int hdev, char *opt)
1148{
1149	int dd;
1150
1151	dd = hci_open_dev(hdev);
1152	if (dd < 0) {
1153		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1154						hdev, strerror(errno), errno);
1155		exit(1);
1156	}
1157
1158	if (opt) {
1159		uint8_t type = atoi(opt);
1160
1161		if (hci_write_inquiry_scan_type(dd, type, 2000) < 0) {
1162			fprintf(stderr, "Can't set inquiry scan type on hci%d: %s (%d)\n",
1163						hdev, strerror(errno), errno);
1164			exit(1);
1165		}
1166	} else {
1167		uint8_t type;
1168
1169		if (hci_read_inquiry_scan_type(dd, &type, 1000) < 0) {
1170			fprintf(stderr, "Can't read inquiry scan type on hci%d: %s (%d)\n",
1171						hdev, strerror(errno), errno);
1172			exit(1);
1173		}
1174
1175		print_dev_hdr(&di);
1176		printf("\tInquiry scan type: %s\n",
1177			type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan");
1178	}
1179
1180	hci_close_dev(dd);
1181}
1182
1183static void cmd_inq_parms(int ctl, int hdev, char *opt)
1184{
1185	struct hci_request rq;
1186	int s;
1187
1188	if ((s = hci_open_dev(hdev)) < 0) {
1189		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1190						hdev, strerror(errno), errno);
1191		exit(1);
1192	}
1193
1194	memset(&rq, 0, sizeof(rq));
1195
1196	if (opt) {
1197		unsigned int window, interval;
1198		write_inq_activity_cp cp;
1199
1200		if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) {
1201			printf("Invalid argument format\n");
1202			exit(1);
1203		}
1204
1205		rq.ogf = OGF_HOST_CTL;
1206		rq.ocf = OCF_WRITE_INQ_ACTIVITY;
1207		rq.cparam = &cp;
1208		rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE;
1209
1210		cp.window = htobs((uint16_t) window);
1211		cp.interval = htobs((uint16_t) interval);
1212
1213		if (window < 0x12 || window > 0x1000)
1214			printf("Warning: inquiry window out of range!\n");
1215
1216		if (interval < 0x12 || interval > 0x1000)
1217			printf("Warning: inquiry interval out of range!\n");
1218
1219		if (hci_send_req(s, &rq, 2000) < 0) {
1220			fprintf(stderr, "Can't set inquiry parameters name on hci%d: %s (%d)\n",
1221						hdev, strerror(errno), errno);
1222			exit(1);
1223		}
1224	} else {
1225		uint16_t window, interval;
1226		read_inq_activity_rp rp;
1227
1228		rq.ogf = OGF_HOST_CTL;
1229		rq.ocf = OCF_READ_INQ_ACTIVITY;
1230		rq.rparam = &rp;
1231		rq.rlen = READ_INQ_ACTIVITY_RP_SIZE;
1232
1233		if (hci_send_req(s, &rq, 1000) < 0) {
1234			fprintf(stderr, "Can't read inquiry parameters on hci%d: %s (%d)\n",
1235						hdev, strerror(errno), errno);
1236			exit(1);
1237		}
1238		if (rp.status) {
1239			printf("Read inquiry parameters on hci%d returned status %d\n",
1240							hdev, rp.status);
1241			exit(1);
1242		}
1243		print_dev_hdr(&di);
1244
1245		window   = btohs(rp.window);
1246		interval = btohs(rp.interval);
1247		printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n",
1248				interval, (float)interval * 0.625, window, (float)window * 0.625);
1249	}
1250}
1251
1252static void cmd_page_parms(int ctl, int hdev, char *opt)
1253{
1254	struct hci_request rq;
1255	int s;
1256
1257	if ((s = hci_open_dev(hdev)) < 0) {
1258		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1259						hdev, strerror(errno), errno);
1260		exit(1);
1261	}
1262
1263	memset(&rq, 0, sizeof(rq));
1264
1265	if (opt) {
1266		unsigned int window, interval;
1267		write_page_activity_cp cp;
1268
1269		if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) {
1270			printf("Invalid argument format\n");
1271			exit(1);
1272		}
1273
1274		rq.ogf = OGF_HOST_CTL;
1275		rq.ocf = OCF_WRITE_PAGE_ACTIVITY;
1276		rq.cparam = &cp;
1277		rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE;
1278
1279		cp.window = htobs((uint16_t) window);
1280		cp.interval = htobs((uint16_t) interval);
1281
1282		if (window < 0x12 || window > 0x1000)
1283			printf("Warning: page window out of range!\n");
1284
1285		if (interval < 0x12 || interval > 0x1000)
1286			printf("Warning: page interval out of range!\n");
1287
1288		if (hci_send_req(s, &rq, 2000) < 0) {
1289			fprintf(stderr, "Can't set page parameters name on hci%d: %s (%d)\n",
1290						hdev, strerror(errno), errno);
1291			exit(1);
1292		}
1293	} else {
1294		uint16_t window, interval;
1295		read_page_activity_rp rp;
1296
1297		rq.ogf = OGF_HOST_CTL;
1298		rq.ocf = OCF_READ_PAGE_ACTIVITY;
1299		rq.rparam = &rp;
1300		rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE;
1301
1302		if (hci_send_req(s, &rq, 1000) < 0) {
1303			fprintf(stderr, "Can't read page parameters on hci%d: %s (%d)\n",
1304						hdev, strerror(errno), errno);
1305			exit(1);
1306		}
1307		if (rp.status) {
1308			printf("Read page parameters on hci%d returned status %d\n",
1309							hdev, rp.status);
1310			exit(1);
1311		}
1312		print_dev_hdr(&di);
1313
1314		window   = btohs(rp.window);
1315		interval = btohs(rp.interval);
1316		printf("\tPage interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n",
1317				interval, (float)interval * 0.625, window, (float)window * 0.625);
1318	}
1319}
1320
1321static void cmd_page_to(int ctl, int hdev, char *opt)
1322{
1323	struct hci_request rq;
1324	int s;
1325
1326	if ((s = hci_open_dev(hdev)) < 0) {
1327		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1328						hdev, strerror(errno), errno);
1329		exit(1);
1330	}
1331
1332	memset(&rq, 0, sizeof(rq));
1333
1334	if (opt) {
1335		unsigned int timeout;
1336		write_page_timeout_cp cp;
1337
1338		if (sscanf(opt,"%5u", &timeout) != 1) {
1339			printf("Invalid argument format\n");
1340			exit(1);
1341		}
1342
1343		rq.ogf = OGF_HOST_CTL;
1344		rq.ocf = OCF_WRITE_PAGE_TIMEOUT;
1345		rq.cparam = &cp;
1346		rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE;
1347
1348		cp.timeout = htobs((uint16_t) timeout);
1349
1350		if (timeout < 0x01 || timeout > 0xFFFF)
1351			printf("Warning: page timeout out of range!\n");
1352
1353		if (hci_send_req(s, &rq, 2000) < 0) {
1354			fprintf(stderr, "Can't set page timeout on hci%d: %s (%d)\n",
1355						hdev, strerror(errno), errno);
1356			exit(1);
1357		}
1358	} else {
1359		uint16_t timeout;
1360		read_page_timeout_rp rp;
1361
1362		rq.ogf = OGF_HOST_CTL;
1363		rq.ocf = OCF_READ_PAGE_TIMEOUT;
1364		rq.rparam = &rp;
1365		rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE;
1366
1367		if (hci_send_req(s, &rq, 1000) < 0) {
1368			fprintf(stderr, "Can't read page timeout on hci%d: %s (%d)\n",
1369						hdev, strerror(errno), errno);
1370			exit(1);
1371		}
1372		if (rp.status) {
1373			printf("Read page timeout on hci%d returned status %d\n",
1374							hdev, rp.status);
1375			exit(1);
1376		}
1377		print_dev_hdr(&di);
1378
1379		timeout = btohs(rp.timeout);
1380		printf("\tPage timeout: %u slots (%.2f ms)\n",
1381				timeout, (float)timeout * 0.625);
1382	}
1383}
1384
1385static void cmd_afh_mode(int ctl, int hdev, char *opt)
1386{
1387	int dd;
1388
1389	dd = hci_open_dev(hdev);
1390	if (dd < 0) {
1391		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1392						hdev, strerror(errno), errno);
1393		exit(1);
1394	}
1395
1396	if (opt) {
1397		uint8_t mode = atoi(opt);
1398
1399		if (hci_write_afh_mode(dd, mode, 2000) < 0) {
1400			fprintf(stderr, "Can't set AFH mode on hci%d: %s (%d)\n",
1401						hdev, strerror(errno), errno);
1402			exit(1);
1403		}
1404	} else {
1405		uint8_t mode;
1406
1407		if (hci_read_afh_mode(dd, &mode, 1000) < 0) {
1408			fprintf(stderr, "Can't read AFH mode on hci%d: %s (%d)\n",
1409						hdev, strerror(errno), errno);
1410			exit(1);
1411		}
1412
1413		print_dev_hdr(&di);
1414		printf("\tAFH mode: %s\n", mode == 1 ? "Enabled" : "Disabled");
1415	}
1416}
1417
1418static void cmd_ssp_mode(int ctl, int hdev, char *opt)
1419{
1420	int dd;
1421
1422	dd = hci_open_dev(hdev);
1423	if (dd < 0) {
1424		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1425						hdev, strerror(errno), errno);
1426		exit(1);
1427	}
1428
1429	if (opt) {
1430		uint8_t mode = atoi(opt);
1431
1432		if (hci_write_simple_pairing_mode(dd, mode, 2000) < 0) {
1433			fprintf(stderr, "Can't set Simple Pairing mode on hci%d: %s (%d)\n",
1434						hdev, strerror(errno), errno);
1435			exit(1);
1436		}
1437	} else {
1438		uint8_t mode;
1439
1440		if (hci_read_simple_pairing_mode(dd, &mode, 1000) < 0) {
1441			fprintf(stderr, "Can't read Simple Pairing mode on hci%d: %s (%d)\n",
1442						hdev, strerror(errno), errno);
1443			exit(1);
1444		}
1445
1446		print_dev_hdr(&di);
1447		printf("\tSimple Pairing mode: %s\n", mode == 1 ? "Enabled" : "Disabled");
1448	}
1449}
1450
1451static void print_rev_ericsson(int dd)
1452{
1453	struct hci_request rq;
1454	unsigned char buf[102];
1455
1456	memset(&rq, 0, sizeof(rq));
1457	rq.ogf    = OGF_VENDOR_CMD;
1458	rq.ocf    = 0x000f;
1459	rq.cparam = NULL;
1460	rq.clen   = 0;
1461	rq.rparam = &buf;
1462	rq.rlen   = sizeof(buf);
1463
1464	if (hci_send_req(dd, &rq, 1000) < 0) {
1465		printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno);
1466		return;
1467	}
1468
1469	printf("\t%s\n", buf + 1);
1470}
1471
1472static void print_rev_csr(int dd, uint16_t rev)
1473{
1474	uint16_t buildid, chipver, chiprev, maxkeylen, mapsco;
1475
1476	if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) {
1477		printf("\t%s\n", csr_buildidtostr(rev));
1478		return;
1479	}
1480
1481	printf("\t%s\n", csr_buildidtostr(buildid));
1482
1483	if (!csr_read_varid_uint16(dd, 1, CSR_VARID_CHIPVER, &chipver)) {
1484		if (csr_read_varid_uint16(dd, 2, CSR_VARID_CHIPREV, &chiprev) < 0)
1485			chiprev = 0;
1486		printf("\tChip version: %s\n", csr_chipvertostr(chipver, chiprev));
1487	}
1488
1489	if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen))
1490		printf("\tMax key size: %d bit\n", maxkeylen * 8);
1491
1492	if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, 0x0000, &mapsco))
1493		printf("\tSCO mapping:  %s\n", mapsco ? "PCM" : "HCI");
1494}
1495
1496static void print_rev_digianswer(int dd)
1497{
1498	struct hci_request rq;
1499	unsigned char req[] = { 0x07 };
1500	unsigned char buf[102];
1501
1502	memset(&rq, 0, sizeof(rq));
1503	rq.ogf    = OGF_VENDOR_CMD;
1504	rq.ocf    = 0x000e;
1505	rq.cparam = req;
1506	rq.clen   = sizeof(req);
1507	rq.rparam = &buf;
1508	rq.rlen   = sizeof(buf);
1509
1510	if (hci_send_req(dd, &rq, 1000) < 0) {
1511		printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno);
1512		return;
1513	}
1514
1515	printf("\t%s\n", buf + 1);
1516}
1517
1518static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver)
1519{
1520	printf("\tFirmware %d.%d / %d\n", hci_rev & 0xff, lmp_subver >> 8, lmp_subver & 0xff);
1521}
1522
1523static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver)
1524{
1525	if (lmp_subver == 0x01)
1526		printf("\tFirmware 03.%d.%d\n", hci_rev >> 8, hci_rev & 0xff);
1527	else
1528		printf("\tUnknown type\n");
1529}
1530
1531static void cmd_revision(int ctl, int hdev, char *opt)
1532{
1533	struct hci_version ver;
1534	int dd;
1535
1536	dd = hci_open_dev(hdev);
1537	if (dd < 0) {
1538		fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
1539						hdev, strerror(errno), errno);
1540		return;
1541	}
1542
1543	if (hci_read_local_version(dd, &ver, 1000) < 0) {
1544		fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n",
1545						hdev, strerror(errno), errno);
1546		return;
1547	}
1548
1549	print_dev_hdr(&di);
1550	switch (ver.manufacturer) {
1551	case 0:
1552	case 37:
1553	case 48:
1554		print_rev_ericsson(dd);
1555		break;
1556	case 10:
1557		print_rev_csr(dd, ver.hci_rev);
1558		break;
1559	case 12:
1560		print_rev_digianswer(dd);
1561		break;
1562	case 15:
1563		print_rev_broadcom(ver.hci_rev, ver.lmp_subver);
1564		break;
1565	case 31:
1566		print_rev_avm(ver.hci_rev, ver.lmp_subver);
1567		break;
1568	default:
1569		printf("\tUnsupported manufacturer\n");
1570		break;
1571	}
1572	return;
1573}
1574
1575static void print_dev_hdr(struct hci_dev_info *di)
1576{
1577	static int hdr = -1;
1578	char addr[18];
1579
1580	if (hdr == di->dev_id)
1581		return;
1582	hdr = di->dev_id;
1583
1584	ba2str(&di->bdaddr, addr);
1585
1586	printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) );
1587	printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n",
1588		addr, di->acl_mtu, di->acl_pkts,
1589		di->sco_mtu, di->sco_pkts);
1590}
1591
1592static void print_dev_info(int ctl, struct hci_dev_info *di)
1593{
1594	struct hci_dev_stats *st = &di->stat;
1595	char *str;
1596
1597	print_dev_hdr(di);
1598
1599	str = hci_dflagstostr(di->flags);
1600	printf("\t%s\n", str);
1601	bt_free(str);
1602
1603	printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n",
1604		st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx);
1605
1606	printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n",
1607		st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx);
1608
1609	if (all && !hci_test_bit(HCI_RAW, &di->flags) &&
1610			bacmp(&di->bdaddr, BDADDR_ANY)) {
1611		print_dev_features(di, 0);
1612		print_pkt_type(di);
1613		print_link_policy(di);
1614		print_link_mode(di);
1615
1616		if (hci_test_bit(HCI_UP, &di->flags)) {
1617			cmd_name(ctl, di->dev_id, NULL);
1618			cmd_class(ctl, di->dev_id, NULL);
1619			cmd_version(ctl, di->dev_id, NULL);
1620		}
1621	}
1622
1623	printf("\n");
1624}
1625
1626static struct {
1627	char *cmd;
1628	void (*func)(int ctl, int hdev, char *opt);
1629	char *opt;
1630	char *doc;
1631} command[] = {
1632	{ "up",		cmd_up,		0,		"Open and initialize HCI device" },
1633	{ "down",	cmd_down,	0,		"Close HCI device" },
1634	{ "reset",	cmd_reset,	0,		"Reset HCI device" },
1635	{ "rstat",	cmd_rstat,	0,		"Reset statistic counters" },
1636	{ "auth",	cmd_auth,	0,		"Enable Authentication" },
1637	{ "noauth",	cmd_auth,	0,		"Disable Authentication" },
1638	{ "encrypt",	cmd_encrypt,	0,		"Enable Encryption" },
1639	{ "noencrypt",	cmd_encrypt,	0,		"Disable Encryption" },
1640	{ "piscan",	cmd_scan,	0,		"Enable Page and Inquiry scan" },
1641	{ "noscan",	cmd_scan,	0,		"Disable scan" },
1642	{ "iscan",	cmd_scan,	0,		"Enable Inquiry scan" },
1643	{ "pscan",	cmd_scan,	0,		"Enable Page scan" },
1644	{ "ptype",	cmd_ptype,	"[type]",	"Get/Set default packet type" },
1645	{ "lm",		cmd_lm,		"[mode]",	"Get/Set default link mode"   },
1646	{ "lp",		cmd_lp,		"[policy]",	"Get/Set default link policy" },
1647	{ "name",	cmd_name,	"[name]",	"Get/Set local name" },
1648	{ "class",	cmd_class,	"[class]",	"Get/Set class of device" },
1649	{ "voice",	cmd_voice,	"[voice]",	"Get/Set voice setting" },
1650	{ "iac",	cmd_iac,	"[iac]",	"Get/Set inquiry access code" },
1651	{ "inqtpl", 	cmd_inq_tpl,	"[level]",	"Get/Set inquiry transmit power level" },
1652	{ "inqmode",	cmd_inq_mode,	"[mode]",	"Get/Set inquiry mode" },
1653	{ "inqdata",	cmd_inq_data,	"[data]",	"Get/Set inquiry data" },
1654	{ "inqtype",	cmd_inq_type,	"[type]",	"Get/Set inquiry scan type" },
1655	{ "inqparms",	cmd_inq_parms,	"[win:int]",	"Get/Set inquiry scan window and interval" },
1656	{ "pageparms",	cmd_page_parms,	"[win:int]",	"Get/Set page scan window and interval" },
1657	{ "pageto",	cmd_page_to,	"[to]",		"Get/Set page timeout" },
1658	{ "afhmode",	cmd_afh_mode,	"[mode]",	"Get/Set AFH mode" },
1659	{ "sspmode",	cmd_ssp_mode,	"[mode]",	"Get/Set Simple Pairing Mode" },
1660	{ "aclmtu",	cmd_aclmtu,	"<mtu:pkt>",	"Set ACL MTU and number of packets" },
1661	{ "scomtu",	cmd_scomtu,	"<mtu:pkt>",	"Set SCO MTU and number of packets" },
1662	{ "putkey",	cmd_putkey,	"<bdaddr>",	"Store link key on the device" },
1663	{ "delkey",	cmd_delkey,	"<bdaddr>",	"Delete link key from the device" },
1664	{ "oobdata",	cmd_oob_data,	0,		"Display local OOB data" },
1665	{ "commands",	cmd_commands,	0,		"Display supported commands" },
1666	{ "features",	cmd_features,	0,		"Display device features" },
1667	{ "version",	cmd_version,	0,		"Display version information" },
1668	{ "revision",	cmd_revision,	0,		"Display revision information" },
1669	{ NULL, NULL, 0 }
1670};
1671
1672static void usage(void)
1673{
1674	int i;
1675
1676	printf("hciconfig - HCI device configuration utility\n");
1677	printf("Usage:\n"
1678		"\thciconfig\n"
1679		"\thciconfig [-a] hciX [command]\n");
1680	printf("Commands:\n");
1681	for (i=0; command[i].cmd; i++)
1682		printf("\t%-10s %-8s\t%s\n", command[i].cmd,
1683		command[i].opt ? command[i].opt : " ",
1684		command[i].doc);
1685}
1686
1687static struct option main_options[] = {
1688	{ "help",	0, 0, 'h' },
1689	{ "all",	0, 0, 'a' },
1690	{ 0, 0, 0, 0 }
1691};
1692
1693int main(int argc, char *argv[])
1694{
1695	int opt, ctl, i, cmd=0;
1696
1697	while ((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) {
1698		switch(opt) {
1699		case 'a':
1700			all = 1;
1701			break;
1702
1703		case 'h':
1704		default:
1705			usage();
1706			exit(0);
1707		}
1708	}
1709
1710	argc -= optind;
1711	argv += optind;
1712	optind = 0;
1713
1714	/* Open HCI socket  */
1715	if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
1716		perror("Can't open HCI socket.");
1717		exit(1);
1718	}
1719
1720	if (argc < 1) {
1721		print_dev_list(ctl, 0);
1722		exit(0);
1723	}
1724
1725	di.dev_id = atoi(argv[0] + 3);
1726	argc--; argv++;
1727
1728	if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) {
1729		perror("Can't get device info");
1730		exit(1);
1731	}
1732
1733	if (hci_test_bit(HCI_RAW, &di.flags) &&
1734			!bacmp(&di.bdaddr, BDADDR_ANY)) {
1735		int dd = hci_open_dev(di.dev_id);
1736		hci_read_bd_addr(dd, &di.bdaddr, 1000);
1737		hci_close_dev(dd);
1738	}
1739
1740	while (argc > 0) {
1741		for (i = 0; command[i].cmd; i++) {
1742			if (strncmp(command[i].cmd, *argv, 5))
1743				continue;
1744
1745			if (command[i].opt) {
1746				argc--; argv++;
1747			}
1748
1749			command[i].func(ctl, di.dev_id, *argv);
1750			cmd = 1;
1751			break;
1752		}
1753		argc--; argv++;
1754	}
1755
1756	if (!cmd)
1757		print_dev_info(ctl, &di);
1758
1759	close(ctl);
1760	return 0;
1761}
1762