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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
3525
3526 create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "trusts");
3527 textfile_foreach(filename, list_remote_devices_do_append, ¶m);
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, ¶m);
3535
3536 create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastused");
3537 textfile_foreach(filename, list_remote_devices_do_append, ¶m);
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