• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2006-2007  Nokia Corporation
6  *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #define _GNU_SOURCE
30 #include <stdio.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <time.h>
36 #include <sys/param.h>
37 #include <sys/ioctl.h>
38 #include <sys/socket.h>
39 
40 #include <bluetooth/bluetooth.h>
41 #include <bluetooth/hci.h>
42 #include <bluetooth/hci_lib.h>
43 #include <bluetooth/l2cap.h>
44 #include <bluetooth/sdp.h>
45 #include <bluetooth/sdp_lib.h>
46 
47 #include <glib.h>
48 #include <dbus/dbus.h>
49 #include <gdbus.h>
50 
51 #include "hcid.h"
52 
53 #include "adapter.h"
54 #include "device.h"
55 
56 #include "textfile.h"
57 #include "oui.h"
58 #include "dbus-common.h"
59 #include "dbus-hci.h"
60 #include "dbus-sdp.h"
61 #include "dbus-database.h"
62 #include "dbus-service.h"
63 #include "dbus-security.h"
64 #include "dbus-error.h"
65 #include "error.h"
66 #include "glib-helper.h"
67 #include "logging.h"
68 #include "agent.h"
69 
70 #define NUM_ELEMENTS(table) (sizeof(table)/sizeof(const char *))
71 
72 #define IO_CAPABILITY_DISPLAYONLY	0x00
73 #define IO_CAPABILITY_DISPLAYYESNO	0x01
74 #define IO_CAPABILITY_KEYBOARDONLY	0x02
75 #define IO_CAPABILITY_NOINPUTOUTPUT	0x03
76 #define IO_CAPABILITY_INVALID		0xFF
77 
78 struct mode_req {
79 	struct adapter	*adapter;
80 	DBusConnection	*conn;		/* Connection reference */
81 	DBusMessage	*msg;		/* Message reference */
82 	uint8_t		mode;		/* Requested mode */
83 	guint		id;		/* Listener id */
84 };
85 
86 static const char *service_cls[] = {
87 	"positioning",
88 	"networking",
89 	"rendering",
90 	"capturing",
91 	"object transfer",
92 	"audio",
93 	"telephony",
94 	"information"
95 };
96 
97 static const char *major_cls[] = {
98 	"miscellaneous",
99 	"computer",
100 	"phone",
101 	"access point",
102 	"audio/video",
103 	"peripheral",
104 	"imaging",
105 	"wearable",
106 	"toy",
107 	"uncategorized"
108 };
109 
110 static const char *computer_minor_cls[] = {
111 	"uncategorized",
112 	"desktop",
113 	"server",
114 	"laptop",
115 	"handheld",
116 	"palm",
117 	"wearable"
118 };
119 
120 static const char *phone_minor_cls[] = {
121 	"uncategorized",
122 	"cellular",
123 	"cordless",
124 	"smart phone",
125 	"modem",
126 	"isdn"
127 };
128 
129 static const char *access_point_minor_cls[] = {
130 	"fully",
131 	"1-17 percent",
132 	"17-33 percent",
133 	"33-50 percent",
134 	"50-67 percent",
135 	"67-83 percent",
136 	"83-99 percent",
137 	"not available"
138 };
139 
140 static const char *audio_video_minor_cls[] = {
141 	"uncategorized",
142 	"headset",
143 	"handsfree",
144 	"unknown",
145 	"microphone",
146 	"loudspeaker",
147 	"headphones",
148 	"portable audio",
149 	"car audio",
150 	"set-top box",
151 	"hifi audio",
152 	"vcr",
153 	"video camera",
154 	"camcorder",
155 	"video monitor",
156 	"video display and loudspeaker",
157 	"video conferencing",
158 	"unknown",
159 	"gaming/toy"
160 };
161 
162 static const char *peripheral_minor_cls[] = {
163 	"uncategorized",
164 	"keyboard",
165 	"pointing",
166 	"combo"
167 };
168 
169 #if 0
170 static const char *peripheral_2_minor_cls[] = {
171 	"uncategorized",
172 	"joystick",
173 	"gamepad",
174 	"remote control",
175 	"sensing",
176 	"digitizer tablet",
177 	"card reader"
178 };
179 #endif
180 
181 static const char *imaging_minor_cls[] = {
182 	"display",
183 	"camera",
184 	"scanner",
185 	"printer"
186 };
187 
188 static const char *wearable_minor_cls[] = {
189 	"wrist watch",
190 	"pager",
191 	"jacket",
192 	"helmet",
193 	"glasses"
194 };
195 
196 static const char *toy_minor_cls[] = {
197 	"robot",
198 	"vehicle",
199 	"doll",
200 	"controller",
201 	"game"
202 };
203 
invalid_args(DBusMessage * msg)204 static inline DBusMessage *invalid_args(DBusMessage *msg)
205 {
206 	return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
207 			"Invalid arguments in method call");
208 }
209 
not_available(DBusMessage * msg)210 static inline DBusMessage *not_available(DBusMessage *msg)
211 {
212 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
213 			"Not Available");
214 }
215 
adapter_not_ready(DBusMessage * msg)216 static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
217 {
218 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
219 			"Adapter is not ready");
220 }
221 
no_such_adapter(DBusMessage * msg)222 static inline DBusMessage *no_such_adapter(DBusMessage *msg)
223 {
224 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter",
225 							"No such adapter");
226 }
227 
failed_strerror(DBusMessage * msg,int err)228 static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
229 {
230 	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
231 			strerror(err));
232 }
233 
in_progress(DBusMessage * msg,const char * str)234 static inline DBusMessage *in_progress(DBusMessage *msg, const char *str)
235 {
236 	return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", str);
237 }
238 
not_in_progress(DBusMessage * msg,const char * str)239 static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
240 {
241 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotInProgress", str);
242 }
243 
not_authorized(DBusMessage * msg)244 static inline DBusMessage *not_authorized(DBusMessage *msg)
245 {
246 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAuthorized",
247 			"Not authorized");
248 }
249 
unsupported_major_class(DBusMessage * msg)250 static inline DBusMessage *unsupported_major_class(DBusMessage *msg)
251 {
252 	return g_dbus_create_error(msg,
253 			ERROR_INTERFACE ".UnsupportedMajorClass",
254 			"Unsupported Major Class");
255 }
256 
auth_req_cmp(const void * p1,const void * p2)257 static int auth_req_cmp(const void *p1, const void *p2)
258 {
259 	const struct pending_auth_info *pb1 = p1;
260 	const bdaddr_t *bda = p2;
261 
262 	return bda ? bacmp(&pb1->bdaddr, bda) : -1;
263 }
264 
adapter_auth_request_replied(struct adapter * adapter,bdaddr_t * dba)265 void adapter_auth_request_replied(struct adapter *adapter, bdaddr_t *dba)
266 {
267 	GSList *l;
268 	struct pending_auth_info *auth;
269 
270 	l = g_slist_find_custom(adapter->auth_reqs, dba, auth_req_cmp);
271 	if (!l)
272 		return;
273 
274 	auth = l->data;
275 
276 	auth->replied = TRUE;
277 }
278 
adapter_find_auth_request(struct adapter * adapter,bdaddr_t * dba)279 struct pending_auth_info *adapter_find_auth_request(struct adapter *adapter,
280 							bdaddr_t *dba)
281 {
282 	GSList *l;
283 
284 	l = g_slist_find_custom(adapter->auth_reqs, dba, auth_req_cmp);
285 	if (l)
286 		return l->data;
287 
288 	return NULL;
289 }
290 
adapter_remove_auth_request(struct adapter * adapter,bdaddr_t * dba)291 void adapter_remove_auth_request(struct adapter *adapter, bdaddr_t *dba)
292 {
293 	GSList *l;
294 	struct pending_auth_info *auth;
295 
296 	l = g_slist_find_custom(adapter->auth_reqs, dba, auth_req_cmp);
297 	if (!l)
298 		return;
299 
300 	auth = l->data;
301 
302 	adapter->auth_reqs = g_slist_remove(adapter->auth_reqs, auth);
303 
304 	g_free(auth);
305 }
306 
adapter_new_auth_request(struct adapter * adapter,bdaddr_t * dba,auth_type_t type)307 struct pending_auth_info *adapter_new_auth_request(struct adapter *adapter,
308 							bdaddr_t *dba,
309 							auth_type_t type)
310 {
311 	struct pending_auth_info *info;
312 
313 	debug("hcid_dbus_new_auth_request");
314 
315 	info = g_new0(struct pending_auth_info, 1);
316 
317 	bacpy(&info->bdaddr, dba);
318 	info->type = type;
319 	adapter->auth_reqs = g_slist_append(adapter->auth_reqs, info);
320 
321 	if (adapter->bonding && !bacmp(dba, &adapter->bonding->bdaddr))
322 		adapter->bonding->auth_active = 1;
323 
324 	return info;
325 }
326 
pending_remote_name_cancel(struct adapter * adapter)327 int pending_remote_name_cancel(struct adapter *adapter)
328 {
329 	struct remote_dev_info *dev, match;
330 	GSList *l;
331 	int dd, err = 0;
332 
333 	/* find the pending remote name request */
334 	memset(&match, 0, sizeof(struct remote_dev_info));
335 	bacpy(&match.bdaddr, BDADDR_ANY);
336 	match.name_status = NAME_REQUESTED;
337 
338 	l = g_slist_find_custom(adapter->found_devices, &match,
339 			(GCompareFunc) found_device_cmp);
340 	if (!l) /* no pending request */
341 		return 0;
342 
343 	dd = hci_open_dev(adapter->dev_id);
344 	if (dd < 0)
345 		return -ENODEV;
346 
347 	dev = l->data;
348 
349 	if (hci_read_remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {
350 		error("Remote name cancel failed: %s(%d)", strerror(errno), errno);
351 		err = -errno;
352 	}
353 
354 	/* free discovered devices list */
355 	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
356 	g_slist_free(adapter->found_devices);
357 	adapter->found_devices = NULL;
358 
359 	hci_close_dev(dd);
360 	return err;
361 }
362 
auth_info_agent_cmp(const void * a,const void * b)363 static int auth_info_agent_cmp(const void *a, const void *b)
364 {
365 	const struct pending_auth_info *auth = a;
366 	const struct agent *agent = b;
367 
368 	if (auth->agent == agent)
369 		return 0;
370 
371 	return -1;
372 }
373 
device_agent_removed(struct agent * agent,void * user_data)374 static void device_agent_removed(struct agent *agent, void *user_data)
375 {
376 	struct device *device = user_data;
377 	struct pending_auth_info *auth;
378 	GSList *l;
379 
380 	device->agent = NULL;
381 
382 	l = g_slist_find_custom(device->adapter->auth_reqs, agent,
383 					auth_info_agent_cmp);
384 	if (!l)
385 		return;
386 
387 	auth = l->data;
388 	auth->agent = NULL;
389 }
390 
bonding_request_new(DBusConnection * conn,DBusMessage * msg,struct adapter * adapter,const char * address,const char * agent_path,uint8_t capability)391 static struct bonding_request_info *bonding_request_new(DBusConnection *conn,
392 							DBusMessage *msg,
393 							struct adapter *adapter,
394 							const char *address,
395 							const char *agent_path,
396 							uint8_t capability)
397 {
398 	struct bonding_request_info *bonding;
399 	struct device *device;
400 
401 	debug("bonding_request_new(%s)", address);
402 
403 	if (hcid_dbus_use_experimental() && agent_path) {
404 		const char *name = dbus_message_get_sender(msg);
405 
406 		device = adapter_get_device(conn, adapter, address);
407 		if (!device)
408 			return NULL;
409 
410 		device->agent = agent_create(adapter, name, agent_path,
411 						capability,
412 						device_agent_removed,
413 						device);
414 		debug("Temporary agent registered for hci%d/%s at %s:%s",
415 				adapter->dev_id, device->address, name,
416 				agent_path);
417 	}
418 
419 	bonding = g_new0(struct bonding_request_info, 1);
420 
421 	bonding->conn = dbus_connection_ref(conn);
422 	bonding->msg = dbus_message_ref(msg);
423 	bonding->adapter = adapter;
424 
425 	str2ba(address, &bonding->bdaddr);
426 
427 	return bonding;
428 }
429 
mode2str(uint8_t mode)430 const char *mode2str(uint8_t mode)
431 {
432 	switch(mode) {
433 	case MODE_OFF:
434 		return "off";
435 	case MODE_CONNECTABLE:
436 		return "connectable";
437 	case MODE_DISCOVERABLE:
438 		return "discoverable";
439 	case MODE_LIMITED:
440 		return "limited";
441 	default:
442 		return "unknown";
443 	}
444 }
445 
on_mode(const char * addr)446 static uint8_t on_mode(const char *addr)
447 {
448 	char mode[14];
449 	bdaddr_t sba;
450 
451 	str2ba(addr, &sba);
452 
453 	if (read_on_mode(&sba, mode, sizeof(mode)) < 0)
454 		return MODE_CONNECTABLE;
455 
456 	return str2mode(addr, mode);
457 }
458 
str2mode(const char * addr,const char * mode)459 uint8_t str2mode(const char *addr, const char *mode)
460 {
461 	if (strcasecmp("off", mode) == 0)
462 		return MODE_OFF;
463 	else if (strcasecmp("connectable", mode) == 0)
464 		return MODE_CONNECTABLE;
465 	else if (strcasecmp("discoverable", mode) == 0)
466 		return MODE_DISCOVERABLE;
467 	else if (strcasecmp("limited", mode) == 0)
468 		return MODE_LIMITED;
469 	else if (strcasecmp("on", mode) == 0)
470 		return on_mode(addr);
471 	else
472 		return MODE_UNKNOWN;
473 }
474 
adapter_get_info(DBusConnection * conn,DBusMessage * msg,void * data)475 static DBusMessage *adapter_get_info(DBusConnection *conn,
476 				DBusMessage *msg, void *data)
477 {
478 	struct adapter *adapter = data;
479 	const char *property;
480 	DBusMessage *reply;
481 	DBusMessageIter iter;
482 	DBusMessageIter dict;
483 	bdaddr_t ba;
484 	char str[249];
485 	uint8_t cls[3];
486 
487 	if (check_address(adapter->address) < 0)
488 		return adapter_not_ready(msg);
489 
490 	reply = dbus_message_new_method_return(msg);
491 	if (!reply)
492 		return NULL;
493 
494 	dbus_message_iter_init_append(reply, &iter);
495 
496 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
497 			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
498 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
499 			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
500 
501 	property = adapter->address;
502 	dbus_message_iter_append_dict_entry(&dict, "address",
503 			DBUS_TYPE_STRING, &property);
504 
505 	memset(str, 0, sizeof(str));
506 	property = str;
507 	str2ba(adapter->address, &ba);
508 
509 	if (!read_local_name(&ba, str))
510 		dbus_message_iter_append_dict_entry(&dict, "name",
511 			DBUS_TYPE_STRING, &property);
512 
513 	get_device_version(adapter->dev_id, str, sizeof(str));
514 	dbus_message_iter_append_dict_entry(&dict, "version",
515 			DBUS_TYPE_STRING, &property);
516 
517 	get_device_revision(adapter->dev_id, str, sizeof(str));
518 	dbus_message_iter_append_dict_entry(&dict, "revision",
519 			DBUS_TYPE_STRING, &property);
520 
521 	get_device_manufacturer(adapter->dev_id, str, sizeof(str));
522 	dbus_message_iter_append_dict_entry(&dict, "manufacturer",
523 			DBUS_TYPE_STRING, &property);
524 
525 	get_device_company(adapter->dev_id, str, sizeof(str));
526 	dbus_message_iter_append_dict_entry(&dict, "company",
527 			DBUS_TYPE_STRING, &property);
528 
529 	property = mode2str(adapter->mode);
530 
531 	dbus_message_iter_append_dict_entry(&dict, "mode",
532 			DBUS_TYPE_STRING, &property);
533 
534 	dbus_message_iter_append_dict_entry(&dict, "discoverable_timeout",
535 				DBUS_TYPE_UINT32, &adapter->discov_timeout);
536 
537 	if (!read_local_class(&ba, cls)) {
538 		uint32_t class;
539 
540 		memcpy(&class, cls, 3);
541 		dbus_message_iter_append_dict_entry(&dict, "class",
542 			DBUS_TYPE_UINT32, &class);
543 
544 		property = major_class_str(class);
545 		dbus_message_iter_append_dict_entry(&dict, "major_class",
546 			DBUS_TYPE_STRING, &property);
547 
548 		property = minor_class_str(class);
549 		dbus_message_iter_append_dict_entry(&dict, "minor_class",
550 			DBUS_TYPE_STRING, &property);
551 	}
552 
553 	dbus_message_iter_close_container(&iter, &dict);
554 
555 	return reply;
556 }
557 
adapter_get_address(DBusConnection * conn,DBusMessage * msg,void * data)558 static DBusMessage *adapter_get_address(DBusConnection *conn,
559 					DBusMessage *msg, void *data)
560 {
561 	struct adapter *adapter = data;
562 	const char *paddr = adapter->address;
563 	DBusMessage *reply;
564 
565 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
566 		return invalid_args(msg);
567 
568 	if (check_address(paddr) < 0)
569 		return adapter_not_ready(msg);
570 
571 	reply = dbus_message_new_method_return(msg);
572 	if (!reply)
573 		return NULL;
574 
575 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &paddr,
576 					DBUS_TYPE_INVALID);
577 
578 	return reply;
579 }
580 
adapter_get_version(DBusConnection * conn,DBusMessage * msg,void * data)581 static DBusMessage *adapter_get_version(DBusConnection *conn,
582 				DBusMessage *msg, void *data)
583 {
584 	struct adapter *adapter = data;
585 	DBusMessage *reply;
586 	char str[20], *str_ptr = str;
587 	int err;
588 
589 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
590 		return invalid_args(msg);
591 
592 	err = get_device_version(adapter->dev_id, str, sizeof(str));
593 	if (err < 0)
594 		return failed_strerror(msg, -err);
595 
596 	reply = dbus_message_new_method_return(msg);
597 	if (!reply)
598 		return NULL;
599 
600 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
601 					DBUS_TYPE_INVALID);
602 
603 	return reply;
604 }
605 
adapter_get_revision(DBusConnection * conn,DBusMessage * msg,void * data)606 static DBusMessage *adapter_get_revision(DBusConnection *conn,
607 					DBusMessage *msg, void *data)
608 {
609 	struct adapter *adapter = data;
610 	DBusMessage *reply;
611 	char str[64], *str_ptr = str;
612 	int err;
613 
614 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
615 		return invalid_args(msg);
616 
617 	err = get_device_revision(adapter->dev_id, str, sizeof(str));
618 	if (err < 0)
619 		return failed_strerror(msg, -err);
620 
621 	reply = dbus_message_new_method_return(msg);
622 	if (!reply)
623 		return NULL;
624 
625 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
626 					DBUS_TYPE_INVALID);
627 
628 	return reply;
629 }
630 
adapter_get_manufacturer(DBusConnection * conn,DBusMessage * msg,void * data)631 static DBusMessage *adapter_get_manufacturer(DBusConnection *conn,
632 					DBusMessage *msg, void *data)
633 {
634 	struct adapter *adapter = data;
635 	DBusMessage *reply;
636 	char str[64], *str_ptr = str;
637 	int err;
638 
639 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
640 		return invalid_args(msg);
641 
642 	err = get_device_manufacturer(adapter->dev_id, str, sizeof(str));
643 	if (err < 0)
644 		return failed_strerror(msg, -err);
645 
646 	reply = dbus_message_new_method_return(msg);
647 	if (!reply)
648 		return NULL;
649 
650 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
651 					DBUS_TYPE_INVALID);
652 
653 	return reply;
654 }
655 
adapter_get_company(DBusConnection * conn,DBusMessage * msg,void * data)656 static DBusMessage *adapter_get_company(DBusConnection *conn,
657 				DBusMessage *msg, void *data)
658 {
659 	struct adapter *adapter = data;
660 	DBusMessage *reply;
661 	char str[64], *str_ptr = str;
662 	int err;
663 
664 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
665 		return invalid_args(msg);
666 
667 	err = get_device_company(adapter->dev_id, str, sizeof(str));
668 	if (err < 0)
669 		return failed_strerror(msg, -err);
670 
671 	reply = dbus_message_new_method_return(msg);
672 	if (!reply)
673 		return NULL;
674 
675 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
676 					DBUS_TYPE_INVALID);
677 
678 	return reply;
679 }
680 
adapter_list_modes(DBusConnection * conn,DBusMessage * msg,void * data)681 static DBusMessage *adapter_list_modes(DBusConnection *conn,
682 					DBusMessage *msg, void *data)
683 {
684 	DBusMessage *reply;
685 	DBusMessageIter iter;
686 	DBusMessageIter array_iter;
687 	const char *mode_ptr[] = { "off", "connectable", "discoverable", "limited" };
688 	int i;
689 
690 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
691 		return invalid_args(msg);
692 
693 	reply = dbus_message_new_method_return(msg);
694 	if (!reply)
695 		return NULL;
696 
697 	dbus_message_iter_init_append(reply, &iter);
698 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
699 						DBUS_TYPE_STRING_AS_STRING, &array_iter);
700 	for (i = 0; i < 4; i++)
701 		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
702 								&mode_ptr[i]);
703 
704 	dbus_message_iter_close_container(&iter, &array_iter);
705 
706 	return reply;
707 }
708 
adapter_get_mode(DBusConnection * conn,DBusMessage * msg,void * data)709 static DBusMessage *adapter_get_mode(DBusConnection *conn,
710 						DBusMessage *msg, void *data)
711 {
712 	const struct adapter *adapter = data;
713 	DBusMessage *reply = NULL;
714 	const char *mode;
715 
716 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
717 		return invalid_args(msg);
718 
719 	reply = dbus_message_new_method_return(msg);
720 	if (!reply)
721 		return NULL;
722 
723 	mode = mode2str(adapter->mode);
724 
725 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &mode,
726 					DBUS_TYPE_INVALID);
727 
728 	return reply;
729 }
730 
set_mode(DBusConnection * conn,DBusMessage * msg,uint8_t new_mode,void * data)731 static DBusMessage *set_mode(DBusConnection *conn, DBusMessage *msg,
732 				uint8_t new_mode, void *data)
733 {
734 	struct adapter *adapter = data;
735 	uint8_t scan_enable;
736 	uint8_t current_scan = adapter->scan_enable;
737 	bdaddr_t local;
738 	gboolean limited;
739 	int err, dd;
740 	const char *mode;
741 
742 	switch(new_mode) {
743 	case MODE_OFF:
744 		scan_enable = SCAN_DISABLED;
745 		break;
746 	case MODE_CONNECTABLE:
747 		scan_enable = SCAN_PAGE;
748 		break;
749 	case MODE_DISCOVERABLE:
750 	case MODE_LIMITED:
751 		scan_enable = (SCAN_PAGE | SCAN_INQUIRY);
752 		break;
753 	default:
754 		return invalid_args(msg);
755 	}
756 
757 	/* Do reverse resolution in case of "on" mode */
758 	mode = mode2str(new_mode);
759 
760 	dd = hci_open_dev(adapter->dev_id);
761 	if (dd < 0)
762 		return no_such_adapter(msg);
763 
764 	if (!adapter->up &&
765 			(hcid.offmode == HCID_OFFMODE_NOSCAN ||
766 			 (hcid.offmode == HCID_OFFMODE_DEVDOWN &&
767 			  scan_enable != SCAN_DISABLED))) {
768 		/* Start HCI device */
769 		if (ioctl(dd, HCIDEVUP, adapter->dev_id) == 0)
770 			goto done; /* on success */
771 
772 		if (errno != EALREADY) {
773 			err = errno;
774 			error("Can't init device hci%d: %s (%d)\n",
775 				adapter->dev_id, strerror(errno), errno);
776 
777 			hci_close_dev(dd);
778 			return failed_strerror(msg, err);
779 		}
780 	}
781 
782 	if (adapter->up && scan_enable == SCAN_DISABLED &&
783 			hcid.offmode == HCID_OFFMODE_DEVDOWN) {
784 		if (ioctl(dd, HCIDEVDOWN, adapter->dev_id) < 0) {
785 			hci_close_dev(dd);
786 			return failed_strerror(msg, errno);
787 		}
788 
789 		goto done;
790 	}
791 
792 	limited = (new_mode == MODE_LIMITED ? TRUE : FALSE);
793 	err = set_limited_discoverable(dd, adapter->class, limited);
794 	if (err < 0) {
795 		hci_close_dev(dd);
796 		return failed_strerror(msg, -err);
797 	}
798 
799 	if (current_scan != scan_enable) {
800 		struct hci_request rq;
801 		uint8_t status = 0;
802 
803 		memset(&rq, 0, sizeof(rq));
804 		rq.ogf    = OGF_HOST_CTL;
805 		rq.ocf    = OCF_WRITE_SCAN_ENABLE;
806 		rq.cparam = &scan_enable;
807 		rq.clen   = sizeof(scan_enable);
808 		rq.rparam = &status;
809 		rq.rlen   = sizeof(status);
810 		rq.event = EVT_CMD_COMPLETE;
811 
812 		if (hci_send_req(dd, &rq, 1000) < 0) {
813 			err = errno;
814 			error("Sending write scan enable command failed: %s (%d)",
815 					strerror(errno), errno);
816 			hci_close_dev(dd);
817 			return failed_strerror(msg, err);
818 		}
819 
820 		if (status) {
821 			error("Setting scan enable failed with status 0x%02x",
822 					status);
823 			hci_close_dev(dd);
824 			return failed_strerror(msg, bt_error(status));
825 		}
826 	} else {
827 		/* discoverable or limited */
828 		if ((scan_enable & SCAN_INQUIRY) && (new_mode != adapter->mode)) {
829 			g_dbus_emit_signal(conn,
830 					dbus_message_get_path(msg),
831 					ADAPTER_INTERFACE,
832 					"ModeChanged",
833 					DBUS_TYPE_STRING, &mode,
834 					DBUS_TYPE_INVALID);
835 
836 			if (adapter->timeout_id)
837 				g_source_remove(adapter->timeout_id);
838 
839 			if (!adapter->sessions && !adapter->discov_timeout)
840 				adapter->timeout_id = g_timeout_add(adapter->discov_timeout * 1000,
841 						discov_timeout_handler, adapter);
842 		}
843 	}
844 done:
845 	str2ba(adapter->address, &local);
846 	write_device_mode(&local, mode);
847 
848 	hci_close_dev(dd);
849 
850 	adapter->mode = new_mode;
851 
852 	return dbus_message_new_method_return(msg);
853 }
854 
find_session(struct mode_req * req,DBusMessage * msg)855 gint find_session(struct mode_req *req, DBusMessage *msg)
856 {
857 	const char *name = dbus_message_get_sender(req->msg);
858 	const char *sender = dbus_message_get_sender(msg);
859 
860 	return strcmp(name, sender);
861 }
862 
confirm_mode_cb(struct agent * agent,DBusError * err,void * data)863 static void confirm_mode_cb(struct agent *agent, DBusError *err, void *data)
864 {
865 	struct mode_req *req = data;
866 	DBusMessage *reply;
867 
868 	if (err && dbus_error_is_set(err)) {
869 		reply = dbus_message_new_error(req->msg, err->name, err->message);
870 		dbus_connection_send(req->conn, reply, NULL);
871 		dbus_message_unref(reply);
872 		goto cleanup;
873 	}
874 
875 	reply = set_mode(req->conn, req->msg, req->mode, req->adapter);
876 	dbus_connection_send(req->conn, reply, NULL);
877 	dbus_message_unref(reply);
878 
879 	if (!g_slist_find_custom(req->adapter->sessions, req->msg,
880 			(GCompareFunc) find_session))
881 		goto cleanup;
882 
883 	return;
884 
885 cleanup:
886 	dbus_message_unref(req->msg);
887 	if (req->id)
888 		g_dbus_remove_watch(req->conn, req->id);
889 	dbus_connection_unref(req->conn);
890 	g_free(req);
891 }
892 
confirm_mode(DBusConnection * conn,DBusMessage * msg,const char * mode,void * data)893 static DBusMessage *confirm_mode(DBusConnection *conn, DBusMessage *msg,
894 					const char *mode, void *data)
895 {
896 	struct adapter *adapter = data;
897 	struct mode_req *req;
898 	int ret;
899 
900 	if (!adapter->agent)
901 		return dbus_message_new_method_return(msg);
902 
903 	req = g_new0(struct mode_req, 1);
904 	req->adapter = adapter;
905 	req->conn = dbus_connection_ref(conn);
906 	req->msg = dbus_message_ref(msg);
907 	req->mode = str2mode(adapter->address, mode);
908 
909 	ret = agent_confirm_mode_change(adapter->agent, mode, confirm_mode_cb,
910 					req);
911 	if (ret < 0) {
912 		dbus_connection_unref(req->conn);
913 		dbus_message_unref(req->msg);
914 		g_free(req);
915 		return invalid_args(msg);
916 	}
917 
918 	return NULL;
919 }
920 
adapter_set_mode(DBusConnection * conn,DBusMessage * msg,void * data)921 static DBusMessage *adapter_set_mode(DBusConnection *conn,
922 				DBusMessage *msg, void *data)
923 {
924 	struct adapter *adapter = data;
925 	const char *mode;
926 
927 	if (!dbus_message_get_args(msg, NULL,
928 				DBUS_TYPE_STRING, &mode,
929 				DBUS_TYPE_INVALID))
930 		return invalid_args(msg);
931 
932 	if (!mode)
933 		return invalid_args(msg);
934 
935 	adapter->global_mode = str2mode(adapter->address, mode);
936 
937 	if (adapter->global_mode == adapter->mode)
938 		return dbus_message_new_method_return(msg);
939 
940 	if (adapter->sessions && adapter->global_mode < adapter->mode)
941 		return confirm_mode(conn, msg, mode, data);
942 
943 	return set_mode(conn, msg, str2mode(adapter->address, mode), data);
944 }
945 
adapter_get_discoverable_to(DBusConnection * conn,DBusMessage * msg,void * data)946 static DBusMessage *adapter_get_discoverable_to(DBusConnection *conn,
947 					DBusMessage *msg, void *data)
948 {
949 	const struct adapter *adapter = data;
950 	DBusMessage *reply;
951 
952 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
953 		return invalid_args(msg);
954 
955 	reply = dbus_message_new_method_return(msg);
956 	if (!reply)
957 		return NULL;
958 
959 	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &adapter->discov_timeout,
960 					DBUS_TYPE_INVALID);
961 
962 	return reply;
963 }
964 
resolve_paths(DBusMessage * msg,char ** old_path,char ** new_path)965 static void resolve_paths(DBusMessage *msg, char **old_path, char **new_path)
966 {
967 	const char *path = dbus_message_get_path(msg);
968 
969 	if (!path)
970 		return;
971 
972 	if (old_path)
973 		*old_path = NULL;
974 
975 	if (new_path)
976 		*new_path = NULL;
977 
978 	/* old path calls */
979 	if (g_str_has_prefix(path, BASE_PATH)) {
980 		if (old_path)
981 			*old_path = g_strdup(path);
982 
983 		if (hcid_dbus_use_experimental() && new_path)
984 			*new_path = g_strdup(path + ADAPTER_PATH_INDEX);
985 
986 		return;
987 	}
988 
989 	if (old_path)
990 		*old_path = g_strconcat(BASE_PATH, path, NULL);
991 
992 	if (new_path)
993 		*new_path = g_strdup(path);
994 }
995 
set_discoverable_timeout(DBusConnection * conn,DBusMessage * msg,uint32_t timeout,void * data)996 static DBusMessage *set_discoverable_timeout(DBusConnection *conn,
997 							DBusMessage *msg,
998 							uint32_t timeout,
999 							void *data)
1000 {
1001 	struct adapter *adapter = data;
1002 	bdaddr_t bdaddr;
1003 	char *old_path, *new_path;
1004 
1005 	if (adapter->timeout_id) {
1006 		g_source_remove(adapter->timeout_id);
1007 		adapter->timeout_id = 0;
1008 	}
1009 
1010 	if ((timeout != 0) && (adapter->scan_enable & SCAN_INQUIRY))
1011 		adapter->timeout_id = g_timeout_add(timeout * 1000,
1012 						discov_timeout_handler,
1013 						adapter);
1014 
1015 	adapter->discov_timeout = timeout;
1016 
1017 	str2ba(adapter->address, &bdaddr);
1018 	write_discoverable_timeout(&bdaddr, timeout);
1019 
1020 	resolve_paths(msg, &old_path, &new_path);
1021 
1022 	g_dbus_emit_signal(conn, old_path,
1023 					ADAPTER_INTERFACE,
1024 					"DiscoverableTimeoutChanged",
1025 					DBUS_TYPE_UINT32, &timeout,
1026 					DBUS_TYPE_INVALID);
1027 	if (new_path) {
1028 		dbus_connection_emit_property_changed(conn, new_path,
1029 						ADAPTER_INTERFACE,
1030 						"DiscoverableTimeout",
1031 						DBUS_TYPE_UINT32, &timeout);
1032 	}
1033 
1034 	g_free(old_path);
1035 	g_free(new_path);
1036 
1037 	return dbus_message_new_method_return(msg);
1038 }
1039 
adapter_set_discoverable_to(DBusConnection * conn,DBusMessage * msg,void * data)1040 static DBusMessage *adapter_set_discoverable_to(DBusConnection *conn,
1041 						DBusMessage *msg, void *data)
1042 {
1043 	struct adapter *adapter = data;
1044 	uint32_t timeout;
1045 
1046 	if (!adapter->up)
1047 		return adapter_not_ready(msg);
1048 
1049 	if (!dbus_message_get_args(msg, NULL,
1050 				DBUS_TYPE_UINT32, &timeout,
1051 				DBUS_TYPE_INVALID))
1052 		return invalid_args(msg);
1053 
1054 	return set_discoverable_timeout(conn, msg, timeout, data);
1055 }
1056 
adapter_is_connectable(DBusConnection * conn,DBusMessage * msg,void * data)1057 static DBusMessage *adapter_is_connectable(DBusConnection *conn,
1058 					DBusMessage *msg, void *data)
1059 {
1060 	const struct adapter *adapter = data;
1061 	DBusMessage *reply;
1062 	const uint8_t scan_enable = adapter->scan_enable;
1063 	dbus_bool_t connectable = FALSE;
1064 
1065 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1066 		return invalid_args(msg);
1067 
1068 	if (scan_enable & SCAN_PAGE)
1069 		connectable = TRUE;
1070 
1071 	reply = dbus_message_new_method_return(msg);
1072 	if (!reply)
1073 		return NULL;
1074 
1075 	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &connectable,
1076 					DBUS_TYPE_INVALID);
1077 
1078 	return reply;
1079 }
1080 
adapter_is_discoverable(DBusConnection * conn,DBusMessage * msg,void * data)1081 static DBusMessage *adapter_is_discoverable(DBusConnection *conn,
1082 					DBusMessage *msg, void *data)
1083 {
1084 	const struct adapter *adapter = data;
1085 	DBusMessage *reply;
1086 	const uint8_t scan_enable = adapter->scan_enable;
1087 	dbus_bool_t discoverable = FALSE;
1088 
1089 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1090 		return invalid_args(msg);
1091 
1092 	if (scan_enable & SCAN_INQUIRY)
1093 		discoverable = TRUE;
1094 
1095 	reply = dbus_message_new_method_return(msg);
1096 	if (!reply)
1097 		return NULL;
1098 
1099 	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &discoverable,
1100 					DBUS_TYPE_INVALID);
1101 
1102 	return reply;
1103 }
1104 
adapter_is_connected(DBusConnection * conn,DBusMessage * msg,void * data)1105 static DBusMessage *adapter_is_connected(DBusConnection *conn,
1106 					DBusMessage *msg, void *data)
1107 {
1108 	DBusMessage *reply;
1109 	dbus_bool_t connected = FALSE;
1110 
1111 	struct adapter *adapter = data;
1112 	GSList *l = adapter->active_conn;
1113 
1114 	const char *peer_addr;
1115 	bdaddr_t peer_bdaddr;
1116 
1117 	if (!dbus_message_get_args(msg, NULL,
1118 				DBUS_TYPE_STRING, &peer_addr,
1119 				DBUS_TYPE_INVALID))
1120 		return invalid_args(msg);
1121 
1122 	if (check_address(peer_addr) < 0)
1123 		return invalid_args(msg);
1124 
1125 	str2ba(peer_addr, &peer_bdaddr);
1126 
1127 	l = g_slist_find_custom(l, &peer_bdaddr, active_conn_find_by_bdaddr);
1128 	if (l)
1129 		connected = TRUE;
1130 
1131 	reply = dbus_message_new_method_return(msg);
1132 	if (!reply)
1133 		return NULL;
1134 
1135 	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &connected,
1136 					DBUS_TYPE_INVALID);
1137 
1138 	return reply;
1139 }
1140 
adapter_list_connections(DBusConnection * conn,DBusMessage * msg,void * data)1141 static DBusMessage *adapter_list_connections(DBusConnection *conn,
1142 					DBusMessage *msg, void *data)
1143 {
1144 	DBusMessage *reply;
1145 	DBusMessageIter iter;
1146 	DBusMessageIter array_iter;
1147 	struct adapter *adapter = data;
1148 	GSList *l = adapter->active_conn;
1149 
1150 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1151 		return invalid_args(msg);
1152 
1153 	reply = dbus_message_new_method_return(msg);
1154 	if (!reply)
1155 		return NULL;
1156 
1157 	dbus_message_iter_init_append(reply, &iter);
1158 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1159 					DBUS_TYPE_STRING_AS_STRING, &array_iter);
1160 
1161 	while (l) {
1162 		char peer_addr[18];
1163 		const char *paddr = peer_addr;
1164 		struct active_conn_info *dev = l->data;
1165 
1166 		ba2str(&dev->bdaddr, peer_addr);
1167 
1168 		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
1169 						&paddr);
1170 
1171 		l = l->next;
1172 	}
1173 
1174 	dbus_message_iter_close_container(&iter, &array_iter);
1175 
1176 	return reply;
1177 }
1178 
adapter_get_major_class(DBusConnection * conn,DBusMessage * msg,void * data)1179 static DBusMessage *adapter_get_major_class(DBusConnection *conn,
1180 					DBusMessage *msg, void *data)
1181 {
1182 	const struct adapter *adapter = data;
1183 	DBusMessage *reply;
1184 	const char *str_ptr = "computer";
1185 
1186 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1187 		return invalid_args(msg);
1188 
1189 	/* FIXME: Currently, only computer major class is supported */
1190 	if ((adapter->class[1] & 0x1f) != 1)
1191 		return unsupported_major_class(msg);
1192 
1193 	reply = dbus_message_new_method_return(msg);
1194 	if (!reply)
1195 		return NULL;
1196 
1197 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
1198 					DBUS_TYPE_INVALID);
1199 
1200 	return reply;
1201 }
1202 
adapter_list_minor_classes(DBusConnection * conn,DBusMessage * msg,void * data)1203 static DBusMessage *adapter_list_minor_classes(DBusConnection *conn,
1204 					DBusMessage *msg, void *data)
1205 {
1206 	const struct adapter *adapter = data;
1207 	DBusMessage *reply;
1208 	DBusMessageIter iter;
1209 	DBusMessageIter array_iter;
1210 	const char **minor_ptr;
1211 	uint8_t major_class;
1212 	int size, i;
1213 
1214 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1215 		return invalid_args(msg);
1216 
1217 	major_class = adapter->class[1] & 0x1F;
1218 
1219 	switch (major_class) {
1220 	case 1: /* computer */
1221 		minor_ptr = computer_minor_cls;
1222 		size = sizeof(computer_minor_cls) / sizeof(*computer_minor_cls);
1223 		break;
1224 	case 2: /* phone */
1225 		minor_ptr = phone_minor_cls;
1226 		size = sizeof(phone_minor_cls) / sizeof(*phone_minor_cls);
1227 		break;
1228 	default:
1229 		return unsupported_major_class(msg);
1230 	}
1231 
1232 	reply = dbus_message_new_method_return(msg);
1233 	if (!reply)
1234 		return NULL;
1235 
1236 	dbus_message_iter_init_append(reply, &iter);
1237 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1238 						DBUS_TYPE_STRING_AS_STRING, &array_iter);
1239 	for (i = 0; i < size; i++)
1240 		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
1241 						&minor_ptr[i]);
1242 
1243 	dbus_message_iter_close_container(&iter, &array_iter);
1244 
1245 	return reply;
1246 }
1247 
adapter_get_minor_class(DBusConnection * conn,DBusMessage * msg,void * data)1248 static DBusMessage *adapter_get_minor_class(DBusConnection *conn,
1249 					DBusMessage *msg, void *data)
1250 {
1251 	struct adapter *adapter = data;
1252 	DBusMessage *reply;
1253 	const char *str_ptr = "";
1254 	uint8_t minor_class;
1255 
1256 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1257 		return invalid_args(msg);
1258 
1259 	/* FIXME: Currently, only computer major class is supported */
1260 	if ((adapter->class[1] & 0x1f) != 1)
1261 		return unsupported_major_class(msg);
1262 
1263 	minor_class = adapter->class[0] >> 2;
1264 
1265 	/* Validate computer minor class */
1266 	if (minor_class > (sizeof(computer_minor_cls) / sizeof(*computer_minor_cls)))
1267 		goto failed;
1268 
1269 	str_ptr = computer_minor_cls[minor_class];
1270 
1271 failed:
1272 	reply = dbus_message_new_method_return(msg);
1273 	if (!reply)
1274 		return NULL;
1275 
1276 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
1277 					DBUS_TYPE_INVALID);
1278 
1279 	return reply;
1280 }
1281 
adapter_set_minor_class(DBusConnection * conn,DBusMessage * msg,void * data)1282 static DBusMessage *adapter_set_minor_class(DBusConnection *conn,
1283 					DBusMessage *msg, void *data)
1284 {
1285 	struct adapter *adapter = data;
1286 	const char *minor;
1287 	uint32_t dev_class = 0xFFFFFFFF;
1288 	int i, dd;
1289 
1290 	if (!adapter->up)
1291 		return adapter_not_ready(msg);
1292 
1293 	if (!dbus_message_get_args(msg, NULL,
1294 				DBUS_TYPE_STRING, &minor,
1295 				DBUS_TYPE_INVALID))
1296 		return invalid_args(msg);
1297 
1298 	if (!minor)
1299 		return invalid_args(msg);
1300 
1301 	dd = hci_open_dev(adapter->dev_id);
1302 	if (dd < 0)
1303 		return no_such_adapter(msg);
1304 
1305 	/* Currently, only computer major class is supported */
1306 	if ((adapter->class[1] & 0x1f) != 1) {
1307 		hci_close_dev(dd);
1308 		return unsupported_major_class(msg);
1309 	}
1310 	for (i = 0; i < sizeof(computer_minor_cls) / sizeof(*computer_minor_cls); i++)
1311 		if (!strcasecmp(minor, computer_minor_cls[i])) {
1312 			/* Remove the format type */
1313 			dev_class = i << 2;
1314 			break;
1315 		}
1316 
1317 	/* Check if it's a valid minor class */
1318 	if (dev_class == 0xFFFFFFFF) {
1319 		hci_close_dev(dd);
1320 		return invalid_args(msg);
1321 	}
1322 
1323 	/* set the service class and major class  */
1324 	dev_class |= (adapter->class[2] << 16) | (adapter->class[1] << 8);
1325 
1326 	if (hci_write_class_of_dev(dd, dev_class, 2000) < 0) {
1327 		int err = errno;
1328 		error("Can't write class of device on hci%d: %s(%d)",
1329 				adapter->dev_id, strerror(errno), errno);
1330 		hci_close_dev(dd);
1331 		return failed_strerror(msg, err);
1332 	}
1333 
1334 	g_dbus_emit_signal(conn, dbus_message_get_path(msg),
1335 					ADAPTER_INTERFACE, "MinorClassChanged",
1336 					DBUS_TYPE_STRING, &minor,
1337 					DBUS_TYPE_INVALID);
1338 
1339 	hci_close_dev(dd);
1340 
1341 	return dbus_message_new_method_return(msg);
1342 }
1343 
adapter_get_service_classes(DBusConnection * conn,DBusMessage * msg,void * data)1344 static DBusMessage *adapter_get_service_classes(DBusConnection *conn,
1345 					DBusMessage *msg, void *data)
1346 {
1347 	struct adapter *adapter = data;
1348 	DBusMessage *reply;
1349 	DBusMessageIter iter;
1350 	DBusMessageIter array_iter;
1351 	const char *str_ptr;
1352 	int i;
1353 
1354 	if (!adapter->up)
1355 		return adapter_not_ready(msg);
1356 
1357 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1358 		return invalid_args(msg);
1359 
1360 	reply = dbus_message_new_method_return(msg);
1361 	if (!reply)
1362 		return NULL;
1363 
1364 	dbus_message_iter_init_append(reply, &iter);
1365 
1366 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1367 				DBUS_TYPE_STRING_AS_STRING, &array_iter);
1368 
1369 	for (i = 0; i < (sizeof(service_cls) / sizeof(*service_cls)); i++) {
1370 		if (adapter->class[2] & (1 << i)) {
1371 			str_ptr = service_cls[i];
1372 			dbus_message_iter_append_basic(&array_iter,
1373 						DBUS_TYPE_STRING, &str_ptr);
1374 		}
1375 	}
1376 
1377 	dbus_message_iter_close_container(&iter, &array_iter);
1378 
1379 	return reply;
1380 }
1381 
adapter_get_name(DBusConnection * conn,DBusMessage * msg,void * data)1382 static DBusMessage *adapter_get_name(DBusConnection *conn,
1383 				DBusMessage *msg, void *data)
1384 {
1385 	struct adapter *adapter = data;
1386 	DBusMessage *reply;
1387 	char str[249], *str_ptr = str;
1388 	int err;
1389 	bdaddr_t ba;
1390 
1391 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
1392 		return invalid_args(msg);
1393 
1394 	str2ba(adapter->address, &ba);
1395 
1396 	err = read_local_name(&ba, str);
1397 	if (err < 0) {
1398 		if (!adapter->up)
1399 			return adapter_not_ready(msg);
1400 
1401 		err = get_device_name(adapter->dev_id, str, sizeof(str));
1402 		if (err < 0)
1403 			return failed_strerror(msg, -err);
1404 	}
1405 
1406 	reply = dbus_message_new_method_return(msg);
1407 	if (!reply)
1408 		return NULL;
1409 
1410 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
1411 					DBUS_TYPE_INVALID);
1412 
1413 	return reply;
1414 }
1415 
set_name(DBusConnection * conn,DBusMessage * msg,const char * name,void * data)1416 static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
1417 					const char *name, void *data)
1418 {
1419 	struct adapter *adapter = data;
1420 	bdaddr_t bdaddr;
1421 	int ecode;
1422 	char *new_path;
1423 
1424 	if (!g_utf8_validate(name, -1, NULL)) {
1425 		error("Name change failed: the supplied name isn't valid UTF-8");
1426 		return invalid_args(msg);
1427 	}
1428 
1429 	str2ba(adapter->address, &bdaddr);
1430 
1431 	write_local_name(&bdaddr, (char *) name);
1432 
1433 	if (!adapter->up)
1434 		goto done;
1435 
1436 	ecode = set_device_name(adapter->dev_id, name);
1437 	if (ecode < 0)
1438 		return failed_strerror(msg, -ecode);
1439 done:
1440 	resolve_paths(msg, NULL, &new_path);
1441 
1442 	if (new_path) {
1443 		dbus_connection_emit_property_changed(conn, new_path,
1444 						ADAPTER_INTERFACE,
1445 						"Name", DBUS_TYPE_STRING,
1446 						&name);
1447 	}
1448 
1449 	g_free(new_path);
1450 	return dbus_message_new_method_return(msg);
1451 }
1452 
adapter_set_name(DBusConnection * conn,DBusMessage * msg,void * data)1453 static DBusMessage *adapter_set_name(DBusConnection *conn,
1454 				DBusMessage *msg, void *data)
1455 {
1456 	char *str_ptr;
1457 
1458 	if (!dbus_message_get_args(msg, NULL,
1459 				DBUS_TYPE_STRING, &str_ptr,
1460 				DBUS_TYPE_INVALID))
1461 		return invalid_args(msg);
1462 
1463 	return set_name(conn, msg, str_ptr, data);
1464 }
1465 
adapter_get_remote_info(DBusConnection * conn,DBusMessage * msg,void * data)1466 static DBusMessage *adapter_get_remote_info(DBusConnection *conn,
1467 					DBusMessage *msg, void *data)
1468 {
1469 	struct adapter *adapter = data;
1470 	DBusMessage *reply;
1471 	DBusMessageIter iter;
1472 	DBusMessageIter dict;
1473 	bdaddr_t src, dst;
1474 	const char *addr_ptr;
1475 	char filename[PATH_MAX + 1];
1476 	char buf[64];
1477 	const char *ptr;
1478 	char *str;
1479 	dbus_bool_t boolean;
1480 	uint32_t class;
1481 	int compid, ver, subver;
1482 
1483 	if (!dbus_message_get_args(msg, NULL,
1484 				DBUS_TYPE_STRING, &addr_ptr,
1485 				DBUS_TYPE_INVALID))
1486 		return invalid_args(msg);
1487 
1488 	if (check_address(addr_ptr) < 0)
1489 		return invalid_args(msg);
1490 
1491 	reply = dbus_message_new_method_return(msg);
1492 	if (!reply)
1493 		return NULL;
1494 
1495 	dbus_message_iter_init_append(reply, &iter);
1496 
1497 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1498 			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1499 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
1500 			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
1501 
1502 	/* Name */
1503 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names");
1504 	str = textfile_caseget(filename, addr_ptr);
1505 	if (str) {
1506 		dbus_message_iter_append_dict_entry(&dict, "name",
1507 				DBUS_TYPE_STRING, &str);
1508 		free(str);
1509 	}
1510 
1511 	str2ba(adapter->address, &src);
1512 	str2ba(addr_ptr, &dst);
1513 
1514 	/* Remote device class */
1515 	if (read_remote_class(&src, &dst, &class) == 0) {
1516 
1517 		dbus_message_iter_append_dict_entry(&dict, "class",
1518 				DBUS_TYPE_UINT32, &class);
1519 
1520 		ptr = major_class_str(class);
1521 		dbus_message_iter_append_dict_entry(&dict, "major_class",
1522 				DBUS_TYPE_STRING, &ptr);
1523 
1524 		ptr = minor_class_str(class);
1525 		dbus_message_iter_append_dict_entry(&dict, "minor_class",
1526 				DBUS_TYPE_STRING, &ptr);
1527 	}
1528 
1529 	/* Alias */
1530 	if (get_device_alias(adapter->dev_id, &dst, buf, sizeof(buf)) > 0) {
1531 		ptr = buf;
1532 		dbus_message_iter_append_dict_entry(&dict, "alias",
1533 				DBUS_TYPE_STRING, &ptr);
1534 	}
1535 
1536 	/* Bonded */
1537 	create_name(filename, PATH_MAX, STORAGEDIR,
1538 			adapter->address, "linkkeys");
1539 	str = textfile_caseget(filename, addr_ptr);
1540 	if (str) {
1541 		boolean = TRUE;
1542 		free(str);
1543 	} else {
1544 		boolean = FALSE;
1545 	}
1546 
1547 	dbus_message_iter_append_dict_entry(&dict, "bonded",
1548 			DBUS_TYPE_BOOLEAN, &boolean);
1549 
1550 	/* Trusted */
1551 	boolean = read_trust(&src, addr_ptr, GLOBAL_TRUST);
1552 	dbus_message_iter_append_dict_entry(&dict, "trusted",
1553 			DBUS_TYPE_BOOLEAN, &boolean);
1554 
1555 	/* Connected */
1556 	if (g_slist_find_custom(adapter->active_conn, &dst,
1557 				active_conn_find_by_bdaddr))
1558 		boolean = TRUE;
1559 	else
1560 		boolean = FALSE;
1561 
1562 	dbus_message_iter_append_dict_entry(&dict, "connected",
1563 			DBUS_TYPE_BOOLEAN, &boolean);
1564 
1565 	/* HCI Revision/Manufacturer/Version */
1566 	create_name(filename, PATH_MAX, STORAGEDIR,
1567 			adapter->address, "manufacturers");
1568 
1569 	str = textfile_caseget(filename, addr_ptr);
1570 	if (!str)
1571 		goto done;
1572 
1573 	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) != 3) {
1574 		/* corrupted file data */
1575 		free(str);
1576 		goto done;
1577 	}
1578 
1579 	free(str);
1580 
1581 	ptr = buf;
1582 	snprintf(buf, 16, "HCI 0x%X", subver);
1583 	dbus_message_iter_append_dict_entry(&dict, "revision",
1584 			DBUS_TYPE_STRING, &ptr);
1585 
1586 	ptr = bt_compidtostr(compid);
1587 	dbus_message_iter_append_dict_entry(&dict, "manufacturer",
1588 			DBUS_TYPE_STRING, &ptr);
1589 
1590 	str = lmp_vertostr(ver);
1591 	snprintf(buf, 64, "Bluetooth %s", str);
1592 	bt_free(str);
1593 
1594 	create_name(filename, PATH_MAX, STORAGEDIR,
1595 			adapter->address, "features");
1596 
1597 	str = textfile_caseget(filename, addr_ptr);
1598 	if (str) {
1599 		if (strlen(str) == 16) {
1600 			uint8_t features;
1601 			/* Getting the third byte */
1602 			features  = ((str[6] - 48) << 4) | (str[7] - 48);
1603 			if (features & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))
1604 				snprintf(buf, 64, "Bluetooth %s + EDR", ptr);
1605 
1606 		}
1607 		free(str);
1608 	}
1609 	ptr = buf;
1610 	dbus_message_iter_append_dict_entry(&dict, "version",
1611 			DBUS_TYPE_STRING, &ptr);
1612 
1613 done:
1614 	dbus_message_iter_close_container(&iter, &dict);
1615 
1616 	return reply;
1617 }
1618 
adapter_get_remote_svc_channel(DBusConnection * conn,DBusMessage * msg,void * data)1619 static DBusMessage *adapter_get_remote_svc_channel(DBusConnection *conn,
1620 					DBusMessage *msg, void *data)
1621 {
1622 	return get_remote_svc_channel(conn, msg, data);
1623 }
1624 
adapter_get_remote_svc(DBusConnection * conn,DBusMessage * msg,void * data)1625 static DBusMessage *adapter_get_remote_svc(DBusConnection *conn,
1626 					DBusMessage *msg, void *data)
1627 {
1628 	return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_BINARY);
1629 }
1630 
adapter_get_remote_svc_xml(DBusConnection * conn,DBusMessage * msg,void * data)1631 static DBusMessage *adapter_get_remote_svc_xml(DBusConnection *conn,
1632 					DBusMessage *msg, void *data)
1633 {
1634 	return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_XML);
1635 }
1636 
adapter_get_remote_svc_handles(DBusConnection * conn,DBusMessage * msg,void * data)1637 static DBusMessage *adapter_get_remote_svc_handles(DBusConnection *conn,
1638 						DBusMessage *msg, void *data)
1639 {
1640 	return get_remote_svc_handles(conn, msg, data);
1641 }
1642 
adapter_get_remote_svc_identifiers(DBusConnection * conn,DBusMessage * msg,void * data)1643 static DBusMessage *adapter_get_remote_svc_identifiers(DBusConnection *conn,
1644 						DBusMessage *msg, void *data)
1645 {
1646 	return get_remote_svc_identifiers(conn, msg, data);
1647 }
1648 
adapter_finish_sdp_transact(DBusConnection * conn,DBusMessage * msg,void * data)1649 static DBusMessage *adapter_finish_sdp_transact(DBusConnection *conn,
1650 					DBusMessage *msg, void *data)
1651 {
1652 	return finish_remote_svc_transact(conn, msg, data);
1653 }
1654 
adapter_get_remote_version(DBusConnection * conn,DBusMessage * msg,void * data)1655 static DBusMessage *adapter_get_remote_version(DBusConnection *conn,
1656 					DBusMessage *msg, void *data)
1657 {
1658 	struct adapter *adapter = data;
1659 	DBusMessage *reply;
1660 	char filename[PATH_MAX + 1];
1661 	char *addr_ptr, *str;
1662 	char *str_ver = NULL;
1663 	char info_array[64], *info = info_array;
1664 	int compid, ver, subver;
1665 
1666 	memset(info_array, 0, 64);
1667 
1668 	if (!dbus_message_get_args(msg, NULL,
1669 				DBUS_TYPE_STRING, &addr_ptr,
1670 				DBUS_TYPE_INVALID))
1671 		return invalid_args(msg);
1672 
1673 	if (check_address(addr_ptr) < 0)
1674 		return invalid_args(msg);
1675 
1676 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
1677 			"manufacturers");
1678 
1679 	str = textfile_caseget(filename, addr_ptr);
1680 	if (!str)
1681 		return not_available(msg);
1682 
1683 	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) != 3) {
1684 		/* corrupted file data */
1685 		free(str);
1686 		goto failed;
1687 	}
1688 
1689 	free(str);
1690 
1691 	str_ver = lmp_vertostr(ver);
1692 
1693 	/* Default value */
1694 	snprintf(info, 64, "Bluetooth %s", str_ver);
1695 
1696 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
1697 			"features");
1698 
1699 	str = textfile_caseget(filename, addr_ptr);
1700 	if (!str)
1701 		goto failed;
1702 
1703 	/* Check if the data is not corrupted */
1704 	if (strlen(str) == 16) {
1705 		uint8_t features;
1706 		/* Getting the third byte */
1707 		features  = ((str[6] - 48) << 4) | (str[7] - 48);
1708 		if (features & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))
1709 			snprintf(info, 64, "Bluetooth %s + EDR", str_ver);
1710 	}
1711 
1712 	free(str);
1713 
1714 failed:
1715 	if (str_ver)
1716 		bt_free(str_ver);
1717 
1718 	reply = dbus_message_new_method_return(msg);
1719 	if (!reply)
1720 		return NULL;
1721 
1722 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &info,
1723 					DBUS_TYPE_INVALID);
1724 
1725 	return reply;
1726 }
1727 
adapter_get_remote_revision(DBusConnection * conn,DBusMessage * msg,void * data)1728 static DBusMessage *adapter_get_remote_revision(DBusConnection *conn,
1729 						DBusMessage *msg, void *data)
1730 {
1731 	struct adapter *adapter = data;
1732 	DBusMessage *reply;
1733 	char filename[PATH_MAX + 1];
1734 	char *addr_ptr, *str;
1735 	char info_array[16], *info = info_array;
1736 	int compid, ver, subver;
1737 
1738 	memset(info_array, 0, 16);
1739 
1740 	if (!dbus_message_get_args(msg, NULL,
1741 				DBUS_TYPE_STRING, &addr_ptr,
1742 				DBUS_TYPE_INVALID))
1743 		return invalid_args(msg);
1744 
1745 	if (check_address(addr_ptr) < 0)
1746 		return invalid_args(msg);
1747 
1748 	reply = dbus_message_new_method_return(msg);
1749 	if (!reply)
1750 		return NULL;
1751 
1752 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
1753 			"manufacturers");
1754 
1755 	str = textfile_caseget(filename, addr_ptr);
1756 	if (!str)
1757 		return not_available(msg);
1758 
1759 	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) == 3)
1760 		snprintf(info, 16, "HCI 0x%X", subver);
1761 
1762 	free(str);
1763 
1764 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &info,
1765 					DBUS_TYPE_INVALID);
1766 
1767 	return reply;
1768 }
1769 
adapter_get_remote_manufacturer(DBusConnection * conn,DBusMessage * msg,void * data)1770 static DBusMessage *adapter_get_remote_manufacturer(DBusConnection *conn,
1771 						DBusMessage *msg, void *data)
1772 {
1773 	struct adapter *adapter = data;
1774 	DBusMessage *reply;
1775 	char filename[PATH_MAX + 1];
1776 	char *addr_ptr, *str;
1777 	char info_array[64], *info = info_array;
1778 	int compid, ver, subver;
1779 
1780 	memset(info_array, 0, 64);
1781 
1782 	if (!dbus_message_get_args(msg, NULL,
1783 				DBUS_TYPE_STRING, &addr_ptr,
1784 				DBUS_TYPE_INVALID))
1785 		return invalid_args(msg);
1786 
1787 	if (check_address(addr_ptr) < 0)
1788 		return invalid_args(msg);
1789 
1790 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
1791 			"manufacturers");
1792 
1793 	str = textfile_caseget(filename, addr_ptr);
1794 	if (!str)
1795 		return not_available(msg);
1796 
1797 	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) == 3)
1798 		info = bt_compidtostr(compid);
1799 
1800 	free(str);
1801 
1802 	reply = dbus_message_new_method_return(msg);
1803 	if (!reply)
1804 		return NULL;
1805 
1806 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &info,
1807 					DBUS_TYPE_INVALID);
1808 
1809 	return reply;
1810 }
1811 
adapter_get_remote_company(DBusConnection * conn,DBusMessage * msg,void * data)1812 static DBusMessage *adapter_get_remote_company(DBusConnection *conn,
1813 						DBusMessage *msg, void *data)
1814 {
1815 	DBusMessage *reply;
1816 	bdaddr_t bdaddr;
1817 	char oui[9], *str_bdaddr, *tmp;
1818 
1819 	if (!dbus_message_get_args(msg, NULL,
1820 				DBUS_TYPE_STRING, &str_bdaddr,
1821 				DBUS_TYPE_INVALID))
1822 		return invalid_args(msg);
1823 
1824 	str2ba(str_bdaddr, &bdaddr);
1825 	ba2oui(&bdaddr, oui);
1826 
1827 	tmp = ouitocomp(oui);
1828 	if (!tmp)
1829 		return not_available(msg);
1830 
1831 	reply = dbus_message_new_method_return(msg);
1832 	if (!reply) {
1833 		free(tmp);
1834 		return NULL;
1835 	}
1836 
1837 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &tmp,
1838 					DBUS_TYPE_INVALID);
1839 
1840 	free(tmp);
1841 
1842 	return reply;
1843 }
1844 
get_remote_class(DBusConnection * conn,DBusMessage * msg,void * data,uint32_t * class)1845 static DBusMessage *get_remote_class(DBusConnection *conn, DBusMessage *msg,
1846 						void *data, uint32_t *class)
1847 {
1848 	struct adapter *adapter = data;
1849 	char *addr_peer;
1850 	bdaddr_t local, peer;
1851 	int ecode;
1852 
1853 	if (!dbus_message_get_args(msg, NULL,
1854 				DBUS_TYPE_STRING, &addr_peer,
1855 				DBUS_TYPE_INVALID)) {
1856 		return invalid_args(msg);
1857 	}
1858 
1859 	if (check_address(addr_peer) < 0)
1860 		return invalid_args(msg);
1861 
1862 	str2ba(addr_peer, &peer);
1863 	str2ba(adapter->address, &local);
1864 
1865 	ecode = read_remote_class(&local, &peer, class);
1866 	if (ecode < 0)
1867 		return not_available(msg);
1868 
1869 	return NULL;
1870 }
1871 
adapter_get_remote_major_class(DBusConnection * conn,DBusMessage * msg,void * data)1872 static DBusMessage *adapter_get_remote_major_class(DBusConnection *conn,
1873 						DBusMessage *msg, void *data)
1874 {
1875 	DBusMessage *reply;
1876 	const char *major_class;
1877 	uint32_t class;
1878 
1879 	reply = get_remote_class(conn, msg, data, &class);
1880 	if (reply)
1881 		return reply;
1882 
1883 	major_class = major_class_str(class);
1884 
1885 	reply = dbus_message_new_method_return(msg);
1886 	if (!reply)
1887 		return NULL;
1888 
1889 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &major_class,
1890 					DBUS_TYPE_INVALID);
1891 
1892 	return reply;
1893 }
1894 
adapter_get_remote_minor_class(DBusConnection * conn,DBusMessage * msg,void * data)1895 static DBusMessage *adapter_get_remote_minor_class(DBusConnection *conn,
1896 						DBusMessage *msg, void *data)
1897 {
1898 	DBusMessage *reply;
1899 	const char *minor_class;
1900 	uint32_t class;
1901 
1902 	reply = get_remote_class(conn, msg, data, &class);
1903 	if (reply)
1904 		return reply;
1905 
1906 	minor_class = minor_class_str(class);
1907 
1908 	reply = dbus_message_new_method_return(msg);
1909 	if (!reply)
1910 		return NULL;
1911 
1912 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &minor_class,
1913 					DBUS_TYPE_INVALID);
1914 
1915 	return reply;
1916 }
1917 
append_class_string(const char * class,DBusMessageIter * iter)1918 static void append_class_string(const char *class, DBusMessageIter *iter)
1919 {
1920 	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &class);
1921 }
1922 
adapter_get_remote_service_cls(DBusConnection * conn,DBusMessage * msg,void * data)1923 static DBusMessage *adapter_get_remote_service_cls(DBusConnection *conn,
1924 							DBusMessage *msg,
1925 							void *data)
1926 {
1927 	DBusMessage *reply;
1928 	DBusMessageIter iter, array_iter;
1929 	GSList *service_classes;
1930 	uint32_t class;
1931 
1932 	reply = get_remote_class(conn, msg, data, &class);
1933 	if (reply)
1934 		return reply;
1935 
1936 	reply = dbus_message_new_method_return(msg);
1937 	if (!reply)
1938 		return NULL;
1939 
1940 	service_classes = service_classes_str(class);
1941 
1942 	dbus_message_iter_init_append(reply, &iter);
1943 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1944 						DBUS_TYPE_STRING_AS_STRING, &array_iter);
1945 
1946 	g_slist_foreach(service_classes, (GFunc) append_class_string,
1947 			&array_iter);
1948 
1949 	dbus_message_iter_close_container(&iter, &array_iter);
1950 
1951 	g_slist_free(service_classes);
1952 
1953 	return reply;
1954 }
1955 
adapter_get_remote_class(DBusConnection * conn,DBusMessage * msg,void * data)1956 static DBusMessage *adapter_get_remote_class(DBusConnection *conn,
1957 					DBusMessage *msg, void *data)
1958 {
1959 	DBusMessage *reply;
1960 	uint32_t class;
1961 
1962 	reply = get_remote_class(conn, msg, data, &class);
1963 	if (reply)
1964 		return reply;
1965 
1966 	reply = dbus_message_new_method_return(msg);
1967 	if (!reply)
1968 		return NULL;
1969 
1970 	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &class,
1971 					DBUS_TYPE_INVALID);
1972 
1973 	return reply;
1974 }
1975 
adapter_get_remote_features(DBusConnection * conn,DBusMessage * msg,void * data)1976 static DBusMessage *adapter_get_remote_features(DBusConnection *conn,
1977 					DBusMessage *msg, void *data)
1978 {
1979 	char filename[PATH_MAX + 1];
1980 	struct adapter *adapter = data;
1981 	DBusMessage *reply = NULL;
1982 	DBusMessageIter iter, array_iter;
1983 	uint8_t features[8], *ptr = features;
1984 	const char *addr;
1985 	char *str;
1986 	int i;
1987 
1988 	if (!dbus_message_get_args(msg, NULL,
1989 				DBUS_TYPE_STRING, &addr,
1990 				DBUS_TYPE_INVALID))
1991 		return invalid_args(msg);
1992 
1993 	if (check_address(addr) < 0)
1994 		return invalid_args(msg);
1995 
1996 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "features");
1997 
1998 	str = textfile_caseget(filename, addr);
1999 	if (!str)
2000 		return not_available(msg);
2001 
2002 	memset(features, 0, sizeof(features));
2003 	for (i = 0; i < sizeof(features); i++) {
2004 		char tmp[3];
2005 
2006 		memcpy(tmp, str + (i * 2), 2);
2007 		tmp[2] = '\0';
2008 
2009 		features[i] = (uint8_t) strtol(tmp, NULL, 16);
2010 	}
2011 
2012 	reply = dbus_message_new_method_return(msg);
2013 	if (!reply) {
2014 		free(str);
2015 		return NULL;
2016 	}
2017 
2018 	dbus_message_iter_init_append(reply, &iter);
2019 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
2020 				DBUS_TYPE_BYTE_AS_STRING, &array_iter);
2021 
2022 	dbus_message_iter_append_fixed_array(&array_iter,
2023 				DBUS_TYPE_BYTE, &ptr, sizeof(features));
2024 
2025 	dbus_message_iter_close_container(&iter, &array_iter);
2026 
2027 	free(str);
2028 
2029 	return reply;
2030 }
2031 
adapter_get_remote_name(DBusConnection * conn,DBusMessage * msg,void * data)2032 static DBusMessage *adapter_get_remote_name(DBusConnection *conn,
2033 					DBusMessage *msg, void *data)
2034 {
2035 	char filename[PATH_MAX + 1];
2036 	struct adapter *adapter = data;
2037 	DBusMessage *reply = NULL;
2038 	const char *peer_addr;
2039 	bdaddr_t peer_bdaddr;
2040 	char *str;
2041 
2042 	if (!dbus_message_get_args(msg, NULL,
2043 				DBUS_TYPE_STRING, &peer_addr,
2044 				DBUS_TYPE_INVALID))
2045 		return invalid_args(msg);
2046 
2047 	if (check_address(peer_addr) < 0)
2048 		return invalid_args(msg);
2049 
2050 	/* check if it is in the cache */
2051 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names");
2052 
2053 	str = textfile_caseget(filename, peer_addr);
2054 
2055 	if (str) {
2056 		reply = dbus_message_new_method_return(msg);
2057 		if (!reply) {
2058 			free(str);
2059 			return NULL;
2060 		}
2061 
2062 		/* send the cached name */
2063 		dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
2064 						DBUS_TYPE_INVALID);
2065 
2066 		free(str);
2067 		return reply;
2068 	}
2069 
2070 	if (!adapter->up)
2071 		return adapter_not_ready(msg);
2072 
2073 	/* If the discover process is not running, return an error */
2074 	if (!adapter->discov_active && !adapter->pdiscov_active)
2075 		return not_available(msg);
2076 
2077 	/* Queue the request when there is a discovery running */
2078 	str2ba(peer_addr, &peer_bdaddr);
2079 	found_device_add(&adapter->found_devices, &peer_bdaddr, 0, NAME_REQUIRED);
2080 
2081         return g_dbus_create_error(msg,
2082 			ERROR_INTERFACE ".RequestDeferred",
2083 			"Request Deferred");
2084 }
2085 
adapter_get_remote_alias(DBusConnection * conn,DBusMessage * msg,void * data)2086 static DBusMessage *adapter_get_remote_alias(DBusConnection *conn,
2087 					DBusMessage *msg, void *data)
2088 {
2089 	struct adapter *adapter = data;
2090 	DBusMessage *reply;
2091 	char str[249], *str_ptr = str, *addr_ptr;
2092 	bdaddr_t bdaddr;
2093 	int ecode;
2094 
2095 	if (!dbus_message_get_args(msg, NULL,
2096 				DBUS_TYPE_STRING, &addr_ptr,
2097 				DBUS_TYPE_INVALID))
2098 		return invalid_args(msg);
2099 
2100 	if (check_address(addr_ptr) < 0)
2101 		return invalid_args(msg);
2102 
2103 	str2ba(addr_ptr, &bdaddr);
2104 
2105 	ecode = get_device_alias(adapter->dev_id, &bdaddr, str, sizeof(str));
2106 	if (ecode < 0)
2107 		return not_available(msg);
2108 
2109 	reply = dbus_message_new_method_return(msg);
2110 	if (!reply)
2111 		return NULL;
2112 
2113 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
2114 					DBUS_TYPE_INVALID);
2115 
2116 	return reply;
2117 }
2118 
adapter_set_remote_alias(DBusConnection * conn,DBusMessage * msg,void * data)2119 static DBusMessage *adapter_set_remote_alias(DBusConnection *conn,
2120 					DBusMessage *msg, void *data)
2121 {
2122 	struct adapter *adapter = data;
2123 	char *alias, *addr, *old_path, *new_path;
2124 	bdaddr_t bdaddr;
2125 	int ecode;
2126 
2127 	if (!dbus_message_get_args(msg, NULL,
2128 				DBUS_TYPE_STRING, &addr,
2129 				DBUS_TYPE_STRING, &alias,
2130 				DBUS_TYPE_INVALID))
2131 		return invalid_args(msg);
2132 
2133 	if ((strlen(alias) == 0) || (check_address(addr) < 0)) {
2134 		error("Alias change failed: Invalid parameter");
2135 		return invalid_args(msg);
2136 	}
2137 
2138 	str2ba(addr, &bdaddr);
2139 
2140 	ecode = set_device_alias(adapter->dev_id, &bdaddr, alias);
2141 	if (ecode < 0)
2142 		return failed_strerror(msg, -ecode);
2143 
2144 	resolve_paths(msg, &old_path, &new_path);
2145 
2146 	g_dbus_emit_signal(conn, old_path,
2147 					ADAPTER_INTERFACE, "RemoteAliasChanged",
2148 					DBUS_TYPE_STRING, &addr,
2149 					DBUS_TYPE_STRING, &alias,
2150 					DBUS_TYPE_INVALID);
2151 
2152 	if (new_path) {
2153 		struct device *device;
2154 
2155 		device = adapter_find_device(adapter, addr);
2156 		if (device) {
2157 			dbus_connection_emit_property_changed(conn,
2158 					device->path, DEVICE_INTERFACE,
2159 					"Alias", DBUS_TYPE_STRING, &alias);
2160 		}
2161 	}
2162 
2163 	g_free(old_path);
2164 	g_free(new_path);
2165 
2166 	return dbus_message_new_method_return(msg);
2167 }
2168 
adapter_clear_remote_alias(DBusConnection * conn,DBusMessage * msg,void * data)2169 static DBusMessage *adapter_clear_remote_alias(DBusConnection *conn,
2170 					DBusMessage *msg, void *data)
2171 {
2172 	struct adapter *adapter = data;
2173 	char *addr_ptr;
2174 	bdaddr_t bdaddr;
2175 	int ecode, had_alias = 1;
2176 
2177 	if (!dbus_message_get_args(msg, NULL,
2178 				DBUS_TYPE_STRING, &addr_ptr,
2179 				DBUS_TYPE_INVALID))
2180 		return invalid_args(msg);
2181 
2182 	if (check_address(addr_ptr) < 0) {
2183 		error("Alias clear failed: Invalid parameter");
2184 		return invalid_args(msg);
2185 	}
2186 
2187 	str2ba(addr_ptr, &bdaddr);
2188 
2189 	ecode = get_device_alias(adapter->dev_id, &bdaddr, NULL, 0);
2190 	if (ecode == -ENXIO)
2191 		had_alias = 0;
2192 
2193 	ecode = set_device_alias(adapter->dev_id, &bdaddr, NULL);
2194 	if (ecode < 0)
2195 		return failed_strerror(msg, -ecode);
2196 
2197 	if (had_alias)
2198 		g_dbus_emit_signal(conn, dbus_message_get_path(msg),
2199 						ADAPTER_INTERFACE,
2200 						"RemoteAliasCleared",
2201 						DBUS_TYPE_STRING, &addr_ptr,
2202 						DBUS_TYPE_INVALID);
2203 
2204 	return dbus_message_new_method_return(msg);
2205 }
2206 
adapter_last_seen(DBusConnection * conn,DBusMessage * msg,void * data)2207 static DBusMessage *adapter_last_seen(DBusConnection *conn,
2208 				DBusMessage *msg, void *data)
2209 {
2210 	struct adapter *adapter = data;
2211 	DBusMessage *reply;
2212 	char filename[PATH_MAX + 1];
2213 	char *addr_ptr, *str;
2214 
2215 	if (!dbus_message_get_args(msg, NULL,
2216 				DBUS_TYPE_STRING, &addr_ptr,
2217 				DBUS_TYPE_INVALID))
2218 		return invalid_args(msg);
2219 
2220 	if (check_address(addr_ptr) < 0)
2221 		return invalid_args(msg);
2222 
2223 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
2224 			"lastseen");
2225 
2226 	str = textfile_caseget(filename, addr_ptr);
2227 	if (!str)
2228 		return not_available(msg);
2229 
2230 	reply = dbus_message_new_method_return(msg);
2231 	if (!reply) {
2232 		free(str);
2233 		return NULL;
2234 	}
2235 
2236 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
2237 					DBUS_TYPE_INVALID);
2238 
2239 	free(str);
2240 
2241 	return reply;
2242 }
2243 
adapter_last_used(DBusConnection * conn,DBusMessage * msg,void * data)2244 static DBusMessage *adapter_last_used(DBusConnection *conn,
2245 				DBusMessage *msg, void *data)
2246 {
2247 	struct adapter *adapter = data;
2248 	DBusMessage *reply;
2249 	char filename[PATH_MAX + 1];
2250 	char *addr_ptr, *str;
2251 
2252 	if (!dbus_message_get_args(msg, NULL,
2253 				DBUS_TYPE_STRING, &addr_ptr,
2254 				DBUS_TYPE_INVALID))
2255 		return invalid_args(msg);
2256 
2257 	if (check_address(addr_ptr) < 0)
2258 		return invalid_args(msg);
2259 
2260 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
2261 			"lastused");
2262 
2263 	str = textfile_caseget(filename, addr_ptr);
2264 	if (!str)
2265 		return not_available(msg);
2266 
2267 	reply = dbus_message_new_method_return(msg);
2268 	if (!reply) {
2269 		free(str);
2270 		return NULL;
2271 	}
2272 
2273 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
2274 					DBUS_TYPE_INVALID);
2275 
2276 	free(str);
2277 
2278 	return reply;
2279 }
2280 
dc_pending_timeout_handler(void * data)2281 gboolean dc_pending_timeout_handler(void *data)
2282 {
2283 	int dd;
2284 	struct adapter *adapter = data;
2285 	struct pending_dc_info *pending_dc = adapter->pending_dc;
2286 	DBusMessage *reply;
2287 
2288 	dd = hci_open_dev(adapter->dev_id);
2289 
2290 	if (dd < 0) {
2291 		error_no_such_adapter(pending_dc->conn,
2292 				      pending_dc->msg);
2293 		dc_pending_timeout_cleanup(adapter);
2294 		return FALSE;
2295 	}
2296 
2297 	/* Send the HCI disconnect command */
2298 	if (hci_disconnect(dd, htobs(pending_dc->conn_handle),
2299 				HCI_OE_USER_ENDED_CONNECTION,
2300 				500) < 0) {
2301 		int err = errno;
2302 		error("Disconnect failed");
2303 		error_failed_errno(pending_dc->conn, pending_dc->msg, err);
2304 	} else {
2305 		reply = dbus_message_new_method_return(pending_dc->msg);
2306 		if (reply) {
2307 			dbus_connection_send(pending_dc->conn, reply, NULL);
2308 			dbus_message_unref(reply);
2309 		} else
2310 			error("Failed to allocate disconnect reply");
2311 	}
2312 
2313 	hci_close_dev(dd);
2314 	dc_pending_timeout_cleanup(adapter);
2315 
2316 	return FALSE;
2317 }
2318 
dc_pending_timeout_cleanup(struct adapter * adapter)2319 void dc_pending_timeout_cleanup(struct adapter *adapter)
2320 {
2321 	dbus_connection_unref(adapter->pending_dc->conn);
2322 	dbus_message_unref(adapter->pending_dc->msg);
2323 	g_free(adapter->pending_dc);
2324 	adapter->pending_dc = NULL;
2325 }
2326 
adapter_dc_remote_device(DBusConnection * conn,DBusMessage * msg,void * data)2327 static DBusMessage *adapter_dc_remote_device(DBusConnection *conn,
2328 						DBusMessage *msg, void *data)
2329 {
2330 	struct adapter *adapter = data;
2331 	GSList *l = adapter->active_conn;
2332 	const char *peer_addr;
2333 	bdaddr_t peer_bdaddr;
2334 
2335 	if (!adapter->up)
2336 		return adapter_not_ready(msg);
2337 
2338 	if (!dbus_message_get_args(msg, NULL,
2339 				DBUS_TYPE_STRING, &peer_addr,
2340 				DBUS_TYPE_INVALID))
2341 		return invalid_args(msg);
2342 
2343 	if (check_address(peer_addr) < 0)
2344 		return invalid_args(msg);
2345 
2346 	str2ba(peer_addr, &peer_bdaddr);
2347 
2348 	l = g_slist_find_custom(l, &peer_bdaddr, active_conn_find_by_bdaddr);
2349 	if (!l)
2350 		return g_dbus_create_error(msg,
2351 				ERROR_INTERFACE ".NotConnected",
2352 				"Device not connected");
2353 
2354 	if (adapter->pending_dc)
2355 		return in_progress(msg, "Disconnection in progress");
2356 
2357 	adapter->pending_dc = g_new0(struct pending_dc_info, 1);
2358 
2359 	/* Start waiting... */
2360 	adapter->pending_dc->timeout_id =
2361 		g_timeout_add(DC_PENDING_TIMEOUT,
2362 			      dc_pending_timeout_handler,
2363 			      adapter);
2364 
2365 	if (!adapter->pending_dc->timeout_id) {
2366 		g_free(adapter->pending_dc);
2367 		adapter->pending_dc = NULL;
2368 		return NULL;
2369 	}
2370 
2371 	adapter->pending_dc->conn = dbus_connection_ref(conn);
2372 	adapter->pending_dc->msg = dbus_message_ref(msg);
2373 	adapter->pending_dc->conn_handle =
2374 		((struct active_conn_info *) l->data)->handle;
2375 
2376 	g_dbus_emit_signal(conn, dbus_message_get_path(msg),
2377 					ADAPTER_INTERFACE,
2378 					"RemoteDeviceDisconnectRequested",
2379 					DBUS_TYPE_STRING, &peer_addr,
2380 					DBUS_TYPE_INVALID);
2381 
2382 	return NULL;
2383 }
2384 
reply_authentication_failure(struct bonding_request_info * bonding)2385 static void reply_authentication_failure(struct bonding_request_info *bonding)
2386 {
2387 	DBusMessage *reply;
2388 	int status;
2389 
2390 	status = bonding->hci_status ?
2391 			bonding->hci_status : HCI_AUTHENTICATION_FAILURE;
2392 
2393 	reply = new_authentication_return(bonding->msg, status);
2394 	if (reply) {
2395 		dbus_connection_send(bonding->conn, reply, NULL);
2396 		dbus_message_unref(reply);
2397 	}
2398 }
2399 
adapter_find_device(struct adapter * adapter,const char * dest)2400 struct device *adapter_find_device(struct adapter *adapter, const char *dest)
2401 {
2402 	struct device *device;
2403 	GSList *l;
2404 
2405 	if (!adapter)
2406 		return NULL;
2407 
2408 	l = g_slist_find_custom(adapter->devices,
2409 				dest, (GCompareFunc) device_address_cmp);
2410 	if (!l)
2411 		return NULL;
2412 
2413 	device = l->data;
2414 
2415 	return device;
2416 }
2417 
adapter_create_device(DBusConnection * conn,struct adapter * adapter,const char * address)2418 struct device *adapter_create_device(DBusConnection *conn,
2419 				struct adapter *adapter, const char *address)
2420 {
2421 	struct device *device;
2422 
2423 	debug("adapter_create_device(%s)", address);
2424 
2425 	device = device_create(conn, adapter, address);
2426 	if (!device)
2427 		return NULL;
2428 
2429 	device->temporary = TRUE;
2430 
2431 	adapter->devices = g_slist_append(adapter->devices, device);
2432 
2433 	return device;
2434 }
2435 
remove_bonding(DBusConnection * conn,DBusMessage * msg,const char * address,void * data)2436 static DBusMessage *remove_bonding(DBusConnection *conn, DBusMessage *msg,
2437 					const char *address, void *data)
2438 {
2439 	struct adapter *adapter = data;
2440 	struct device *device;
2441 	char path[MAX_PATH_LENGTH], filename[PATH_MAX + 1];
2442 	char *str;
2443 	bdaddr_t src, dst;
2444 	GSList *l;
2445 	int dev, err;
2446 	gboolean paired;
2447 
2448 	str2ba(adapter->address, &src);
2449 	str2ba(address, &dst);
2450 
2451 	dev = hci_open_dev(adapter->dev_id);
2452 	if (dev < 0 && msg)
2453 		return no_such_adapter(msg);
2454 
2455 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
2456 			"linkkeys");
2457 
2458 	/* textfile_del doesn't return an error when the key is not found */
2459 	str = textfile_caseget(filename, address);
2460 	paired = str ? TRUE : FALSE;
2461 	g_free(str);
2462 
2463 	if (!paired && msg) {
2464 		hci_close_dev(dev);
2465 		return g_dbus_create_error(msg,
2466 				ERROR_INTERFACE ".DoesNotExist",
2467 				"Bonding does not exist");
2468 	}
2469 
2470 	/* Delete the link key from storage */
2471 	if (textfile_casedel(filename, address) < 0 && msg) {
2472 		hci_close_dev(dev);
2473 		err = errno;
2474 		return failed_strerror(msg, err);
2475 	}
2476 
2477 	/* Delete the link key from the Bluetooth chip */
2478 	hci_delete_stored_link_key(dev, &dst, 0, 1000);
2479 
2480 	/* find the connection */
2481 	l = g_slist_find_custom(adapter->active_conn, &dst,
2482 				active_conn_find_by_bdaddr);
2483 	if (l) {
2484 		struct active_conn_info *con = l->data;
2485 		/* Send the HCI disconnect command */
2486 		if ((hci_disconnect(dev, htobs(con->handle),
2487 					HCI_OE_USER_ENDED_CONNECTION, 500) < 0)
2488 					&& msg){
2489 			int err = errno;
2490 			error("Disconnect failed");
2491 		}
2492 	}
2493 
2494 	hci_close_dev(dev);
2495 
2496 	if (paired) {
2497 		snprintf(path, MAX_PATH_LENGTH, BASE_PATH "/hci%d",
2498 			adapter->dev_id);
2499 		g_dbus_emit_signal(conn, path,
2500 					ADAPTER_INTERFACE, "BondingRemoved",
2501 					DBUS_TYPE_STRING, &address,
2502 					DBUS_TYPE_INVALID);
2503 	}
2504 
2505 	device = adapter_find_device(adapter, address);
2506 	if (!device)
2507 		goto proceed;
2508 
2509 	if (paired) {
2510 		gboolean paired = FALSE;
2511 		dbus_connection_emit_property_changed(conn, device->path,
2512 					DEVICE_INTERFACE, "Paired",
2513 					DBUS_TYPE_BOOLEAN, &paired);
2514 	}
2515 
2516 proceed:
2517 	if(!msg)
2518 		goto done;
2519 
2520 	return dbus_message_new_method_return(msg);
2521 
2522 done:
2523 	return NULL;
2524 }
2525 
2526 
adapter_remove_device(DBusConnection * conn,struct adapter * adapter,struct device * device)2527 void adapter_remove_device(DBusConnection *conn, struct adapter *adapter,
2528 				struct device *device)
2529 {
2530 	bdaddr_t src;
2531 	char path[MAX_PATH_LENGTH];
2532 
2533 	str2ba(adapter->address, &src);
2534 	delete_entry(&src, "profiles", device->address);
2535 
2536 	remove_bonding(conn, NULL, device->address, adapter);
2537 
2538 	if (!device->temporary) {
2539 		snprintf(path, MAX_PATH_LENGTH, "/hci%d", adapter->dev_id);
2540 		g_dbus_emit_signal(conn, path,
2541 				ADAPTER_INTERFACE,
2542 				"DeviceRemoved",
2543 				DBUS_TYPE_OBJECT_PATH, &device->path,
2544 				DBUS_TYPE_INVALID);
2545 	}
2546 
2547 	if (device->agent) {
2548 		agent_destroy(device->agent, FALSE);
2549 		device->agent = NULL;
2550 	}
2551 
2552 	adapter->devices = g_slist_remove(adapter->devices, device);
2553 
2554 	device_remove(conn, device);
2555 }
2556 
adapter_get_device(DBusConnection * conn,struct adapter * adapter,const gchar * address)2557 struct device *adapter_get_device(DBusConnection *conn,
2558 				struct adapter *adapter, const gchar *address)
2559 {
2560 	struct device *device;
2561 
2562 	debug("adapter_get_device(%s)", address);
2563 
2564 	if (!adapter)
2565 		return NULL;
2566 
2567 	device = adapter_find_device(adapter, address);
2568 	if (device)
2569 		return device;
2570 
2571 	return adapter_create_device(conn, adapter, address);
2572 }
2573 
remove_pending_device(struct adapter * adapter)2574 void remove_pending_device(struct adapter *adapter)
2575 {
2576 	struct device *device;
2577 	char address[18];
2578 
2579 	ba2str(&adapter->bonding->bdaddr, address);
2580 	device = adapter_find_device(adapter, address);
2581 	if (!device)
2582 		return;
2583 
2584 	if (device->temporary)
2585 		adapter_remove_device(adapter->bonding->conn, adapter, device);
2586 }
2587 
create_bonding_conn_complete(GIOChannel * io,GIOCondition cond,struct adapter * adapter)2588 static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,
2589 						struct adapter *adapter)
2590 {
2591 	struct hci_request rq;
2592 	auth_requested_cp cp;
2593 	evt_cmd_status rp;
2594 	struct l2cap_conninfo cinfo;
2595 	socklen_t len;
2596 	int sk, dd, ret;
2597 
2598 	if (!adapter->bonding) {
2599 		/* If we come here it implies a bug somewhere */
2600 		debug("create_bonding_conn_complete: no pending bonding!");
2601 		adapter->bonding->io_id = 0;
2602 		g_io_channel_close(io);
2603 		g_io_channel_unref(io);
2604 		return FALSE;
2605 	}
2606 
2607 	if (cond & G_IO_NVAL) {
2608 		error_authentication_canceled(adapter->bonding->conn,
2609 						adapter->bonding->msg);
2610 		goto cleanup;
2611 	}
2612 
2613 	if (cond & (G_IO_HUP | G_IO_ERR)) {
2614 		debug("Hangup or error on bonding IO channel");
2615 
2616 		if (!adapter->bonding->auth_active)
2617 			error_connection_attempt_failed(adapter->bonding->conn,
2618 							adapter->bonding->msg,
2619 							ENETDOWN);
2620 		else
2621 			reply_authentication_failure(adapter->bonding);
2622 
2623 		goto failed;
2624 	}
2625 
2626 	sk = g_io_channel_unix_get_fd(io);
2627 
2628 	len = sizeof(ret);
2629 	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
2630 		error("Can't get socket error: %s (%d)",
2631 				strerror(errno), errno);
2632 		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
2633 				errno);
2634 		goto failed;
2635 	}
2636 
2637 	if (ret != 0) {
2638 		if (adapter->bonding->auth_active)
2639 			reply_authentication_failure(adapter->bonding);
2640 		else
2641 			error_connection_attempt_failed(adapter->bonding->conn,
2642 							adapter->bonding->msg,
2643 							ret);
2644 		goto failed;
2645 	}
2646 
2647 	len = sizeof(cinfo);
2648 	if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) {
2649 		error("Can't get connection info: %s (%d)",
2650 				strerror(errno), errno);
2651 		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
2652 				errno);
2653 		goto failed;
2654 	}
2655 
2656 	dd = hci_open_dev(adapter->dev_id);
2657 	if (dd < 0) {
2658 		error_no_such_adapter(adapter->bonding->conn,
2659 					adapter->bonding->msg);
2660 		goto failed;
2661 	}
2662 
2663 	memset(&rp, 0, sizeof(rp));
2664 
2665 	memset(&cp, 0, sizeof(cp));
2666 	cp.handle = htobs(cinfo.hci_handle);
2667 
2668 	memset(&rq, 0, sizeof(rq));
2669 	rq.ogf    = OGF_LINK_CTL;
2670 	rq.ocf    = OCF_AUTH_REQUESTED;
2671 	rq.cparam = &cp;
2672 	rq.clen   = AUTH_REQUESTED_CP_SIZE;
2673 	rq.rparam = &rp;
2674 	rq.rlen   = EVT_CMD_STATUS_SIZE;
2675 	rq.event  = EVT_CMD_STATUS;
2676 
2677 	if (hci_send_req(dd, &rq, 500) < 0) {
2678 		error("Unable to send HCI request: %s (%d)",
2679 					strerror(errno), errno);
2680 		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
2681 				errno);
2682 		hci_close_dev(dd);
2683 		goto failed;
2684 	}
2685 
2686 	if (rp.status) {
2687 		error("HCI_Authentication_Requested failed with status 0x%02x",
2688 				rp.status);
2689 		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
2690 				bt_error(rp.status));
2691 		hci_close_dev(dd);
2692 		goto failed;
2693 	}
2694 
2695 	hci_close_dev(dd);
2696 
2697 	adapter->bonding->auth_active = 1;
2698 
2699 	adapter->bonding->io_id = g_io_add_watch(io,
2700 						G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2701 						(GIOFunc) create_bonding_conn_complete,
2702 						adapter);
2703 
2704 	return FALSE;
2705 
2706 failed:
2707 	g_io_channel_close(io);
2708 	remove_pending_device(adapter);
2709 
2710 cleanup:
2711 	g_dbus_remove_watch(adapter->bonding->conn,
2712 				adapter->bonding->listener_id);
2713 	bonding_request_free(adapter->bonding);
2714 	adapter->bonding = NULL;
2715 
2716 	return FALSE;
2717 }
2718 
cancel_auth_request(struct pending_auth_info * auth,int dev_id)2719 static void cancel_auth_request(struct pending_auth_info *auth, int dev_id)
2720 {
2721 	int dd;
2722 
2723 	if (auth->replied)
2724 		return;
2725 
2726 	dd = hci_open_dev(dev_id);
2727 	if (dd < 0) {
2728 		error("hci_open_dev: %s (%d)", strerror(errno), errno);
2729 		return;
2730 	}
2731 
2732 	switch (auth->type) {
2733 	case AUTH_TYPE_PINCODE:
2734 		hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY,
2735 				6, &auth->bdaddr);
2736 		break;
2737 	case AUTH_TYPE_CONFIRM:
2738 		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY,
2739 				6, &auth->bdaddr);
2740 		break;
2741 	case AUTH_TYPE_PASSKEY:
2742 		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_PASSKEY_NEG_REPLY,
2743 				6, &auth->bdaddr);
2744 		break;
2745 	case AUTH_TYPE_NOTIFY:
2746 		/* User Notify doesn't require any reply */
2747 		break;
2748 	}
2749 
2750 	auth->replied = TRUE;
2751 
2752 	hci_close_dev(dd);
2753 }
2754 
create_bond_req_exit(void * user_data)2755 static void create_bond_req_exit(void *user_data)
2756 {
2757 	struct adapter *adapter = user_data;
2758 	struct pending_auth_info *auth;
2759 	char path[MAX_PATH_LENGTH];
2760 
2761 	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id);
2762 
2763 	debug("CreateConnection requestor exited before bonding was completed");
2764 
2765 	cancel_passkey_agent_requests(adapter->passkey_agents, path,
2766 					&adapter->bonding->bdaddr);
2767 	release_passkey_agents(adapter, &adapter->bonding->bdaddr);
2768 
2769 	auth = adapter_find_auth_request(adapter, &adapter->bonding->bdaddr);
2770 	if (auth) {
2771 		cancel_auth_request(auth, adapter->dev_id);
2772 		if (auth->agent)
2773 			agent_cancel(auth->agent);
2774 		adapter_remove_auth_request(adapter, &adapter->bonding->bdaddr);
2775 	}
2776 
2777 	remove_pending_device(adapter);
2778 
2779 	g_io_channel_close(adapter->bonding->io);
2780 	if (adapter->bonding->io_id)
2781 		g_source_remove(adapter->bonding->io_id);
2782 	bonding_request_free(adapter->bonding);
2783 	adapter->bonding = NULL;
2784 }
2785 
create_bonding(DBusConnection * conn,DBusMessage * msg,const char * address,const char * agent_path,uint8_t capability,void * data)2786 static DBusMessage *create_bonding(DBusConnection *conn, DBusMessage *msg,
2787 				const char *address, const char *agent_path,
2788 				uint8_t capability, void *data)
2789 {
2790 	char filename[PATH_MAX + 1];
2791 	char *str;
2792 	struct adapter *adapter = data;
2793 	struct bonding_request_info *bonding;
2794 	bdaddr_t bdaddr;
2795 	int sk;
2796 
2797 	str2ba(address, &bdaddr);
2798 
2799 	/* check if there is a pending discover: requested by D-Bus/non clients */
2800 	if (adapter->discov_active || (adapter->pdiscov_active && !adapter->pinq_idle))
2801 		return in_progress(msg, "Discover in progress");
2802 
2803 	pending_remote_name_cancel(adapter);
2804 
2805 	if (adapter->bonding)
2806 		return in_progress(msg, "Bonding in progress");
2807 
2808 	if (adapter_find_auth_request(adapter, &bdaddr))
2809 		return in_progress(msg, "Bonding in progress");
2810 
2811 	/* check if a link key already exists */
2812 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
2813 			"linkkeys");
2814 
2815 	str = textfile_caseget(filename, address);
2816 	if (str) {
2817 		free(str);
2818 		return g_dbus_create_error(msg,
2819 				ERROR_INTERFACE ".AlreadyExists",
2820 				"Bonding already exists");
2821 	}
2822 
2823 	sk = l2raw_connect(adapter->address, &bdaddr);
2824 	if (sk < 0)
2825 		return g_dbus_create_error(msg,
2826 				ERROR_INTERFACE ".ConnectionAttemptFailed",
2827 				"Connection attempt failed");
2828 
2829 	bonding = bonding_request_new(conn, msg, adapter, address, agent_path,
2830 					capability);
2831 	if (!bonding) {
2832 		close(sk);
2833 		return NULL;
2834 	}
2835 
2836 	bonding->io = g_io_channel_unix_new(sk);
2837 	bonding->io_id = g_io_add_watch(bonding->io,
2838 					G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2839 					(GIOFunc) create_bonding_conn_complete,
2840 					adapter);
2841 
2842 	bonding->listener_id = g_dbus_add_disconnect_watch(conn,
2843 						dbus_message_get_sender(msg),
2844 						create_bond_req_exit, adapter,
2845 						NULL);
2846 
2847 	adapter->bonding = bonding;
2848 
2849 	return NULL;
2850 }
2851 
adapter_create_bonding(DBusConnection * conn,DBusMessage * msg,void * data)2852 static DBusMessage *adapter_create_bonding(DBusConnection *conn,
2853 					DBusMessage *msg, void *data)
2854 {
2855 	struct adapter *adapter = data;
2856 	char *address;
2857 
2858 	if (!adapter->up)
2859 		return adapter_not_ready(msg);
2860 
2861 	if (!dbus_message_get_args(msg, NULL,
2862 				DBUS_TYPE_STRING, &address,
2863 				DBUS_TYPE_INVALID))
2864 		return invalid_args(msg);
2865 
2866 	if (check_address(address) < 0)
2867 		return invalid_args(msg);
2868 
2869 	return create_bonding(conn, msg, address, NULL,
2870 				IO_CAPABILITY_INVALID, data);
2871 }
adapter_cancel_bonding(DBusConnection * conn,DBusMessage * msg,void * data)2872 static DBusMessage *adapter_cancel_bonding(DBusConnection *conn,
2873 					DBusMessage *msg, void *data)
2874 {
2875 	struct adapter *adapter = data;
2876 	const char *address;
2877 	bdaddr_t bdaddr;
2878 	struct bonding_request_info *bonding = adapter->bonding;
2879 	struct pending_auth_info *auth_req;
2880 
2881 	if (!adapter->up)
2882 		return adapter_not_ready(msg);
2883 
2884 	if (!dbus_message_get_args(msg, NULL,
2885 				DBUS_TYPE_STRING, &address,
2886 				DBUS_TYPE_INVALID))
2887 		return invalid_args(msg);
2888 
2889 	if (check_address(address) < 0)
2890 		return invalid_args(msg);
2891 
2892 	str2ba(address, &bdaddr);
2893 	if (!bonding || bacmp(&bonding->bdaddr, &bdaddr))
2894 		return not_in_progress(msg, "Bonding is not in progress");
2895 
2896 	if (strcmp(dbus_message_get_sender(adapter->bonding->msg),
2897 				dbus_message_get_sender(msg)))
2898 		return not_authorized(msg);
2899 
2900 	adapter->bonding->cancel = 1;
2901 
2902 	auth_req = adapter_find_auth_request(adapter, &bdaddr);
2903 	if (auth_req) {
2904 		if (auth_req->replied) {
2905 			/*
2906 			 * If disconnect can't be applied and the PIN code
2907 			 * request was already replied it doesn't make sense
2908 			 * cancel the remote passkey: return not authorized.
2909 			 */
2910 			g_io_channel_close(adapter->bonding->io);
2911 			return not_authorized(msg);
2912 		}
2913 
2914 		cancel_auth_request(auth_req, adapter->dev_id);
2915 		if (auth_req->agent)
2916 			agent_cancel(auth_req->agent);
2917 		adapter_remove_auth_request(adapter, &bdaddr);
2918 	}
2919 
2920 	g_io_channel_close(adapter->bonding->io);
2921 
2922 	return dbus_message_new_method_return(msg);
2923 }
2924 
adapter_remove_bonding(DBusConnection * conn,DBusMessage * msg,void * data)2925 static DBusMessage *adapter_remove_bonding(DBusConnection *conn,
2926 						DBusMessage *msg, void *data)
2927 {
2928 	struct adapter *adapter = data;
2929 	char *address;
2930 
2931 	if (!adapter->up)
2932 		return adapter_not_ready(msg);
2933 
2934 	if (!dbus_message_get_args(msg, NULL,
2935 				DBUS_TYPE_STRING, &address,
2936 				DBUS_TYPE_INVALID))
2937 		return invalid_args(msg);
2938 
2939 	if (check_address(address) < 0)
2940 		return invalid_args(msg);
2941 
2942 	return remove_bonding(conn, msg, address, data);
2943 }
2944 
adapter_has_bonding(DBusConnection * conn,DBusMessage * msg,void * data)2945 static DBusMessage *adapter_has_bonding(DBusConnection *conn,
2946 						DBusMessage *msg, void *data)
2947 {
2948 	struct adapter *adapter = data;
2949 	DBusMessage *reply;
2950 	char filename[PATH_MAX + 1];
2951 	char *addr_ptr, *str;
2952 	dbus_bool_t result;
2953 
2954 	if (!dbus_message_get_args(msg, NULL,
2955 				DBUS_TYPE_STRING, &addr_ptr,
2956 				DBUS_TYPE_INVALID))
2957 		return invalid_args(msg);
2958 
2959 	if (check_address(addr_ptr) < 0)
2960 		return invalid_args(msg);
2961 
2962 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
2963 			"linkkeys");
2964 
2965 	str = textfile_caseget(filename, addr_ptr);
2966 	if (str) {
2967 		result = TRUE;
2968 		free(str);
2969 	} else
2970 		result = FALSE;
2971 
2972 	reply = dbus_message_new_method_return(msg);
2973 
2974 	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &result,
2975 					DBUS_TYPE_INVALID);
2976 
2977 	return reply;
2978 }
2979 
list_bondings_do_append(char * key,char * value,void * data)2980 static void list_bondings_do_append(char *key, char *value, void *data)
2981 {
2982 	DBusMessageIter *iter = data;
2983 	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
2984 }
2985 
adapter_list_bondings(DBusConnection * conn,DBusMessage * msg,void * data)2986 static DBusMessage *adapter_list_bondings(DBusConnection *conn,
2987 						DBusMessage *msg, void *data)
2988 {
2989 	struct adapter *adapter = data;
2990 	DBusMessageIter iter;
2991 	DBusMessageIter array_iter;
2992 	DBusMessage *reply;
2993 	char filename[PATH_MAX + 1];
2994 
2995 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
2996 		return invalid_args(msg);
2997 
2998 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
2999 			"linkkeys");
3000 
3001 	reply = dbus_message_new_method_return(msg);
3002 
3003 	dbus_message_iter_init_append(reply, &iter);
3004 
3005 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3006 				DBUS_TYPE_STRING_AS_STRING, &array_iter);
3007 
3008 	textfile_foreach(filename, list_bondings_do_append, &array_iter);
3009 
3010 	dbus_message_iter_close_container(&iter, &array_iter);
3011 
3012 	return reply;
3013 }
3014 
adapter_get_pin_code_length(DBusConnection * conn,DBusMessage * msg,void * data)3015 static DBusMessage *adapter_get_pin_code_length(DBusConnection *conn,
3016 							DBusMessage *msg,
3017 							void *data)
3018 {
3019 	struct adapter *adapter = data;
3020 	DBusMessage *reply;
3021 	bdaddr_t local, peer;
3022 	char *addr_ptr;
3023 	uint8_t length;
3024 	int len;
3025 
3026 	if (!dbus_message_get_args(msg, NULL,
3027 				DBUS_TYPE_STRING, &addr_ptr,
3028 				DBUS_TYPE_INVALID))
3029 		return invalid_args(msg);
3030 
3031 	if (check_address(addr_ptr) < 0)
3032 		return invalid_args(msg);
3033 
3034 	str2ba(adapter->address, &local);
3035 
3036 	str2ba(addr_ptr, &peer);
3037 
3038 	len = read_pin_length(&local, &peer);
3039 	if (len < 0)
3040 		return g_dbus_create_error(msg,
3041 				ERROR_INTERFACE ".DoesNotExist",
3042 				"Record does not exist");
3043 
3044 	reply = dbus_message_new_method_return(msg);
3045 
3046 	length = len;
3047 
3048 	dbus_message_append_args(reply, DBUS_TYPE_BYTE, &length,
3049 					DBUS_TYPE_INVALID);
3050 
3051 	return reply;
3052 }
3053 
adapter_get_encryption_key_size(DBusConnection * conn,DBusMessage * msg,void * data)3054 static DBusMessage *adapter_get_encryption_key_size(DBusConnection *conn,
3055 							DBusMessage *msg,
3056 							void *data)
3057 {
3058 	struct adapter *adapter = data;
3059 	DBusMessage *reply;
3060 	bdaddr_t bdaddr;
3061 	char *addr_ptr;
3062 	uint8_t size;
3063 	int val;
3064 
3065 	if (!dbus_message_get_args(msg, NULL,
3066 				DBUS_TYPE_STRING, &addr_ptr,
3067 				DBUS_TYPE_INVALID))
3068 		return invalid_args(msg);
3069 
3070 	if (check_address(addr_ptr) < 0)
3071 		return invalid_args(msg);
3072 
3073 	str2ba(addr_ptr, &bdaddr);
3074 
3075 	val = get_encryption_key_size(adapter->dev_id, &bdaddr);
3076 	if (val < 0)
3077 		return failed_strerror(msg, -val);
3078 
3079 	reply = dbus_message_new_method_return(msg);
3080 
3081 	size = val;
3082 
3083 	dbus_message_append_args(reply, DBUS_TYPE_BYTE, &size,
3084 					DBUS_TYPE_INVALID);
3085 
3086 	return reply;
3087 }
3088 
periodic_discover_req_exit(void * user_data)3089 static void periodic_discover_req_exit(void *user_data)
3090 {
3091 	struct adapter *adapter = user_data;
3092 
3093 	debug("PeriodicDiscovery requestor exited");
3094 
3095 	/* Cleanup the discovered devices list and send the cmd to exit from
3096 	 * periodic inquiry or cancel remote name request. The return value can
3097 	 * be ignored. */
3098 
3099 	cancel_periodic_discovery(adapter);
3100 }
3101 
adapter_start_periodic(DBusConnection * conn,DBusMessage * msg,void * data)3102 static DBusMessage *adapter_start_periodic(DBusConnection *conn,
3103 						DBusMessage *msg, void *data)
3104 {
3105 	periodic_inquiry_cp cp;
3106 	struct hci_request rq;
3107 	struct adapter *adapter = data;
3108 	uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
3109 	uint8_t status;
3110 	int dd;
3111 
3112 	if (!adapter->up)
3113 		return adapter_not_ready(msg);
3114 
3115 	if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
3116 				"StartPeriodicDiscovery")) {
3117 		if (!dbus_message_has_signature(msg,
3118 					DBUS_TYPE_INVALID_AS_STRING))
3119 			return invalid_args(msg);
3120 	}
3121 
3122 	if (adapter->discov_active || adapter->pdiscov_active)
3123 		return in_progress(msg, "Discover in progress");
3124 
3125 	pending_remote_name_cancel(adapter);
3126 
3127 	dd = hci_open_dev(adapter->dev_id);
3128 	if (dd < 0)
3129 		return no_such_adapter(msg);
3130 
3131 	memset(&cp, 0, sizeof(cp));
3132 	memcpy(&cp.lap, lap, 3);
3133 	cp.max_period = htobs(24);
3134 	cp.min_period = htobs(16);
3135 	cp.length  = 0x08;
3136 	cp.num_rsp = 0x00;
3137 
3138 	memset(&rq, 0, sizeof(rq));
3139 	rq.ogf    = OGF_LINK_CTL;
3140 	rq.ocf    = OCF_PERIODIC_INQUIRY;
3141 	rq.cparam = &cp;
3142 	rq.clen   = PERIODIC_INQUIRY_CP_SIZE;
3143 	rq.rparam = &status;
3144 	rq.rlen   = sizeof(status);
3145 	rq.event  = EVT_CMD_COMPLETE;
3146 
3147 	if (hci_send_req(dd, &rq, 1000) < 0) {
3148 		int err = errno;
3149 		error("Unable to start periodic inquiry: %s (%d)",
3150 				strerror(errno), errno);
3151 		hci_close_dev(dd);
3152 		return failed_strerror(msg, err);
3153 	}
3154 
3155 	if (status) {
3156 		error("HCI_Periodic_Inquiry_Mode failed with status 0x%02x",
3157 				status);
3158 		hci_close_dev(dd);
3159 		return failed_strerror(msg, bt_error(status));
3160 	}
3161 
3162 	adapter->pdiscov_requestor = g_strdup(dbus_message_get_sender(msg));
3163 
3164 	if (adapter->pdiscov_resolve_names)
3165 		adapter->discov_type = PERIODIC_INQUIRY | RESOLVE_NAME;
3166 	else
3167 		adapter->discov_type = PERIODIC_INQUIRY;
3168 
3169 	hci_close_dev(dd);
3170 
3171 	/* track the request owner to cancel it automatically if the owner
3172 	 * exits */
3173 	adapter->pdiscov_listener = g_dbus_add_disconnect_watch(conn,
3174 						dbus_message_get_sender(msg),
3175 						periodic_discover_req_exit,
3176 						adapter, NULL);
3177 
3178 	return dbus_message_new_method_return(msg);
3179 }
3180 
adapter_stop_periodic(DBusConnection * conn,DBusMessage * msg,void * data)3181 static DBusMessage *adapter_stop_periodic(DBusConnection *conn,
3182 						DBusMessage *msg, void *data)
3183 {
3184 	struct adapter *adapter = data;
3185 	int err;
3186 
3187 	if (!adapter->up)
3188 		return adapter_not_ready(msg);
3189 
3190 	if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
3191 				"StopPeriodicDiscovery")) {
3192 		if (!dbus_message_has_signature(msg,
3193 					DBUS_TYPE_INVALID_AS_STRING))
3194 			return invalid_args(msg);
3195 	}
3196 
3197 	if (!adapter->pdiscov_active)
3198 		return g_dbus_create_error(msg,
3199 				ERROR_INTERFACE ".NotAuthorized",
3200 				"Not authorized");
3201 	/*
3202 	 * Cleanup the discovered devices list and send the cmd to exit
3203 	 * from periodic inquiry mode or cancel remote name request.
3204 	 */
3205 	err = cancel_periodic_discovery(adapter);
3206 	if (err < 0) {
3207 		if (err == -ENODEV)
3208 			return no_such_adapter(msg);
3209 
3210 		else
3211 			return failed_strerror(msg, -err);
3212 	}
3213 
3214 	return dbus_message_new_method_return(msg);
3215 }
3216 
adapter_is_periodic(DBusConnection * conn,DBusMessage * msg,void * data)3217 static DBusMessage *adapter_is_periodic(DBusConnection *conn,
3218 						DBusMessage *msg, void *data)
3219 {
3220 	DBusMessage *reply;
3221 	struct adapter *adapter = data;
3222 	dbus_bool_t active = adapter->pdiscov_active;
3223 
3224 	reply = dbus_message_new_method_return(msg);
3225 	if (!reply)
3226 		return NULL;
3227 
3228 	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &active,
3229 					DBUS_TYPE_INVALID);
3230 
3231 	return reply;
3232 }
3233 
adapter_set_pdiscov_resolve(DBusConnection * conn,DBusMessage * msg,void * data)3234 static DBusMessage *adapter_set_pdiscov_resolve(DBusConnection *conn,
3235 						DBusMessage *msg, void *data)
3236 {
3237 	struct adapter *adapter = data;
3238 	dbus_bool_t resolve;
3239 
3240 	if (!dbus_message_get_args(msg, NULL,
3241 				DBUS_TYPE_BOOLEAN, &resolve,
3242 				DBUS_TYPE_INVALID))
3243 		return invalid_args(msg);
3244 
3245 	debug("SetPeriodicDiscoveryNameResolving(%s)",
3246 			resolve ? "TRUE" : "FALSE");
3247 
3248 	adapter->pdiscov_resolve_names = resolve;
3249 
3250 	if (adapter->pdiscov_active) {
3251 		if (resolve)
3252 			adapter->discov_type |= RESOLVE_NAME;
3253 		else
3254 			adapter->discov_type &= ~RESOLVE_NAME;
3255 	}
3256 
3257 	return dbus_message_new_method_return(msg);
3258 }
3259 
adapter_get_pdiscov_resolve(DBusConnection * conn,DBusMessage * msg,void * data)3260 static DBusMessage *adapter_get_pdiscov_resolve(DBusConnection *conn,
3261 							DBusMessage *msg,
3262 							void *data)
3263 {
3264 	DBusMessage *reply;
3265 	struct adapter *adapter = data;
3266 	dbus_bool_t resolve = adapter->pdiscov_resolve_names;
3267 
3268 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
3269 		return invalid_args(msg);
3270 
3271 	reply = dbus_message_new_method_return(msg);
3272 	if (!reply)
3273 		return NULL;
3274 
3275 	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &resolve,
3276 					DBUS_TYPE_INVALID);
3277 
3278 	return reply;
3279 }
3280 
discover_devices_req_exit(void * user_data)3281 static void discover_devices_req_exit(void *user_data)
3282 {
3283 	struct adapter *adapter = user_data;
3284 
3285 	debug("DiscoverDevices requestor exited");
3286 
3287 	/* Cleanup the discovered devices list and send the command to cancel
3288 	 * inquiry or cancel remote name request. The return can be ignored. */
3289 	cancel_discovery(adapter);
3290 }
3291 
adapter_discover_devices(DBusConnection * conn,DBusMessage * msg,void * data)3292 static DBusMessage *adapter_discover_devices(DBusConnection *conn,
3293 						DBusMessage *msg, void *data)
3294 {
3295 	const char *method;
3296 	inquiry_cp cp;
3297 	evt_cmd_status rp;
3298 	struct hci_request rq;
3299 	struct adapter *adapter = data;
3300 	uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
3301 	int dd;
3302 
3303 	if (!adapter->up)
3304 		return adapter_not_ready(msg);
3305 
3306 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
3307 		return invalid_args(msg);
3308 
3309 	if (adapter->discov_active)
3310 		return in_progress(msg, "Discover in progress");
3311 
3312 	pending_remote_name_cancel(adapter);
3313 
3314 	if (adapter->bonding)
3315 		return in_progress(msg, "Bonding in progress");
3316 
3317 	dd = hci_open_dev(adapter->dev_id);
3318 	if (dd < 0)
3319 		return no_such_adapter(msg);
3320 
3321 	memset(&cp, 0, sizeof(cp));
3322 	memcpy(&cp.lap, lap, 3);
3323 	cp.length  = 0x08;
3324 	cp.num_rsp = 0x00;
3325 
3326 	memset(&rq, 0, sizeof(rq));
3327 	rq.ogf    = OGF_LINK_CTL;
3328 	rq.ocf    = OCF_INQUIRY;
3329 	rq.cparam = &cp;
3330 	rq.clen   = INQUIRY_CP_SIZE;
3331 	rq.rparam = &rp;
3332 	rq.rlen   = EVT_CMD_STATUS_SIZE;
3333 	rq.event  = EVT_CMD_STATUS;
3334 
3335 	if (hci_send_req(dd, &rq, 500) < 0) {
3336 		int err = errno;
3337 		error("Unable to start inquiry: %s (%d)",
3338 				strerror(errno), errno);
3339 		hci_close_dev(dd);
3340 		return failed_strerror(msg, err);
3341 	}
3342 
3343 	if (rp.status) {
3344 		error("HCI_Inquiry command failed with status 0x%02x",
3345 				rp.status);
3346 		hci_close_dev(dd);
3347 		return failed_strerror(msg, bt_error(rp.status));
3348 	}
3349 
3350 	method = dbus_message_get_member(msg);
3351 	if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0)
3352 		adapter->discov_type |= STD_INQUIRY;
3353 	else
3354 		adapter->discov_type |= (STD_INQUIRY | RESOLVE_NAME);
3355 
3356 	adapter->discov_requestor = g_strdup(dbus_message_get_sender(msg));
3357 
3358 
3359 	hci_close_dev(dd);
3360 
3361 	/* track the request owner to cancel it automatically if the owner
3362 	 * exits */
3363 	adapter->discov_listener = g_dbus_add_disconnect_watch(conn,
3364 						dbus_message_get_sender(msg),
3365 						discover_devices_req_exit,
3366 						adapter, NULL);
3367 
3368 	return dbus_message_new_method_return(msg);
3369 }
3370 
adapter_cancel_discovery(DBusConnection * conn,DBusMessage * msg,void * data)3371 static DBusMessage *adapter_cancel_discovery(DBusConnection *conn,
3372 						DBusMessage *msg, void *data)
3373 {
3374 	struct adapter *adapter = data;
3375 	int err;
3376 
3377 	if (!adapter->up)
3378 		return adapter_not_ready(msg);
3379 
3380 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
3381 		return invalid_args(msg);
3382 
3383 	/* is there discover pending? or discovery cancel was requested
3384 	 * previously */
3385 	if (!adapter->discov_active || adapter->discovery_cancel)
3386 		return g_dbus_create_error(msg,
3387 				ERROR_INTERFACE ".NotAuthorized",
3388 				"Not Authorized");
3389 
3390 	/* only the discover requestor can cancel the inquiry process */
3391 	if (!adapter->discov_requestor ||
3392 			strcmp(adapter->discov_requestor, dbus_message_get_sender(msg)))
3393 		return g_dbus_create_error(msg,
3394 				ERROR_INTERFACE ".NotAuthorized",
3395 				"Not Authorized");
3396 
3397 	/* Cleanup the discovered devices list and send the cmd to cancel
3398 	 * inquiry or cancel remote name request */
3399 	err = cancel_discovery(adapter);
3400 	if (err < 0) {
3401 		if (err == -ENODEV)
3402 			return no_such_adapter(msg);
3403 		else
3404 			return failed_strerror(msg, -err);
3405 	}
3406 
3407 	/* Reply before send DiscoveryCompleted */
3408 	adapter->discovery_cancel = dbus_message_ref(msg);
3409 
3410 	return NULL;
3411 }
3412 
3413 struct remote_device_list_t {
3414 	GSList *list;
3415 	time_t time;
3416 };
3417 
list_remote_devices_do_append(char * key,char * value,void * data)3418 static void list_remote_devices_do_append(char *key, char *value, void *data)
3419 {
3420 	struct remote_device_list_t *param = data;
3421 	char *address;
3422 	struct tm date;
3423 
3424 	if (g_slist_find_custom(param->list, key, (GCompareFunc) strcasecmp))
3425 		return;
3426 
3427 	if (param->time){
3428 		strptime(value, "%Y-%m-%d %H:%M:%S %Z", &date);
3429 		if (difftime(mktime(&date), param->time) < 0)
3430 			return;
3431 	}
3432 
3433 	address = g_strdup(key);
3434 
3435 	param->list = g_slist_append(param->list, address);
3436 }
3437 
remote_devices_do_append(void * data,void * user_data)3438 static void remote_devices_do_append(void *data, void *user_data)
3439 {
3440 	DBusMessageIter *iter = user_data;
3441 
3442 	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &data);
3443 }
3444 
adapter_list_remote_devices(DBusConnection * conn,DBusMessage * msg,void * data)3445 static DBusMessage *adapter_list_remote_devices(DBusConnection *conn,
3446 							DBusMessage *msg,
3447 							void *data)
3448 {
3449 	struct adapter *adapter = data;
3450 	DBusMessageIter iter;
3451 	DBusMessageIter array_iter;
3452 	DBusMessage *reply;
3453 	char filename[PATH_MAX + 1];
3454 	struct remote_device_list_t param = { NULL, 0 };
3455 
3456 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
3457 		return invalid_args(msg);
3458 
3459 	/* Add Bonded devices to the list */
3460 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "linkkeys");
3461 	textfile_foreach(filename, list_remote_devices_do_append, &param);
3462 
3463 	/* Add Trusted devices to the list */
3464 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "trusts");
3465 	textfile_foreach(filename, list_remote_devices_do_append, &param);
3466 
3467 	/* Add Last Used devices to the list */
3468 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastused");
3469 	textfile_foreach(filename, list_remote_devices_do_append, &param);
3470 
3471 	reply = dbus_message_new_method_return(msg);
3472 
3473 	dbus_message_iter_init_append(reply, &iter);
3474 
3475 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3476 				DBUS_TYPE_STRING_AS_STRING, &array_iter);
3477 
3478 	g_slist_foreach(param.list, remote_devices_do_append, &array_iter);
3479 
3480 	g_slist_foreach(param.list, (GFunc) free, NULL);
3481 	g_slist_free(param.list);
3482 
3483 	dbus_message_iter_close_container(&iter, &array_iter);
3484 
3485 	return reply;
3486 }
3487 
append_connected(struct active_conn_info * dev,GSList * list)3488 static void append_connected(struct active_conn_info *dev, GSList *list)
3489 {
3490 	char address[18];
3491 
3492 	ba2str(&dev->bdaddr, address);
3493 	if (g_slist_find_custom(list, address, (GCompareFunc) strcasecmp))
3494 		return;
3495 
3496 	list = g_slist_append(list, g_strdup(address));
3497 }
3498 
adapter_list_recent_remote_devices(DBusConnection * conn,DBusMessage * msg,void * data)3499 static DBusMessage *adapter_list_recent_remote_devices(DBusConnection *conn,
3500 						DBusMessage *msg, void *data)
3501 {
3502 	struct adapter *adapter = data;
3503 	struct tm date;
3504 	const char *string;
3505 	DBusMessageIter iter;
3506 	DBusMessageIter array_iter;
3507 	DBusMessage *reply;
3508 	char filename[PATH_MAX + 1];
3509 	struct remote_device_list_t param = { NULL, 0 };
3510 	int len;
3511 
3512 	if (!dbus_message_get_args(msg, NULL,
3513 				DBUS_TYPE_STRING, &string,
3514 				DBUS_TYPE_INVALID))
3515 		return invalid_args(msg);
3516 
3517 	/* Date format is "YYYY-MM-DD HH:MM:SS GMT" */
3518 	len = strlen(string);
3519 	if (len && (strptime(string, "%Y-%m-%d %H:%M:%S", &date) == NULL))
3520 		return invalid_args(msg);
3521 
3522 	/* Bonded and trusted: mandatory entries(no matter the date/time) */
3523 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "linkkeys");
3524 	textfile_foreach(filename, list_remote_devices_do_append, &param);
3525 
3526 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "trusts");
3527 	textfile_foreach(filename, list_remote_devices_do_append, &param);
3528 
3529 	/* Last seen/used: append devices since the date informed */
3530 	if (len)
3531 		param.time = mktime(&date);
3532 
3533 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastseen");
3534 	textfile_foreach(filename, list_remote_devices_do_append, &param);
3535 
3536 	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastused");
3537 	textfile_foreach(filename, list_remote_devices_do_append, &param);
3538 
3539 	/* connected: force appending connected devices, lastused might not match */
3540 	g_slist_foreach(adapter->active_conn, (GFunc) append_connected, param.list);
3541 
3542 	reply = dbus_message_new_method_return(msg);
3543 
3544 	dbus_message_iter_init_append(reply, &iter);
3545 
3546 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3547 				DBUS_TYPE_STRING_AS_STRING, &array_iter);
3548 
3549 	g_slist_foreach(param.list, remote_devices_do_append, &array_iter);
3550 
3551 	g_slist_foreach(param.list, (GFunc) free, NULL);
3552 	g_slist_free(param.list);
3553 
3554 	dbus_message_iter_close_container(&iter, &array_iter);
3555 
3556 	return reply;
3557 }
3558 
3559 
adapter_set_trusted(DBusConnection * conn,DBusMessage * msg,void * data)3560 static DBusMessage *adapter_set_trusted(DBusConnection *conn,
3561 				DBusMessage *msg, void *data)
3562 {
3563 	struct adapter *adapter = data;
3564 	bdaddr_t local;
3565 	const char *address;
3566 	char *old_path, *new_path;
3567 
3568 	if (!dbus_message_get_args(msg, NULL,
3569 			DBUS_TYPE_STRING, &address,
3570 			DBUS_TYPE_INVALID))
3571 		return invalid_args(msg);
3572 
3573 	if (check_address(address) < 0)
3574 		return invalid_args(msg);
3575 
3576 	str2ba(adapter->address, &local);
3577 
3578 	write_trust(&local, address, GLOBAL_TRUST, TRUE);
3579 
3580 	resolve_paths(msg, &old_path, &new_path);
3581 
3582 	g_dbus_emit_signal(conn, old_path,
3583 					ADAPTER_INTERFACE, "TrustAdded",
3584 					DBUS_TYPE_STRING, &address,
3585 					DBUS_TYPE_INVALID);
3586 
3587 	if (new_path) {
3588 		struct device *device;
3589 		gboolean trust = TRUE;
3590 
3591 		device = adapter_find_device(adapter, address);
3592 		if (device) {
3593 			dbus_connection_emit_property_changed(conn,
3594 					device->path, DEVICE_INTERFACE,
3595 					"Trusted", DBUS_TYPE_BOOLEAN, &trust);
3596 		}
3597 	}
3598 
3599 	return dbus_message_new_method_return(msg);
3600 }
3601 
adapter_is_trusted(DBusConnection * conn,DBusMessage * msg,void * data)3602 static DBusMessage *adapter_is_trusted(DBusConnection *conn,
3603 				DBusMessage *msg, void *data)
3604 {
3605 	struct adapter *adapter = data;
3606 	DBusMessage *reply;
3607 	const char *address;
3608 	dbus_bool_t trusted;
3609 	bdaddr_t local;
3610 
3611 	if (!dbus_message_get_args(msg, NULL,
3612 			DBUS_TYPE_STRING, &address,
3613 			DBUS_TYPE_INVALID))
3614 		return invalid_args(msg);
3615 
3616 	if (check_address(address) < 0)
3617 		return invalid_args(msg);
3618 
3619 	str2ba(adapter->address, &local);
3620 
3621 	trusted = read_trust(&local, address, GLOBAL_TRUST);
3622 
3623 	reply = dbus_message_new_method_return(msg);
3624 	if (!reply)
3625 		return NULL;
3626 
3627 	dbus_message_append_args(reply,
3628 				DBUS_TYPE_BOOLEAN, &trusted,
3629 				DBUS_TYPE_INVALID);
3630 
3631 	return reply;
3632 }
3633 
adapter_remove_trust(DBusConnection * conn,DBusMessage * msg,void * data)3634 static DBusMessage *adapter_remove_trust(DBusConnection *conn,
3635 					DBusMessage *msg, void *data)
3636 {
3637 	struct adapter *adapter = data;
3638 	const char *address;
3639 	bdaddr_t local;
3640 	char *old_path, *new_path;
3641 
3642 	if (!dbus_message_get_args(msg, NULL,
3643 			DBUS_TYPE_STRING, &address,
3644 			DBUS_TYPE_INVALID))
3645 		return invalid_args(msg);
3646 
3647 	if (check_address(address) < 0)
3648 		return invalid_args(msg);
3649 
3650 	str2ba(adapter->address, &local);
3651 
3652 	write_trust(&local, address, GLOBAL_TRUST, FALSE);
3653 
3654 	resolve_paths(msg, &old_path, &new_path);
3655 
3656 	g_dbus_emit_signal(conn, old_path,
3657 					ADAPTER_INTERFACE, "TrustRemoved",
3658 					DBUS_TYPE_STRING, &address,
3659 					DBUS_TYPE_INVALID);
3660 
3661 	if (new_path) {
3662 		struct device *device;
3663 		gboolean trust = FALSE;
3664 
3665 		device = adapter_find_device(adapter, address);
3666 		if (device) {
3667 			dbus_connection_emit_property_changed(conn,
3668 					device->path, DEVICE_INTERFACE,
3669 					"Trusted", DBUS_TYPE_BOOLEAN, &trust);
3670 		}
3671 	}
3672 
3673 	return dbus_message_new_method_return(msg);
3674 }
3675 
adapter_list_trusts(DBusConnection * conn,DBusMessage * msg,void * data)3676 static DBusMessage *adapter_list_trusts(DBusConnection *conn,
3677 						DBusMessage *msg,
3678 						void *data)
3679 {
3680 	struct adapter *adapter = data;
3681 	DBusMessage *reply;
3682 	GSList *trusts, *l;
3683 	char **addrs;
3684 	bdaddr_t local;
3685 	int len;
3686 
3687 	reply = dbus_message_new_method_return(msg);
3688 	if (!reply)
3689 		return NULL;
3690 
3691 	str2ba(adapter->address, &local);
3692 
3693 	trusts = list_trusts(&local, GLOBAL_TRUST);
3694 
3695 	addrs = g_new(char *, g_slist_length(trusts));
3696 
3697 	for (l = trusts, len = 0; l; l = l->next, len++)
3698 		addrs[len] = l->data;
3699 
3700 	dbus_message_append_args(reply,
3701 			DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
3702 			&addrs, len,
3703 			DBUS_TYPE_INVALID);
3704 
3705 	g_free(addrs);
3706 	g_slist_foreach(trusts, (GFunc) g_free, NULL);
3707 	g_slist_free(trusts);
3708 
3709 	return reply;
3710 }
3711 
get_properties(DBusConnection * conn,DBusMessage * msg,void * data)3712 static DBusMessage *get_properties(DBusConnection *conn,
3713 					DBusMessage *msg, void *data)
3714 {
3715 	struct adapter *adapter = data;
3716 	const char *property;
3717 	DBusMessage *reply;
3718 	DBusMessageIter iter;
3719 	DBusMessageIter dict;
3720 	bdaddr_t ba;
3721 	char str[249];
3722 
3723 	if (check_address(adapter->address) < 0)
3724 		return adapter_not_ready(msg);
3725 
3726 	reply = dbus_message_new_method_return(msg);
3727 	if (!reply)
3728 		return NULL;
3729 
3730 	dbus_message_iter_init_append(reply, &iter);
3731 
3732 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3733 			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3734 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
3735 			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
3736 
3737 	/* Address */
3738 	property = adapter->address;
3739 	dbus_message_iter_append_dict_entry(&dict, "Address",
3740 			DBUS_TYPE_STRING, &property);
3741 
3742 	/* Name */
3743 	memset(str, 0, sizeof(str));
3744 	property = str;
3745 	str2ba(adapter->address, &ba);
3746 
3747 	if (!read_local_name(&ba, str))
3748 		dbus_message_iter_append_dict_entry(&dict, "Name",
3749 			DBUS_TYPE_STRING, &property);
3750 
3751 	/* Mode */
3752 	property = mode2str(adapter->mode);
3753 
3754 	dbus_message_iter_append_dict_entry(&dict, "Mode",
3755 			DBUS_TYPE_STRING, &property);
3756 
3757 	/* DiscoverableTimeout */
3758 	dbus_message_iter_append_dict_entry(&dict, "DiscoverableTimeout",
3759 				DBUS_TYPE_UINT32, &adapter->discov_timeout);
3760 
3761 	/* PeriodicDiscovery */
3762 	dbus_message_iter_append_dict_entry(&dict, "PeriodicDiscovery",
3763 				DBUS_TYPE_BOOLEAN, &adapter->pdiscov_active);
3764 
3765 	dbus_message_iter_close_container(&iter, &dict);
3766 
3767 	return reply;
3768 }
3769 
set_property(DBusConnection * conn,DBusMessage * msg,void * data)3770 static DBusMessage *set_property(DBusConnection *conn,
3771 					DBusMessage *msg, void *data)
3772 {
3773 	struct adapter *adapter = data;
3774 	DBusMessageIter iter;
3775 	DBusMessageIter sub;
3776 	const char *property;
3777 
3778 	if (!dbus_message_iter_init(msg, &iter))
3779 		return invalid_args(msg);
3780 
3781 	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
3782 		return invalid_args(msg);
3783 
3784 	dbus_message_iter_get_basic(&iter, &property);
3785 	dbus_message_iter_next(&iter);
3786 
3787 	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
3788 		return invalid_args(msg);
3789 	dbus_message_iter_recurse(&iter, &sub);
3790 
3791 	if (g_str_equal("Name", property)) {
3792 		const char *name;
3793 
3794 		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
3795 			return invalid_args(msg);
3796 		dbus_message_iter_get_basic(&sub, &name);
3797 
3798 		return set_name(conn, msg, name, data);
3799 	} else if (g_str_equal("DiscoverableTimeout", property)) {
3800 		uint32_t timeout;
3801 
3802 		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32)
3803 			return invalid_args(msg);
3804 		dbus_message_iter_get_basic(&sub, &timeout);
3805 
3806 		return set_discoverable_timeout(conn, msg, timeout, data);
3807 	} else if (g_str_equal("PeriodicDiscovery", property)) {
3808 		dbus_bool_t value;
3809 
3810 		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
3811 			return invalid_args(msg);
3812 		dbus_message_iter_get_basic(&sub, &value);
3813 
3814 		if (value)
3815 			return adapter_start_periodic(conn, msg, data);
3816 		else
3817 			return adapter_stop_periodic(conn, msg, data);
3818 	} else if (g_str_equal("Mode", property)) {
3819 		const char *mode;
3820 
3821 		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
3822 			return invalid_args(msg);
3823 
3824 		dbus_message_iter_get_basic(&sub, &mode);
3825 
3826 		adapter->global_mode = str2mode(adapter->address, mode);
3827 
3828 		if (adapter->global_mode == adapter->mode)
3829 			return dbus_message_new_method_return(msg);
3830 
3831 		if (adapter->sessions && adapter->global_mode < adapter->mode)
3832 			return confirm_mode(conn, msg, mode, data);
3833 
3834 		return set_mode(conn, msg, str2mode(adapter->address, mode),
3835 				data);
3836 	}
3837 
3838 	return invalid_args(msg);
3839 }
3840 
session_exit(void * data)3841 static void session_exit(void *data)
3842 {
3843 	struct mode_req *req = data;
3844 	struct adapter *adapter = req->adapter;
3845 
3846 	adapter->sessions = g_slist_remove(adapter->sessions, req);
3847 
3848 	if (!adapter->sessions) {
3849 		debug("Falling back to '%s' mode", mode2str(adapter->global_mode));
3850 		/* FIXME: fallback to previous mode
3851 		set_mode(req->conn, req->msg, adapter->global_mode, adapter);
3852 		*/
3853 	}
3854 	dbus_connection_unref(req->conn);
3855 	dbus_message_unref(req->msg);
3856 	g_free(req);
3857 }
3858 
request_mode(DBusConnection * conn,DBusMessage * msg,void * data)3859 static DBusMessage *request_mode(DBusConnection *conn,
3860 					DBusMessage *msg, void *data)
3861 {
3862 	const char *mode;
3863 	struct adapter *adapter = data;
3864 	struct mode_req *req;
3865 	uint8_t new_mode;
3866 	int ret;
3867 
3868 	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &mode,
3869 						DBUS_TYPE_INVALID))
3870 		return invalid_args(msg);
3871 
3872 	new_mode = str2mode(adapter->address, mode);
3873 	if (new_mode != MODE_CONNECTABLE && new_mode != MODE_DISCOVERABLE)
3874 		return invalid_args(msg);
3875 
3876 	if (!adapter->agent)
3877 		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
3878 				"No agent registered");
3879 
3880 	if (g_slist_find_custom(adapter->sessions, msg,
3881 			(GCompareFunc) find_session))
3882 		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
3883 				"Mode already requested");
3884 
3885 	req = g_new0(struct mode_req, 1);
3886 	req->adapter = adapter;
3887 	req->conn = dbus_connection_ref(conn);
3888 	req->msg = dbus_message_ref(msg);
3889 	req->mode = new_mode;
3890 	req->id = g_dbus_add_disconnect_watch(conn,
3891 					dbus_message_get_sender(msg),
3892 					session_exit, req, NULL);
3893 
3894 	if (!adapter->sessions)
3895 		adapter->global_mode = adapter->mode;
3896 	adapter->sessions = g_slist_append(adapter->sessions, req);
3897 
3898 	/* No need to change mode */
3899 	if (adapter->mode >= new_mode)
3900 		return dbus_message_new_method_return(msg);
3901 
3902 	ret = agent_confirm_mode_change(adapter->agent, mode, confirm_mode_cb,
3903 					req);
3904 	if (ret < 0) {
3905 		dbus_message_unref(req->msg);
3906 		g_dbus_remove_watch(req->conn, req->id);
3907 		dbus_connection_unref(req->conn);
3908 		g_free(req);
3909 		return invalid_args(msg);
3910 	}
3911 
3912 	return NULL;
3913 }
3914 
release_mode(DBusConnection * conn,DBusMessage * msg,void * data)3915 static DBusMessage *release_mode(DBusConnection *conn,
3916 					DBusMessage *msg, void *data)
3917 {
3918 	struct adapter *adapter = data;
3919 	GSList *l;
3920 
3921 	l = g_slist_find_custom(adapter->sessions, msg,
3922 			(GCompareFunc) find_session);
3923 	if (!l)
3924 		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
3925 				"No Mode to release");
3926 
3927 	session_exit(l->data);
3928 
3929 	return dbus_message_new_method_return(msg);
3930 }
3931 
list_devices(DBusConnection * conn,DBusMessage * msg,void * data)3932 static DBusMessage *list_devices(DBusConnection *conn,
3933 						DBusMessage *msg, void *data)
3934 {
3935 	struct adapter *adapter = data;
3936 	DBusMessage *reply;
3937 	GSList *l;
3938 	DBusMessageIter iter;
3939 	DBusMessageIter array_iter;
3940 
3941 	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
3942 		return invalid_args(msg);
3943 
3944 	reply = dbus_message_new_method_return(msg);
3945 	if (!reply)
3946 		return NULL;
3947 
3948 	dbus_message_iter_init_append(reply, &iter);
3949 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3950 				DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter);
3951 
3952 	for (l = adapter->devices; l; l = l->next) {
3953 		struct device *device = l->data;
3954 
3955 		if (device->temporary)
3956 			continue;
3957 
3958 		dbus_message_iter_append_basic(&array_iter,
3959 				DBUS_TYPE_OBJECT_PATH, &device->path);
3960 	}
3961 
3962 	dbus_message_iter_close_container(&iter, &array_iter);
3963 
3964 	return reply;
3965 }
3966 
create_device(DBusConnection * conn,DBusMessage * msg,void * data)3967 static DBusMessage *create_device(DBusConnection *conn,
3968 					DBusMessage *msg, void *data)
3969 {
3970 	struct adapter *adapter = data;
3971 	struct device *device;
3972 	const gchar *address;
3973 
3974 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
3975 						DBUS_TYPE_INVALID) == FALSE)
3976 		return invalid_args(msg);
3977 
3978 	if (check_address(address) < 0)
3979 		return invalid_args(msg);
3980 
3981 	if (adapter_find_device(adapter, address))
3982 		return g_dbus_create_error(msg,
3983 				ERROR_INTERFACE ".AlreadyExists",
3984 				"Device already exists");
3985 
3986 	debug("create_device(%s)", address);
3987 
3988 	device = device_create(conn, adapter, address);
3989 	if (!device)
3990 		return NULL;
3991 
3992 	device->temporary = FALSE;
3993 
3994 	device_browse(device, conn, msg, NULL);
3995 
3996 	adapter->devices = g_slist_append(adapter->devices, device);
3997 
3998 	return NULL;
3999 }
4000 
parse_io_capability(const char * capability)4001 static uint8_t parse_io_capability(const char *capability)
4002 {
4003 	if (g_str_equal(capability, ""))
4004 		return IO_CAPABILITY_DISPLAYYESNO;
4005 	if (g_str_equal(capability, "DisplayOnly"))
4006 		return IO_CAPABILITY_DISPLAYONLY;
4007 	if (g_str_equal(capability, "DisplayYesNo"))
4008 		return IO_CAPABILITY_DISPLAYYESNO;
4009 	if (g_str_equal(capability, "KeyboardOnly"))
4010 		return IO_CAPABILITY_KEYBOARDONLY;
4011 	if (g_str_equal(capability, "NoInputOutput"))
4012 		return IO_CAPABILITY_NOINPUTOUTPUT;
4013 	return IO_CAPABILITY_INVALID;
4014 }
4015 
create_paired_device(DBusConnection * conn,DBusMessage * msg,void * data)4016 static DBusMessage *create_paired_device(DBusConnection *conn,
4017 					DBusMessage *msg, void *data)
4018 {
4019 	const gchar *address, *agent_path, *capability;
4020 	uint8_t cap;
4021 
4022 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
4023 					DBUS_TYPE_OBJECT_PATH, &agent_path,
4024 					DBUS_TYPE_STRING, &capability,
4025 						DBUS_TYPE_INVALID) == FALSE)
4026 		return invalid_args(msg);
4027 
4028 	if (check_address(address) < 0)
4029 		return invalid_args(msg);
4030 
4031 	cap = parse_io_capability(capability);
4032 	if (cap == IO_CAPABILITY_INVALID)
4033 		return invalid_args(msg);
4034 
4035 	return create_bonding(conn, msg, address, agent_path, cap, data);
4036 }
4037 
device_path_cmp(struct device * device,const gchar * path)4038 static gint device_path_cmp(struct device *device, const gchar *path)
4039 {
4040 	return strcasecmp(device->path, path);
4041 }
4042 
remove_device(DBusConnection * conn,DBusMessage * msg,void * data)4043 static DBusMessage *remove_device(DBusConnection *conn,
4044 						DBusMessage *msg, void *data)
4045 {
4046 	struct adapter *adapter = data;
4047 	struct device *device;
4048 	const char *path;
4049 	GSList *l;
4050 
4051 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
4052 						DBUS_TYPE_INVALID) == FALSE)
4053 		return invalid_args(msg);
4054 
4055 	l = g_slist_find_custom(adapter->devices,
4056 			path, (GCompareFunc) device_path_cmp);
4057 	if (!l)
4058 		return g_dbus_create_error(msg,
4059 				ERROR_INTERFACE ".DoesNotExist",
4060 				"Device does not exist");
4061 	device = l->data;
4062 
4063 	if (device->temporary || device->discov_active)
4064 		return g_dbus_create_error(msg,
4065 				ERROR_INTERFACE ".DoesNotExist",
4066 				"Device creation in progress");
4067 
4068 	adapter_remove_device(conn, adapter, device);
4069 
4070 	return dbus_message_new_method_return(msg);
4071 }
4072 
find_device(DBusConnection * conn,DBusMessage * msg,void * data)4073 static DBusMessage *find_device(DBusConnection *conn,
4074 					DBusMessage *msg, void *data)
4075 {
4076 	struct adapter *adapter = data;
4077 	struct device *device;
4078 	DBusMessage *reply;
4079 	const gchar *address;
4080 	GSList *l;
4081 
4082 	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
4083 						DBUS_TYPE_INVALID))
4084 		return invalid_args(msg);
4085 
4086 	l = g_slist_find_custom(adapter->devices,
4087 			address, (GCompareFunc) device_address_cmp);
4088 	if (!l)
4089 		return g_dbus_create_error(msg,
4090 				ERROR_INTERFACE ".DoesNotExist",
4091 				"Device does not exist");
4092 
4093 	device = l->data;
4094 
4095 	if (device->temporary)
4096 		return g_dbus_create_error(msg,
4097 				ERROR_INTERFACE ".DoesNotExist",
4098 				"Device creation in progress");
4099 
4100 	reply = dbus_message_new_method_return(msg);
4101 	if (!reply)
4102 		return NULL;
4103 
4104 	dbus_message_append_args(reply,
4105 				DBUS_TYPE_OBJECT_PATH, &device->path,
4106 				DBUS_TYPE_INVALID);
4107 
4108 	return reply;
4109 }
4110 
agent_removed(struct agent * agent,struct adapter * adapter)4111 static void agent_removed(struct agent *agent, struct adapter *adapter)
4112 {
4113 	struct pending_auth_info *auth;
4114 	GSList *l;
4115 
4116 	adapter->agent = NULL;
4117 
4118 	l = g_slist_find_custom(adapter->auth_reqs, agent,
4119 					auth_info_agent_cmp);
4120 	if (!l)
4121 		return;
4122 
4123 	auth = l->data;
4124 	auth->agent = NULL;
4125 }
4126 
register_agent(DBusConnection * conn,DBusMessage * msg,void * data)4127 static DBusMessage *register_agent(DBusConnection *conn,
4128 					DBusMessage *msg, void *data)
4129 {
4130 	const char *path, *name, *capability;
4131 	struct agent *agent;
4132 	struct adapter *adapter = data;
4133 	uint8_t cap;
4134 
4135 	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
4136 			DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID))
4137 		return NULL;
4138 
4139 	if (adapter->agent)
4140 		return g_dbus_create_error(msg,
4141 				ERROR_INTERFACE ".AlreadyExists",
4142 				"Agent already exists");
4143 
4144 	cap = parse_io_capability(capability);
4145 	if (cap == IO_CAPABILITY_INVALID)
4146 		return invalid_args(msg);
4147 
4148 	name = dbus_message_get_sender(msg);
4149 
4150 	agent = agent_create(adapter, name, path, cap,
4151 				(agent_remove_cb) agent_removed, adapter);
4152 	if (!agent)
4153 		return g_dbus_create_error(msg,
4154 				ERROR_INTERFACE ".Failed",
4155 				"Failed to create a new agent");
4156 
4157 	adapter->agent = agent;
4158 
4159 	debug("Agent registered for hci%d at %s:%s", adapter->dev_id, name,
4160 			path);
4161 
4162 	return dbus_message_new_method_return(msg);
4163 }
4164 
unregister_agent(DBusConnection * conn,DBusMessage * msg,void * data)4165 static DBusMessage *unregister_agent(DBusConnection *conn,
4166 					DBusMessage *msg, void *data)
4167 {
4168 	const char *path, *name;
4169 	struct adapter *adapter = data;
4170 
4171 	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
4172 						DBUS_TYPE_INVALID))
4173 		return NULL;
4174 
4175 	name = dbus_message_get_sender(msg);
4176 
4177 	if (!adapter->agent || !agent_matches(adapter->agent, name, path))
4178 		return g_dbus_create_error(msg,
4179 				ERROR_INTERFACE ".DoesNotExist",
4180 				"No such agent");
4181 
4182 	agent_destroy(adapter->agent, FALSE);
4183 	adapter->agent = NULL;
4184 
4185 	return dbus_message_new_method_return(msg);
4186 }
4187 
add_service_record(DBusConnection * conn,DBusMessage * msg,void * data)4188 static DBusMessage *add_service_record(DBusConnection *conn,
4189 						DBusMessage *msg, void *data)
4190 {
4191 	struct adapter *adapter = data;
4192 	DBusMessage *reply;
4193 	const char *sender, *record;
4194 	dbus_uint32_t handle;
4195 	bdaddr_t src;
4196 	int err;
4197 
4198 	if (dbus_message_get_args(msg, NULL,
4199 			DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)
4200 		return NULL;
4201 
4202 	sender = dbus_message_get_sender(msg);
4203 	str2ba(adapter->address, &src);
4204 	err = add_xml_record(conn, sender, &src, record, &handle);
4205 	if (err < 0)
4206 		return failed_strerror(msg, err);
4207 
4208 	reply = dbus_message_new_method_return(msg);
4209 	if (!reply)
4210 		return NULL;
4211 
4212 	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &handle,
4213 							DBUS_TYPE_INVALID);
4214 
4215 	return reply;
4216 }
4217 
update_service_record(DBusConnection * conn,DBusMessage * msg,void * data)4218 static DBusMessage *update_service_record(DBusConnection *conn,
4219 						DBusMessage *msg, void *data)
4220 {
4221 	struct adapter *adapter = data;
4222 	bdaddr_t src;
4223 
4224 	str2ba(adapter->address, &src);
4225 
4226 	return update_xml_record(conn, msg, &src);
4227 }
4228 
remove_service_record(DBusConnection * conn,DBusMessage * msg,void * data)4229 static DBusMessage *remove_service_record(DBusConnection *conn,
4230 						DBusMessage *msg, void *data)
4231 {
4232 	dbus_uint32_t handle;
4233 	const char *sender;
4234 
4235 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
4236 						DBUS_TYPE_INVALID) == FALSE)
4237 		return NULL;
4238 
4239 	sender = dbus_message_get_sender(msg);
4240 
4241 	if (remove_record(conn, sender, handle) < 0)
4242 		return not_available(msg);
4243 
4244 	return dbus_message_new_method_return(msg);
4245 }
4246 
request_authorization(DBusConnection * conn,DBusMessage * msg,void * data)4247 static DBusMessage *request_authorization(DBusConnection *conn,
4248 						DBusMessage *msg, void *data)
4249 {
4250 	/* FIXME implement the request */
4251 
4252 	return NULL;
4253 }
4254 
cancel_authorization(DBusConnection * conn,DBusMessage * msg,void * data)4255 static DBusMessage *cancel_authorization(DBusConnection *conn,
4256 						DBusMessage *msg, void *data)
4257 {
4258 	/* FIXME implement cancel request */
4259 
4260 	return dbus_message_new_method_return(msg);
4261 }
4262 
4263 /* BlueZ 4.0 API */
4264 static GDBusMethodTable adapter_methods[] = {
4265 	{ "GetProperties",	"",	"a{sv}",get_properties		},
4266 	{ "SetProperty",	"sv",	"",	set_property,
4267 						G_DBUS_METHOD_FLAG_ASYNC},
4268 	{ "RequestMode",	"s",	"",	request_mode,
4269 						G_DBUS_METHOD_FLAG_ASYNC},
4270 	{ "ReleaseMode",	"",	"",	release_mode		},
4271 	{ "DiscoverDevices",	"",	"",	adapter_discover_devices},
4272 	{ "CancelDiscovery",	"",	"",	adapter_cancel_discovery,
4273 						G_DBUS_METHOD_FLAG_ASYNC},
4274 	{ "ListDevices",	"",	"ao",	list_devices		},
4275 	{ "CreateDevice",	"s",	"o",	create_device,
4276 						G_DBUS_METHOD_FLAG_ASYNC},
4277 	{ "CreatePairedDevice",	"sos",	"o",	create_paired_device,
4278 						G_DBUS_METHOD_FLAG_ASYNC},
4279 	{ "RemoveDevice",	"o",	"",	remove_device		},
4280 	{ "FindDevice",		"s",	"o",	find_device		},
4281 	{ "RegisterAgent",	"os",	"",	register_agent		},
4282 	{ "UnregisterAgent",	"o",	"",	unregister_agent	},
4283 	{ "AddServiceRecord",	"s",	"u",	add_service_record	},
4284 	{ "UpdateServiceRecord","us",	"",	update_service_record	},
4285 	{ "RemoveServiceRecord","u",	"",	remove_service_record	},
4286 	{ "RequestAuthorization","su",	"",	request_authorization,
4287 						G_DBUS_METHOD_FLAG_ASYNC},
4288 	{ "CancelAuthorization","",	"",	cancel_authorization	},
4289 	{ }
4290 };
4291 
4292 /* Deprecated */
4293 static GDBusMethodTable old_adapter_methods[] = {
4294 	{ "GetInfo",			"",	"a{sv}",
4295 						adapter_get_info		},
4296 	{ "GetAddress",			"",	"s",
4297 						adapter_get_address		},
4298 	{ "GetVersion",			"",	"s",
4299 						adapter_get_version		},
4300 	{ "GetRevision",		"",	"s",
4301 						adapter_get_revision		},
4302 	{ "GetManufacturer",		"",	"s",
4303 						adapter_get_manufacturer	},
4304 	{ "GetCompany",			"",	"s",
4305 						adapter_get_company		},
4306 	{ "ListAvailableModes",		"",	"as",
4307 						adapter_list_modes		},
4308 	{ "GetMode",			"",	"s",
4309 						adapter_get_mode		},
4310 	{ "SetMode",			"s",	"",
4311 						adapter_set_mode		},
4312 	{ "GetDiscoverableTimeout",	"",	"u",
4313 						adapter_get_discoverable_to	},
4314 	{ "SetDiscoverableTimeout",	"u",	"",
4315 						adapter_set_discoverable_to	},
4316 	{ "IsConnectable",		"",	"b",
4317 						adapter_is_connectable		},
4318 	{ "IsDiscoverable",		"",	"b",
4319 						adapter_is_discoverable		},
4320 	{ "IsConnected",		"s",	"b",
4321 						adapter_is_connected		},
4322 	{ "ListConnections",		"",	"as",
4323 						adapter_list_connections	},
4324 	{ "GetMajorClass",		"",	"s",
4325 						adapter_get_major_class		},
4326 	{ "ListAvailableMinorClasses",	"",	"as",
4327 						adapter_list_minor_classes	},
4328 	{ "GetMinorClass",		"",	"s",
4329 						adapter_get_minor_class		},
4330 	{ "SetMinorClass",		"s",	"",
4331 						adapter_set_minor_class		},
4332 	{ "GetServiceClasses",		"",	"as",
4333 						adapter_get_service_classes	},
4334 	{ "GetName",			"",	"s",
4335 						adapter_get_name		},
4336 	{ "SetName",			"s",	"",
4337 						adapter_set_name		},
4338 
4339 	{ "GetRemoteInfo",			"s",	"a{sv}",
4340 						adapter_get_remote_info		},
4341 	{ "GetRemoteServiceRecord",		"su",	"ay",
4342 		adapter_get_remote_svc,		G_DBUS_METHOD_FLAG_ASYNC	},
4343 	{ "GetRemoteServiceRecordAsXML",	"su",	"s",
4344 		adapter_get_remote_svc_xml,	G_DBUS_METHOD_FLAG_ASYNC	},
4345 	{ "GetRemoteServiceHandles",		"ss",	"au",
4346 		adapter_get_remote_svc_handles,	G_DBUS_METHOD_FLAG_ASYNC	},
4347 	{ "GetRemoteServiceIdentifiers",	"s",	"as",
4348 		adapter_get_remote_svc_identifiers, G_DBUS_METHOD_FLAG_ASYNC	},
4349 	{ "GetRemoteServiceChannel",		"sq",	"i",
4350 		adapter_get_remote_svc_channel,		G_DBUS_METHOD_FLAG_ASYNC	},
4351 	{ "FinishRemoteServiceTransaction",	"s",	"",
4352 						adapter_finish_sdp_transact	},
4353 	{ "GetRemoteVersion",			"s",	"s",
4354 						adapter_get_remote_version	},
4355 	{ "GetRemoteRevision",			"s",	"s",
4356 						adapter_get_remote_revision	},
4357 	{ "GetRemoteManufacturer",		"s",	"s",
4358 						adapter_get_remote_manufacturer	},
4359 	{ "GetRemoteCompany",			"s",	"s",
4360 						adapter_get_remote_company	},
4361 	{ "GetRemoteMajorClass",		"s",	"s",
4362 						adapter_get_remote_major_class	},
4363 	{ "GetRemoteMinorClass",		"s",	"s",
4364 						adapter_get_remote_minor_class	},
4365 	{ "GetRemoteServiceClasses",		"s",	"as",
4366 						adapter_get_remote_service_cls	},
4367 	{ "GetRemoteClass",			"s",	"u",
4368 						adapter_get_remote_class	},
4369 	{ "GetRemoteFeatures",			"s",	"ay",
4370 						adapter_get_remote_features	},
4371 	{ "GetRemoteName",			"s",	"s",
4372 						adapter_get_remote_name		},
4373 	{ "GetRemoteAlias",			"s",	"s",
4374 						adapter_get_remote_alias	},
4375 	{ "SetRemoteAlias",			"ss",	"",
4376 						adapter_set_remote_alias	},
4377 	{ "ClearRemoteAlias",			"s",	"",
4378 						adapter_clear_remote_alias	},
4379 
4380 	{ "LastSeen",		"s",	"s",
4381 						adapter_last_seen		},
4382 	{ "LastUsed",		"s",	"s",
4383 						adapter_last_used		},
4384 
4385 	{ "DisconnectRemoteDevice",	"s",	"",
4386 			adapter_dc_remote_device,	G_DBUS_METHOD_FLAG_ASYNC},
4387 
4388 	{ "CreateBonding",		"s",	"",
4389 			adapter_create_bonding,		G_DBUS_METHOD_FLAG_ASYNC},
4390 	{ "CancelBondingProcess",	"s",	"",
4391 						adapter_cancel_bonding		},
4392 	{ "RemoveBonding",		"s",	"",
4393 						adapter_remove_bonding		},
4394 	{ "HasBonding",			"s",	"b",
4395 						adapter_has_bonding		},
4396 	{ "ListBondings",		"",	"as",
4397 						adapter_list_bondings		},
4398 	{ "GetPinCodeLength",		"s",	"y",
4399 						adapter_get_pin_code_length	},
4400 	{ "GetEncryptionKeySize",	"s",	"y",
4401 						adapter_get_encryption_key_size	},
4402 
4403 	{ "StartPeriodicDiscovery",	"",	"",
4404 						adapter_start_periodic		},
4405 	{ "StopPeriodicDiscovery",	"",	"",
4406 						adapter_stop_periodic		},
4407 	{ "IsPeriodicDiscovery",	"",	"b",
4408 						adapter_is_periodic		},
4409 	{ "SetPeriodicDiscoveryNameResolving",	"b",	"",
4410 						adapter_set_pdiscov_resolve	},
4411 	{ "GetPeriodicDiscoveryNameResolving",	"",	"b",
4412 						adapter_get_pdiscov_resolve	},
4413 	{ "DiscoverDevices",			"",	"",
4414 						adapter_discover_devices	},
4415 	{ "CancelDiscovery",			"",	"",
4416 			adapter_cancel_discovery, G_DBUS_METHOD_FLAG_ASYNC	},
4417 	{ "DiscoverDevicesWithoutNameResolving","",	"",
4418 						adapter_discover_devices	},
4419 	{ "ListRemoteDevices",			"",	"as",
4420 						adapter_list_remote_devices	},
4421 	{ "ListRecentRemoteDevices",		"s",	"as",
4422 						adapter_list_recent_remote_devices},
4423 
4424 	{ "SetTrusted",		"s",	"",
4425 						adapter_set_trusted		},
4426 	{ "IsTrusted",		"s",	"b",
4427 						adapter_is_trusted		},
4428 	{ "RemoveTrust",	"s",	"",
4429 						adapter_remove_trust		},
4430 	{ "ListTrusts",		"",	"as",
4431 						adapter_list_trusts		},
4432 
4433 	{ }
4434 };
4435 
4436 /* BlueZ 4.X */
4437 static GDBusSignalTable adapter_signals[] = {
4438 	{ "DiscoveryStarted",		""		},
4439 	{ "DiscoveryCompleted",		""		},
4440 	{ "DeviceCreated",		"o"		},
4441 	{ "DeviceRemoved",		"o"		},
4442 	{ "DeviceFound",		"sa{sv}"	},
4443 	{ "PropertyChanged",		"sv"		},
4444 	{ "DeviceDisappeared",		"s"		},
4445 	{ }
4446 };
4447 
4448 /* Deprecated */
4449 static GDBusSignalTable old_adapter_signals[] = {
4450 	{ "DiscoveryStarted",			""	},
4451 	{ "DiscoveryCompleted",			""	},
4452 	{ "ModeChanged",			"s"	},
4453 	{ "DiscoverableTimeoutChanged",		"u"	},
4454 	{ "MinorClassChanged",			"s"	},
4455 	{ "NameChanged",			"s"	},
4456 	{ "PeriodicDiscoveryStarted",		""	},
4457 	{ "PeriodicDiscoveryStopped",		""	},
4458 	{ "RemoteDeviceFound",			"sun"	},
4459 	{ "RemoteDeviceDisappeared",		"s"	},
4460 	{ "RemoteClassUpdated",			"su"	},
4461 	{ "RemoteNameUpdated",			"ss"	},
4462 	{ "RemoteNameFailed",			"s"	},
4463 	{ "RemoteNameRequested",		"s"	},
4464 	{ "RemoteAliasChanged",			"ss"	},
4465 	{ "RemoteAliasCleared",			"s"	},
4466 	{ "RemoteDeviceConnected",		"s"	},
4467 	{ "RemoteDeviceDisconnectRequested",	"s"	},
4468 	{ "RemoteDeviceDisconnected",		"s"	},
4469 	{ "RemoteIdentifiersUpdated",		"sas"	},
4470 	{ "BondingCreated",			"s"	},
4471 	{ "BondingRemoved",			"s"	},
4472 	{ "TrustAdded",				"s"	},
4473 	{ "TrustRemoved",			"s"	},
4474 	{ }
4475 };
4476 
adapter_init(DBusConnection * conn,const char * path,struct adapter * adapter)4477 dbus_bool_t adapter_init(DBusConnection *conn,
4478 		const char *path, struct adapter *adapter)
4479 {
4480 	if (hcid_dbus_use_experimental())
4481 		g_dbus_register_interface(conn, path + ADAPTER_PATH_INDEX,
4482 				ADAPTER_INTERFACE, adapter_methods,
4483 				adapter_signals, NULL, adapter, NULL);
4484 
4485 	return g_dbus_register_interface(conn,
4486 			path, ADAPTER_INTERFACE,
4487 			old_adapter_methods, old_adapter_signals,
4488 			NULL, adapter, NULL);
4489 }
4490 
adapter_cleanup(DBusConnection * conn,const char * path)4491 dbus_bool_t adapter_cleanup(DBusConnection *conn, const char *path)
4492 {
4493 	return g_dbus_unregister_interface(conn, path, ADAPTER_INTERFACE);
4494 }
4495 
major_class_str(uint32_t class)4496 const char *major_class_str(uint32_t class)
4497 {
4498 	uint8_t index = (class >> 8) & 0x1F;
4499 
4500 	if (index > 8)
4501 		return major_cls[9]; /* uncategorized */
4502 
4503 	return major_cls[index];
4504 }
4505 
minor_class_str(uint32_t class)4506 const char *minor_class_str(uint32_t class)
4507 {
4508 	uint8_t major_index = (class >> 8) & 0x1F;
4509 	uint8_t minor_index;
4510 
4511 	switch (major_index) {
4512 	case 1: /* computer */
4513 		minor_index = (class >> 2) & 0x3F;
4514 		if (minor_index < NUM_ELEMENTS(computer_minor_cls))
4515 			return computer_minor_cls[minor_index];
4516 		else
4517 			return "";
4518 	case 2: /* phone */
4519 		minor_index = (class >> 2) & 0x3F;
4520 		if (minor_index < NUM_ELEMENTS(phone_minor_cls))
4521 			return phone_minor_cls[minor_index];
4522 		return "";
4523 	case 3: /* access point */
4524 		minor_index = (class >> 5) & 0x07;
4525 		if (minor_index < NUM_ELEMENTS(access_point_minor_cls))
4526 			return access_point_minor_cls[minor_index];
4527 		else
4528 			return "";
4529 	case 4: /* audio/video */
4530 		minor_index = (class >> 2) & 0x3F;
4531 		if (minor_index < NUM_ELEMENTS(audio_video_minor_cls))
4532 			return audio_video_minor_cls[minor_index];
4533 		else
4534 			return "";
4535 	case 5: /* peripheral */
4536 		minor_index = (class >> 6) & 0x03;
4537 		if (minor_index < NUM_ELEMENTS(peripheral_minor_cls))
4538 			return peripheral_minor_cls[minor_index];
4539 		else
4540 			return "";
4541 	case 6: /* imaging */
4542 		{
4543 			uint8_t shift_minor = 0;
4544 
4545 			minor_index = (class >> 4) & 0x0F;
4546 			while (shift_minor < (sizeof(imaging_minor_cls) / sizeof(*imaging_minor_cls))) {
4547 				if (((minor_index >> shift_minor) & 0x01) == 0x01)
4548 					return imaging_minor_cls[shift_minor];
4549 				shift_minor++;
4550 			}
4551 		}
4552 		break;
4553 	case 7: /* wearable */
4554 		minor_index = (class >> 2) & 0x3F;
4555 		if (minor_index < NUM_ELEMENTS(wearable_minor_cls))
4556 			return wearable_minor_cls[minor_index];
4557 		else
4558 			return "";
4559 	case 8: /* toy */
4560 		minor_index = (class >> 2) & 0x3F;
4561 		if (minor_index < NUM_ELEMENTS(toy_minor_cls))
4562 			return toy_minor_cls[minor_index];
4563 		else
4564 			return "";
4565 	}
4566 
4567 	return "";
4568 }
4569 
service_classes_str(uint32_t class)4570 GSList *service_classes_str(uint32_t class)
4571 {
4572 	uint8_t services = class >> 16;
4573 	GSList *l = NULL;
4574 	int i;
4575 
4576 	for (i = 0; i < (sizeof(service_cls) / sizeof(*service_cls)); i++) {
4577 		if (!(services & (1 << i)))
4578 			continue;
4579 
4580 		l = g_slist_append(l, (void *) service_cls[i]);
4581 	}
4582 
4583 	return l;
4584 }
4585