1 /*
2 *
3 * BlueZ - Bluetooth protocol stack for Linux
4 *
5 * Copyright (C) 2006-2007 Nokia Corporation
6 * Copyright (C) 2004-2009 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 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <sys/stat.h>
34 #include <errno.h>
35
36 #include <bluetooth/bluetooth.h>
37 #include <bluetooth/hci.h>
38 #include <bluetooth/hci_lib.h>
39 #include <bluetooth/l2cap.h>
40 #include <bluetooth/sdp.h>
41 #include <bluetooth/sdp_lib.h>
42
43 #include <glib.h>
44 #include <dbus/dbus.h>
45 #include <gdbus.h>
46
47 #include "logging.h"
48 #include "textfile.h"
49
50 #include "hcid.h"
51 #include "adapter.h"
52 #include "device.h"
53 #include "dbus-common.h"
54 #include "dbus-hci.h"
55 #include "error.h"
56 #include "glib-helper.h"
57 #include "agent.h"
58 #include "sdp-xml.h"
59 #include "storage.h"
60 #include "btio.h"
61
62 #define DEFAULT_XML_BUF_SIZE 1024
63 #define DISCONNECT_TIMER 2
64 #define DISCOVERY_TIMER 2
65
66 struct btd_driver_data {
67 guint id;
68 struct btd_device_driver *driver;
69 void *priv;
70 };
71
72 struct btd_disconnect_data {
73 guint id;
74 disconnect_watch watch;
75 void *user_data;
76 GDestroyNotify destroy;
77 };
78
79 struct bonding_req {
80 DBusConnection *conn;
81 DBusMessage *msg;
82 GIOChannel *io;
83 guint io_id;
84 guint listener_id;
85 struct btd_device *device;
86 };
87
88 struct authentication_req {
89 auth_type_t type;
90 void *cb;
91 struct agent *agent;
92 struct btd_device *device;
93 };
94
95 struct browse_req {
96 DBusConnection *conn;
97 DBusMessage *msg;
98 struct btd_device *device;
99 GSList *match_uuids;
100 GSList *profiles_added;
101 GSList *profiles_removed;
102 sdp_list_t *records;
103 int search_uuid;
104 int reconnect_attempt;
105 guint listener_id;
106 guint timer;
107 };
108
109 struct btd_device {
110 bdaddr_t bdaddr;
111 gchar *path;
112 char name[MAX_NAME_LENGTH + 1];
113 struct btd_adapter *adapter;
114 GSList *uuids;
115 GSList *drivers; /* List of driver_data */
116 GSList *watches; /* List of disconnect_data */
117 gboolean temporary;
118 struct agent *agent;
119 guint disconn_timer;
120 guint discov_timer;
121 struct browse_req *browse; /* service discover request */
122 struct bonding_req *bonding;
123 struct authentication_req *authr; /* authentication request */
124 GSList *disconnects; /* disconnects message */
125
126 /* For Secure Simple Pairing */
127 uint8_t cap;
128 uint8_t auth;
129
130 uint16_t handle; /* Connection handle */
131
132 /* Whether were creating a security mode 3 connection */
133 gboolean secmode3;
134
135 sdp_list_t *tmp_records;
136
137 gboolean renewed_key;
138
139 gboolean authorizing;
140 gint ref;
141 };
142
143 static uint16_t uuid_list[] = {
144 L2CAP_UUID,
145 PNP_INFO_SVCLASS_ID,
146 PUBLIC_BROWSE_GROUP,
147 0
148 };
149
150 static GSList *device_drivers = NULL;
151
error_connection_attempt_failed(DBusConnection * conn,DBusMessage * msg,int err)152 static DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn,
153 DBusMessage *msg, int err)
154 {
155 return error_common_reply(conn, msg,
156 ERROR_INTERFACE ".ConnectionAttemptFailed",
157 err > 0 ? strerror(err) : "Connection attempt failed");
158 }
159
error_failed(DBusConnection * conn,DBusMessage * msg,const char * desc)160 static DBusHandlerResult error_failed(DBusConnection *conn,
161 DBusMessage *msg, const char * desc)
162 {
163 return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
164 }
165
error_failed_errno(DBusConnection * conn,DBusMessage * msg,int err)166 static DBusHandlerResult error_failed_errno(DBusConnection *conn,
167 DBusMessage *msg, int err)
168 {
169 const char *desc = strerror(err);
170
171 return error_failed(conn, msg, desc);
172 }
173
no_such_adapter(DBusMessage * msg)174 static inline DBusMessage *no_such_adapter(DBusMessage *msg)
175 {
176 return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter",
177 "No such adapter");
178 }
179
in_progress(DBusMessage * msg,const char * str)180 static inline DBusMessage *in_progress(DBusMessage *msg, const char *str)
181 {
182 return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", str);
183 }
184
browse_request_free(struct browse_req * req)185 static void browse_request_free(struct browse_req *req)
186 {
187 if (req->listener_id)
188 g_dbus_remove_watch(req->conn, req->listener_id);
189 if (req->msg)
190 dbus_message_unref(req->msg);
191 if (req->conn)
192 dbus_connection_unref(req->conn);
193 g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL);
194 g_slist_free(req->profiles_added);
195 g_slist_free(req->profiles_removed);
196 if (req->records)
197 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
198 g_free(req);
199 }
200
browse_request_cancel(struct browse_req * req)201 static void browse_request_cancel(struct browse_req *req)
202 {
203 struct btd_device *device = req->device;
204 struct btd_adapter *adapter = device->adapter;
205 bdaddr_t src;
206
207 if (device_is_creating(device, NULL))
208 device_set_temporary(device, TRUE);
209
210 adapter_get_address(adapter, &src);
211
212 bt_cancel_discovery(&src, &device->bdaddr);
213
214 browse_request_free(req);
215 device->browse = NULL;
216 }
217
device_free(gpointer user_data)218 static void device_free(gpointer user_data)
219 {
220 struct btd_device *device = user_data;
221 struct btd_adapter *adapter = device->adapter;
222 struct agent *agent = adapter_get_agent(adapter);
223
224 if (device->agent)
225 agent_destroy(device->agent, FALSE);
226
227 if (agent && (agent_is_busy(agent, device) ||
228 agent_is_busy(agent, device->authr)))
229 agent_cancel(agent);
230
231 g_slist_foreach(device->uuids, (GFunc) g_free, NULL);
232 g_slist_free(device->uuids);
233
234 if (device->disconn_timer)
235 g_source_remove(device->disconn_timer);
236
237 debug("device_free(%p)", device);
238
239 g_free(device->authr);
240 g_free(device->path);
241 g_free(device);
242 }
243
device_is_paired(struct btd_device * device)244 gboolean device_is_paired(struct btd_device *device)
245 {
246 struct btd_adapter *adapter = device->adapter;
247 char filename[PATH_MAX + 1], *str;
248 char srcaddr[18], dstaddr[18];
249 gboolean ret;
250 bdaddr_t src;
251
252 adapter_get_address(adapter, &src);
253 ba2str(&src, srcaddr);
254 ba2str(&device->bdaddr, dstaddr);
255
256 create_name(filename, PATH_MAX, STORAGEDIR,
257 srcaddr, "linkkeys");
258 str = textfile_caseget(filename, dstaddr);
259 ret = str ? TRUE : FALSE;
260 g_free(str);
261
262 return ret;
263 }
264
get_properties(DBusConnection * conn,DBusMessage * msg,void * user_data)265 static DBusMessage *get_properties(DBusConnection *conn,
266 DBusMessage *msg, void *user_data)
267 {
268 struct btd_device *device = user_data;
269 struct btd_adapter *adapter = device->adapter;
270 DBusMessage *reply;
271 DBusMessageIter iter;
272 DBusMessageIter dict;
273 bdaddr_t src;
274 char name[MAX_NAME_LENGTH + 1], srcaddr[18], dstaddr[18];
275 char **uuids;
276 const char *ptr;
277 dbus_bool_t boolean;
278 uint32_t class;
279 int i;
280 GSList *l;
281
282 ba2str(&device->bdaddr, dstaddr);
283
284 reply = dbus_message_new_method_return(msg);
285 if (!reply)
286 return NULL;
287
288 dbus_message_iter_init_append(reply, &iter);
289
290 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
291 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
292 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
293 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
294
295 /* Address */
296 ptr = dstaddr;
297 dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr);
298
299 /* Name */
300 ptr = NULL;
301 memset(name, 0, sizeof(name));
302 adapter_get_address(adapter, &src);
303 ba2str(&src, srcaddr);
304
305 ptr = device->name;
306 dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr);
307
308 /* Alias (fallback to name or address) */
309 if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) < 1) {
310 if (strlen(ptr) == 0) {
311 g_strdelimit(dstaddr, ":", '-');
312 ptr = dstaddr;
313 }
314 } else
315 ptr = name;
316
317 dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr);
318
319 /* Class */
320 if (read_remote_class(&src, &device->bdaddr, &class) == 0) {
321 const char *icon = class_to_icon(class);
322
323 dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class);
324
325 if (icon)
326 dict_append_entry(&dict, "Icon",
327 DBUS_TYPE_STRING, &icon);
328 }
329
330 /* Paired */
331 boolean = device_is_paired(device);
332 dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean);
333
334 /* Trusted */
335 boolean = read_trust(&src, dstaddr, GLOBAL_TRUST);
336 dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);
337
338 /* Connected */
339 boolean = (device->handle != 0);
340 dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,
341 &boolean);
342
343 /* UUIDs */
344 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
345 for (i = 0, l = device->uuids; l; l = l->next, i++)
346 uuids[i] = l->data;
347 dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &uuids, i);
348 g_free(uuids);
349
350 /* Adapter */
351 ptr = adapter_get_path(adapter);
352 dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
353
354 dbus_message_iter_close_container(&iter, &dict);
355
356 return reply;
357 }
358
set_alias(DBusConnection * conn,DBusMessage * msg,const char * alias,void * data)359 static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
360 const char *alias, void *data)
361 {
362 struct btd_device *device = data;
363 struct btd_adapter *adapter = device->adapter;
364 char srcaddr[18], dstaddr[18];
365 bdaddr_t src;
366 int err;
367
368 adapter_get_address(adapter, &src);
369 ba2str(&src, srcaddr);
370 ba2str(&device->bdaddr, dstaddr);
371
372 /* Remove alias if empty string */
373 err = write_device_alias(srcaddr, dstaddr,
374 g_str_equal(alias, "") ? NULL : alias);
375 if (err < 0)
376 return g_dbus_create_error(msg,
377 ERROR_INTERFACE ".Failed",
378 strerror(-err));
379
380 emit_property_changed(conn, dbus_message_get_path(msg),
381 DEVICE_INTERFACE, "Alias",
382 DBUS_TYPE_STRING, &alias);
383
384 return dbus_message_new_method_return(msg);
385 }
386
set_trust(DBusConnection * conn,DBusMessage * msg,dbus_bool_t value,void * data)387 static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
388 dbus_bool_t value, void *data)
389 {
390 struct btd_device *device = data;
391 struct btd_adapter *adapter = device->adapter;
392 char srcaddr[18], dstaddr[18];
393 bdaddr_t src;
394
395 adapter_get_address(adapter, &src);
396 ba2str(&src, srcaddr);
397 ba2str(&device->bdaddr, dstaddr);
398
399 write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
400
401 emit_property_changed(conn, dbus_message_get_path(msg),
402 DEVICE_INTERFACE, "Trusted",
403 DBUS_TYPE_BOOLEAN, &value);
404
405 return dbus_message_new_method_return(msg);
406 }
407
invalid_args(DBusMessage * msg)408 static inline DBusMessage *invalid_args(DBusMessage *msg)
409 {
410 return g_dbus_create_error(msg,
411 ERROR_INTERFACE ".InvalidArguments",
412 "Invalid arguments in method call");
413 }
414
set_property(DBusConnection * conn,DBusMessage * msg,void * data)415 static DBusMessage *set_property(DBusConnection *conn,
416 DBusMessage *msg, void *data)
417 {
418 DBusMessageIter iter;
419 DBusMessageIter sub;
420 const char *property;
421
422 if (!dbus_message_iter_init(msg, &iter))
423 return invalid_args(msg);
424
425 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
426 return invalid_args(msg);
427
428 dbus_message_iter_get_basic(&iter, &property);
429 dbus_message_iter_next(&iter);
430
431 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
432 return invalid_args(msg);
433 dbus_message_iter_recurse(&iter, &sub);
434
435 if (g_str_equal("Trusted", property)) {
436 dbus_bool_t value;
437
438 if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
439 return invalid_args(msg);
440 dbus_message_iter_get_basic(&sub, &value);
441
442 return set_trust(conn, msg, value, data);
443 } else if (g_str_equal("Alias", property)) {
444 const char *alias;
445
446 if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
447 return invalid_args(msg);
448 dbus_message_iter_get_basic(&sub, &alias);
449
450 return set_alias(conn, msg, alias, data);
451 }
452
453 return invalid_args(msg);
454 }
455
discover_services_req_exit(DBusConnection * conn,void * user_data)456 static void discover_services_req_exit(DBusConnection *conn, void *user_data)
457 {
458 struct browse_req *req = user_data;
459
460 debug("DiscoverServices requestor exited");
461
462 browse_request_cancel(req);
463 }
464
discover_services(DBusConnection * conn,DBusMessage * msg,void * user_data)465 static DBusMessage *discover_services(DBusConnection *conn,
466 DBusMessage *msg, void *user_data)
467 {
468 struct btd_device *device = user_data;
469 const char *pattern;
470 int err;
471
472 if (device->browse)
473 return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
474 "Discover in progress");
475
476 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
477 DBUS_TYPE_INVALID) == FALSE)
478 goto fail;
479
480 if (strlen(pattern) == 0) {
481 err = device_browse(device, conn, msg, NULL, FALSE);
482 if (err < 0)
483 goto fail;
484 } else {
485 uuid_t uuid;
486
487 if (bt_string2uuid(&uuid, pattern) < 0)
488 return invalid_args(msg);
489
490 sdp_uuid128_to_uuid(&uuid);
491
492 err = device_browse(device, conn, msg, &uuid, FALSE);
493 if (err < 0)
494 goto fail;
495 }
496
497 return NULL;
498
499 fail:
500 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
501 "Discovery Failed");
502 }
503
browse_request_get_requestor(struct browse_req * req)504 static const char *browse_request_get_requestor(struct browse_req *req)
505 {
506 if (!req->msg)
507 return NULL;
508
509 return dbus_message_get_sender(req->msg);
510 }
511
iter_append_record(DBusMessageIter * dict,uint32_t handle,const char * record)512 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
513 const char *record)
514 {
515 DBusMessageIter entry;
516
517 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
518 NULL, &entry);
519
520 dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
521
522 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
523
524 dbus_message_iter_close_container(dict, &entry);
525 }
526
discover_services_reply(struct browse_req * req,int err,sdp_list_t * recs)527 static void discover_services_reply(struct browse_req *req, int err,
528 sdp_list_t *recs)
529 {
530 DBusMessage *reply;
531 DBusMessageIter iter, dict;
532 sdp_list_t *seq;
533
534 if (err) {
535 const char *err_if;
536
537 if (err == -EHOSTDOWN)
538 err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
539 else
540 err_if = ERROR_INTERFACE ".Failed";
541
542 reply = dbus_message_new_error(req->msg, err_if,
543 strerror(-err));
544 g_dbus_send_message(req->conn, reply);
545 return;
546 }
547
548 reply = dbus_message_new_method_return(req->msg);
549 if (!reply)
550 return;
551
552 dbus_message_iter_init_append(reply, &iter);
553
554 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
555 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
556 DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
557 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
558
559 for (seq = recs; seq; seq = seq->next) {
560 sdp_record_t *rec = (sdp_record_t *) seq->data;
561 GString *result;
562
563 if (!rec)
564 break;
565
566 result = g_string_new(NULL);
567
568 convert_sdp_record_to_xml(rec, result,
569 (void *) g_string_append);
570
571 if (result->len)
572 iter_append_record(&dict, rec->handle, result->str);
573
574 g_string_free(result, TRUE);
575 }
576
577 dbus_message_iter_close_container(&iter, &dict);
578
579 g_dbus_send_message(req->conn, reply);
580 }
581
cancel_discover(DBusConnection * conn,DBusMessage * msg,void * user_data)582 static DBusMessage *cancel_discover(DBusConnection *conn,
583 DBusMessage *msg, void *user_data)
584 {
585 struct btd_device *device = user_data;
586 const char *sender = dbus_message_get_sender(msg);
587 const char *requestor;
588
589 if (!device->browse)
590 return g_dbus_create_error(msg,
591 ERROR_INTERFACE ".Failed",
592 "No pending discovery");
593
594 if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
595 "DiscoverServices"))
596 return g_dbus_create_error(msg,
597 ERROR_INTERFACE ".NotAuthorized",
598 "Not Authorized");
599
600 requestor = browse_request_get_requestor(device->browse);
601
602 /* only the discover requestor can cancel the inquiry process */
603 if (!requestor || !g_str_equal(requestor, sender))
604 return g_dbus_create_error(msg,
605 ERROR_INTERFACE ".NotAuthorized",
606 "Not Authorized");
607
608 discover_services_reply(device->browse, -ECANCELED, NULL);
609
610 browse_request_cancel(device->browse);
611
612 return dbus_message_new_method_return(msg);
613 }
614
do_disconnect(gpointer user_data)615 static gboolean do_disconnect(gpointer user_data)
616 {
617 struct btd_device *device = user_data;
618 disconnect_cp cp;
619 int dd;
620 uint16_t dev_id = adapter_get_dev_id(device->adapter);
621
622 device->disconn_timer = 0;
623
624 dd = hci_open_dev(dev_id);
625 if (dd < 0)
626 goto fail;
627
628 memset(&cp, 0, sizeof(cp));
629 cp.handle = htobs(device->handle);
630 cp.reason = HCI_OE_USER_ENDED_CONNECTION;
631
632 hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT,
633 DISCONNECT_CP_SIZE, &cp);
634
635 close(dd);
636
637 fail:
638 return FALSE;
639 }
640
bonding_request_cancel(struct bonding_req * bonding)641 static void bonding_request_cancel(struct bonding_req *bonding)
642 {
643 if (!bonding->io)
644 return;
645
646 if (bonding->io_id) {
647 g_source_remove(bonding->io_id);
648 bonding->io_id = 0;
649 }
650
651 g_io_channel_shutdown(bonding->io, TRUE, NULL);
652 g_io_channel_unref(bonding->io);
653 bonding->io = NULL;
654 }
655
device_request_disconnect(struct btd_device * device,DBusMessage * msg)656 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
657 {
658 GSList *l;
659 DBusConnection *conn = get_dbus_connection();
660
661 if (device->bonding)
662 bonding_request_cancel(device->bonding);
663
664 if (device->browse)
665 browse_request_cancel(device->browse);
666
667 if (msg)
668 device->disconnects = g_slist_append(device->disconnects,
669 dbus_message_ref(msg));
670
671 if (device->disconn_timer)
672 return;
673
674 l = device->watches;
675 while (l) {
676 struct btd_disconnect_data *data = l->data;
677
678 l = l->next;
679
680 if (data->watch)
681 /* temporary is set if device is going to be removed */
682 data->watch(device, device->temporary,
683 data->user_data);
684 }
685
686 g_slist_foreach(device->watches, (GFunc) g_free, NULL);
687 g_slist_free(device->watches);
688 device->watches = NULL;
689
690 device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
691 do_disconnect, device);
692
693 g_dbus_emit_signal(conn, device->path,
694 DEVICE_INTERFACE, "DisconnectRequested",
695 DBUS_TYPE_INVALID);
696 }
697
disconnect(DBusConnection * conn,DBusMessage * msg,void * user_data)698 static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
699 void *user_data)
700 {
701 struct btd_device *device = user_data;
702
703 if (!device->handle)
704 return g_dbus_create_error(msg,
705 ERROR_INTERFACE ".NotConnected",
706 "Device is not connected");
707
708 device_request_disconnect(device, msg);
709
710 return NULL;
711 }
712
get_service_attribute_value_reply(DBusMessage * msg,DBusConnection * conn,sdp_data_t * attr)713 static DBusMessage *get_service_attribute_value_reply(DBusMessage *msg, DBusConnection *conn,
714 sdp_data_t *attr)
715 {
716 DBusMessage *reply;
717 DBusMessageIter iter;
718
719 reply = dbus_message_new_method_return(msg);
720 if (!reply)
721 return NULL;
722 sdp_data_t *curr;
723 sdp_list_t *ap = 0;
724 for (; attr; attr = attr->next) {
725 sdp_list_t *pds = 0;
726 for (curr = attr->val.dataseq; curr; curr = curr->next)
727 pds = sdp_list_append(pds, curr->val.dataseq);
728 ap = sdp_list_append(ap, pds);
729 }
730
731 int ch = sdp_get_proto_port(ap, RFCOMM_UUID);
732 sdp_list_foreach(ap, (sdp_list_func_t) sdp_list_free, NULL);
733 sdp_list_free(ap, NULL);
734 ap = NULL;
735
736 dbus_message_append_args(reply, DBUS_TYPE_INT32, &ch, DBUS_TYPE_INVALID);
737
738 return reply;
739 }
740
get_service_attribute_value(DBusConnection * conn,DBusMessage * msg,void * user_data)741 static DBusMessage *get_service_attribute_value(DBusConnection *conn,
742 DBusMessage *msg,
743 void *user_data)
744 {
745 struct btd_device *device = user_data;
746 sdp_record_t *rec;
747 sdp_data_t *attr_data;
748 const char *pattern;
749 uint16_t attrId;
750 int err;
751
752 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
753 DBUS_TYPE_UINT16, &attrId,
754 DBUS_TYPE_INVALID) == FALSE)
755 goto fail;
756
757 if (strlen(pattern) == 0)
758 return invalid_args(msg);
759
760 rec = btd_device_get_record(device, pattern);
761 if (rec == NULL) {
762 error("rec is NULL");
763 goto fail;
764 }
765
766 attr_data = sdp_data_get(rec, attrId);
767
768 if (attr_data == NULL) {
769 error("attr in null");
770 goto fail;
771 }
772 return get_service_attribute_value_reply(msg, conn, attr_data);
773 fail:
774 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
775 "GetServiceAttribute Failed");
776 }
777
778 static GDBusMethodTable device_methods[] = {
779 { "GetProperties", "", "a{sv}", get_properties },
780 { "SetProperty", "sv", "", set_property },
781 { "DiscoverServices", "s", "a{us}", discover_services,
782 G_DBUS_METHOD_FLAG_ASYNC},
783 { "CancelDiscovery", "", "", cancel_discover },
784 { "Disconnect", "", "", disconnect,
785 G_DBUS_METHOD_FLAG_ASYNC},
786 { "GetServiceAttributeValue", "sq", "i", get_service_attribute_value},
787 { }
788 };
789
790 static GDBusSignalTable device_signals[] = {
791 { "PropertyChanged", "sv" },
792 { "DisconnectRequested", "" },
793 { }
794 };
795
device_is_connected(struct btd_device * device)796 gboolean device_is_connected(struct btd_device *device)
797 {
798 return (device->handle != 0);
799 }
800
device_set_connected(struct btd_device * device,DBusConnection * conn,gboolean connected)801 static void device_set_connected(struct btd_device *device,
802 DBusConnection *conn,
803 gboolean connected)
804 {
805 emit_property_changed(conn, device->path, DEVICE_INTERFACE,
806 "Connected", DBUS_TYPE_BOOLEAN, &connected);
807
808 if (connected && device->secmode3) {
809 struct btd_adapter *adapter = device_get_adapter(device);
810 bdaddr_t sba;
811
812 adapter_get_address(adapter, &sba);
813
814 device->secmode3 = FALSE;
815
816 hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0);
817 }
818 }
819
device_add_connection(struct btd_device * device,DBusConnection * conn,uint16_t handle)820 void device_add_connection(struct btd_device *device, DBusConnection *conn,
821 uint16_t handle)
822 {
823 if (device->handle) {
824 error("%s: Unable to add connection %u, %u already exist)",
825 device->path, handle, device->handle);
826 return;
827 }
828
829 device->handle = handle;
830
831 device_set_connected(device, conn, TRUE);
832 }
833
device_remove_connection(struct btd_device * device,DBusConnection * conn,uint16_t handle)834 void device_remove_connection(struct btd_device *device, DBusConnection *conn,
835 uint16_t handle)
836 {
837 if (handle && device->handle != handle) {
838 error("%s: Unable to remove connection %u, handle mismatch (%u)",
839 device->path, handle, device->handle);
840 return;
841 }
842
843 device->handle = 0;
844
845 while (device->disconnects) {
846 DBusMessage *msg = device->disconnects->data;
847
848 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
849 device->disconnects = g_slist_remove(device->disconnects, msg);
850 }
851
852 device_set_connected(device, conn, FALSE);
853 }
854
device_has_connection(struct btd_device * device,uint16_t handle)855 gboolean device_has_connection(struct btd_device *device, uint16_t handle)
856 {
857 return (handle == device->handle);
858 }
859
device_add_disconnect_watch(struct btd_device * device,disconnect_watch watch,void * user_data,GDestroyNotify destroy)860 guint device_add_disconnect_watch(struct btd_device *device,
861 disconnect_watch watch, void *user_data,
862 GDestroyNotify destroy)
863 {
864 struct btd_disconnect_data *data;
865 static guint id = 0;
866
867 data = g_new0(struct btd_disconnect_data, 1);
868 data->id = ++id;
869 data->watch = watch;
870 data->user_data = user_data;
871 data->destroy = destroy;
872
873 device->watches = g_slist_append(device->watches, data);
874
875 return data->id;
876 }
877
device_remove_disconnect_watch(struct btd_device * device,guint id)878 void device_remove_disconnect_watch(struct btd_device *device, guint id)
879 {
880 GSList *l;
881
882 for (l = device->watches; l; l = l->next) {
883 struct btd_disconnect_data *data = l->data;
884
885 if (data->id == id) {
886 device->watches = g_slist_remove(device->watches,
887 data);
888 if (data->destroy)
889 data->destroy(data->user_data);
890 g_free(data);
891 return;
892 }
893 }
894 }
895
device_set_secmode3_conn(struct btd_device * device,gboolean enable)896 void device_set_secmode3_conn(struct btd_device *device, gboolean enable)
897 {
898 device->secmode3 = enable;
899 }
900
device_create(DBusConnection * conn,struct btd_adapter * adapter,const gchar * address)901 struct btd_device *device_create(DBusConnection *conn,
902 struct btd_adapter *adapter,
903 const gchar *address)
904 {
905 gchar *address_up;
906 struct btd_device *device;
907 const gchar *adapter_path = adapter_get_path(adapter);
908 bdaddr_t src;
909 char srcaddr[18];
910
911 device = g_try_malloc0(sizeof(struct btd_device));
912 if (device == NULL)
913 return NULL;
914
915 address_up = g_ascii_strup(address, -1);
916 device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
917 g_strdelimit(device->path, ":", '_');
918 g_free(address_up);
919
920 debug("Creating device %s", device->path);
921
922 if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
923 device_methods, device_signals, NULL,
924 device, device_free) == FALSE) {
925 device_free(device);
926 return NULL;
927 }
928
929 str2ba(address, &device->bdaddr);
930 device->adapter = adapter;
931 adapter_get_address(adapter, &src);
932 ba2str(&src, srcaddr);
933 read_device_name(srcaddr, address, device->name);
934
935 device->auth = 0xff;
936
937 return btd_device_ref(device);
938 }
939
device_set_name(struct btd_device * device,const char * name)940 void device_set_name(struct btd_device *device, const char *name)
941 {
942 DBusConnection *conn = get_dbus_connection();
943 char alias[MAX_NAME_LENGTH + 1];
944 char srcaddr[18], dstaddr[18];
945 bdaddr_t src;
946
947 if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
948 return;
949
950 strncpy(device->name, name, MAX_NAME_LENGTH);
951
952 emit_property_changed(conn, device->path,
953 DEVICE_INTERFACE, "Name",
954 DBUS_TYPE_STRING, &name);
955
956 adapter_get_address(device->adapter, &src);
957 ba2str(&src, srcaddr);
958 ba2str(&device->bdaddr, dstaddr);
959
960 if (read_device_alias(srcaddr, dstaddr, alias, sizeof(alias)) == 0)
961 return;
962
963 emit_property_changed(conn, device->path,
964 DEVICE_INTERFACE, "Alias",
965 DBUS_TYPE_STRING, &name);
966 }
967
device_remove_bonding(struct btd_device * device,DBusConnection * conn)968 static void device_remove_bonding(struct btd_device *device,
969 DBusConnection *conn)
970 {
971 char filename[PATH_MAX + 1];
972 char *str, srcaddr[18], dstaddr[18];
973 int dd, dev_id;
974 bdaddr_t bdaddr;
975 gboolean paired;
976
977 adapter_get_address(device->adapter, &bdaddr);
978 ba2str(&bdaddr, srcaddr);
979 ba2str(&device->bdaddr, dstaddr);
980
981 create_name(filename, PATH_MAX, STORAGEDIR, srcaddr,
982 "linkkeys");
983
984 /* textfile_del doesn't return an error when the key is not found */
985 str = textfile_caseget(filename, dstaddr);
986 paired = str ? TRUE : FALSE;
987 g_free(str);
988
989 if (!paired)
990 return;
991
992 dev_id = adapter_get_dev_id(device->adapter);
993
994 dd = hci_open_dev(dev_id);
995 if (dd < 0)
996 return;
997
998 /* Delete the link key from storage */
999 textfile_casedel(filename, dstaddr);
1000
1001 /* Delete the link key from the Bluetooth chip */
1002 hci_delete_stored_link_key(dd, &device->bdaddr, 0, HCI_REQ_TIMEOUT);
1003
1004 hci_close_dev(dd);
1005
1006 paired = FALSE;
1007 emit_property_changed(conn, device->path, DEVICE_INTERFACE,
1008 "Paired", DBUS_TYPE_BOOLEAN, &paired);
1009 }
1010
device_remove_stored(struct btd_device * device,DBusConnection * conn)1011 static void device_remove_stored(struct btd_device *device,
1012 DBusConnection *conn)
1013 {
1014 bdaddr_t src;
1015 char addr[18];
1016
1017 adapter_get_address(device->adapter, &src);
1018 ba2str(&device->bdaddr, addr);
1019
1020 device_remove_bonding(device, conn);
1021 delete_entry(&src, "profiles", addr);
1022 delete_entry(&src, "trusts", addr);
1023 delete_all_records(&src, &device->bdaddr);
1024 }
1025
device_remove(struct btd_device * device,DBusConnection * conn,gboolean remove_stored)1026 void device_remove(struct btd_device *device, DBusConnection *conn,
1027 gboolean remove_stored)
1028 {
1029 GSList *list;
1030 struct btd_device_driver *driver;
1031
1032 debug("Removing device %s", device->path);
1033
1034 if (device->bonding)
1035 device_cancel_bonding(device, HCI_OE_USER_ENDED_CONNECTION);
1036
1037 if (device->browse)
1038 browse_request_cancel(device->browse);
1039
1040 if (device->handle)
1041 do_disconnect(device);
1042
1043 if (remove_stored)
1044 device_remove_stored(device, conn);
1045
1046 for (list = device->drivers; list; list = list->next) {
1047 struct btd_driver_data *driver_data = list->data;
1048 driver = driver_data->driver;
1049
1050 driver->remove(device);
1051 g_free(driver_data);
1052 }
1053
1054 btd_device_unref(device);
1055 }
1056
device_address_cmp(struct btd_device * device,const gchar * address)1057 gint device_address_cmp(struct btd_device *device, const gchar *address)
1058 {
1059 char addr[18];
1060
1061 ba2str(&device->bdaddr, addr);
1062 return strcasecmp(addr, address);
1063 }
1064
record_has_uuid(const sdp_record_t * rec,const char * profile_uuid)1065 static gboolean record_has_uuid(const sdp_record_t *rec,
1066 const char *profile_uuid)
1067 {
1068 sdp_list_t *pat;
1069
1070 for (pat = rec->pattern; pat != NULL; pat = pat->next) {
1071 char *uuid;
1072 int ret;
1073
1074 uuid = bt_uuid2string(pat->data);
1075 if (!uuid)
1076 continue;
1077
1078 ret = strcasecmp(uuid, profile_uuid);
1079
1080 g_free(uuid);
1081
1082 if (ret == 0)
1083 return TRUE;
1084 }
1085
1086 return FALSE;
1087 }
1088
device_match_pattern(struct btd_device * device,const char * match_uuid,GSList * profiles)1089 static GSList *device_match_pattern(struct btd_device *device,
1090 const char *match_uuid,
1091 GSList *profiles)
1092 {
1093 GSList *l, *uuids = NULL;
1094
1095 for (l = profiles; l; l = l->next) {
1096 char *profile_uuid = l->data;
1097 const sdp_record_t *rec;
1098
1099 rec = btd_device_get_record(device, profile_uuid);
1100 if (!rec)
1101 continue;
1102
1103 if (record_has_uuid(rec, match_uuid))
1104 uuids = g_slist_append(uuids, profile_uuid);
1105 }
1106
1107 return uuids;
1108 }
1109
device_match_driver(struct btd_device * device,struct btd_device_driver * driver,GSList * profiles)1110 static GSList *device_match_driver(struct btd_device *device,
1111 struct btd_device_driver *driver,
1112 GSList *profiles)
1113 {
1114 const char **uuid;
1115 GSList *uuids = NULL;
1116
1117 for (uuid = driver->uuids; *uuid; uuid++) {
1118 GSList *match;
1119
1120 /* skip duplicated uuids */
1121 if (g_slist_find_custom(uuids, *uuid,
1122 (GCompareFunc) strcasecmp))
1123 continue;
1124
1125 /* match profile driver */
1126 match = g_slist_find_custom(profiles, *uuid,
1127 (GCompareFunc) strcasecmp);
1128 if (match) {
1129 uuids = g_slist_append(uuids, match->data);
1130 continue;
1131 }
1132
1133 /* match pattern driver */
1134 match = device_match_pattern(device, *uuid, profiles);
1135 for (; match; match = match->next)
1136 uuids = g_slist_append(uuids, match->data);
1137 }
1138
1139 return uuids;
1140 }
1141
device_probe_drivers(struct btd_device * device,GSList * profiles)1142 void device_probe_drivers(struct btd_device *device, GSList *profiles)
1143 {
1144 GSList *list;
1145 int err;
1146
1147 debug("Probe drivers for %s", device->path);
1148
1149 for (list = device_drivers; list; list = list->next) {
1150 struct btd_device_driver *driver = list->data;
1151 GSList *probe_uuids;
1152 struct btd_driver_data *driver_data;
1153
1154 probe_uuids = device_match_driver(device, driver, profiles);
1155
1156 if (!probe_uuids)
1157 continue;
1158
1159 driver_data = g_new0(struct btd_driver_data, 1);
1160
1161 err = driver->probe(device, probe_uuids);
1162 if (err < 0) {
1163 error("probe failed with driver %s for device %s",
1164 driver->name, device->path);
1165
1166 g_free(driver_data);
1167 g_slist_free(probe_uuids);
1168 continue;
1169 }
1170
1171 driver_data->driver = driver;
1172 device->drivers = g_slist_append(device->drivers, driver_data);
1173 g_slist_free(probe_uuids);
1174 }
1175
1176 for (list = profiles; list; list = list->next) {
1177 GSList *l = g_slist_find_custom(device->uuids, list->data,
1178 (GCompareFunc) strcasecmp);
1179 if (l)
1180 continue;
1181
1182 device->uuids = g_slist_insert_sorted(device->uuids,
1183 g_strdup(list->data),
1184 (GCompareFunc) strcasecmp);
1185 }
1186
1187 if (device->tmp_records) {
1188 sdp_list_free(device->tmp_records,
1189 (sdp_free_func_t) sdp_record_free);
1190 device->tmp_records = NULL;
1191 }
1192 }
1193
device_remove_drivers(struct btd_device * device,GSList * uuids)1194 static void device_remove_drivers(struct btd_device *device, GSList *uuids)
1195 {
1196 struct btd_adapter *adapter = device_get_adapter(device);
1197 GSList *list, *next;
1198 char srcaddr[18], dstaddr[18];
1199 bdaddr_t src;
1200 sdp_list_t *records;
1201
1202 adapter_get_address(adapter, &src);
1203 ba2str(&src, srcaddr);
1204 ba2str(&device->bdaddr, dstaddr);
1205
1206 records = read_records(&src, &device->bdaddr);
1207
1208 debug("Remove drivers for %s", device->path);
1209
1210 for (list = device->drivers; list; list = next) {
1211 struct btd_driver_data *driver_data = list->data;
1212 struct btd_device_driver *driver = driver_data->driver;
1213 const char **uuid;
1214
1215 next = list->next;
1216
1217 for (uuid = driver->uuids; *uuid; uuid++) {
1218 if (!g_slist_find_custom(uuids, *uuid,
1219 (GCompareFunc) strcasecmp))
1220 continue;
1221
1222 debug("UUID %s was removed from device %s",
1223 *uuid, dstaddr);
1224
1225 driver->remove(device);
1226 device->drivers = g_slist_remove(device->drivers,
1227 driver_data);
1228 g_free(driver_data);
1229
1230 break;
1231 }
1232 }
1233
1234 for (list = uuids; list; list = list->next) {
1235 sdp_record_t *rec;
1236
1237 device->uuids = g_slist_remove(device->uuids, list->data);
1238
1239 rec = find_record_in_list(records, list->data);
1240 if (!rec)
1241 continue;
1242
1243 delete_record(srcaddr, dstaddr, rec->handle);
1244
1245 records = sdp_list_remove(records, rec);
1246 sdp_record_free(rec);
1247
1248 }
1249
1250 if (records)
1251 sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
1252 }
1253
services_changed(struct btd_device * device)1254 static void services_changed(struct btd_device *device)
1255 {
1256 DBusConnection *conn = get_dbus_connection();
1257 char **uuids;
1258 GSList *l;
1259 int i;
1260
1261 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
1262 for (i = 0, l = device->uuids; l; l = l->next, i++)
1263 uuids[i] = l->data;
1264
1265 emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
1266 "UUIDs", DBUS_TYPE_STRING, &uuids);
1267
1268 g_free(uuids);
1269 }
1270
rec_cmp(const void * a,const void * b)1271 static int rec_cmp(const void *a, const void *b)
1272 {
1273 const sdp_record_t *r1 = a;
1274 const sdp_record_t *r2 = b;
1275
1276 return r1->handle - r2->handle;
1277 }
1278
update_services(struct browse_req * req,sdp_list_t * recs)1279 static void update_services(struct browse_req *req, sdp_list_t *recs)
1280 {
1281 struct btd_device *device = req->device;
1282 struct btd_adapter *adapter = device_get_adapter(device);
1283 sdp_list_t *seq;
1284 char srcaddr[18], dstaddr[18];
1285 bdaddr_t src;
1286
1287 adapter_get_address(adapter, &src);
1288 ba2str(&src, srcaddr);
1289 ba2str(&device->bdaddr, dstaddr);
1290
1291 for (seq = recs; seq; seq = seq->next) {
1292 sdp_record_t *rec = (sdp_record_t *) seq->data;
1293 sdp_list_t *svcclass = NULL;
1294 gchar *profile_uuid;
1295 GSList *l;
1296
1297 if (!rec)
1298 break;
1299
1300 if (sdp_get_service_classes(rec, &svcclass) < 0)
1301 continue;
1302
1303 /* Extract the first element and skip the remainning */
1304 profile_uuid = bt_uuid2string(svcclass->data);
1305 if (!profile_uuid) {
1306 sdp_list_free(svcclass, free);
1307 continue;
1308 }
1309
1310 if (!strcasecmp(profile_uuid, PNP_UUID)) {
1311 uint16_t source, vendor, product, version;
1312 sdp_data_t *pdlist;
1313
1314 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
1315 source = pdlist ? pdlist->val.uint16 : 0x0000;
1316
1317 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
1318 vendor = pdlist ? pdlist->val.uint16 : 0x0000;
1319
1320 pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
1321 product = pdlist ? pdlist->val.uint16 : 0x0000;
1322
1323 pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
1324 version = pdlist ? pdlist->val.uint16 : 0x0000;
1325
1326 if (source || vendor || product || version)
1327 store_device_id(srcaddr, dstaddr, source,
1328 vendor, product, version);
1329 }
1330
1331 /* Check for duplicates */
1332 if (sdp_list_find(req->records, rec, rec_cmp)) {
1333 g_free(profile_uuid);
1334 sdp_list_free(svcclass, free);
1335 continue;
1336 }
1337
1338 store_record(srcaddr, dstaddr, rec);
1339
1340 /* Copy record */
1341 req->records = sdp_list_append(req->records,
1342 sdp_copy_record(rec));
1343
1344 l = g_slist_find_custom(device->uuids, profile_uuid,
1345 (GCompareFunc) strcmp);
1346 if (!l)
1347 req->profiles_added =
1348 g_slist_append(req->profiles_added,
1349 profile_uuid);
1350 else {
1351 req->profiles_removed =
1352 g_slist_remove(req->profiles_removed,
1353 l->data);
1354 g_free(profile_uuid);
1355 }
1356
1357 sdp_list_free(svcclass, free);
1358 }
1359 }
1360
store_profiles(struct btd_device * device)1361 static void store_profiles(struct btd_device *device)
1362 {
1363 struct btd_adapter *adapter = device->adapter;
1364 bdaddr_t src;
1365 char *str;
1366
1367 adapter_get_address(adapter, &src);
1368
1369 if (!device->uuids) {
1370 write_device_profiles(&src, &device->bdaddr, "");
1371 return;
1372 }
1373
1374 str = bt_list2string(device->uuids);
1375 write_device_profiles(&src, &device->bdaddr, str);
1376 g_free(str);
1377 }
1378
search_cb(sdp_list_t * recs,int err,gpointer user_data)1379 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
1380 {
1381 struct browse_req *req = user_data;
1382 struct btd_device *device = req->device;
1383 DBusMessage *reply;
1384
1385 if (err < 0) {
1386 error("%s: error updating services: %s (%d)",
1387 device->path, strerror(-err), -err);
1388 goto proceed;
1389 }
1390
1391 update_services(req, recs);
1392
1393 if (device->tmp_records && req->records) {
1394 sdp_list_free(device->tmp_records,
1395 (sdp_free_func_t) sdp_record_free);
1396 device->tmp_records = req->records;
1397 req->records = NULL;
1398 }
1399
1400 if (!req->profiles_added && !req->profiles_removed) {
1401 debug("%s: No service update", device->path);
1402 goto proceed;
1403 }
1404
1405 /* Probe matching drivers for services added */
1406 if (req->profiles_added)
1407 device_probe_drivers(device, req->profiles_added);
1408
1409 /* Remove drivers for services removed */
1410 if (req->profiles_removed)
1411 device_remove_drivers(device, req->profiles_removed);
1412
1413 /* Propagate services changes */
1414 services_changed(req->device);
1415
1416 proceed:
1417 /* Store the device's profiles in the filesystem */
1418 store_profiles(device);
1419
1420 if (!req->msg)
1421 goto cleanup;
1422
1423 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
1424 "DiscoverServices")) {
1425 discover_services_reply(req, err, req->records);
1426 goto cleanup;
1427 }
1428
1429 /* Reply create device request */
1430 reply = dbus_message_new_method_return(req->msg);
1431 if (!reply)
1432 goto cleanup;
1433
1434 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
1435 DBUS_TYPE_INVALID);
1436
1437 g_dbus_send_message(req->conn, reply);
1438
1439 device_set_temporary(device, FALSE);
1440
1441 cleanup:
1442 browse_request_free(req);
1443 device->browse = NULL;
1444 }
1445
browse_cb(sdp_list_t * recs,int err,gpointer user_data)1446 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
1447 {
1448 struct browse_req *req = user_data;
1449 struct btd_device *device = req->device;
1450 struct btd_adapter *adapter = device->adapter;
1451 bdaddr_t src;
1452 uuid_t uuid;
1453
1454 /* If we have a valid response and req->search_uuid == 2, then L2CAP
1455 * UUID & PNP searching was successful -- we are done */
1456 if (err < 0 || (req->search_uuid == 2 && req->records)) {
1457 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
1458 req->search_uuid--;
1459 req->reconnect_attempt++;
1460 } else
1461 goto done;
1462 }
1463
1464 update_services(req, recs);
1465
1466 adapter_get_address(adapter, &src);
1467
1468 /* Search for mandatory uuids */
1469 if (uuid_list[req->search_uuid]) {
1470 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1471 bt_search_service(&src, &device->bdaddr, &uuid,
1472 browse_cb, user_data, NULL);
1473 return;
1474 }
1475
1476 done:
1477 search_cb(recs, err, user_data);
1478 }
1479
init_browse(struct browse_req * req,gboolean reverse)1480 static void init_browse(struct browse_req *req, gboolean reverse)
1481 {
1482 GSList *l;
1483
1484 /* If we are doing reverse-SDP don't try to detect removed profiles
1485 * since some devices hide their service records while they are
1486 * connected
1487 */
1488 if (reverse)
1489 return;
1490
1491 for (l = req->device->uuids; l; l = l->next)
1492 req->profiles_removed = g_slist_append(req->profiles_removed,
1493 l->data);
1494 }
1495
device_browse(struct btd_device * device,DBusConnection * conn,DBusMessage * msg,uuid_t * search,gboolean reverse)1496 int device_browse(struct btd_device *device, DBusConnection *conn,
1497 DBusMessage *msg, uuid_t *search, gboolean reverse)
1498 {
1499 struct btd_adapter *adapter = device->adapter;
1500 struct browse_req *req;
1501 bdaddr_t src;
1502 uuid_t uuid;
1503 bt_callback_t cb;
1504 int err;
1505
1506 if (device->browse)
1507 return -EBUSY;
1508
1509 adapter_get_address(adapter, &src);
1510
1511 req = g_new0(struct browse_req, 1);
1512
1513 if (conn == NULL)
1514 conn = get_dbus_connection();
1515
1516 req->conn = dbus_connection_ref(conn);
1517 req->device = device;
1518
1519 if (search) {
1520 memcpy(&uuid, search, sizeof(uuid_t));
1521 cb = search_cb;
1522 } else {
1523 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1524 init_browse(req, reverse);
1525 cb = browse_cb;
1526 }
1527
1528 device->browse = req;
1529
1530 if (msg) {
1531 const char *sender = dbus_message_get_sender(msg);
1532
1533 req->msg = dbus_message_ref(msg);
1534 /* Track the request owner to cancel it
1535 * automatically if the owner exits */
1536 req->listener_id = g_dbus_add_disconnect_watch(conn,
1537 sender,
1538 discover_services_req_exit,
1539 req, NULL);
1540 }
1541
1542 err = bt_search_service(&src, &device->bdaddr,
1543 &uuid, cb, req, NULL);
1544 if (err < 0) {
1545 browse_request_free(req);
1546 device->browse = NULL;
1547 }
1548
1549 return err;
1550 }
1551
device_get_adapter(struct btd_device * device)1552 struct btd_adapter *device_get_adapter(struct btd_device *device)
1553 {
1554 if (!device)
1555 return NULL;
1556
1557 return device->adapter;
1558 }
1559
device_get_address(struct btd_device * device,bdaddr_t * bdaddr)1560 void device_get_address(struct btd_device *device, bdaddr_t *bdaddr)
1561 {
1562 bacpy(bdaddr, &device->bdaddr);
1563 }
1564
device_get_path(struct btd_device * device)1565 const gchar *device_get_path(struct btd_device *device)
1566 {
1567 if (!device)
1568 return NULL;
1569
1570 return device->path;
1571 }
1572
device_get_agent(struct btd_device * device)1573 struct agent *device_get_agent(struct btd_device *device)
1574 {
1575 if (!device)
1576 return NULL;
1577
1578 return device->agent;
1579 }
1580
device_set_agent(struct btd_device * device,struct agent * agent)1581 void device_set_agent(struct btd_device *device, struct agent *agent)
1582 {
1583 if (!device)
1584 return;
1585
1586 device->agent = agent;
1587 }
1588
device_is_busy(struct btd_device * device)1589 gboolean device_is_busy(struct btd_device *device)
1590 {
1591 return device->browse ? TRUE : FALSE;
1592 }
1593
device_is_temporary(struct btd_device * device)1594 gboolean device_is_temporary(struct btd_device *device)
1595 {
1596 return device->temporary;
1597 }
1598
device_set_temporary(struct btd_device * device,gboolean temporary)1599 void device_set_temporary(struct btd_device *device, gboolean temporary)
1600 {
1601 if (!device)
1602 return;
1603
1604 device->temporary = temporary;
1605 }
1606
device_set_cap(struct btd_device * device,uint8_t cap)1607 void device_set_cap(struct btd_device *device, uint8_t cap)
1608 {
1609 if (!device)
1610 return;
1611
1612 device->cap = cap;
1613 }
1614
device_get_cap(struct btd_device * device)1615 uint8_t device_get_cap(struct btd_device *device)
1616 {
1617 return device->cap;
1618 }
1619
device_set_auth(struct btd_device * device,uint8_t auth)1620 void device_set_auth(struct btd_device *device, uint8_t auth)
1621 {
1622 if (!device)
1623 return;
1624
1625 device->auth = auth;
1626 }
1627
device_get_auth(struct btd_device * device)1628 uint8_t device_get_auth(struct btd_device *device)
1629 {
1630 return device->auth;
1631 }
1632
start_discovery(gpointer user_data)1633 static gboolean start_discovery(gpointer user_data)
1634 {
1635 struct btd_device *device = user_data;
1636
1637 device_browse(device, NULL, NULL, NULL, TRUE);
1638
1639 device->discov_timer = 0;
1640
1641 return FALSE;
1642 }
1643
new_authentication_return(DBusMessage * msg,uint8_t status)1644 DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
1645 {
1646 switch (status) {
1647 case 0x00: /* success */
1648 return dbus_message_new_method_return(msg);
1649
1650 case 0x04: /* page timeout */
1651 return dbus_message_new_error(msg,
1652 ERROR_INTERFACE ".ConnectionAttemptFailed",
1653 "Page Timeout");
1654 case 0x08: /* connection timeout */
1655 return dbus_message_new_error(msg,
1656 ERROR_INTERFACE ".ConnectionAttemptFailed",
1657 "Connection Timeout");
1658 case 0x10: /* connection accept timeout */
1659 case 0x22: /* LMP response timeout */
1660 case 0x28: /* instant passed - is this a timeout? */
1661 return dbus_message_new_error(msg,
1662 ERROR_INTERFACE ".AuthenticationTimeout",
1663 "Authentication Timeout");
1664 case 0x17: /* too frequent pairing attempts */
1665 return dbus_message_new_error(msg,
1666 ERROR_INTERFACE ".RepeatedAttempts",
1667 "Repeated Attempts");
1668
1669 case 0x06:
1670 case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */
1671 return dbus_message_new_error(msg,
1672 ERROR_INTERFACE ".AuthenticationRejected",
1673 "Authentication Rejected");
1674
1675 case 0x07: /* memory capacity */
1676 case 0x09: /* connection limit */
1677 case 0x0a: /* synchronous connection limit */
1678 case 0x0d: /* limited resources */
1679 case 0x13: /* user ended the connection */
1680 case 0x14: /* terminated due to low resources */
1681 case 0x16: /* connection terminated */
1682 return dbus_message_new_error(msg,
1683 ERROR_INTERFACE ".AuthenticationCanceled",
1684 "Authentication Canceled");
1685
1686 case 0x05: /* authentication failure */
1687 case 0x0E: /* rejected due to security reasons - is this auth failure? */
1688 case 0x25: /* encryption mode not acceptable - is this auth failure? */
1689 case 0x26: /* link key cannot be changed - is this auth failure? */
1690 case 0x29: /* pairing with unit key unsupported - is this auth failure? */
1691 case 0x2f: /* insufficient security - is this auth failure? */
1692 default:
1693 return dbus_message_new_error(msg,
1694 ERROR_INTERFACE ".AuthenticationFailed",
1695 "Authentication Failed");
1696 }
1697 }
1698
bonding_request_free(struct bonding_req * bonding)1699 static void bonding_request_free(struct bonding_req *bonding)
1700 {
1701 struct btd_device *device;
1702
1703 if (!bonding)
1704 return;
1705
1706 if (bonding->listener_id)
1707 g_dbus_remove_watch(bonding->conn, bonding->listener_id);
1708
1709 if (bonding->msg)
1710 dbus_message_unref(bonding->msg);
1711
1712 if (bonding->conn)
1713 dbus_connection_unref(bonding->conn);
1714
1715 if (bonding->io_id)
1716 g_source_remove(bonding->io_id);
1717
1718 if (bonding->io)
1719 g_io_channel_unref(bonding->io);
1720
1721 device = bonding->device;
1722 g_free(bonding);
1723
1724 if (!device)
1725 return;
1726
1727 device->bonding = NULL;
1728
1729 if (!device->agent)
1730 return;
1731
1732 agent_destroy(device->agent, FALSE);
1733 device->agent = NULL;
1734 }
1735
device_set_paired(struct btd_device * device,gboolean value)1736 static void device_set_paired(struct btd_device *device, gboolean value)
1737 {
1738 DBusConnection *conn = get_dbus_connection();
1739
1740 emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired",
1741 DBUS_TYPE_BOOLEAN, &value);
1742 }
1743
device_agent_removed(struct agent * agent,void * user_data)1744 static void device_agent_removed(struct agent *agent, void *user_data)
1745 {
1746 struct btd_device *device = user_data;
1747
1748 device_set_agent(device, NULL);
1749
1750 if (device->authr)
1751 device->authr->agent = NULL;
1752 }
1753
bonding_request_new(DBusConnection * conn,DBusMessage * msg,struct btd_device * device,const char * agent_path,uint8_t capability)1754 static struct bonding_req *bonding_request_new(DBusConnection *conn,
1755 DBusMessage *msg,
1756 struct btd_device *device,
1757 const char *agent_path,
1758 uint8_t capability)
1759 {
1760 struct bonding_req *bonding;
1761 const char *name = dbus_message_get_sender(msg);
1762 struct agent *agent;
1763
1764 debug("%s: requesting bonding", device->path);
1765
1766 if (!agent_path)
1767 goto proceed;
1768
1769 agent = agent_create(device->adapter, name, agent_path,
1770 capability,
1771 device_agent_removed,
1772 device);
1773 if (!agent) {
1774 error("Unable to create a new agent");
1775 return NULL;
1776 }
1777
1778 device->agent = agent;
1779
1780 debug("Temporary agent registered for %s at %s:%s",
1781 device->path, name, agent_path);
1782
1783 proceed:
1784 bonding = g_new0(struct bonding_req, 1);
1785
1786 bonding->conn = dbus_connection_ref(conn);
1787 bonding->msg = dbus_message_ref(msg);
1788
1789 return bonding;
1790 }
1791
bonding_io_cb(GIOChannel * io,GIOCondition cond,gpointer user_data)1792 static gboolean bonding_io_cb(GIOChannel *io, GIOCondition cond,
1793 gpointer user_data)
1794 {
1795 struct btd_device *device = user_data;
1796 DBusMessage *reply;
1797
1798 if (!device->bonding)
1799 return FALSE;
1800
1801 reply = new_authentication_return(device->bonding->msg,
1802 HCI_CONNECTION_TERMINATED);
1803 g_dbus_send_message(device->bonding->conn, reply);
1804
1805 bonding_request_free(device->bonding);
1806
1807 return FALSE;
1808 }
1809
bonding_connect_cb(GIOChannel * io,GError * err,gpointer user_data)1810 static void bonding_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
1811 {
1812 struct btd_device *device = user_data;
1813 struct hci_request rq;
1814 auth_requested_cp cp;
1815 evt_cmd_status rp;
1816 int dd;
1817 uint16_t handle;
1818
1819 if (!device->bonding) {
1820 if (!err)
1821 g_io_channel_shutdown(io, TRUE, NULL);
1822 return;
1823 }
1824
1825 if (err) {
1826 error("%s", err->message);
1827 error_connection_attempt_failed(device->bonding->conn,
1828 device->bonding->msg,
1829 ENETDOWN);
1830 goto cleanup;
1831 }
1832
1833 if (!bt_io_get(io, BT_IO_L2RAW, &err,
1834 BT_IO_OPT_HANDLE, &handle,
1835 BT_IO_OPT_INVALID)) {
1836 error("Unable to get connection handle: %s", err->message);
1837 error_connection_attempt_failed(device->bonding->conn,
1838 device->bonding->msg,
1839 ENETDOWN);
1840 g_error_free(err);
1841 goto failed;
1842 }
1843
1844 dd = hci_open_dev(adapter_get_dev_id(device->adapter));
1845 if (dd < 0) {
1846 DBusMessage *reply = no_such_adapter(device->bonding->msg);
1847 g_dbus_send_message(device->bonding->conn, reply);
1848 goto failed;
1849 }
1850
1851 memset(&rp, 0, sizeof(rp));
1852
1853 memset(&cp, 0, sizeof(cp));
1854 cp.handle = htobs(handle);
1855
1856 memset(&rq, 0, sizeof(rq));
1857 rq.ogf = OGF_LINK_CTL;
1858 rq.ocf = OCF_AUTH_REQUESTED;
1859 rq.cparam = &cp;
1860 rq.clen = AUTH_REQUESTED_CP_SIZE;
1861 rq.rparam = &rp;
1862 rq.rlen = EVT_CMD_STATUS_SIZE;
1863 rq.event = EVT_CMD_STATUS;
1864
1865 if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) {
1866 error("Unable to send HCI request: %s (%d)",
1867 strerror(errno), errno);
1868 error_failed_errno(device->bonding->conn, device->bonding->msg,
1869 errno);
1870 hci_close_dev(dd);
1871 goto failed;
1872 }
1873
1874 if (rp.status) {
1875 error("HCI_Authentication_Requested failed with status 0x%02x",
1876 rp.status);
1877 error_failed_errno(device->bonding->conn, device->bonding->msg,
1878 bt_error(rp.status));
1879 hci_close_dev(dd);
1880 goto failed;
1881 }
1882
1883 hci_close_dev(dd);
1884
1885 device->bonding->io_id = g_io_add_watch(io,
1886 G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1887 bonding_io_cb, device);
1888
1889 return;
1890
1891 failed:
1892 g_io_channel_shutdown(io, TRUE, NULL);
1893
1894 cleanup:
1895 device->bonding->io_id = 0;
1896 bonding_request_free(device->bonding);
1897 }
1898
create_bond_req_exit(DBusConnection * conn,void * user_data)1899 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
1900 {
1901 struct btd_device *device = user_data;
1902
1903 debug("%s: requestor exited before bonding was completed", device->path);
1904
1905 if (device->authr)
1906 device_cancel_authentication(device, FALSE);
1907
1908 if (device->bonding) {
1909 device->bonding->listener_id = 0;
1910 device_request_disconnect(device, NULL);
1911 }
1912 }
1913
device_create_bonding(struct btd_device * device,DBusConnection * conn,DBusMessage * msg,const char * agent_path,uint8_t capability)1914 DBusMessage *device_create_bonding(struct btd_device *device,
1915 DBusConnection *conn,
1916 DBusMessage *msg,
1917 const char *agent_path,
1918 uint8_t capability)
1919 {
1920 char filename[PATH_MAX + 1];
1921 char *str, srcaddr[18], dstaddr[18];
1922 struct btd_adapter *adapter = device->adapter;
1923 struct bonding_req *bonding;
1924 bdaddr_t src;
1925 GError *err = NULL;
1926 GIOChannel *io;
1927
1928 adapter_get_address(adapter, &src);
1929 ba2str(&src, srcaddr);
1930 ba2str(&device->bdaddr, dstaddr);
1931
1932 if (device->bonding)
1933 return in_progress(msg, "Bonding in progress");
1934
1935 /* check if a link key already exists */
1936 create_name(filename, PATH_MAX, STORAGEDIR, srcaddr,
1937 "linkkeys");
1938
1939 str = textfile_caseget(filename, dstaddr);
1940 if (str) {
1941 free(str);
1942 return g_dbus_create_error(msg,
1943 ERROR_INTERFACE ".AlreadyExists",
1944 "Bonding already exists");
1945 }
1946
1947
1948 io = bt_io_connect(BT_IO_L2RAW, bonding_connect_cb, device,
1949 NULL, &err,
1950 BT_IO_OPT_SOURCE_BDADDR, &src,
1951 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
1952 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
1953 BT_IO_OPT_INVALID);
1954 if (io == NULL) {
1955 DBusMessage *reply;
1956 reply = g_dbus_create_error(msg,
1957 ERROR_INTERFACE ".ConnectionAttemptFailed",
1958 err->message);
1959 error("bt_io_connect: %s", err->message);
1960 g_error_free(err);
1961 return reply;
1962 }
1963
1964 bonding = bonding_request_new(conn, msg, device, agent_path,
1965 capability);
1966 if (!bonding) {
1967 g_io_channel_shutdown(io, TRUE, NULL);
1968 return NULL;
1969 }
1970
1971 bonding->io = io;
1972
1973 bonding->listener_id = g_dbus_add_disconnect_watch(conn,
1974 dbus_message_get_sender(msg),
1975 create_bond_req_exit, device,
1976 NULL);
1977
1978 device->bonding = bonding;
1979 bonding->device = device;
1980
1981 return NULL;
1982 }
1983
device_simple_pairing_complete(struct btd_device * device,uint8_t status)1984 void device_simple_pairing_complete(struct btd_device *device, uint8_t status)
1985 {
1986 struct authentication_req *auth = device->authr;
1987
1988 if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent)
1989 agent_cancel(auth->agent);
1990 }
1991
device_bonding_complete(struct btd_device * device,uint8_t status)1992 void device_bonding_complete(struct btd_device *device, uint8_t status)
1993 {
1994 struct bonding_req *bonding = device->bonding;
1995 struct authentication_req *auth = device->authr;
1996
1997 if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent)
1998 agent_cancel(auth->agent);
1999
2000 if (status)
2001 goto failed;
2002
2003 device->auth = 0xff;
2004
2005 g_free(device->authr);
2006 device->authr = NULL;
2007
2008 if (device->renewed_key)
2009 return;
2010
2011 device_set_temporary(device, FALSE);
2012
2013 /* If we were initiators start service discovery immediately.
2014 * However if the other end was the initator wait a few seconds
2015 * before SDP. This is due to potential IOP issues if the other
2016 * end starts doing SDP at the same time as us */
2017 if (bonding) {
2018 /* If we are initiators remove any discovery timer and just
2019 * start discovering services directly */
2020 if (device->discov_timer) {
2021 g_source_remove(device->discov_timer);
2022 device->discov_timer = 0;
2023 }
2024
2025 device_browse(device, bonding->conn, bonding->msg,
2026 NULL, FALSE);
2027
2028 bonding_request_free(bonding);
2029 } else {
2030 if (!device->browse && !device->discov_timer &&
2031 main_opts.reverse_sdp) {
2032 /* If we are not initiators and there is no currently
2033 * active discovery or discovery timer, set discovery
2034 * timer */
2035 debug("setting timer for reverse service discovery");
2036 device->discov_timer = g_timeout_add_seconds(
2037 DISCOVERY_TIMER,
2038 start_discovery,
2039 device);
2040 }
2041 }
2042
2043 device_set_paired(device, TRUE);
2044
2045 return;
2046
2047 failed:
2048 device_cancel_bonding(device, status);
2049 }
2050
device_is_creating(struct btd_device * device,const char * sender)2051 gboolean device_is_creating(struct btd_device *device, const char *sender)
2052 {
2053 DBusMessage *msg;
2054
2055 if (device->bonding && device->bonding->msg)
2056 msg = device->bonding->msg;
2057 else if (device->browse && device->browse->msg)
2058 msg = device->browse->msg;
2059 else
2060 return FALSE;
2061
2062 if (!dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2063 "CreatePairedDevice") &&
2064 !dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2065 "CreateDevice"))
2066 return FALSE;
2067
2068 if (sender == NULL)
2069 return TRUE;
2070
2071 return g_str_equal(sender, dbus_message_get_sender(msg));
2072 }
2073
device_is_bonding(struct btd_device * device,const char * sender)2074 gboolean device_is_bonding(struct btd_device *device, const char *sender)
2075 {
2076 struct bonding_req *bonding = device->bonding;
2077
2078 if (!device->bonding)
2079 return FALSE;
2080
2081 if (!sender)
2082 return TRUE;
2083
2084 return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
2085 }
2086
device_cancel_bonding(struct btd_device * device,uint8_t status)2087 void device_cancel_bonding(struct btd_device *device, uint8_t status)
2088 {
2089 struct bonding_req *bonding = device->bonding;
2090 DBusMessage *reply;
2091
2092 if (!bonding)
2093 return;
2094
2095 debug("%s: canceling bonding request", device->path);
2096
2097 if (device->authr)
2098 device_cancel_authentication(device, FALSE);
2099
2100 reply = new_authentication_return(bonding->msg, status);
2101 g_dbus_send_message(bonding->conn, reply);
2102
2103 bonding_request_cancel(bonding);
2104 bonding_request_free(bonding);
2105 }
2106
pincode_cb(struct agent * agent,DBusError * err,const char * pincode,void * data)2107 static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode,
2108 void *data)
2109 {
2110 struct authentication_req *auth = data;
2111 struct btd_device *device = auth->device;
2112
2113 /* No need to reply anything if the authentication already failed */
2114 if (!auth->cb)
2115 return;
2116
2117 ((agent_pincode_cb) auth->cb)(agent, err, pincode, device);
2118
2119 auth->cb = NULL;
2120 }
2121
confirm_cb(struct agent * agent,DBusError * err,void * data)2122 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
2123 {
2124 struct authentication_req *auth = data;
2125 struct btd_device *device = auth->device;
2126
2127 /* No need to reply anything if the authentication already failed */
2128 if (!auth->cb)
2129 return;
2130
2131 ((agent_cb) auth->cb)(agent, err, device);
2132
2133 auth->cb = NULL;
2134 }
2135
passkey_cb(struct agent * agent,DBusError * err,uint32_t passkey,void * data)2136 static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
2137 void *data)
2138 {
2139 struct authentication_req *auth = data;
2140 struct btd_device *device = auth->device;
2141
2142 /* No need to reply anything if the authentication already failed */
2143 if (!auth->cb)
2144 return;
2145
2146 ((agent_passkey_cb) auth->cb)(agent, err, passkey, device);
2147
2148 auth->cb = NULL;
2149 }
2150
pairing_consent_cb(struct agent * agent,DBusError * err,void * data)2151 static void pairing_consent_cb(struct agent *agent, DBusError *err, void *data)
2152 {
2153 struct authentication_req *auth = data;
2154 struct btd_device *device = auth->device;
2155
2156 /* No need to reply anything if the authentication already failed */
2157 if (!auth->cb)
2158 return;
2159
2160 ((agent_cb) auth->cb)(agent, err, device);
2161
2162 auth->cb = NULL;
2163 }
2164
device_request_authentication(struct btd_device * device,auth_type_t type,uint32_t passkey,void * cb)2165 int device_request_authentication(struct btd_device *device, auth_type_t type,
2166 uint32_t passkey, void *cb)
2167 {
2168 struct authentication_req *auth;
2169 struct agent *agent;
2170 int ret;
2171
2172 debug("%s: requesting agent authentication", device->path);
2173
2174 agent = device->agent;
2175
2176 if (!agent)
2177 agent = adapter_get_agent(device->adapter);
2178
2179 if (!agent) {
2180 error("No agent available for %u request", type);
2181 return -EPERM;
2182 }
2183
2184 auth = g_new0(struct authentication_req, 1);
2185 auth->agent = agent;
2186 auth->device = device;
2187 auth->cb = cb;
2188 auth->type = type;
2189 device->authr = auth;
2190
2191 switch (type) {
2192 case AUTH_TYPE_PINCODE:
2193 ret = agent_request_pincode(agent, device, pincode_cb,
2194 auth, NULL);
2195 break;
2196 case AUTH_TYPE_PASSKEY:
2197 ret = agent_request_passkey(agent, device, passkey_cb,
2198 auth, NULL);
2199 break;
2200 case AUTH_TYPE_CONFIRM:
2201 ret = agent_request_confirmation(agent, device, passkey,
2202 confirm_cb, auth, NULL);
2203 break;
2204 case AUTH_TYPE_NOTIFY:
2205 ret = agent_display_passkey(agent, device, passkey);
2206 break;
2207 case AUTH_TYPE_AUTO:
2208 ret = 0;
2209 break;
2210 case AUTH_TYPE_PAIRING_CONSENT:
2211 ret = agent_request_pairing_consent(agent, device,
2212 pairing_consent_cb, auth, NULL);
2213 break;
2214 default:
2215 ret = -EINVAL;
2216 }
2217
2218 if (ret < 0) {
2219 error("Failed requesting authentication");
2220 g_free(auth);
2221 device->authr = NULL;
2222 }
2223
2224 return ret;
2225 }
2226
cancel_authentication(struct authentication_req * auth)2227 static void cancel_authentication(struct authentication_req *auth)
2228 {
2229 struct btd_device *device = auth->device;
2230 struct agent *agent = auth->agent;
2231 DBusError err;
2232
2233 if (!auth->cb)
2234 return;
2235
2236 dbus_error_init(&err);
2237 dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL);
2238
2239 switch (auth->type) {
2240 case AUTH_TYPE_PINCODE:
2241 ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
2242 break;
2243 case AUTH_TYPE_CONFIRM:
2244 ((agent_cb) auth->cb)(agent, &err, device);
2245 break;
2246 case AUTH_TYPE_PASSKEY:
2247 ((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
2248 break;
2249 case AUTH_TYPE_PAIRING_CONSENT:
2250 ((agent_cb) auth->cb) (agent, &err, device);
2251 break;
2252 case AUTH_TYPE_NOTIFY:
2253 case AUTH_TYPE_AUTO:
2254 /* User Notify/Auto doesn't require any reply */
2255 break;
2256 }
2257
2258 dbus_error_free(&err);
2259 auth->cb = NULL;
2260 }
2261
device_cancel_authentication(struct btd_device * device,gboolean aborted)2262 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
2263 {
2264 struct authentication_req *auth = device->authr;
2265
2266 if (!auth)
2267 return;
2268
2269 debug("%s: canceling authentication request", device->path);
2270
2271 if (auth->agent)
2272 agent_cancel(auth->agent);
2273
2274 if (!aborted)
2275 cancel_authentication(auth);
2276
2277 device->authr = NULL;
2278 g_free(auth);
2279 }
2280
device_is_authenticating(struct btd_device * device)2281 gboolean device_is_authenticating(struct btd_device *device)
2282 {
2283 return (device->authr != NULL);
2284 }
2285
device_is_authorizing(struct btd_device * device)2286 gboolean device_is_authorizing(struct btd_device *device)
2287 {
2288 return device->authorizing;
2289 }
2290
device_set_authorizing(struct btd_device * device,gboolean auth)2291 void device_set_authorizing(struct btd_device *device, gboolean auth)
2292 {
2293 device->authorizing = auth;
2294 }
2295
device_set_renewed_key(struct btd_device * device,gboolean renewed)2296 void device_set_renewed_key(struct btd_device *device, gboolean renewed)
2297 {
2298 device->renewed_key = renewed;
2299 }
2300
btd_device_add_uuid(struct btd_device * device,const char * uuid)2301 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
2302 {
2303 GSList *uuid_list;
2304 char *new_uuid;
2305
2306 if (g_slist_find_custom(device->uuids, uuid,
2307 (GCompareFunc) strcasecmp))
2308 return;
2309
2310 new_uuid = g_strdup(uuid);
2311 uuid_list = g_slist_append(NULL, new_uuid);
2312
2313 device_probe_drivers(device, uuid_list);
2314
2315 g_free(new_uuid);
2316 g_slist_free(uuid_list);
2317
2318 store_profiles(device);
2319 services_changed(device);
2320 }
2321
btd_device_get_record(struct btd_device * device,const char * uuid)2322 const sdp_record_t *btd_device_get_record(struct btd_device *device,
2323 const char *uuid)
2324 {
2325 bdaddr_t src;
2326
2327 if (device->tmp_records)
2328 return find_record_in_list(device->tmp_records, uuid);
2329
2330 adapter_get_address(device->adapter, &src);
2331
2332 device->tmp_records = read_records(&src, &device->bdaddr);
2333 if (!device->tmp_records)
2334 return NULL;
2335
2336 return find_record_in_list(device->tmp_records, uuid);
2337 }
2338
btd_register_device_driver(struct btd_device_driver * driver)2339 int btd_register_device_driver(struct btd_device_driver *driver)
2340 {
2341 device_drivers = g_slist_append(device_drivers, driver);
2342
2343 return 0;
2344 }
2345
btd_unregister_device_driver(struct btd_device_driver * driver)2346 void btd_unregister_device_driver(struct btd_device_driver *driver)
2347 {
2348 device_drivers = g_slist_remove(device_drivers, driver);
2349 }
2350
btd_device_ref(struct btd_device * device)2351 struct btd_device *btd_device_ref(struct btd_device *device)
2352 {
2353 device->ref++;
2354
2355 debug("btd_device_ref(%p): ref=%d", device, device->ref);
2356
2357 return device;
2358 }
2359
btd_device_unref(struct btd_device * device)2360 void btd_device_unref(struct btd_device *device)
2361 {
2362 DBusConnection *conn = get_dbus_connection();
2363 gchar *path;
2364
2365 device->ref--;
2366
2367 debug("btd_device_unref(%p): ref=%d", device, device->ref);
2368
2369 if (device->ref > 0)
2370 return;
2371
2372 path = g_strdup(device->path);
2373
2374 g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);
2375
2376 g_free(path);
2377 }
2378