hciops.c revision 0133f1bc40e609103b90b7544e17aa19819c3c03
1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
6 *
7 *  This program is free software; you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation; either version 2 of the License, or
10 *  (at your option) any later version.
11 *
12 *  This program is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *  GNU General Public License for more details.
16 *
17 *  You should have received a copy of the GNU General Public License
18 *  along with this program; if not, write to the Free Software
19 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdio.h>
28#include <errno.h>
29#include <unistd.h>
30#include <stdlib.h>
31#include <sys/types.h>
32#include <sys/ioctl.h>
33#include <sys/wait.h>
34
35#include <bluetooth/bluetooth.h>
36#include <bluetooth/hci.h>
37#include <bluetooth/hci_lib.h>
38
39#include <glib.h>
40
41#include "hcid.h"
42#include "sdpd.h"
43#include "adapter.h"
44#include "plugin.h"
45#include "log.h"
46#include "manager.h"
47
48static int child_pipe[2] = { -1, -1 };
49
50static guint child_io_id = 0;
51static guint ctl_io_id = 0;
52
53static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data)
54{
55	int status, fd = g_io_channel_unix_get_fd(io);
56	pid_t child_pid;
57
58	if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) {
59		error("child_exit: unable to read child pid from pipe");
60		return TRUE;
61	}
62
63	if (waitpid(child_pid, &status, 0) != child_pid)
64		error("waitpid(%d) failed", child_pid);
65	else
66		DBG("child %d exited", child_pid);
67
68	return TRUE;
69}
70
71static void at_child_exit(void)
72{
73	pid_t pid = getpid();
74
75	if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid))
76		error("unable to write to child pipe");
77}
78
79static void device_devup_setup(int index)
80{
81	struct hci_dev_info di;
82	uint16_t policy;
83	int dd;
84
85	if (hci_devinfo(index, &di) < 0)
86		return;
87
88	if (ignore_device(&di))
89		return;
90
91	dd = hci_open_dev(index);
92	if (dd < 0) {
93		error("Can't open device hci%d: %s (%d)", index,
94						strerror(errno), errno);
95		return;
96	}
97
98	/* Set page timeout */
99	if ((main_opts.flags & (1 << HCID_SET_PAGETO))) {
100		write_page_timeout_cp cp;
101
102		cp.timeout = htobs(main_opts.pageto);
103		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT,
104					WRITE_PAGE_TIMEOUT_CP_SIZE, &cp);
105	}
106
107	/* Set default link policy */
108	policy = htobs(main_opts.link_policy);
109	hci_send_cmd(dd, OGF_LINK_POLICY, OCF_WRITE_DEFAULT_LINK_POLICY,
110								2, &policy);
111
112	hci_close_dev(dd);
113
114	start_security_manager(index);
115
116	/* Return value 1 means ioctl(DEVDOWN) was performed */
117	if (manager_start_adapter(index) == 1)
118		stop_security_manager(index);
119}
120
121static void init_device(int index)
122{
123	struct hci_dev_req dr;
124	struct hci_dev_info di;
125	pid_t pid;
126	int dd;
127
128	/* Do initialization in the separate process */
129	pid = fork();
130	switch (pid) {
131		case 0:
132			atexit(at_child_exit);
133			break;
134		case -1:
135			error("Fork failed. Can't init device hci%d: %s (%d)",
136					index, strerror(errno), errno);
137		default:
138			DBG("child %d forked", pid);
139			return;
140	}
141
142	dd = hci_open_dev(index);
143	if (dd < 0) {
144		error("Can't open device hci%d: %s (%d)",
145					index, strerror(errno), errno);
146		exit(1);
147	}
148
149	memset(&dr, 0, sizeof(dr));
150	dr.dev_id = index;
151
152	/* Set link mode */
153	dr.dev_opt = main_opts.link_mode;
154	if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0)
155		error("Can't set link mode on hci%d: %s (%d)",
156						index, strerror(errno), errno);
157
158	/* Set link policy for BR/EDR HCI devices */
159	if (hci_devinfo(index, &di) < 0)
160		goto fail;
161
162	if (!ignore_device(&di)) {
163		dr.dev_opt = main_opts.link_policy;
164		if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
165							errno != ENETDOWN) {
166			error("Can't set link policy on hci%d: %s (%d)",
167						index, strerror(errno), errno);
168		}
169	}
170
171	/* Start HCI device */
172	if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) {
173		error("Can't init device hci%d: %s (%d)",
174					index, strerror(errno), errno);
175		goto fail;
176	}
177
178	hci_close_dev(dd);
179	exit(0);
180
181fail:
182	hci_close_dev(dd);
183	exit(1);
184}
185
186static void device_devreg_setup(int index)
187{
188	struct hci_dev_info di;
189	gboolean devup;
190
191	init_device(index);
192
193	memset(&di, 0, sizeof(di));
194
195	if (hci_devinfo(index, &di) < 0)
196		return;
197
198	devup = hci_test_bit(HCI_UP, &di.flags);
199
200	if (!ignore_device(&di))
201		manager_register_adapter(index, devup);
202}
203
204static void device_event(int event, int index)
205{
206	switch (event) {
207	case HCI_DEV_REG:
208		info("HCI dev %d registered", index);
209		device_devreg_setup(index);
210		break;
211
212	case HCI_DEV_UNREG:
213		info("HCI dev %d unregistered", index);
214		manager_unregister_adapter(index);
215		break;
216
217	case HCI_DEV_UP:
218		info("HCI dev %d up", index);
219		device_devup_setup(index);
220		break;
221
222	case HCI_DEV_DOWN:
223		info("HCI dev %d down", index);
224		manager_stop_adapter(index);
225		stop_security_manager(index);
226		break;
227	}
228}
229
230static int init_known_adapters(int ctl)
231{
232	struct hci_dev_list_req *dl;
233	struct hci_dev_req *dr;
234	int i, err;
235	size_t req_size;
236
237	req_size = HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t);
238
239	dl = g_try_malloc0(req_size);
240	if (!dl) {
241		error("Can't allocate devlist buffer");
242		return -ENOMEM;
243	}
244
245	dl->dev_num = HCI_MAX_DEV;
246	dr = dl->dev_req;
247
248	if (ioctl(ctl, HCIGETDEVLIST, dl) < 0) {
249		err = -errno;
250		error("Can't get device list: %s (%d)", strerror(-err), -err);
251		g_free(dl);
252		return err;
253	}
254
255	for (i = 0; i < dl->dev_num; i++, dr++) {
256		device_event(HCI_DEV_REG, dr->dev_id);
257
258		if (hci_test_bit(HCI_UP, &dr->dev_opt))
259			device_event(HCI_DEV_UP, dr->dev_id);
260	}
261
262	g_free(dl);
263	return 0;
264}
265
266static gboolean io_stack_event(GIOChannel *chan, GIOCondition cond,
267								gpointer data)
268{
269	unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr;
270	evt_stack_internal *si;
271	evt_si_device *sd;
272	hci_event_hdr *eh;
273	int type;
274	size_t len;
275	GIOError err;
276
277	ptr = buf;
278
279	err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len);
280	if (err) {
281		if (err == G_IO_ERROR_AGAIN)
282			return TRUE;
283
284		error("Read from control socket failed: %s (%d)",
285						strerror(errno), errno);
286		return FALSE;
287	}
288
289	type = *ptr++;
290
291	if (type != HCI_EVENT_PKT)
292		return TRUE;
293
294	eh = (hci_event_hdr *) ptr;
295	if (eh->evt != EVT_STACK_INTERNAL)
296		return TRUE;
297
298	ptr += HCI_EVENT_HDR_SIZE;
299
300	si = (evt_stack_internal *) ptr;
301	switch (si->type) {
302	case EVT_SI_DEVICE:
303		sd = (void *) &si->data;
304		device_event(sd->event, sd->dev_id);
305		break;
306	}
307
308	return TRUE;
309}
310
311static int hciops_setup(void)
312{
313	struct sockaddr_hci addr;
314	struct hci_filter flt;
315	GIOChannel *ctl_io, *child_io;
316	int sock, err;
317
318	if (child_pipe[0] != -1)
319		return -EALREADY;
320
321	if (pipe(child_pipe) < 0) {
322		err = -errno;
323		error("pipe(): %s (%d)", strerror(-err), -err);
324		return err;
325	}
326
327	child_io = g_io_channel_unix_new(child_pipe[0]);
328	g_io_channel_set_close_on_unref(child_io, TRUE);
329	child_io_id = g_io_add_watch(child_io,
330				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
331				child_exit, NULL);
332	g_io_channel_unref(child_io);
333
334	/* Create and bind HCI socket */
335	sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
336	if (sock < 0) {
337		err = -errno;
338		error("Can't open HCI socket: %s (%d)", strerror(-err),
339								-err);
340		return err;
341	}
342
343	/* Set filter */
344	hci_filter_clear(&flt);
345	hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
346	hci_filter_set_event(EVT_STACK_INTERNAL, &flt);
347	if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt,
348							sizeof(flt)) < 0) {
349		err = -errno;
350		error("Can't set filter: %s (%d)", strerror(-err), -err);
351		return err;
352	}
353
354	memset(&addr, 0, sizeof(addr));
355	addr.hci_family = AF_BLUETOOTH;
356	addr.hci_dev = HCI_DEV_NONE;
357	if (bind(sock, (struct sockaddr *) &addr,
358							sizeof(addr)) < 0) {
359		err = -errno;
360		error("Can't bind HCI socket: %s (%d)",
361							strerror(-err), -err);
362		return err;
363	}
364
365	ctl_io = g_io_channel_unix_new(sock);
366	g_io_channel_set_close_on_unref(ctl_io, TRUE);
367
368	ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL);
369
370	g_io_channel_unref(ctl_io);
371
372	/* Initialize already connected devices */
373	return init_known_adapters(sock);
374}
375
376static void hciops_cleanup(void)
377{
378	if (child_io_id) {
379		g_source_remove(child_io_id);
380		child_io_id = 0;
381	}
382
383	if (ctl_io_id) {
384		g_source_remove(ctl_io_id);
385		ctl_io_id = 0;
386	}
387
388	if (child_pipe[0] >= 0) {
389		close(child_pipe[0]);
390		child_pipe[0] = -1;
391	}
392
393	if (child_pipe[1] >= 0) {
394		close(child_pipe[1]);
395		child_pipe[1] = -1;
396	}
397}
398
399static int hciops_start(int index)
400{
401	int dd;
402	int err = 0;
403
404	dd = hci_open_dev(index);
405	if (dd < 0)
406		return -EIO;
407
408	if (ioctl(dd, HCIDEVUP, index) == 0)
409		goto done; /* on success */
410
411	if (errno != EALREADY) {
412		err = -errno;
413		error("Can't init device hci%d: %s (%d)",
414				index, strerror(-err), -err);
415	}
416
417done:
418	hci_close_dev(dd);
419	return err;
420}
421
422static int hciops_stop(int index)
423{
424	int dd;
425	int err = 0;
426
427	dd = hci_open_dev(index);
428	if (dd < 0)
429		return -EIO;
430
431	if (ioctl(dd, HCIDEVDOWN, index) == 0)
432		goto done; /* on success */
433
434	if (errno != EALREADY) {
435		err = -errno;
436		error("Can't stop device hci%d: %s (%d)",
437				index, strerror(-err), -err);
438	}
439
440done:
441	hci_close_dev(dd);
442	return err;
443}
444
445static int hciops_powered(int index, gboolean powered)
446{
447	int dd, err;
448	uint8_t mode = SCAN_DISABLED;
449
450	if (powered)
451		return hciops_start(index);
452
453	dd = hci_open_dev(index);
454	if (dd < 0)
455		return -EIO;
456
457	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,
458					1, &mode);
459	if (err < 0) {
460		err = -errno;
461		hci_close_dev(dd);
462		return err;
463	}
464
465	hci_close_dev(dd);
466
467	return hciops_stop(index);
468}
469
470static int hciops_connectable(int index)
471{
472	int dd, err;
473	uint8_t mode = SCAN_PAGE;
474
475	dd = hci_open_dev(index);
476	if (dd < 0)
477		return -EIO;
478
479	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,
480					1, &mode);
481	if (err < 0)
482		err = -errno;
483
484	hci_close_dev(dd);
485
486	return err;
487}
488
489static int hciops_discoverable(int index)
490{
491	int dd, err;
492	uint8_t mode = (SCAN_PAGE | SCAN_INQUIRY);
493
494	dd = hci_open_dev(index);
495	if (dd < 0)
496		return -EIO;
497
498	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,
499					1, &mode);
500	if (err < 0)
501		err = -errno;
502
503	hci_close_dev(dd);
504
505	return err;
506}
507
508static int hciops_set_class(int index, uint32_t class)
509{
510	int dd, err;
511	write_class_of_dev_cp cp;
512
513	dd = hci_open_dev(index);
514	if (dd < 0)
515		return -EIO;
516
517	memcpy(cp.dev_class, &class, 3);
518
519	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV,
520					WRITE_CLASS_OF_DEV_CP_SIZE, &cp);
521
522	if (err < 0)
523		err = -errno;
524
525	hci_close_dev(dd);
526
527	return err;
528}
529
530static int hciops_set_limited_discoverable(int index, uint32_t class,
531							gboolean limited)
532{
533	int dd, err;
534	int num = (limited ? 2 : 1);
535	uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e };
536	write_current_iac_lap_cp cp;
537
538	/*
539	 * 1: giac
540	 * 2: giac + liac
541	 */
542	dd = hci_open_dev(index);
543	if (dd < 0)
544		return -EIO;
545
546	memset(&cp, 0, sizeof(cp));
547	cp.num_current_iac = num;
548	memcpy(&cp.lap, lap, num * 3);
549
550	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CURRENT_IAC_LAP,
551			(num * 3 + 1), &cp);
552	if (err < 0) {
553		err = -errno;
554		goto fail;
555	}
556
557	err = hciops_set_class(index, class);
558
559fail:
560	hci_close_dev(dd);
561	return err;
562}
563
564static int hciops_start_discovery(int index, gboolean periodic)
565{
566	uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
567	int dd, err;
568
569	dd = hci_open_dev(index);
570	if (dd < 0)
571		return -EIO;
572
573	if (periodic) {
574		periodic_inquiry_cp cp;
575
576		memset(&cp, 0, sizeof(cp));
577		memcpy(&cp.lap, lap, 3);
578		cp.max_period = htobs(24);
579		cp.min_period = htobs(16);
580		cp.length  = 0x08;
581		cp.num_rsp = 0x00;
582
583		err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY,
584					PERIODIC_INQUIRY_CP_SIZE, &cp);
585	} else {
586		inquiry_cp inq_cp;
587
588		memset(&inq_cp, 0, sizeof(inq_cp));
589		memcpy(&inq_cp.lap, lap, 3);
590		inq_cp.length = 0x08;
591		inq_cp.num_rsp = 0x00;
592
593		err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY,
594					INQUIRY_CP_SIZE, &inq_cp);
595	}
596
597	if (err < 0)
598		err = -errno;
599
600	hci_close_dev(dd);
601
602	return err;
603}
604
605static int hciops_stop_discovery(int index)
606{
607	struct hci_dev_info di;
608	int dd, err;
609
610	if (hci_devinfo(index, &di) < 0)
611		return -errno;
612
613	dd = hci_open_dev(index);
614	if (dd < 0)
615		return -EIO;
616
617	if (hci_test_bit(HCI_INQUIRY, &di.flags))
618		err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY_CANCEL, 0, 0);
619	else
620		err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY,
621									0, 0);
622	if (err < 0)
623		err = -errno;
624
625	hci_close_dev(dd);
626
627	return err;
628}
629
630static int hciops_resolve_name(int index, bdaddr_t *bdaddr)
631{
632	remote_name_req_cp cp;
633	int dd, err;
634
635	dd = hci_open_dev(index);
636	if (dd < 0)
637		return -EIO;
638
639	memset(&cp, 0, sizeof(cp));
640	bacpy(&cp.bdaddr, bdaddr);
641	cp.pscan_rep_mode = 0x02;
642
643	err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ,
644						REMOTE_NAME_REQ_CP_SIZE, &cp);
645	if (err < 0)
646		err = -errno;
647
648	hci_close_dev(dd);
649
650	return err;
651}
652
653static int hciops_set_name(int index, const char *name)
654{
655	change_local_name_cp cp;
656	int dd, err;
657
658	dd = hci_open_dev(index);
659	if (dd < 0)
660		return -EIO;
661
662	memset(&cp, 0, sizeof(cp));
663	strncpy((char *) cp.name, name, sizeof(cp.name));
664
665	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME,
666					CHANGE_LOCAL_NAME_CP_SIZE, &cp);
667	if (err < 0)
668		err = -errno;
669
670	hci_close_dev(dd);
671
672	return err;
673}
674
675static int hciops_read_name(int index)
676{
677	int dd, err;
678
679	dd = hci_open_dev(index);
680	if (dd < 0)
681		return -EIO;
682
683	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_READ_LOCAL_NAME, 0, 0);
684	if (err < 0)
685		err = -errno;
686
687	hci_close_dev(dd);
688
689	return err;
690}
691
692static int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr)
693{
694	remote_name_req_cancel_cp cp;
695	int dd, err;
696
697	dd = hci_open_dev(index);
698	if (dd < 0)
699		return -EIO;
700
701	memset(&cp, 0, sizeof(cp));
702	bacpy(&cp.bdaddr, bdaddr);
703
704	err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL,
705					REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp);
706	if (err < 0)
707		err = -errno;
708
709	hci_close_dev(dd);
710
711	return err;
712}
713
714static int hciops_fast_connectable(int index, gboolean enable)
715{
716	int dd, err = 0;
717	write_page_activity_cp cp;
718	uint8_t type;
719
720	if (enable) {
721		type = PAGE_SCAN_TYPE_INTERLACED;
722		cp.interval = 0x0024;	/* 22.5 msec page scan interval */
723	} else {
724		type = PAGE_SCAN_TYPE_STANDARD;	/* default */
725		cp.interval = 0x0800;	/* default 1.28 sec page scan */
726	}
727
728	cp.window = 0x0012;	/* default 11.25 msec page scan window */
729
730	dd = hci_open_dev(index);
731	if (dd < 0)
732		return -EIO;
733
734	if (hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_ACTIVITY,
735					WRITE_PAGE_ACTIVITY_CP_SIZE, &cp) < 0)
736		err = -errno;
737	else if (hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_SCAN_TYPE,
738								1, &type) < 0)
739		err = -errno;
740
741	hci_close_dev(dd);
742
743	return err;
744}
745
746static int hciops_read_clock(int index, int handle, int which, int timeout,
747					uint32_t *clock, uint16_t *accuracy)
748{
749	int dd, err = 0;
750
751	dd = hci_open_dev(index);
752	if (dd < 0)
753		return -EIO;
754
755	if (hci_read_clock(dd, handle, which, clock, accuracy, timeout) < 0)
756		err = -errno;
757
758	hci_close_dev(dd);
759
760	return err;
761}
762
763static int hciops_conn_handle(int index, const bdaddr_t *bdaddr, int *handle)
764{
765	struct hci_conn_info_req *cr;
766	int dd, err = 0;
767
768	dd = hci_open_dev(index);
769	if (dd < 0)
770		return -EIO;
771
772	cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
773	bacpy(&cr->bdaddr, bdaddr);
774	cr->type = ACL_LINK;
775
776	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
777		err = -errno;
778		goto fail;
779	}
780
781	*handle = htobs(cr->conn_info->handle);
782
783fail:
784	hci_close_dev(dd);
785	g_free(cr);
786	return err;
787}
788
789static int hciops_write_eir_data(int index, uint8_t *data)
790{
791	uint8_t fec = 0;
792	int ret, dd;
793
794	dd = hci_open_dev(index);
795	if (dd < 0)
796		return -errno;
797
798	if (hci_write_ext_inquiry_response(dd, fec, data, HCI_REQ_TIMEOUT) < 0)
799		ret = -errno;
800	else
801		ret = 0;
802
803	hci_close_dev(dd);
804
805	return ret;
806}
807
808static int hciops_read_bdaddr(int index, bdaddr_t *bdaddr)
809{
810	int dd, err;
811
812	dd = hci_open_dev(index);
813	if (dd < 0)
814		return -errno;
815
816	if (hci_read_bd_addr(dd, bdaddr, HCI_REQ_TIMEOUT) < 0)
817		err = -errno;
818	else
819		err = 0;
820
821	hci_close_dev(dd);
822
823	return err;
824}
825
826static int hciops_set_event_mask(int index, uint8_t *events, size_t count)
827{
828	int dd, err;
829
830	dd = hci_open_dev(index);
831	if (dd < 0)
832		return -errno;
833
834	if (hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK,
835						count, events) < 0)
836		err = -errno;
837	else
838		err = 0;
839
840	hci_close_dev(dd);
841
842	return err;
843}
844
845static int hciops_write_inq_mode(int index, uint8_t mode)
846{
847	int dd, err;
848
849	dd = hci_open_dev(index);
850	if (dd < 0)
851		return -errno;
852
853	if (hci_write_inquiry_mode(dd, mode, HCI_REQ_TIMEOUT) < 0)
854		err = -errno;
855	else
856		err = 0;
857
858	hci_close_dev(dd);
859
860	return err;
861}
862
863static int hciops_read_inq_tx_pwr(int index)
864{
865	int dd, err;
866
867	dd = hci_open_dev(index);
868	if (dd < 0)
869		return -errno;
870
871	if (hci_send_cmd(dd, OGF_HOST_CTL,
872			OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL, 0, NULL) < 0)
873		err = -errno;
874	else
875		err = 0;
876
877	hci_close_dev(dd);
878
879	return err;
880}
881
882static int hciops_block_device(int index, bdaddr_t *bdaddr)
883{
884	int dd, err;
885
886	dd = hci_open_dev(index);
887	if (dd < 0)
888		return -errno;
889
890	if (ioctl(dd, HCIBLOCKADDR, bdaddr) < 0)
891		err = -errno;
892	else
893		err = 0;
894
895	hci_close_dev(dd);
896
897	return err;
898}
899
900static int hciops_unblock_device(int index, bdaddr_t *bdaddr)
901{
902	int dd, err;
903
904	dd = hci_open_dev(index);
905	if (dd < 0)
906		return -errno;
907
908	if (ioctl(dd, HCIUNBLOCKADDR, bdaddr) < 0)
909		err = -errno;
910	else
911		err = 0;
912
913	hci_close_dev(dd);
914
915	return err;
916}
917
918static int hciops_get_conn_list(int index, GSList **conns)
919{
920	struct hci_conn_list_req *cl;
921	struct hci_conn_info *ci;
922	int dd, err, i;
923
924	dd = hci_open_dev(index);
925	if (dd < 0)
926		return -errno;
927
928	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl));
929
930	cl->dev_id = index;
931	cl->conn_num = 10;
932	ci = cl->conn_info;
933
934	if (ioctl(dd, HCIGETCONNLIST, cl) < 0) {
935		err = -errno;
936		goto fail;
937	}
938
939	err = 0;
940	*conns = NULL;
941
942	for (i = 0; i < cl->conn_num; i++, ci++)
943		*conns = g_slist_append(*conns, g_memdup(ci, sizeof(*ci)));
944
945fail:
946	hci_close_dev(dd);
947	g_free(cl);
948	return err;
949}
950
951static int hciops_read_local_version(int index, struct hci_version *ver)
952{
953	int dd, err;
954
955	dd = hci_open_dev(index);
956	if (dd < 0)
957		return -errno;
958
959	if (hci_read_local_version(dd, ver, HCI_REQ_TIMEOUT) < 0)
960		err = -errno;
961	else
962		err = 0;
963
964	hci_close_dev(dd);
965
966	return err;
967}
968
969static int hciops_read_local_features(int index, uint8_t *features)
970{
971	int dd, err;
972
973	dd = hci_open_dev(index);
974	if (dd < 0)
975		return -errno;
976
977	if (hci_read_local_features(dd, features, HCI_REQ_TIMEOUT) < 0)
978		err = -errno;
979	else
980		err = 0;
981
982	hci_close_dev(dd);
983
984	return err;
985}
986
987static int hciops_init_ssp_mode(int index, uint8_t *mode)
988{
989	int dd, err;
990
991	dd = hci_open_dev(index);
992	if (dd < 0)
993		return -errno;
994
995	if (ioctl(dd, HCIGETAUTHINFO, NULL) < 0 && errno != EINVAL)
996		hci_write_simple_pairing_mode(dd, 0x01, HCI_REQ_TIMEOUT);
997
998	if (hci_read_simple_pairing_mode(dd, mode, HCI_REQ_TIMEOUT) < 0)
999		err = -errno;
1000	else
1001		err = 0;
1002
1003	hci_close_dev(dd);
1004
1005	return err;
1006}
1007
1008static struct btd_adapter_ops hci_ops = {
1009	.setup = hciops_setup,
1010	.cleanup = hciops_cleanup,
1011	.start = hciops_start,
1012	.stop = hciops_stop,
1013	.set_powered = hciops_powered,
1014	.set_connectable = hciops_connectable,
1015	.set_discoverable = hciops_discoverable,
1016	.set_limited_discoverable = hciops_set_limited_discoverable,
1017	.start_discovery = hciops_start_discovery,
1018	.stop_discovery = hciops_stop_discovery,
1019	.resolve_name = hciops_resolve_name,
1020	.cancel_resolve_name = hciops_cancel_resolve_name,
1021	.set_name = hciops_set_name,
1022	.read_name = hciops_read_name,
1023	.set_class = hciops_set_class,
1024	.set_fast_connectable = hciops_fast_connectable,
1025	.read_clock = hciops_read_clock,
1026	.get_conn_handle = hciops_conn_handle,
1027	.write_eir_data = hciops_write_eir_data,
1028	.read_bdaddr = hciops_read_bdaddr,
1029	.set_event_mask = hciops_set_event_mask,
1030	.write_inq_mode = hciops_write_inq_mode,
1031	.read_inq_tx_pwr = hciops_read_inq_tx_pwr,
1032	.block_device = hciops_block_device,
1033	.unblock_device = hciops_unblock_device,
1034	.get_conn_list = hciops_get_conn_list,
1035	.read_local_version = hciops_read_local_version,
1036	.read_local_features = hciops_read_local_features,
1037	.init_ssp_mode = hciops_init_ssp_mode,
1038};
1039
1040static int hciops_init(void)
1041{
1042	return btd_register_adapter_ops(&hci_ops);
1043}
1044static void hciops_exit(void)
1045{
1046	btd_adapter_cleanup_ops(&hci_ops);
1047}
1048
1049BLUETOOTH_PLUGIN_DEFINE(hciops, VERSION,
1050		BLUETOOTH_PLUGIN_PRIORITY_LOW, hciops_init, hciops_exit)
1051