• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2010  Nokia Corporation
6  *  Copyright (C) 2010  Marcel Holtmann <marcel@holtmann.org>
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 <sys/types.h>
33 #include <sys/ioctl.h>
34 #include <sys/wait.h>
35 
36 #include <glib.h>
37 
38 #include <bluetooth/bluetooth.h>
39 #include <bluetooth/hci.h>
40 #include <bluetooth/sdp.h>
41 #include <bluetooth/sdp_lib.h>
42 #include <bluetooth/mgmt.h>
43 
44 #include "plugin.h"
45 #include "log.h"
46 #include "adapter.h"
47 #include "manager.h"
48 #include "device.h"
49 #include "event.h"
50 #include "oob.h"
51 
52 #define MGMT_BUF_SIZE 1024
53 
54 static int max_index = -1;
55 static struct controller_info {
56 	gboolean valid;
57 	gboolean notified;
58 	uint8_t type;
59 	bdaddr_t bdaddr;
60 	uint8_t features[8];
61 	uint8_t dev_class[3];
62 	uint16_t manufacturer;
63 	uint8_t hci_ver;
64 	uint16_t hci_rev;
65 	gboolean enabled;
66 	gboolean connectable;
67 	gboolean discoverable;
68 	gboolean pairable;
69 	uint8_t sec_mode;
70 	GSList *connections;
71 } *controllers = NULL;
72 
73 static int mgmt_sock = -1;
74 static guint mgmt_watch = 0;
75 
76 static uint8_t mgmt_version = 0;
77 static uint16_t mgmt_revision = 0;
78 
read_version_complete(int sk,void * buf,size_t len)79 static void read_version_complete(int sk, void *buf, size_t len)
80 {
81 	struct mgmt_hdr hdr;
82 	struct mgmt_rp_read_version *rp = buf;
83 
84 	if (len < sizeof(*rp)) {
85 		error("Too small read version complete event");
86 		return;
87 	}
88 
89 	mgmt_revision = btohs(bt_get_unaligned(&rp->revision));
90 	mgmt_version = rp->version;
91 
92 	DBG("version %u revision %u", mgmt_version, mgmt_revision);
93 
94 	memset(&hdr, 0, sizeof(hdr));
95 	hdr.opcode = htobs(MGMT_OP_READ_INDEX_LIST);
96 	hdr.index = htobs(MGMT_INDEX_NONE);
97 	if (write(sk, &hdr, sizeof(hdr)) < 0)
98 		error("Unable to read controller index list: %s (%d)",
99 						strerror(errno), errno);
100 }
101 
add_controller(uint16_t index)102 static void add_controller(uint16_t index)
103 {
104 	if (index > max_index) {
105 		size_t size = sizeof(struct controller_info) * (index + 1);
106 		max_index = index;
107 		controllers = g_realloc(controllers, size);
108 	}
109 
110 	memset(&controllers[index], 0, sizeof(struct controller_info));
111 
112 	controllers[index].valid = TRUE;
113 
114 	DBG("Added controller %u", index);
115 }
116 
read_info(int sk,uint16_t index)117 static void read_info(int sk, uint16_t index)
118 {
119 	struct mgmt_hdr hdr;
120 
121 	memset(&hdr, 0, sizeof(hdr));
122 	hdr.opcode = htobs(MGMT_OP_READ_INFO);
123 	hdr.index = htobs(index);
124 
125 	if (write(sk, &hdr, sizeof(hdr)) < 0)
126 		error("Unable to send read_info command: %s (%d)",
127 						strerror(errno), errno);
128 }
129 
get_connections(int sk,uint16_t index)130 static void get_connections(int sk, uint16_t index)
131 {
132 	struct mgmt_hdr hdr;
133 
134 	memset(&hdr, 0, sizeof(hdr));
135 	hdr.opcode = htobs(MGMT_OP_GET_CONNECTIONS);
136 	hdr.index = htobs(index);
137 
138 	if (write(sk, &hdr, sizeof(hdr)) < 0)
139 		error("Unable to send get_connections command: %s (%d)",
140 						strerror(errno), errno);
141 }
142 
mgmt_index_added(int sk,uint16_t index)143 static void mgmt_index_added(int sk, uint16_t index)
144 {
145 	add_controller(index);
146 	read_info(sk, index);
147 }
148 
remove_controller(uint16_t index)149 static void remove_controller(uint16_t index)
150 {
151 	if (index > max_index)
152 		return;
153 
154 	if (!controllers[index].valid)
155 		return;
156 
157 	btd_manager_unregister_adapter(index);
158 
159 	memset(&controllers[index], 0, sizeof(struct controller_info));
160 
161 	DBG("Removed controller %u", index);
162 }
163 
mgmt_index_removed(int sk,uint16_t index)164 static void mgmt_index_removed(int sk, uint16_t index)
165 {
166 	remove_controller(index);
167 }
168 
mgmt_set_mode(int index,uint16_t opcode,uint8_t val)169 static int mgmt_set_mode(int index, uint16_t opcode, uint8_t val)
170 {
171 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_mode)];
172 	struct mgmt_hdr *hdr = (void *) buf;
173 	struct mgmt_mode *cp = (void *) &buf[sizeof(*hdr)];
174 
175 	memset(buf, 0, sizeof(buf));
176 	hdr->opcode = htobs(opcode);
177 	hdr->index = htobs(index);
178 	hdr->len = htobs(sizeof(*cp));
179 
180 	cp->val = val;
181 
182 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
183 		return -errno;
184 
185 	return 0;
186 }
187 
mgmt_set_connectable(int index,gboolean connectable)188 static int mgmt_set_connectable(int index, gboolean connectable)
189 {
190 	DBG("index %d connectable %d", index, connectable);
191 	return mgmt_set_mode(index, MGMT_OP_SET_CONNECTABLE, connectable);
192 }
193 
mgmt_set_discoverable(int index,gboolean discoverable)194 static int mgmt_set_discoverable(int index, gboolean discoverable)
195 {
196 	DBG("index %d discoverable %d", index, discoverable);
197 	return mgmt_set_mode(index, MGMT_OP_SET_DISCOVERABLE, discoverable);
198 }
199 
mgmt_set_pairable(int index,gboolean pairable)200 static int mgmt_set_pairable(int index, gboolean pairable)
201 {
202 	DBG("index %d pairable %d", index, pairable);
203 	return mgmt_set_mode(index, MGMT_OP_SET_PAIRABLE, pairable);
204 }
205 
mgmt_update_powered(int index,uint8_t powered)206 static int mgmt_update_powered(int index, uint8_t powered)
207 {
208 	struct controller_info *info;
209 	struct btd_adapter *adapter;
210 	gboolean pairable;
211 	uint8_t on_mode;
212 
213 	if (index > max_index) {
214 		error("Unexpected index %u", index);
215 		return -ENODEV;
216 	}
217 
218 	info = &controllers[index];
219 
220 	info->enabled = powered;
221 
222 	adapter = manager_find_adapter(&info->bdaddr);
223 	if (adapter == NULL) {
224 		DBG("Adapter not found");
225 		return -ENODEV;
226 	}
227 
228 	if (!powered) {
229 		info->connectable = FALSE;
230 		info->pairable = FALSE;
231 		info->discoverable = FALSE;
232 
233 		btd_adapter_stop(adapter);
234 		return 0;
235 	}
236 
237 	btd_adapter_start(adapter);
238 
239 	btd_adapter_get_mode(adapter, NULL, &on_mode, &pairable);
240 
241 	if (on_mode == MODE_DISCOVERABLE && !info->discoverable)
242 		mgmt_set_discoverable(index, TRUE);
243 	else if (on_mode == MODE_CONNECTABLE && !info->connectable)
244 		mgmt_set_connectable(index, TRUE);
245 	else {
246 		uint8_t mode = 0;
247 
248 		if (info->connectable)
249 			mode |= SCAN_PAGE;
250 		if (info->discoverable)
251 			mode |= SCAN_INQUIRY;
252 
253 		adapter_mode_changed(adapter, mode);
254 	}
255 
256 	if (info->pairable != pairable)
257 		mgmt_set_pairable(index, pairable);
258 
259 	return 0;
260 }
261 
mgmt_powered(int sk,uint16_t index,void * buf,size_t len)262 static void mgmt_powered(int sk, uint16_t index, void *buf, size_t len)
263 {
264 	struct mgmt_mode *ev = buf;
265 
266 	if (len < sizeof(*ev)) {
267 		error("Too small powered event");
268 		return;
269 	}
270 
271 	DBG("Controller %u powered %u", index, ev->val);
272 
273 	mgmt_update_powered(index, ev->val);
274 }
275 
mgmt_discoverable(int sk,uint16_t index,void * buf,size_t len)276 static void mgmt_discoverable(int sk, uint16_t index, void *buf, size_t len)
277 {
278 	struct mgmt_mode *ev = buf;
279 	struct controller_info *info;
280 	struct btd_adapter *adapter;
281 	uint8_t mode;
282 
283 	if (len < sizeof(*ev)) {
284 		error("Too small discoverable event");
285 		return;
286 	}
287 
288 	DBG("Controller %u discoverable %u", index, ev->val);
289 
290 	if (index > max_index) {
291 		error("Unexpected index %u in discoverable event", index);
292 		return;
293 	}
294 
295 	info = &controllers[index];
296 
297 	info->discoverable = ev->val ? TRUE : FALSE;
298 
299 	adapter = manager_find_adapter(&info->bdaddr);
300 	if (!adapter)
301 		return;
302 
303 	if (info->connectable)
304 		mode = SCAN_PAGE;
305 	else
306 		mode = 0;
307 
308 	if (info->discoverable)
309 		mode |= SCAN_INQUIRY;
310 
311 	adapter_mode_changed(adapter, mode);
312 }
313 
mgmt_connectable(int sk,uint16_t index,void * buf,size_t len)314 static void mgmt_connectable(int sk, uint16_t index, void *buf, size_t len)
315 {
316 	struct mgmt_mode *ev = buf;
317 	struct controller_info *info;
318 	struct btd_adapter *adapter;
319 	uint8_t mode;
320 
321 	if (len < sizeof(*ev)) {
322 		error("Too small connectable event");
323 		return;
324 	}
325 
326 	DBG("Controller %u connectable %u", index, ev->val);
327 
328 	if (index > max_index) {
329 		error("Unexpected index %u in connectable event", index);
330 		return;
331 	}
332 
333 	info = &controllers[index];
334 
335 	info->connectable = ev->val ? TRUE : FALSE;
336 
337 	adapter = manager_find_adapter(&info->bdaddr);
338 	if (!adapter)
339 		return;
340 
341 	if (info->discoverable)
342 		mode = SCAN_INQUIRY;
343 	else
344 		mode = 0;
345 
346 	if (info->connectable)
347 		mode |= SCAN_PAGE;
348 
349 	adapter_mode_changed(adapter, mode);
350 }
351 
mgmt_pairable(int sk,uint16_t index,void * buf,size_t len)352 static void mgmt_pairable(int sk, uint16_t index, void *buf, size_t len)
353 {
354 	struct mgmt_mode *ev = buf;
355 	struct controller_info *info;
356 	struct btd_adapter *adapter;
357 
358 	if (len < sizeof(*ev)) {
359 		error("Too small pairable event");
360 		return;
361 	}
362 
363 	DBG("Controller %u pairable %u", index, ev->val);
364 
365 	if (index > max_index) {
366 		error("Unexpected index %u in pairable event", index);
367 		return;
368 	}
369 
370 	info = &controllers[index];
371 
372 	info->pairable = ev->val ? TRUE : FALSE;
373 
374 	adapter = manager_find_adapter(&info->bdaddr);
375 	if (!adapter)
376 		return;
377 
378 	btd_adapter_pairable_changed(adapter, info->pairable);
379 }
380 
mgmt_new_key(int sk,uint16_t index,void * buf,size_t len)381 static void mgmt_new_key(int sk, uint16_t index, void *buf, size_t len)
382 {
383 	struct mgmt_ev_new_key *ev = buf;
384 	struct controller_info *info;
385 
386 	if (len != sizeof(*ev)) {
387 		error("new_key event size mismatch (%zu != %zu)",
388 							len, sizeof(*ev));
389 		return;
390 	}
391 
392 	DBG("Controller %u new key of type %u pin_len %u", index,
393 					ev->key.type, ev->key.pin_len);
394 
395 	if (index > max_index) {
396 		error("Unexpected index %u in new_key event", index);
397 		return;
398 	}
399 
400 	if (ev->key.pin_len > 16) {
401 		error("Invalid PIN length (%u) in new_key event",
402 							ev->key.pin_len);
403 		return;
404 	}
405 
406 	info = &controllers[index];
407 
408 	if (ev->store_hint)
409 		btd_event_link_key_notify(&info->bdaddr, &ev->key.bdaddr,
410 						ev->key.val, ev->key.type,
411 						ev->key.pin_len);
412 
413 	btd_event_bonding_complete(&info->bdaddr, &ev->key.bdaddr, 0);
414 }
415 
mgmt_device_connected(int sk,uint16_t index,void * buf,size_t len)416 static void mgmt_device_connected(int sk, uint16_t index, void *buf, size_t len)
417 {
418 	struct mgmt_ev_device_connected *ev = buf;
419 	struct controller_info *info;
420 	char addr[18];
421 
422 	if (len < sizeof(*ev)) {
423 		error("Too small device_connected event");
424 		return;
425 	}
426 
427 	ba2str(&ev->bdaddr, addr);
428 
429 	DBG("hci%u device %s connected", index, addr);
430 
431 	if (index > max_index) {
432 		error("Unexpected index %u in device_connected event", index);
433 		return;
434 	}
435 
436 	info = &controllers[index];
437 
438 	btd_event_conn_complete(&info->bdaddr, &ev->bdaddr);
439 }
440 
mgmt_device_disconnected(int sk,uint16_t index,void * buf,size_t len)441 static void mgmt_device_disconnected(int sk, uint16_t index, void *buf,
442 								size_t len)
443 {
444 	struct mgmt_ev_device_disconnected *ev = buf;
445 	struct controller_info *info;
446 	char addr[18];
447 
448 	if (len < sizeof(*ev)) {
449 		error("Too small device_disconnected event");
450 		return;
451 	}
452 
453 	ba2str(&ev->bdaddr, addr);
454 
455 	DBG("hci%u device %s disconnected", index, addr);
456 
457 	if (index > max_index) {
458 		error("Unexpected index %u in device_disconnected event", index);
459 		return;
460 	}
461 
462 	info = &controllers[index];
463 
464 	btd_event_disconn_complete(&info->bdaddr, &ev->bdaddr);
465 }
466 
mgmt_connect_failed(int sk,uint16_t index,void * buf,size_t len)467 static void mgmt_connect_failed(int sk, uint16_t index, void *buf, size_t len)
468 {
469 	struct mgmt_ev_connect_failed *ev = buf;
470 	struct controller_info *info;
471 	char addr[18];
472 
473 	if (len < sizeof(*ev)) {
474 		error("Too small connect_failed event");
475 		return;
476 	}
477 
478 	ba2str(&ev->bdaddr, addr);
479 
480 	DBG("hci%u %s status %u", index, addr, ev->status);
481 
482 	if (index > max_index) {
483 		error("Unexpected index %u in connect_failed event", index);
484 		return;
485 	}
486 
487 	info = &controllers[index];
488 
489 	btd_event_conn_failed(&info->bdaddr, &ev->bdaddr, ev->status);
490 
491 	/* In the case of security mode 3 devices */
492 	btd_event_bonding_complete(&info->bdaddr, &ev->bdaddr, ev->status);
493 }
494 
mgmt_pincode_reply(int index,bdaddr_t * bdaddr,const char * pin,size_t pin_len)495 static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin,
496 								size_t pin_len)
497 {
498 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pin_code_reply)];
499 	struct mgmt_hdr *hdr = (void *) buf;
500 	size_t buf_len;
501 	char addr[18];
502 
503 	ba2str(bdaddr, addr);
504 	DBG("index %d addr %s pinlen %zu", index, addr, pin_len);
505 
506 	memset(buf, 0, sizeof(buf));
507 
508 	if (pin == NULL) {
509 		struct mgmt_cp_pin_code_neg_reply *cp;
510 
511 		hdr->opcode = htobs(MGMT_OP_PIN_CODE_NEG_REPLY);
512 		hdr->len = htobs(sizeof(*cp));
513 		hdr->index = htobs(index);
514 
515 		cp = (void *) &buf[sizeof(*hdr)];
516 		bacpy(&cp->bdaddr, bdaddr);
517 
518 		buf_len = sizeof(*hdr) + sizeof(*cp);
519 	} else {
520 		struct mgmt_cp_pin_code_reply *cp;
521 
522 		if (pin_len > 16)
523 			return -EINVAL;
524 
525 		hdr->opcode = htobs(MGMT_OP_PIN_CODE_REPLY);
526 		hdr->len = htobs(sizeof(*cp));
527 		hdr->index = htobs(index);
528 
529 		cp = (void *) &buf[sizeof(*hdr)];
530 		bacpy(&cp->bdaddr, bdaddr);
531 		cp->pin_len = pin_len;
532 		memcpy(cp->pin_code, pin, pin_len);
533 
534 		buf_len = sizeof(*hdr) + sizeof(*cp);
535 	}
536 
537 	if (write(mgmt_sock, buf, buf_len) < 0)
538 		return -errno;
539 
540 	return 0;
541 }
542 
mgmt_pin_code_request(int sk,uint16_t index,void * buf,size_t len)543 static void mgmt_pin_code_request(int sk, uint16_t index, void *buf, size_t len)
544 {
545 	struct mgmt_ev_pin_code_request *ev = buf;
546 	struct controller_info *info;
547 	char addr[18];
548 	int err;
549 
550 	if (len < sizeof(*ev)) {
551 		error("Too small pin_code_request event");
552 		return;
553 	}
554 
555 	ba2str(&ev->bdaddr, addr);
556 
557 	DBG("hci%u %s", index, addr);
558 
559 	if (index > max_index) {
560 		error("Unexpected index %u in pin_code_request event", index);
561 		return;
562 	}
563 
564 	info = &controllers[index];
565 
566 	err = btd_event_request_pin(&info->bdaddr, &ev->bdaddr);
567 	if (err < 0) {
568 		error("btd_event_request_pin: %s", strerror(-err));
569 		mgmt_pincode_reply(index, &ev->bdaddr, NULL, 0);
570 	}
571 }
572 
mgmt_confirm_reply(int index,bdaddr_t * bdaddr,gboolean success)573 static int mgmt_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success)
574 {
575 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_user_confirm_reply)];
576 	struct mgmt_hdr *hdr = (void *) buf;
577 	struct mgmt_cp_user_confirm_reply *cp;
578 	char addr[18];
579 
580 	ba2str(bdaddr, addr);
581 	DBG("index %d addr %s success %d", index, addr, success);
582 
583 	memset(buf, 0, sizeof(buf));
584 
585 	if (success)
586 		hdr->opcode = htobs(MGMT_OP_USER_CONFIRM_REPLY);
587 	else
588 		hdr->opcode = htobs(MGMT_OP_USER_CONFIRM_NEG_REPLY);
589 
590 	hdr->len = htobs(sizeof(*cp));
591 	hdr->index = htobs(index);
592 
593 	cp = (void *) &buf[sizeof(*hdr)];
594 	bacpy(&cp->bdaddr, bdaddr);
595 
596 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
597 		return -errno;
598 
599 	return 0;
600 }
601 
602 struct confirm_data {
603 	int index;
604 	bdaddr_t bdaddr;
605 };
606 
confirm_accept(gpointer user_data)607 static gboolean confirm_accept(gpointer user_data)
608 {
609 	struct confirm_data *data = user_data;
610 	struct controller_info *info = &controllers[data->index];
611 
612 	DBG("auto-accepting incoming pairing request");
613 
614 	if (data->index > max_index || !info->valid)
615 		return FALSE;
616 
617 	mgmt_confirm_reply(data->index, &data->bdaddr, TRUE);
618 
619 	return FALSE;
620 }
621 
mgmt_user_confirm_request(int sk,uint16_t index,void * buf,size_t len)622 static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf,
623 								size_t len)
624 {
625 	struct mgmt_ev_user_confirm_request *ev = buf;
626 	struct controller_info *info;
627 	char addr[18];
628 	int err;
629 
630 	if (len < sizeof(*ev)) {
631 		error("Too small user_confirm_request event");
632 		return;
633 	}
634 
635 	ba2str(&ev->bdaddr, addr);
636 
637 	DBG("hci%u %s confirm_hint %u", index, addr, ev->confirm_hint);
638 
639 	if (index > max_index) {
640 		error("Unexpected index %u in user_confirm_request event",
641 									index);
642 		return;
643 	}
644 
645 	if (ev->confirm_hint) {
646 		struct confirm_data *data;
647 
648 		data = g_new0(struct confirm_data, 1);
649 		data->index = index;
650 		bacpy(&data->bdaddr, &ev->bdaddr);
651 
652 		g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1,
653 						confirm_accept, data, g_free);
654 		return;
655 	}
656 
657 	info = &controllers[index];
658 
659 	err = btd_event_user_confirm(&info->bdaddr, &ev->bdaddr,
660 							btohl(ev->value));
661 	if (err < 0) {
662 		error("btd_event_user_confirm: %s", strerror(-err));
663 		mgmt_confirm_reply(index, &ev->bdaddr, FALSE);
664 	}
665 }
666 
uuid_to_uuid128(uuid_t * uuid128,const uuid_t * uuid)667 static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
668 {
669 	if (uuid->type == SDP_UUID16)
670 		sdp_uuid16_to_uuid128(uuid128, uuid);
671 	else if (uuid->type == SDP_UUID32)
672 		sdp_uuid32_to_uuid128(uuid128, uuid);
673 	else
674 		memcpy(uuid128, uuid, sizeof(*uuid));
675 }
676 
mgmt_add_uuid(int index,uuid_t * uuid,uint8_t svc_hint)677 static int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
678 {
679 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_uuid)];
680 	struct mgmt_hdr *hdr = (void *) buf;
681 	struct mgmt_cp_add_uuid *cp = (void *) &buf[sizeof(*hdr)];
682 	uuid_t uuid128;
683 	uint128_t uint128;
684 
685 	DBG("index %d", index);
686 
687 	uuid_to_uuid128(&uuid128, uuid);
688 
689 	memset(buf, 0, sizeof(buf));
690 	hdr->opcode = htobs(MGMT_OP_ADD_UUID);
691 	hdr->len = htobs(sizeof(*cp));
692 	hdr->index = htobs(index);
693 
694 	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
695 	htob128(&uint128, (uint128_t *) cp->uuid);
696 
697 	cp->svc_hint = svc_hint;
698 
699 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
700 		return -errno;
701 
702 	return 0;
703 }
704 
mgmt_remove_uuid(int index,uuid_t * uuid)705 static int mgmt_remove_uuid(int index, uuid_t *uuid)
706 {
707 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_uuid)];
708 	struct mgmt_hdr *hdr = (void *) buf;
709 	struct mgmt_cp_remove_uuid *cp = (void *) &buf[sizeof(*hdr)];
710 	uuid_t uuid128;
711 	uint128_t uint128;
712 
713 	DBG("index %d", index);
714 
715 	uuid_to_uuid128(&uuid128, uuid);
716 
717 	memset(buf, 0, sizeof(buf));
718 	hdr->opcode = htobs(MGMT_OP_REMOVE_UUID);
719 	hdr->len = htobs(sizeof(*cp));
720 	hdr->index = htobs(index);
721 
722 	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
723 	htob128(&uint128, (uint128_t *) cp->uuid);
724 
725 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
726 		return -errno;
727 
728 	return 0;
729 }
730 
clear_uuids(int index)731 static int clear_uuids(int index)
732 {
733 	uuid_t uuid_any;
734 
735 	memset(&uuid_any, 0, sizeof(uuid_any));
736 	uuid_any.type = SDP_UUID128;
737 
738 	return mgmt_remove_uuid(index, &uuid_any);
739 }
740 
read_index_list_complete(int sk,void * buf,size_t len)741 static void read_index_list_complete(int sk, void *buf, size_t len)
742 {
743 	struct mgmt_rp_read_index_list *rp = buf;
744 	uint16_t num;
745 	int i;
746 
747 	if (len < sizeof(*rp)) {
748 		error("Too small read index list complete event");
749 		return;
750 	}
751 
752 	num = btohs(bt_get_unaligned(&rp->num_controllers));
753 
754 	if (num * sizeof(uint16_t) + sizeof(*rp) != len) {
755 		error("Incorrect packet size for index list event");
756 		return;
757 	}
758 
759 	for (i = 0; i < num; i++) {
760 		uint16_t index;
761 
762 		index = btohs(bt_get_unaligned(&rp->index[i]));
763 
764 		add_controller(index);
765 		get_connections(sk, index);
766 		clear_uuids(index);
767 	}
768 }
769 
mgmt_set_powered(int index,gboolean powered)770 static int mgmt_set_powered(int index, gboolean powered)
771 {
772 	DBG("index %d powered %d", index, powered);
773 	return mgmt_set_mode(index, MGMT_OP_SET_POWERED, powered);
774 }
775 
read_info_complete(int sk,uint16_t index,void * buf,size_t len)776 static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
777 {
778 	struct mgmt_rp_read_info *rp = buf;
779 	struct controller_info *info;
780 	struct btd_adapter *adapter;
781 	uint8_t mode;
782 	char addr[18];
783 
784 	if (len < sizeof(*rp)) {
785 		error("Too small read info complete event");
786 		return;
787 	}
788 
789 	if (index > max_index) {
790 		error("Unexpected index %u in read info complete", index);
791 		return;
792 	}
793 
794 	mgmt_set_mode(index, MGMT_OP_SET_SERVICE_CACHE, 1);
795 
796 	info = &controllers[index];
797 	info->type = rp->type;
798 	info->enabled = rp->powered;
799 	info->connectable = rp->connectable;
800 	info->discoverable = rp->discoverable;
801 	info->pairable = rp->pairable;
802 	info->sec_mode = rp->sec_mode;
803 	bacpy(&info->bdaddr, &rp->bdaddr);
804 	memcpy(info->dev_class, rp->dev_class, 3);
805 	memcpy(info->features, rp->features, 8);
806 	info->manufacturer = btohs(bt_get_unaligned(&rp->manufacturer));
807 	info->hci_ver = rp->hci_ver;
808 	info->hci_rev = btohs(bt_get_unaligned(&rp->hci_rev));
809 
810 	ba2str(&info->bdaddr, addr);
811 	DBG("hci%u type %u addr %s", index, info->type, addr);
812 	DBG("hci%u class 0x%02x%02x%02x", index,
813 		info->dev_class[2], info->dev_class[1], info->dev_class[0]);
814 	DBG("hci%u manufacturer %d HCI ver %d:%d", index, info->manufacturer,
815 						info->hci_ver, info->hci_rev);
816 	DBG("hci%u enabled %u discoverable %u pairable %u sec_mode %u", index,
817 					info->enabled, info->discoverable,
818 					info->pairable, info->sec_mode);
819 	DBG("hci%u name %s", index, (char *) rp->name);
820 
821 	adapter = btd_manager_register_adapter(index);
822 	if (adapter == NULL) {
823 		error("mgmtops: unable to register adapter");
824 		return;
825 	}
826 
827 	btd_adapter_get_mode(adapter, &mode, NULL, NULL);
828 	if (mode == MODE_OFF) {
829 		mgmt_set_powered(index, FALSE);
830 		return;
831 	}
832 
833 	if (info->enabled)
834 		mgmt_update_powered(index, TRUE);
835 	else
836 		mgmt_set_powered(index, TRUE);
837 
838 	adapter_update_local_name(adapter, (char *) rp->name);
839 
840 	btd_adapter_unref(adapter);
841 }
842 
set_powered_complete(int sk,uint16_t index,void * buf,size_t len)843 static void set_powered_complete(int sk, uint16_t index, void *buf, size_t len)
844 {
845 	struct mgmt_mode *rp = buf;
846 
847 	if (len < sizeof(*rp)) {
848 		error("Too small set powered complete event");
849 		return;
850 	}
851 
852 	DBG("hci%d powered %u", index, rp->val);
853 
854 	mgmt_update_powered(index, rp->val);
855 }
856 
set_discoverable_complete(int sk,uint16_t index,void * buf,size_t len)857 static void set_discoverable_complete(int sk, uint16_t index, void *buf,
858 								size_t len)
859 {
860 	struct mgmt_mode *rp = buf;
861 	struct controller_info *info;
862 	struct btd_adapter *adapter;
863 	uint8_t mode;
864 
865 	if (len < sizeof(*rp)) {
866 		error("Too small set discoverable complete event");
867 		return;
868 	}
869 
870 	DBG("hci%d discoverable %u", index, rp->val);
871 
872 	if (index > max_index) {
873 		error("Unexpected index %u in discoverable complete", index);
874 		return;
875 	}
876 
877 	info = &controllers[index];
878 
879 	info->discoverable = rp->val ? TRUE : FALSE;
880 
881 	adapter = manager_find_adapter(&info->bdaddr);
882 	if (!adapter)
883 		return;
884 
885 	/* set_discoverable will always also change page scanning */
886 	mode = SCAN_PAGE;
887 
888 	if (info->discoverable)
889 		mode |= SCAN_INQUIRY;
890 
891 	adapter_mode_changed(adapter, mode);
892 }
893 
set_connectable_complete(int sk,uint16_t index,void * buf,size_t len)894 static void set_connectable_complete(int sk, uint16_t index, void *buf,
895 								size_t len)
896 {
897 	struct mgmt_mode *rp = buf;
898 	struct controller_info *info;
899 	struct btd_adapter *adapter;
900 
901 	if (len < sizeof(*rp)) {
902 		error("Too small set connectable complete event");
903 		return;
904 	}
905 
906 	DBG("hci%d connectable %u", index, rp->val);
907 
908 	if (index > max_index) {
909 		error("Unexpected index %u in connectable complete", index);
910 		return;
911 	}
912 
913 	info = &controllers[index];
914 
915 	info->connectable = rp->val ? TRUE : FALSE;
916 
917 	adapter = manager_find_adapter(&info->bdaddr);
918 	if (adapter)
919 		adapter_mode_changed(adapter, rp->val ? SCAN_PAGE : 0);
920 }
921 
set_pairable_complete(int sk,uint16_t index,void * buf,size_t len)922 static void set_pairable_complete(int sk, uint16_t index, void *buf,
923 								size_t len)
924 {
925 	struct mgmt_mode *rp = buf;
926 	struct controller_info *info;
927 	struct btd_adapter *adapter;
928 
929 	if (len < sizeof(*rp)) {
930 		error("Too small set pairable complete event");
931 		return;
932 	}
933 
934 	DBG("hci%d pairable %u", index, rp->val);
935 
936 	if (index > max_index) {
937 		error("Unexpected index %u in pairable complete", index);
938 		return;
939 	}
940 
941 	info = &controllers[index];
942 
943 	info->pairable = rp->val ? TRUE : FALSE;
944 
945 	adapter = manager_find_adapter(&info->bdaddr);
946 	if (!adapter)
947 		return;
948 
949 	btd_adapter_pairable_changed(adapter, info->pairable);
950 }
951 
disconnect_complete(int sk,uint16_t index,void * buf,size_t len)952 static void disconnect_complete(int sk, uint16_t index, void *buf, size_t len)
953 {
954 	struct mgmt_rp_disconnect *rp = buf;
955 	struct controller_info *info;
956 	char addr[18];
957 
958 	if (len < sizeof(*rp)) {
959 		error("Too small disconnect complete event");
960 		return;
961 	}
962 
963 	ba2str(&rp->bdaddr, addr);
964 
965 	DBG("hci%d %s disconnected", index, addr);
966 
967 	if (index > max_index) {
968 		error("Unexpected index %u in disconnect complete", index);
969 		return;
970 	}
971 
972 	info = &controllers[index];
973 
974 	btd_event_disconn_complete(&info->bdaddr, &rp->bdaddr);
975 
976 	btd_event_bonding_complete(&info->bdaddr, &rp->bdaddr,
977 						HCI_CONNECTION_TERMINATED);
978 }
979 
pair_device_complete(int sk,uint16_t index,void * buf,size_t len)980 static void pair_device_complete(int sk, uint16_t index, void *buf, size_t len)
981 {
982 	struct mgmt_rp_pair_device *rp = buf;
983 	struct controller_info *info;
984 	char addr[18];
985 
986 	if (len < sizeof(*rp)) {
987 		error("Too small pair_device complete event");
988 		return;
989 	}
990 
991 	ba2str(&rp->bdaddr, addr);
992 
993 	DBG("hci%d %s pairing complete status %u", index, addr, rp->status);
994 
995 	if (index > max_index) {
996 		error("Unexpected index %u in pair_device complete", index);
997 		return;
998 	}
999 
1000 	info = &controllers[index];
1001 
1002 	btd_event_bonding_complete(&info->bdaddr, &rp->bdaddr, rp->status);
1003 }
1004 
get_connections_complete(int sk,uint16_t index,void * buf,size_t len)1005 static void get_connections_complete(int sk, uint16_t index, void *buf,
1006 								size_t len)
1007 {
1008 	struct mgmt_rp_get_connections *rp = buf;
1009 	struct controller_info *info;
1010 	int i;
1011 
1012 	if (len < sizeof(*rp)) {
1013 		error("Too small get_connections complete event");
1014 		return;
1015 	}
1016 
1017 	if (len < (sizeof(*rp) + (rp->conn_count * sizeof(bdaddr_t)))) {
1018 		error("Too small get_connections complete event");
1019 		return;
1020 	}
1021 
1022 	if (index > max_index) {
1023 		error("Unexpected index %u in get_connections complete",
1024 								index);
1025 		return;
1026 	}
1027 
1028 	info = &controllers[index];
1029 
1030 	for (i = 0; i < rp->conn_count; i++) {
1031 		bdaddr_t *bdaddr = g_memdup(&rp->conn[i], sizeof(bdaddr_t));
1032 		info->connections = g_slist_append(info->connections, bdaddr);
1033 	}
1034 
1035 	read_info(sk, index);
1036 }
1037 
set_local_name_complete(int sk,uint16_t index,void * buf,size_t len)1038 static void set_local_name_complete(int sk, uint16_t index, void *buf,
1039 								size_t len)
1040 {
1041 	struct mgmt_cp_set_local_name *rp = buf;
1042 	struct controller_info *info;
1043 	struct btd_adapter *adapter;
1044 
1045 	if (len < sizeof(*rp)) {
1046 		error("Too small set_local_name complete event");
1047 		return;
1048 	}
1049 
1050 	DBG("hci%d name %s", index, (char *) rp->name);
1051 
1052 	if (index > max_index) {
1053 		error("Unexpected index %u in set_local_name complete", index);
1054 		return;
1055 	}
1056 
1057 	info = &controllers[index];
1058 
1059 	adapter = manager_find_adapter(&info->bdaddr);
1060 	if (adapter == NULL) {
1061 		DBG("Adapter not found");
1062 		return;
1063 	}
1064 
1065 	adapter_update_local_name(adapter, (char *) rp->name);
1066 }
1067 
read_local_oob_data_complete(int sk,uint16_t index,void * buf,size_t len)1068 static void read_local_oob_data_complete(int sk, uint16_t index, void *buf,
1069 								size_t len)
1070 {
1071 	struct mgmt_rp_read_local_oob_data *rp = buf;
1072 	struct btd_adapter *adapter;
1073 
1074 	if (len != sizeof(*rp)) {
1075 		error("Wrong read_local_oob_data_complete event size");
1076 		return;
1077 	}
1078 
1079 	if (index > max_index) {
1080 		error("Unexpected index %u in read_local_oob_data_complete",
1081 								index);
1082 		return;
1083 	}
1084 
1085 	DBG("hci%u", index);
1086 
1087 	adapter = manager_find_adapter_by_id(index);
1088 
1089 	if (adapter)
1090 		oob_read_local_data_complete(adapter, rp->hash, rp->randomizer);
1091 }
1092 
read_local_oob_data_failed(int sk,uint16_t index)1093 static void read_local_oob_data_failed(int sk, uint16_t index)
1094 {
1095 	struct btd_adapter *adapter;
1096 
1097 	if (index > max_index) {
1098 		error("Unexpected index %u in read_local_oob_data_failed",
1099 								index);
1100 		return;
1101 	}
1102 
1103 	DBG("hci%u", index);
1104 
1105 	adapter = manager_find_adapter_by_id(index);
1106 
1107 	if (adapter)
1108 		oob_read_local_data_complete(adapter, NULL, NULL);
1109 }
1110 
mgmt_cmd_complete(int sk,uint16_t index,void * buf,size_t len)1111 static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
1112 {
1113 	struct mgmt_ev_cmd_complete *ev = buf;
1114 	uint16_t opcode;
1115 
1116 	DBG("");
1117 
1118 	if (len < sizeof(*ev)) {
1119 		error("Too small management command complete event packet");
1120 		return;
1121 	}
1122 
1123 	opcode = btohs(bt_get_unaligned(&ev->opcode));
1124 
1125 	len -= sizeof(*ev);
1126 
1127 	switch (opcode) {
1128 	case MGMT_OP_READ_VERSION:
1129 		read_version_complete(sk, ev->data, len);
1130 		break;
1131 	case MGMT_OP_READ_INDEX_LIST:
1132 		read_index_list_complete(sk, ev->data, len);
1133 		break;
1134 	case MGMT_OP_READ_INFO:
1135 		read_info_complete(sk, index, ev->data, len);
1136 		break;
1137 	case MGMT_OP_SET_POWERED:
1138 		set_powered_complete(sk, index, ev->data, len);
1139 		break;
1140 	case MGMT_OP_SET_DISCOVERABLE:
1141 		set_discoverable_complete(sk, index, ev->data, len);
1142 		break;
1143 	case MGMT_OP_SET_CONNECTABLE:
1144 		set_connectable_complete(sk, index, ev->data, len);
1145 		break;
1146 	case MGMT_OP_SET_PAIRABLE:
1147 		set_pairable_complete(sk, index, ev->data, len);
1148 		break;
1149 	case MGMT_OP_ADD_UUID:
1150 		DBG("add_uuid complete");
1151 		break;
1152 	case MGMT_OP_REMOVE_UUID:
1153 		DBG("remove_uuid complete");
1154 		break;
1155 	case MGMT_OP_SET_DEV_CLASS:
1156 		DBG("set_dev_class complete");
1157 		break;
1158 	case MGMT_OP_SET_SERVICE_CACHE:
1159 		DBG("set_service_cache complete");
1160 		break;
1161 	case MGMT_OP_LOAD_KEYS:
1162 		DBG("load_keys complete");
1163 		break;
1164 	case MGMT_OP_REMOVE_KEY:
1165 		DBG("remove_key complete");
1166 		break;
1167 	case MGMT_OP_DISCONNECT:
1168 		DBG("disconnect complete");
1169 		disconnect_complete(sk, index, ev->data, len);
1170 		break;
1171 	case MGMT_OP_GET_CONNECTIONS:
1172 		get_connections_complete(sk, index, ev->data, len);
1173 		break;
1174 	case MGMT_OP_PIN_CODE_REPLY:
1175 		DBG("pin_code_reply complete");
1176 		break;
1177 	case MGMT_OP_PIN_CODE_NEG_REPLY:
1178 		DBG("pin_code_neg_reply complete");
1179 		break;
1180 	case MGMT_OP_SET_IO_CAPABILITY:
1181 		DBG("set_io_capability complete");
1182 		break;
1183 	case MGMT_OP_PAIR_DEVICE:
1184 		pair_device_complete(sk, index, ev->data, len);
1185 		break;
1186 	case MGMT_OP_USER_CONFIRM_REPLY:
1187 		DBG("user_confirm_reply complete");
1188 		break;
1189 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1190 		DBG("user_confirm_net_reply complete");
1191 		break;
1192 	case MGMT_OP_SET_LOCAL_NAME:
1193 		set_local_name_complete(sk, index, ev->data, len);
1194 		break;
1195 	case MGMT_OP_READ_LOCAL_OOB_DATA:
1196 		read_local_oob_data_complete(sk, index, ev->data, len);
1197 		break;
1198 	case MGMT_OP_ADD_REMOTE_OOB_DATA:
1199 		DBG("add_remote_oob_data complete");
1200 		break;
1201 	case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
1202 		DBG("remove_remote_oob_data complete");
1203 		break;
1204 	default:
1205 		error("Unknown command complete for opcode %u", opcode);
1206 		break;
1207 	}
1208 }
1209 
mgmt_cmd_status(int sk,uint16_t index,void * buf,size_t len)1210 static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
1211 {
1212 	struct mgmt_ev_cmd_status *ev = buf;
1213 	uint16_t opcode;
1214 
1215 	if (len < sizeof(*ev)) {
1216 		error("Too small management command status event packet");
1217 		return;
1218 	}
1219 
1220 	opcode = btohs(bt_get_unaligned(&ev->opcode));
1221 
1222 	DBG("status %u opcode %u (index %u)", ev->status, opcode, index);
1223 
1224 	switch (opcode) {
1225 	case MGMT_OP_READ_LOCAL_OOB_DATA:
1226 		read_local_oob_data_failed(sk, index);
1227 		break;
1228 	}
1229 }
1230 
mgmt_controller_error(int sk,uint16_t index,void * buf,size_t len)1231 static void mgmt_controller_error(int sk, uint16_t index, void *buf, size_t len)
1232 {
1233 	struct mgmt_ev_controller_error *ev = buf;
1234 
1235 	if (len < sizeof(*ev)) {
1236 		error("Too small management controller error event packet");
1237 		return;
1238 	}
1239 
1240 	DBG("index %u error_code %u", index, ev->error_code);
1241 }
1242 
mgmt_auth_failed(int sk,uint16_t index,void * buf,size_t len)1243 static void mgmt_auth_failed(int sk, uint16_t index, void *buf, size_t len)
1244 {
1245 	struct controller_info *info;
1246 	struct mgmt_ev_auth_failed *ev = buf;
1247 
1248 	if (len < sizeof(*ev)) {
1249 		error("Too small mgmt_auth_failed event packet");
1250 		return;
1251 	}
1252 
1253 	DBG("hci%u auth failed status %u", index, ev->status);
1254 
1255 	if (index > max_index) {
1256 		error("Unexpected index %u in auth_failed event", index);
1257 		return;
1258 	}
1259 
1260 	info = &controllers[index];
1261 
1262 	btd_event_bonding_complete(&info->bdaddr, &ev->bdaddr, ev->status);
1263 }
1264 
mgmt_local_name_changed(int sk,uint16_t index,void * buf,size_t len)1265 static void mgmt_local_name_changed(int sk, uint16_t index, void *buf, size_t len)
1266 {
1267 	struct mgmt_cp_set_local_name *ev = buf;
1268 	struct controller_info *info;
1269 	struct btd_adapter *adapter;
1270 
1271 	if (len < sizeof(*ev)) {
1272 		error("Too small mgmt_local_name_changed event packet");
1273 		return;
1274 	}
1275 
1276 	DBG("hci%u local name changed: %s", index, (char *) ev->name);
1277 
1278 	if (index > max_index) {
1279 		error("Unexpected index %u in name_changed event", index);
1280 		return;
1281 	}
1282 
1283 	info = &controllers[index];
1284 
1285 	adapter = manager_find_adapter(&info->bdaddr);
1286 	if (adapter)
1287 		adapter_update_local_name(adapter, (char *) ev->name);
1288 }
1289 
mgmt_device_found(int sk,uint16_t index,void * buf,size_t len)1290 static void mgmt_device_found(int sk, uint16_t index, void *buf, size_t len)
1291 {
1292 	struct mgmt_ev_device_found *ev = buf;
1293 	struct controller_info *info;
1294 	char addr[18];
1295 	uint8_t *eir;
1296 	uint32_t cls;
1297 
1298 	if (len < sizeof(*ev)) {
1299 		error("Too small mgmt_device_found event packet");
1300 		return;
1301 	}
1302 
1303 	if (index > max_index) {
1304 		error("Unexpected index %u in device_found event", index);
1305 		return;
1306 	}
1307 
1308 	info = &controllers[index];
1309 
1310 	cls = ev->dev_class[0] | (ev->dev_class[1] << 8) |
1311 						(ev->dev_class[2] << 16);
1312 
1313 	if (ev->eir[0] == 0)
1314 		eir = NULL;
1315 	else
1316 		eir = ev->eir;
1317 
1318 	ba2str(&ev->bdaddr, addr);
1319 	DBG("hci%u addr %s, class %u rssi %d %s", index, addr, cls,
1320 						ev->rssi, eir ? "eir" : "");
1321 
1322 	btd_event_device_found(&info->bdaddr, &ev->bdaddr, cls, ev->rssi, eir);
1323 }
1324 
mgmt_remote_name(int sk,uint16_t index,void * buf,size_t len)1325 static void mgmt_remote_name(int sk, uint16_t index, void *buf, size_t len)
1326 {
1327 	struct mgmt_ev_remote_name *ev = buf;
1328 	struct controller_info *info;
1329 	char addr[18];
1330 
1331 	if (len < sizeof(*ev)) {
1332 		error("Too small mgmt_remote_name packet");
1333 		return;
1334 	}
1335 
1336 	if (index > max_index) {
1337 		error("Unexpected index %u in remote_name event", index);
1338 		return;
1339 	}
1340 
1341 	info = &controllers[index];
1342 
1343 	ba2str(&ev->bdaddr, addr);
1344 	DBG("hci%u addr %s, name %s", index, addr, ev->name);
1345 
1346 	btd_event_remote_name(&info->bdaddr, &ev->bdaddr, 0, (char *) ev->name);
1347 }
1348 
mgmt_discovering(int sk,uint16_t index,void * buf,size_t len)1349 static void mgmt_discovering(int sk, uint16_t index, void *buf, size_t len)
1350 {
1351 	struct mgmt_mode *ev = buf;
1352 	struct controller_info *info;
1353 	struct btd_adapter *adapter;
1354 	int state;
1355 
1356 	if (len < sizeof(*ev)) {
1357 		error("Too small discovering event");
1358 		return;
1359 	}
1360 
1361 	DBG("Controller %u discovering %u", index, ev->val);
1362 
1363 	if (index > max_index) {
1364 		error("Unexpected index %u in discovering event", index);
1365 		return;
1366 	}
1367 
1368 	info = &controllers[index];
1369 
1370 	adapter = manager_find_adapter(&info->bdaddr);
1371 	if (!adapter)
1372 		return;
1373 
1374 	if (ev->val)
1375 		state = STATE_DISCOV;
1376 	else
1377 		state = STATE_IDLE;
1378 
1379 	adapter_set_state(adapter, state);
1380 }
1381 
mgmt_event(GIOChannel * io,GIOCondition cond,gpointer user_data)1382 static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data)
1383 {
1384 	char buf[MGMT_BUF_SIZE];
1385 	struct mgmt_hdr *hdr = (void *) buf;
1386 	int sk;
1387 	ssize_t ret;
1388 	uint16_t len, opcode, index;
1389 
1390 	DBG("cond %d", cond);
1391 
1392 	if (cond & G_IO_NVAL)
1393 		return FALSE;
1394 
1395 	sk = g_io_channel_unix_get_fd(io);
1396 
1397 	if (cond & (G_IO_ERR | G_IO_HUP)) {
1398 		error("Error on management socket");
1399 		return FALSE;
1400 	}
1401 
1402 	ret = read(sk, buf, sizeof(buf));
1403 	if (ret < 0) {
1404 		error("Unable to read from management socket: %s (%d)",
1405 						strerror(errno), errno);
1406 		return TRUE;
1407 	}
1408 
1409 	DBG("Received %zd bytes from management socket", ret);
1410 
1411 	if (ret < MGMT_HDR_SIZE) {
1412 		error("Too small Management packet");
1413 		return TRUE;
1414 	}
1415 
1416 	opcode = btohs(bt_get_unaligned(&hdr->opcode));
1417 	len = btohs(bt_get_unaligned(&hdr->len));
1418 	index = btohs(bt_get_unaligned(&hdr->index));
1419 
1420 	if (ret != MGMT_HDR_SIZE + len) {
1421 		error("Packet length mismatch. ret %zd len %u", ret, len);
1422 		return TRUE;
1423 	}
1424 
1425 	switch (opcode) {
1426 	case MGMT_EV_CMD_COMPLETE:
1427 		mgmt_cmd_complete(sk, index, buf + MGMT_HDR_SIZE, len);
1428 		break;
1429 	case MGMT_EV_CMD_STATUS:
1430 		mgmt_cmd_status(sk, index, buf + MGMT_HDR_SIZE, len);
1431 		break;
1432 	case MGMT_EV_CONTROLLER_ERROR:
1433 		mgmt_controller_error(sk, index, buf + MGMT_HDR_SIZE, len);
1434 		break;
1435 	case MGMT_EV_INDEX_ADDED:
1436 		mgmt_index_added(sk, index);
1437 		break;
1438 	case MGMT_EV_INDEX_REMOVED:
1439 		mgmt_index_removed(sk, index);
1440 		break;
1441 	case MGMT_EV_POWERED:
1442 		mgmt_powered(sk, index, buf + MGMT_HDR_SIZE, len);
1443 		break;
1444 	case MGMT_EV_DISCOVERABLE:
1445 		mgmt_discoverable(sk, index, buf + MGMT_HDR_SIZE, len);
1446 		break;
1447 	case MGMT_EV_CONNECTABLE:
1448 		mgmt_connectable(sk, index, buf + MGMT_HDR_SIZE, len);
1449 		break;
1450 	case MGMT_EV_PAIRABLE:
1451 		mgmt_pairable(sk, index, buf + MGMT_HDR_SIZE, len);
1452 		break;
1453 	case MGMT_EV_NEW_KEY:
1454 		mgmt_new_key(sk, index, buf + MGMT_HDR_SIZE, len);
1455 		break;
1456 	case MGMT_EV_DEVICE_CONNECTED:
1457 		mgmt_device_connected(sk, index, buf + MGMT_HDR_SIZE, len);
1458 		break;
1459 	case MGMT_EV_DEVICE_DISCONNECTED:
1460 		mgmt_device_disconnected(sk, index, buf + MGMT_HDR_SIZE, len);
1461 		break;
1462 	case MGMT_EV_CONNECT_FAILED:
1463 		mgmt_connect_failed(sk, index, buf + MGMT_HDR_SIZE, len);
1464 		break;
1465 	case MGMT_EV_PIN_CODE_REQUEST:
1466 		mgmt_pin_code_request(sk, index, buf + MGMT_HDR_SIZE, len);
1467 		break;
1468 	case MGMT_EV_USER_CONFIRM_REQUEST:
1469 		mgmt_user_confirm_request(sk, index, buf + MGMT_HDR_SIZE, len);
1470 		break;
1471 	case MGMT_EV_AUTH_FAILED:
1472 		mgmt_auth_failed(sk, index, buf + MGMT_HDR_SIZE, len);
1473 		break;
1474 	case MGMT_EV_LOCAL_NAME_CHANGED:
1475 		mgmt_local_name_changed(sk, index, buf + MGMT_HDR_SIZE, len);
1476 		break;
1477 	case MGMT_EV_DEVICE_FOUND:
1478 		mgmt_device_found(sk, index, buf + MGMT_HDR_SIZE, len);
1479 		break;
1480 	case MGMT_EV_REMOTE_NAME:
1481 		mgmt_remote_name(sk, index, buf + MGMT_HDR_SIZE, len);
1482 		break;
1483 	case MGMT_EV_DISCOVERING:
1484 		mgmt_discovering(sk, index, buf + MGMT_HDR_SIZE, len);
1485 		break;
1486 	default:
1487 		error("Unknown Management opcode %u (index %u)", opcode, index);
1488 		break;
1489 	}
1490 
1491 	return TRUE;
1492 }
1493 
mgmt_setup(void)1494 static int mgmt_setup(void)
1495 {
1496 	struct mgmt_hdr hdr;
1497 	struct sockaddr_hci addr;
1498 	GIOChannel *io;
1499 	GIOCondition condition;
1500 	int dd, err;
1501 
1502 	dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1503 	if (dd < 0)
1504 		return -errno;
1505 
1506 	memset(&addr, 0, sizeof(addr));
1507 	addr.hci_family = AF_BLUETOOTH;
1508 	addr.hci_dev = HCI_DEV_NONE;
1509 	addr.hci_channel = HCI_CHANNEL_CONTROL;
1510 
1511 	if (bind(dd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1512 		err = -errno;
1513 		goto fail;
1514 	}
1515 
1516 	memset(&hdr, 0, sizeof(hdr));
1517 	hdr.opcode = htobs(MGMT_OP_READ_VERSION);
1518 	hdr.index = htobs(MGMT_INDEX_NONE);
1519 	if (write(dd, &hdr, sizeof(hdr)) < 0) {
1520 		err = -errno;
1521 		goto fail;
1522 	}
1523 
1524 	io = g_io_channel_unix_new(dd);
1525 	condition = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
1526 	mgmt_watch = g_io_add_watch(io, condition, mgmt_event, NULL);
1527 	g_io_channel_unref(io);
1528 
1529 	mgmt_sock = dd;
1530 
1531 	info("Bluetooth Management interface initialized");
1532 
1533 	return 0;
1534 
1535 fail:
1536 	close(dd);
1537 	return err;
1538 }
1539 
mgmt_cleanup(void)1540 static void mgmt_cleanup(void)
1541 {
1542 	g_free(controllers);
1543 	controllers = NULL;
1544 	max_index = -1;
1545 
1546 	if (mgmt_sock >= 0) {
1547 		close(mgmt_sock);
1548 		mgmt_sock = -1;
1549 	}
1550 
1551 	if (mgmt_watch > 0) {
1552 		g_source_remove(mgmt_watch);
1553 		mgmt_watch = 0;
1554 	}
1555 }
1556 
mgmt_set_dev_class(int index,uint8_t major,uint8_t minor)1557 static int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor)
1558 {
1559 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)];
1560 	struct mgmt_hdr *hdr = (void *) buf;
1561 	struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)];
1562 
1563 	DBG("index %d major %u minor %u", index, major, minor);
1564 
1565 	memset(buf, 0, sizeof(buf));
1566 	hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS);
1567 	hdr->len = htobs(sizeof(*cp));
1568 	hdr->index = htobs(index);
1569 
1570 	cp->major = major;
1571 	cp->minor = minor;
1572 
1573 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
1574 		return -errno;
1575 
1576 	return 0;
1577 }
1578 
mgmt_set_limited_discoverable(int index,gboolean limited)1579 static int mgmt_set_limited_discoverable(int index, gboolean limited)
1580 {
1581 	DBG("index %d limited %d", index, limited);
1582 	return -ENOSYS;
1583 }
1584 
mgmt_start_discovery(int index)1585 static int mgmt_start_discovery(int index)
1586 {
1587 	struct mgmt_hdr hdr;
1588 
1589 	DBG("index %d", index);
1590 
1591 	memset(&hdr, 0, sizeof(hdr));
1592 	hdr.opcode = htobs(MGMT_OP_START_DISCOVERY);
1593 	hdr.index = htobs(index);
1594 
1595 	if (write(mgmt_sock, &hdr, sizeof(hdr)) < 0)
1596 		return -errno;
1597 
1598 	return 0;
1599 }
1600 
mgmt_stop_discovery(int index)1601 static int mgmt_stop_discovery(int index)
1602 {
1603 	struct mgmt_hdr hdr;
1604 
1605 	DBG("index %d", index);
1606 
1607 	memset(&hdr, 0, sizeof(hdr));
1608 	hdr.opcode = htobs(MGMT_OP_STOP_DISCOVERY);
1609 	hdr.index = htobs(index);
1610 
1611 	if (write(mgmt_sock, &hdr, sizeof(hdr)) < 0)
1612 		return -errno;
1613 
1614 	return 0;
1615 }
1616 
mgmt_resolve_name(int index,bdaddr_t * bdaddr)1617 static int mgmt_resolve_name(int index, bdaddr_t *bdaddr)
1618 {
1619 	char addr[18];
1620 
1621 	ba2str(bdaddr, addr);
1622 	DBG("index %d addr %s", index, addr);
1623 
1624 	return -ENOSYS;
1625 }
1626 
mgmt_set_name(int index,const char * name)1627 static int mgmt_set_name(int index, const char *name)
1628 {
1629 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)];
1630 	struct mgmt_hdr *hdr = (void *) buf;
1631 	struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];
1632 
1633 	DBG("index %d, name %s", index, name);
1634 
1635 	memset(buf, 0, sizeof(buf));
1636 	hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME);
1637 	hdr->len = htobs(sizeof(*cp));
1638 	hdr->index = htobs(index);
1639 
1640 	strncpy((char *) cp->name, name, sizeof(cp->name) - 1);
1641 
1642 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
1643 		return -errno;
1644 
1645 	return 0;
1646 }
1647 
mgmt_cancel_resolve_name(int index,bdaddr_t * bdaddr)1648 static int mgmt_cancel_resolve_name(int index, bdaddr_t *bdaddr)
1649 {
1650 	char addr[18];
1651 
1652 	ba2str(bdaddr, addr);
1653 	DBG("index %d addr %s", index, addr);
1654 
1655 	return -ENOSYS;
1656 }
1657 
mgmt_fast_connectable(int index,gboolean enable)1658 static int mgmt_fast_connectable(int index, gboolean enable)
1659 {
1660 	DBG("index %d enable %d", index, enable);
1661 	return -ENOSYS;
1662 }
1663 
mgmt_read_clock(int index,bdaddr_t * bdaddr,int which,int timeout,uint32_t * clock,uint16_t * accuracy)1664 static int mgmt_read_clock(int index, bdaddr_t *bdaddr, int which, int timeout,
1665 					uint32_t *clock, uint16_t *accuracy)
1666 {
1667 	char addr[18];
1668 
1669 	ba2str(bdaddr, addr);
1670 	DBG("index %d addr %s which %d timeout %d", index, addr, which,
1671 								timeout);
1672 
1673 	return -ENOSYS;
1674 }
1675 
mgmt_read_bdaddr(int index,bdaddr_t * bdaddr)1676 static int mgmt_read_bdaddr(int index, bdaddr_t *bdaddr)
1677 {
1678 	char addr[18];
1679 	struct controller_info *info = &controllers[index];
1680 
1681 	ba2str(&info->bdaddr, addr);
1682 	DBG("index %d addr %s", index, addr);
1683 
1684 	if (!info->valid)
1685 		return -ENODEV;
1686 
1687 	bacpy(bdaddr, &info->bdaddr);
1688 
1689 	return 0;
1690 }
1691 
mgmt_block_device(int index,bdaddr_t * bdaddr)1692 static int mgmt_block_device(int index, bdaddr_t *bdaddr)
1693 {
1694 	char addr[18];
1695 
1696 	ba2str(bdaddr, addr);
1697 	DBG("index %d addr %s", index, addr);
1698 
1699 	return -ENOSYS;
1700 }
1701 
mgmt_unblock_device(int index,bdaddr_t * bdaddr)1702 static int mgmt_unblock_device(int index, bdaddr_t *bdaddr)
1703 {
1704 	char addr[18];
1705 
1706 	ba2str(bdaddr, addr);
1707 	DBG("index %d addr %s", index, addr);
1708 
1709 	return -ENOSYS;
1710 }
1711 
mgmt_get_conn_list(int index,GSList ** conns)1712 static int mgmt_get_conn_list(int index, GSList **conns)
1713 {
1714 	struct controller_info *info = &controllers[index];
1715 
1716 	DBG("index %d", index);
1717 
1718 	*conns = info->connections;
1719 	info->connections = NULL;
1720 
1721 	return 0;
1722 }
1723 
mgmt_read_local_features(int index,uint8_t * features)1724 static int mgmt_read_local_features(int index, uint8_t *features)
1725 {
1726 	struct controller_info *info = &controllers[index];
1727 
1728 	DBG("index %d", index);
1729 
1730 	if (!info->valid)
1731 		return -ENODEV;
1732 
1733 	memcpy(features, info->features, 8);
1734 
1735 	return 0;
1736 }
1737 
mgmt_disconnect(int index,bdaddr_t * bdaddr)1738 static int mgmt_disconnect(int index, bdaddr_t *bdaddr)
1739 {
1740 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_disconnect)];
1741 	struct mgmt_hdr *hdr = (void *) buf;
1742 	struct mgmt_cp_disconnect *cp = (void *) &buf[sizeof(*hdr)];
1743 	char addr[18];
1744 
1745 	ba2str(bdaddr, addr);
1746 	DBG("index %d %s", index, addr);
1747 
1748 	memset(buf, 0, sizeof(buf));
1749 	hdr->opcode = htobs(MGMT_OP_DISCONNECT);
1750 	hdr->len = htobs(sizeof(*cp));
1751 	hdr->index = htobs(index);
1752 
1753 	bacpy(&cp->bdaddr, bdaddr);
1754 
1755 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
1756 		error("write: %s (%d)", strerror(errno), errno);
1757 
1758 	return 0;
1759 }
1760 
mgmt_remove_bonding(int index,bdaddr_t * bdaddr)1761 static int mgmt_remove_bonding(int index, bdaddr_t *bdaddr)
1762 {
1763 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_key)];
1764 	struct mgmt_hdr *hdr = (void *) buf;
1765 	struct mgmt_cp_remove_key *cp = (void *) &buf[sizeof(*hdr)];
1766 	char addr[18];
1767 
1768 	ba2str(bdaddr, addr);
1769 	DBG("index %d addr %s", index, addr);
1770 
1771 	memset(buf, 0, sizeof(buf));
1772 	hdr->opcode = htobs(MGMT_OP_REMOVE_KEY);
1773 	hdr->len = htobs(sizeof(*cp));
1774 	hdr->index = htobs(index);
1775 
1776 	bacpy(&cp->bdaddr, bdaddr);
1777 	cp->disconnect = 1;
1778 
1779 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
1780 		return -errno;
1781 
1782 	return 0;
1783 }
1784 
mgmt_passkey_reply(int index,bdaddr_t * bdaddr,uint32_t passkey)1785 static int mgmt_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey)
1786 {
1787 	char addr[18];
1788 
1789 	ba2str(bdaddr, addr);
1790 	DBG("index %d addr %s passkey %06u", index, addr, passkey);
1791 
1792 	return -ENOSYS;
1793 }
1794 
mgmt_enable_le(int index)1795 static int mgmt_enable_le(int index)
1796 {
1797 	DBG("index %d", index);
1798 	return -ENOSYS;
1799 }
1800 
mgmt_encrypt_link(int index,bdaddr_t * dst,bt_hci_result_t cb,gpointer user_data)1801 static int mgmt_encrypt_link(int index, bdaddr_t *dst, bt_hci_result_t cb,
1802 							gpointer user_data)
1803 {
1804 	char addr[18];
1805 
1806 	ba2str(dst, addr);
1807 	DBG("index %d addr %s", index, addr);
1808 
1809 	return -ENOSYS;
1810 }
1811 
mgmt_set_did(int index,uint16_t vendor,uint16_t product,uint16_t version)1812 static int mgmt_set_did(int index, uint16_t vendor, uint16_t product,
1813 							uint16_t version)
1814 {
1815 	DBG("index %d vendor %u product %u version %u",
1816 					index, vendor, product, version);
1817 	return -ENOSYS;
1818 }
1819 
mgmt_disable_cod_cache(int index)1820 static int mgmt_disable_cod_cache(int index)
1821 {
1822 	DBG("index %d", index);
1823 	return mgmt_set_mode(index, MGMT_OP_SET_SERVICE_CACHE, 0);
1824 }
1825 
mgmt_restore_powered(int index)1826 static int mgmt_restore_powered(int index)
1827 {
1828 	DBG("index %d", index);
1829 	return -ENOSYS;
1830 }
1831 
mgmt_load_keys(int index,GSList * keys,gboolean debug_keys)1832 static int mgmt_load_keys(int index, GSList *keys, gboolean debug_keys)
1833 {
1834 	char *buf;
1835 	struct mgmt_hdr *hdr;
1836 	struct mgmt_cp_load_keys *cp;
1837 	struct mgmt_key_info *key;
1838 	size_t key_count, cp_size;
1839 	GSList *l;
1840 	int err;
1841 
1842 	key_count = g_slist_length(keys);
1843 
1844 	DBG("index %d keys %zu debug_keys %d", index, key_count, debug_keys);
1845 
1846 	cp_size = sizeof(*cp) + (key_count * sizeof(*key));
1847 
1848 	buf = g_try_malloc0(sizeof(*hdr) + cp_size);
1849 	if (buf == NULL)
1850 		return -ENOMEM;
1851 
1852 	memset(buf, 0, sizeof(buf));
1853 
1854 	hdr = (void *) buf;
1855 	hdr->opcode = htobs(MGMT_OP_LOAD_KEYS);
1856 	hdr->len = htobs(cp_size);
1857 	hdr->index = htobs(index);
1858 
1859 	cp = (void *) (buf + sizeof(*hdr));
1860 	cp->debug_keys = debug_keys;
1861 	cp->key_count = htobs(key_count);
1862 
1863 	for (l = keys, key = cp->keys; l != NULL; l = g_slist_next(l), key++) {
1864 		struct link_key_info *info = l->data;
1865 
1866 		bacpy(&key->bdaddr, &info->bdaddr);
1867 		key->type = info->type;
1868 		memcpy(key->val, info->key, 16);
1869 		key->pin_len = info->pin_len;
1870 	}
1871 
1872 	if (write(mgmt_sock, buf, sizeof(*hdr) + cp_size) < 0)
1873 		err = -errno;
1874 	else
1875 		err = 0;
1876 
1877 	g_free(buf);
1878 
1879 	return err;
1880 }
1881 
mgmt_set_io_capability(int index,uint8_t io_capability)1882 static int mgmt_set_io_capability(int index, uint8_t io_capability)
1883 {
1884 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_io_capability)];
1885 	struct mgmt_hdr *hdr = (void *) buf;
1886 	struct mgmt_cp_set_io_capability *cp = (void *) &buf[sizeof(*hdr)];
1887 
1888 	DBG("hci%d io_capability 0x%02x", index, io_capability);
1889 
1890 	memset(buf, 0, sizeof(buf));
1891 	hdr->opcode = htobs(MGMT_OP_SET_IO_CAPABILITY);
1892 	hdr->len = htobs(sizeof(*cp));
1893 	hdr->index = htobs(index);
1894 
1895 	cp->io_capability = io_capability;
1896 
1897 	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
1898 		return -errno;
1899 
1900 	return 0;
1901 }
1902 
mgmt_create_bonding(int index,bdaddr_t * bdaddr,uint8_t io_cap)1903 static int mgmt_create_bonding(int index, bdaddr_t *bdaddr, uint8_t io_cap)
1904 {
1905 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pair_device)];
1906 	struct mgmt_hdr *hdr = (void *) buf;
1907 	struct mgmt_cp_pair_device *cp = (void *) &buf[sizeof(*hdr)];
1908 	char addr[18];
1909 
1910 	ba2str(bdaddr, addr);
1911 	DBG("hci%d bdaddr %s io_cap 0x%02x", index, addr, io_cap);
1912 
1913 	memset(buf, 0, sizeof(buf));
1914 	hdr->opcode = htobs(MGMT_OP_PAIR_DEVICE);
1915 	hdr->len = htobs(sizeof(*cp));
1916 	hdr->index = htobs(index);
1917 
1918 	bacpy(&cp->bdaddr, bdaddr);
1919 	cp->io_cap = io_cap;
1920 
1921 	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
1922 		return -errno;
1923 
1924 	return 0;
1925 }
1926 
mgmt_cancel_bonding(int index,bdaddr_t * bdaddr)1927 static int mgmt_cancel_bonding(int index, bdaddr_t *bdaddr)
1928 {
1929 	char addr[18];
1930 
1931 	ba2str(bdaddr, addr);
1932 	DBG("hci%d bdaddr %s", index, addr);
1933 
1934 	return -ENOSYS;
1935 }
1936 
mgmt_read_local_oob_data(int index)1937 static int mgmt_read_local_oob_data(int index)
1938 {
1939 	struct mgmt_hdr hdr;
1940 
1941 	DBG("hci%d", index);
1942 
1943 	hdr.opcode = htobs(MGMT_OP_READ_LOCAL_OOB_DATA);
1944 	hdr.len = 0;
1945 	hdr.index = htobs(index);
1946 
1947 	if (write(mgmt_sock, &hdr, sizeof(hdr)) < 0)
1948 		return -errno;
1949 
1950 	return 0;
1951 }
1952 
mgmt_add_remote_oob_data(int index,bdaddr_t * bdaddr,uint8_t * hash,uint8_t * randomizer)1953 static int mgmt_add_remote_oob_data(int index, bdaddr_t *bdaddr,
1954 					uint8_t *hash, uint8_t *randomizer)
1955 {
1956 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_remote_oob_data)];
1957 	struct mgmt_hdr *hdr = (void *) buf;
1958 	struct mgmt_cp_add_remote_oob_data *cp = (void *) &buf[sizeof(*hdr)];
1959 	char addr[18];
1960 
1961 	ba2str(bdaddr, addr);
1962 	DBG("hci%d bdaddr %s", index, addr);
1963 
1964 	memset(buf, 0, sizeof(buf));
1965 
1966 	hdr->opcode = htobs(MGMT_OP_ADD_REMOTE_OOB_DATA);
1967 	hdr->index = htobs(index);
1968 	hdr->len = htobs(sizeof(*cp));
1969 
1970 	bacpy(&cp->bdaddr, bdaddr);
1971 	memcpy(cp->hash, hash, 16);
1972 	memcpy(cp->randomizer, randomizer, 16);
1973 
1974 	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
1975 		return -errno;
1976 
1977 	return 0;
1978 }
1979 
mgmt_remove_remote_oob_data(int index,bdaddr_t * bdaddr)1980 static int mgmt_remove_remote_oob_data(int index, bdaddr_t *bdaddr)
1981 {
1982 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_remote_oob_data)];
1983 	struct mgmt_hdr *hdr = (void *) buf;
1984 	struct mgmt_cp_remove_remote_oob_data *cp = (void *) &buf[sizeof(*hdr)];
1985 	char addr[18];
1986 
1987 	ba2str(bdaddr, addr);
1988 	DBG("hci%d bdaddr %s", index, addr);
1989 
1990 	memset(buf, 0, sizeof(buf));
1991 
1992 	hdr->opcode = htobs(MGMT_OP_REMOVE_REMOTE_OOB_DATA);
1993 	hdr->index = htobs(index);
1994 	hdr->len = htobs(sizeof(*cp));
1995 
1996 	bacpy(&cp->bdaddr, bdaddr);
1997 
1998 	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
1999 		return -errno;
2000 
2001 	return 0;
2002 }
2003 
2004 static struct btd_adapter_ops mgmt_ops = {
2005 	.setup = mgmt_setup,
2006 	.cleanup = mgmt_cleanup,
2007 	.set_powered = mgmt_set_powered,
2008 	.set_discoverable = mgmt_set_discoverable,
2009 	.set_pairable = mgmt_set_pairable,
2010 	.set_limited_discoverable = mgmt_set_limited_discoverable,
2011 	.start_discovery = mgmt_start_discovery,
2012 	.stop_discovery = mgmt_stop_discovery,
2013 	.resolve_name = mgmt_resolve_name,
2014 	.cancel_resolve_name = mgmt_cancel_resolve_name,
2015 	.set_name = mgmt_set_name,
2016 	.set_dev_class = mgmt_set_dev_class,
2017 	.set_fast_connectable = mgmt_fast_connectable,
2018 	.read_clock = mgmt_read_clock,
2019 	.read_bdaddr = mgmt_read_bdaddr,
2020 	.block_device = mgmt_block_device,
2021 	.unblock_device = mgmt_unblock_device,
2022 	.get_conn_list = mgmt_get_conn_list,
2023 	.read_local_features = mgmt_read_local_features,
2024 	.disconnect = mgmt_disconnect,
2025 	.remove_bonding = mgmt_remove_bonding,
2026 	.pincode_reply = mgmt_pincode_reply,
2027 	.confirm_reply = mgmt_confirm_reply,
2028 	.passkey_reply = mgmt_passkey_reply,
2029 	.enable_le = mgmt_enable_le,
2030 	.encrypt_link = mgmt_encrypt_link,
2031 	.set_did = mgmt_set_did,
2032 	.add_uuid = mgmt_add_uuid,
2033 	.remove_uuid = mgmt_remove_uuid,
2034 	.disable_cod_cache = mgmt_disable_cod_cache,
2035 	.restore_powered = mgmt_restore_powered,
2036 	.load_keys = mgmt_load_keys,
2037 	.set_io_capability = mgmt_set_io_capability,
2038 	.create_bonding = mgmt_create_bonding,
2039 	.cancel_bonding = mgmt_cancel_bonding,
2040 	.read_local_oob_data = mgmt_read_local_oob_data,
2041 	.add_remote_oob_data = mgmt_add_remote_oob_data,
2042 	.remove_remote_oob_data = mgmt_remove_remote_oob_data,
2043 };
2044 
mgmt_init(void)2045 static int mgmt_init(void)
2046 {
2047 	return btd_register_adapter_ops(&mgmt_ops, TRUE);
2048 }
2049 
mgmt_exit(void)2050 static void mgmt_exit(void)
2051 {
2052 	btd_adapter_cleanup_ops(&mgmt_ops);
2053 }
2054 
2055 BLUETOOTH_PLUGIN_DEFINE(mgmtops, VERSION,
2056 		BLUETOOTH_PLUGIN_PRIORITY_LOW, mgmt_init, mgmt_exit)
2057