3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2006-2010 Nokia Corporation
6
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
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.
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.
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
34
#include <sys/ioctl.h>
37
#include <bluetooth/bluetooth.h>
38
#include <bluetooth/uuid.h>
39
#include <bluetooth/sdp.h>
40
#include <bluetooth/sdp_lib.h>
43
#include <dbus/dbus.h>
54
#include "dbus-common.h"
56
#include "glib-helper.h"
57
#include "sdp-client.h"
63
#include "attrib-server.h"
64
#include "attrib/client.h"
66
#define DISCONNECT_TIMER 2
67
#define DISCOVERY_TIMER 2
69
#define AUTO_CONNECTION_INTERVAL 5 /* Next connection attempt */
71
/* When all services should trust a remote device */
72
#define GLOBAL_TRUST "[all]"
74
#define APPEARANCE_CHR_UUID 0x2a01
76
struct btd_disconnect_data {
78
disconnect_watch watch;
80
GDestroyNotify destroy;
87
struct btd_device *device;
90
struct authentication_req {
94
struct btd_device *device;
101
DBusConnection *conn;
103
struct btd_device *device;
105
GSList *profiles_added;
106
GSList *profiles_removed;
109
int reconnect_attempt;
115
attio_connect_cb cfunc;
116
attio_disconnect_cb dcfunc;
120
typedef void (*attio_error_cb) (const GError *gerr, gpointer user_data);
121
typedef void (*attio_success_cb) (gpointer user_data);
123
struct att_callbacks {
124
attio_error_cb error; /* Callback for error */
125
attio_success_cb success; /* Callback for success */
133
char name[MAX_NAME_LENGTH + 1];
139
struct btd_adapter *adapter;
141
GSList *services; /* Primary services path */
142
GSList *primaries; /* List of primary services */
143
GSList *drivers; /* List of device drivers */
144
GSList *watches; /* List of disconnect_data */
149
struct browse_req *browse; /* service discover request */
150
struct bonding_req *bonding;
151
struct authentication_req *authr; /* authentication request */
152
GSList *disconnects; /* disconnects message */
155
GSList *attios_offline;
156
guint attachid; /* Attrib server attach */
157
guint auto_id; /* Auto connect source id */
161
sdp_list_t *tmp_records;
167
gboolean auto_connect;
169
gboolean authorizing;
176
static uint16_t uuid_list[] = {
183
static GSList *device_drivers = NULL;
185
static void browse_request_free(struct browse_req *req)
187
if (req->listener_id)
188
g_dbus_remove_watch(req->conn, req->listener_id);
190
dbus_message_unref(req->msg);
192
dbus_connection_unref(req->conn);
194
btd_device_unref(req->device);
195
g_slist_free_full(req->profiles_added, g_free);
196
g_slist_free(req->profiles_removed);
198
sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
203
static void att_cleanup(struct btd_device *device)
205
if (device->attachid) {
206
attrib_channel_detach(device->attrib, device->attachid);
207
device->attachid = 0;
210
if (device->cleanup_id) {
211
g_source_remove(device->cleanup_id);
212
device->cleanup_id = 0;
215
if (device->att_io) {
216
g_io_channel_shutdown(device->att_io, FALSE, NULL);
217
g_io_channel_unref(device->att_io);
218
device->att_io = NULL;
221
if (device->attrib) {
222
g_attrib_unref(device->attrib);
223
device->attrib = NULL;
227
static void browse_request_cancel(struct browse_req *req)
229
struct btd_device *device = req->device;
230
struct btd_adapter *adapter = device->adapter;
233
if (device_is_creating(device, NULL))
234
device_set_temporary(device, TRUE);
236
adapter_get_address(adapter, &src);
238
bt_cancel_discovery(&src, &device->bdaddr);
242
device->browse = NULL;
243
browse_request_free(req);
246
static void device_free(gpointer user_data)
248
struct btd_device *device = user_data;
249
struct btd_adapter *adapter = device->adapter;
250
struct agent *agent = adapter_get_agent(adapter);
253
agent_free(device->agent);
255
if (agent && (agent_is_busy(agent, device) ||
256
agent_is_busy(agent, device->authr)))
259
g_slist_free_full(device->services, g_free);
260
g_slist_free_full(device->uuids, g_free);
261
g_slist_free_full(device->primaries, g_free);
262
g_slist_free_full(device->attios, g_free);
263
g_slist_free_full(device->attios_offline, g_free);
267
if (device->tmp_records)
268
sdp_list_free(device->tmp_records,
269
(sdp_free_func_t) sdp_record_free);
271
if (device->disconn_timer)
272
g_source_remove(device->disconn_timer);
274
if (device->discov_timer)
275
g_source_remove(device->discov_timer);
278
g_source_remove(device->auto_id);
283
g_free(device->authr->pincode);
284
g_free(device->authr);
285
g_free(device->path);
286
g_free(device->alias);
290
gboolean device_is_bredr(struct btd_device *device)
292
return (device->bdaddr_type == BDADDR_BREDR);
295
gboolean device_is_le(struct btd_device *device)
297
return (device->bdaddr_type != BDADDR_BREDR);
300
gboolean device_is_paired(struct btd_device *device)
302
return device->paired;
305
gboolean device_is_bonded(struct btd_device *device)
307
return device->bonded;
310
gboolean device_is_trusted(struct btd_device *device)
312
return device->trusted;
315
static DBusMessage *get_properties(DBusConnection *conn,
316
DBusMessage *msg, void *user_data)
318
struct btd_device *device = user_data;
319
struct btd_adapter *adapter = device->adapter;
321
DBusMessageIter iter;
322
DBusMessageIter dict;
324
char name[MAX_NAME_LENGTH + 1], srcaddr[18], dstaddr[18];
326
const char *ptr, *icon = NULL;
333
ba2str(&device->bdaddr, dstaddr);
335
reply = dbus_message_new_method_return(msg);
339
dbus_message_iter_init_append(reply, &iter);
341
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
342
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
343
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
344
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
348
dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr);
352
memset(name, 0, sizeof(name));
353
adapter_get_address(adapter, &src);
354
ba2str(&src, srcaddr);
357
dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr);
359
/* Alias (fallback to name or address) */
360
if (device->alias != NULL)
362
else if (strlen(ptr) == 0) {
363
g_strdelimit(dstaddr, ":", '-');
367
dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr);
370
if (read_remote_class(&src, &device->bdaddr, &class) == 0) {
371
icon = class_to_icon(class);
373
dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class);
374
} else if (read_remote_appearance(&src, &device->bdaddr,
375
device->bdaddr_type, &app) == 0)
377
icon = gap_appearance_to_icon(app);
379
dict_append_entry(&dict, "Icon", DBUS_TYPE_STRING, &icon);
383
dict_append_entry(&dict, "Vendor", DBUS_TYPE_UINT16,
387
if (device->vendor_src)
388
dict_append_entry(&dict, "VendorSource", DBUS_TYPE_UINT16,
389
&device->vendor_src);
393
dict_append_entry(&dict, "Product", DBUS_TYPE_UINT16,
398
dict_append_entry(&dict, "Version", DBUS_TYPE_UINT16,
402
boolean = device_is_paired(device);
403
dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean);
406
boolean = device_is_trusted(device);
407
dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);
410
boolean = device->blocked;
411
dict_append_entry(&dict, "Blocked", DBUS_TYPE_BOOLEAN, &boolean);
414
dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,
418
str = g_new0(char *, g_slist_length(device->uuids) + 1);
419
for (i = 0, l = device->uuids; l; l = l->next, i++)
421
dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &str, i);
425
str = g_new0(char *, g_slist_length(device->services) + 1);
426
for (i = 0, l = device->services; l; l = l->next, i++)
428
dict_append_array(&dict, "Services", DBUS_TYPE_OBJECT_PATH, &str, i);
432
ptr = adapter_get_path(adapter);
433
dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
435
dbus_message_iter_close_container(&iter, &dict);
440
static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
441
const char *alias, void *data)
443
struct btd_device *device = data;
444
struct btd_adapter *adapter = device->adapter;
445
char srcaddr[18], dstaddr[18];
450
if ((device->alias == NULL && g_str_equal(alias, "")) ||
451
g_strcmp0(device->alias, alias) == 0)
452
return dbus_message_new_method_return(msg);
454
adapter_get_address(adapter, &src);
455
ba2str(&src, srcaddr);
456
ba2str(&device->bdaddr, dstaddr);
458
/* Remove alias if empty string */
459
err = write_device_alias(srcaddr, dstaddr,
460
g_str_equal(alias, "") ? NULL : alias);
462
return btd_error_failed(msg, strerror(-err));
464
g_free(device->alias);
465
device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
467
emit_property_changed(conn, dbus_message_get_path(msg),
468
DEVICE_INTERFACE, "Alias",
469
DBUS_TYPE_STRING, &alias);
471
return dbus_message_new_method_return(msg);
474
static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
475
gboolean value, void *data)
477
struct btd_device *device = data;
478
struct btd_adapter *adapter = device->adapter;
479
char srcaddr[18], dstaddr[18];
483
if (device->trusted == value)
484
return dbus_message_new_method_return(msg);
486
adapter_get_address(adapter, &src);
487
ba2str(&src, srcaddr);
488
ba2str(&device->bdaddr, dstaddr);
490
err = write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
492
return btd_error_failed(msg, strerror(-err));
494
device->trusted = value;
496
emit_property_changed(conn, dbus_message_get_path(msg),
497
DEVICE_INTERFACE, "Trusted",
498
DBUS_TYPE_BOOLEAN, &value);
500
return dbus_message_new_method_return(msg);
503
static void driver_remove(struct btd_device_driver *driver,
504
struct btd_device *device)
506
driver->remove(device);
508
device->drivers = g_slist_remove(device->drivers, driver);
511
static gboolean do_disconnect(gpointer user_data)
513
struct btd_device *device = user_data;
515
device->disconn_timer = 0;
517
btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
518
device->bdaddr_type);
523
int device_block(DBusConnection *conn, struct btd_device *device,
524
gboolean update_only)
532
if (device->connected)
533
do_disconnect(device);
535
g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
538
err = btd_adapter_block_address(device->adapter,
539
&device->bdaddr, device->bdaddr_type);
544
device->blocked = TRUE;
546
adapter_get_address(device->adapter, &src);
548
err = write_blocked(&src, &device->bdaddr, TRUE);
550
error("write_blocked(): %s (%d)", strerror(-err), -err);
552
device_set_temporary(device, FALSE);
554
emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Blocked",
555
DBUS_TYPE_BOOLEAN, &device->blocked);
560
int device_unblock(DBusConnection *conn, struct btd_device *device,
561
gboolean silent, gboolean update_only)
566
if (!device->blocked)
570
err = btd_adapter_unblock_address(device->adapter,
571
&device->bdaddr, device->bdaddr_type);
576
device->blocked = FALSE;
578
adapter_get_address(device->adapter, &src);
580
err = write_blocked(&src, &device->bdaddr, FALSE);
582
error("write_blocked(): %s (%d)", strerror(-err), -err);
585
emit_property_changed(conn, device->path,
586
DEVICE_INTERFACE, "Blocked",
587
DBUS_TYPE_BOOLEAN, &device->blocked);
588
device_probe_drivers(device, device->uuids);
594
static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
595
gboolean value, void *data)
597
struct btd_device *device = data;
601
err = device_block(conn, device, FALSE);
603
err = device_unblock(conn, device, FALSE, FALSE);
607
return dbus_message_new_method_return(msg);
609
return btd_error_failed(msg, "Kernel lacks blacklist support");
611
return btd_error_failed(msg, strerror(-err));
615
static DBusMessage *set_property(DBusConnection *conn,
616
DBusMessage *msg, void *data)
618
DBusMessageIter iter;
620
const char *property;
622
if (!dbus_message_iter_init(msg, &iter))
623
return btd_error_invalid_args(msg);
625
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
626
return btd_error_invalid_args(msg);
628
dbus_message_iter_get_basic(&iter, &property);
629
dbus_message_iter_next(&iter);
631
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
632
return btd_error_invalid_args(msg);
633
dbus_message_iter_recurse(&iter, &sub);
635
if (g_str_equal("Trusted", property)) {
637
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
638
return btd_error_invalid_args(msg);
639
dbus_message_iter_get_basic(&sub, &value);
641
return set_trust(conn, msg, value, data);
642
} else if (g_str_equal("Alias", property)) {
645
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
646
return btd_error_invalid_args(msg);
647
dbus_message_iter_get_basic(&sub, &alias);
649
return set_alias(conn, msg, alias, data);
650
} else if (g_str_equal("Blocked", property)) {
653
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
654
return btd_error_invalid_args(msg);
656
dbus_message_iter_get_basic(&sub, &value);
658
return set_blocked(conn, msg, value, data);
661
return btd_error_invalid_args(msg);
664
static void discover_services_req_exit(DBusConnection *conn, void *user_data)
666
struct browse_req *req = user_data;
668
DBG("DiscoverServices requestor exited");
670
browse_request_cancel(req);
673
static DBusMessage *discover_services(DBusConnection *conn,
674
DBusMessage *msg, void *user_data)
676
struct btd_device *device = user_data;
681
return btd_error_in_progress(msg);
683
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
684
DBUS_TYPE_INVALID) == FALSE)
685
return btd_error_invalid_args(msg);
687
if (strlen(pattern) == 0) {
688
err = device_browse_sdp(device, conn, msg, NULL, FALSE);
694
if (bt_string2uuid(&uuid, pattern) < 0)
695
return btd_error_invalid_args(msg);
697
sdp_uuid128_to_uuid(&uuid);
699
err = device_browse_sdp(device, conn, msg, &uuid, FALSE);
707
return btd_error_failed(msg, strerror(-err));
710
static const char *browse_request_get_requestor(struct browse_req *req)
715
return dbus_message_get_sender(req->msg);
718
static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
721
DBusMessageIter entry;
723
dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
726
dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
728
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
730
dbus_message_iter_close_container(dict, &entry);
733
static void discover_services_reply(struct browse_req *req, int err,
737
DBusMessageIter iter, dict;
743
if (err == -EHOSTDOWN)
744
err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
746
err_if = ERROR_INTERFACE ".Failed";
748
reply = dbus_message_new_error(req->msg, err_if,
750
g_dbus_send_message(req->conn, reply);
754
reply = dbus_message_new_method_return(req->msg);
758
dbus_message_iter_init_append(reply, &iter);
760
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
761
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
762
DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
763
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
765
for (seq = recs; seq; seq = seq->next) {
766
sdp_record_t *rec = (sdp_record_t *) seq->data;
772
result = g_string_new(NULL);
774
convert_sdp_record_to_xml(rec, result,
775
(void *) g_string_append);
778
iter_append_record(&dict, rec->handle, result->str);
780
g_string_free(result, TRUE);
783
dbus_message_iter_close_container(&iter, &dict);
785
g_dbus_send_message(req->conn, reply);
788
static DBusMessage *cancel_discover(DBusConnection *conn,
789
DBusMessage *msg, void *user_data)
791
struct btd_device *device = user_data;
792
const char *sender = dbus_message_get_sender(msg);
793
const char *requestor;
796
return btd_error_does_not_exist(msg);
798
if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
800
return btd_error_not_authorized(msg);
802
requestor = browse_request_get_requestor(device->browse);
804
/* only the discover requestor can cancel the inquiry process */
805
if (!requestor || !g_str_equal(requestor, sender))
806
return btd_error_not_authorized(msg);
808
discover_services_reply(device->browse, -ECANCELED, NULL);
810
browse_request_cancel(device->browse);
812
return dbus_message_new_method_return(msg);
815
static void bonding_request_cancel(struct bonding_req *bonding)
817
struct btd_device *device = bonding->device;
818
struct btd_adapter *adapter = device->adapter;
820
adapter_cancel_bonding(adapter, &device->bdaddr);
823
void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
825
DBusConnection *conn = get_dbus_connection();
828
bonding_request_cancel(device->bonding);
830
if (device->browse) {
831
discover_services_reply(device->browse, -ECANCELED, NULL);
832
browse_request_cancel(device->browse);
836
device->disconnects = g_slist_append(device->disconnects,
837
dbus_message_ref(msg));
839
if (device->disconn_timer)
842
while (device->watches) {
843
struct btd_disconnect_data *data = device->watches->data;
846
/* temporary is set if device is going to be removed */
847
data->watch(device, device->temporary,
850
/* Check if the watch has been removed by callback function */
851
if (!g_slist_find(device->watches, data))
854
device->watches = g_slist_remove(device->watches, data);
858
device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
859
do_disconnect, device);
861
g_dbus_emit_signal(conn, device->path,
862
DEVICE_INTERFACE, "DisconnectRequested",
866
static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
869
struct btd_device *device = user_data;
871
if (!device->connected)
872
return btd_error_not_connected(msg);
874
device_request_disconnect(device, msg);
879
static const GDBusMethodTable device_methods[] = {
880
{ GDBUS_METHOD("GetProperties",
881
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
883
{ GDBUS_METHOD("SetProperty",
884
GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
886
{ GDBUS_ASYNC_METHOD("DiscoverServices",
887
GDBUS_ARGS({ "pattern", "s" }),
888
GDBUS_ARGS({ "services", "a{us}" }),
889
discover_services) },
890
{ GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
891
{ GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, disconnect) },
895
static const GDBusSignalTable device_signals[] = {
896
{ GDBUS_SIGNAL("PropertyChanged",
897
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
898
{ GDBUS_SIGNAL("DisconnectRequested", NULL) },
902
gboolean device_is_connected(struct btd_device *device)
904
return device->connected;
907
void device_add_connection(struct btd_device *device, DBusConnection *conn)
909
if (device->connected) {
911
ba2str(&device->bdaddr, addr);
912
error("Device %s is already connected", addr);
916
device->connected = TRUE;
918
emit_property_changed(conn, device->path,
919
DEVICE_INTERFACE, "Connected",
920
DBUS_TYPE_BOOLEAN, &device->connected);
923
void device_remove_connection(struct btd_device *device, DBusConnection *conn)
925
if (!device->connected) {
927
ba2str(&device->bdaddr, addr);
928
error("Device %s isn't connected", addr);
932
device->connected = FALSE;
934
if (device->disconn_timer > 0) {
935
g_source_remove(device->disconn_timer);
936
device->disconn_timer = 0;
939
while (device->disconnects) {
940
DBusMessage *msg = device->disconnects->data;
942
g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
943
device->disconnects = g_slist_remove(device->disconnects, msg);
946
if (device_is_paired(device) && !device_is_bonded(device))
947
device_set_paired(device, FALSE);
949
emit_property_changed(conn, device->path,
950
DEVICE_INTERFACE, "Connected",
951
DBUS_TYPE_BOOLEAN, &device->connected);
954
guint device_add_disconnect_watch(struct btd_device *device,
955
disconnect_watch watch, void *user_data,
956
GDestroyNotify destroy)
958
struct btd_disconnect_data *data;
961
data = g_new0(struct btd_disconnect_data, 1);
964
data->user_data = user_data;
965
data->destroy = destroy;
967
device->watches = g_slist_append(device->watches, data);
972
void device_remove_disconnect_watch(struct btd_device *device, guint id)
976
for (l = device->watches; l; l = l->next) {
977
struct btd_disconnect_data *data = l->data;
979
if (data->id == id) {
980
device->watches = g_slist_remove(device->watches,
983
data->destroy(data->user_data);
990
static void device_set_vendor(struct btd_device *device, uint16_t value)
992
DBusConnection *conn = get_dbus_connection();
994
if (device->vendor == value)
997
device->vendor = value;
999
emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Vendor",
1000
DBUS_TYPE_UINT16, &value);
1003
static void device_set_vendor_src(struct btd_device *device, uint16_t value)
1005
DBusConnection *conn = get_dbus_connection();
1007
if (device->vendor_src == value)
1010
device->vendor_src = value;
1012
emit_property_changed(conn, device->path, DEVICE_INTERFACE,
1013
"VendorSource", DBUS_TYPE_UINT16, &value);
1016
static void device_set_product(struct btd_device *device, uint16_t value)
1018
DBusConnection *conn = get_dbus_connection();
1020
if (device->product == value)
1023
device->product = value;
1025
emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Product",
1026
DBUS_TYPE_UINT16, &value);
1029
static void device_set_version(struct btd_device *device, uint16_t value)
1031
DBusConnection *conn = get_dbus_connection();
1033
if (device->version == value)
1036
device->version = value;
1038
emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Version",
1039
DBUS_TYPE_UINT16, &value);
1042
struct btd_device *device_create(DBusConnection *conn,
1043
struct btd_adapter *adapter,
1044
const gchar *address, uint8_t bdaddr_type)
1047
struct btd_device *device;
1048
const gchar *adapter_path = adapter_get_path(adapter);
1050
char srcaddr[18], alias[MAX_NAME_LENGTH + 1];
1051
uint16_t vendor, product, version;
1053
device = g_try_malloc0(sizeof(struct btd_device));
1057
address_up = g_ascii_strup(address, -1);
1058
device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
1059
g_strdelimit(device->path, ":", '_');
1062
DBG("Creating device %s", device->path);
1064
if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
1065
device_methods, device_signals, NULL,
1066
device, device_free) == FALSE) {
1067
device_free(device);
1071
str2ba(address, &device->bdaddr);
1072
device->adapter = adapter;
1073
device->bdaddr_type = bdaddr_type;
1074
adapter_get_address(adapter, &src);
1075
ba2str(&src, srcaddr);
1076
read_device_name(srcaddr, address, device->name);
1077
if (read_device_alias(srcaddr, address, alias, sizeof(alias)) == 0)
1078
device->alias = g_strdup(alias);
1079
device->trusted = read_trust(&src, address, GLOBAL_TRUST);
1081
if (read_blocked(&src, &device->bdaddr))
1082
device_block(conn, device, FALSE);
1084
if (read_link_key(&src, &device->bdaddr, NULL, NULL) == 0) {
1085
device_set_paired(device, TRUE);
1086
device_set_bonded(device, TRUE);
1089
if (device_is_le(device) && has_longtermkeys(&src, &device->bdaddr,
1090
device->bdaddr_type)) {
1091
device_set_paired(device, TRUE);
1092
device_set_bonded(device, TRUE);
1095
if (read_device_id(srcaddr, address, NULL, &vendor, &product, &version)
1097
device_set_vendor(device, vendor);
1098
device_set_product(device, product);
1099
device_set_version(device, version);
1102
return btd_device_ref(device);
1105
void device_set_name(struct btd_device *device, const char *name)
1107
DBusConnection *conn = get_dbus_connection();
1109
if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
1112
strncpy(device->name, name, MAX_NAME_LENGTH);
1114
emit_property_changed(conn, device->path,
1115
DEVICE_INTERFACE, "Name",
1116
DBUS_TYPE_STRING, &name);
1118
if (device->alias != NULL)
1121
emit_property_changed(conn, device->path,
1122
DEVICE_INTERFACE, "Alias",
1123
DBUS_TYPE_STRING, &name);
1126
void device_get_name(struct btd_device *device, char *name, size_t len)
1128
strncpy(name, device->name, len);
1131
uint16_t btd_device_get_vendor(struct btd_device *device)
1133
return device->vendor;
1136
uint16_t btd_device_get_vendor_src(struct btd_device *device)
1138
return device->vendor_src;
1141
uint16_t btd_device_get_product(struct btd_device *device)
1143
return device->product;
1146
uint16_t btd_device_get_version(struct btd_device *device)
1148
return device->version;
1151
static void device_remove_stored(struct btd_device *device)
1155
DBusConnection *conn = get_dbus_connection();
1157
adapter_get_address(device->adapter, &src);
1158
ba2str(&device->bdaddr, key);
1160
/* key: address only */
1161
delete_entry(&src, "profiles", key);
1162
delete_entry(&src, "trusts", key);
1164
if (device_is_bonded(device)) {
1165
delete_entry(&src, "linkkeys", key);
1166
delete_entry(&src, "aliases", key);
1168
/* key: address#type */
1169
sprintf(&key[17], "#%hhu", device->bdaddr_type);
1171
delete_entry(&src, "longtermkeys", key);
1173
device_set_bonded(device, FALSE);
1174
device->paired = FALSE;
1175
btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
1176
device->bdaddr_type);
1179
delete_all_records(&src, &device->bdaddr);
1180
delete_device_service(&src, &device->bdaddr, device->bdaddr_type);
1182
if (device->blocked)
1183
device_unblock(conn, device, TRUE, FALSE);
1186
void device_remove(struct btd_device *device, gboolean remove_stored)
1189
DBG("Removing device %s", device->path);
1192
agent_free(device->agent);
1194
if (device->bonding) {
1197
if (device->connected)
1198
status = HCI_OE_USER_ENDED_CONNECTION;
1200
status = HCI_PAGE_TIMEOUT;
1202
device_cancel_bonding(device, status);
1205
if (device->browse) {
1206
discover_services_reply(device->browse, -ECANCELED, NULL);
1207
browse_request_cancel(device->browse);
1210
if (device->connected)
1211
do_disconnect(device);
1214
device_remove_stored(device);
1216
g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
1217
g_slist_free(device->drivers);
1218
device->drivers = NULL;
1220
attrib_client_unregister(device->services);
1222
btd_device_unref(device);
1225
gint device_address_cmp(struct btd_device *device, const gchar *address)
1229
ba2str(&device->bdaddr, addr);
1230
return strcasecmp(addr, address);
1233
static gboolean record_has_uuid(const sdp_record_t *rec,
1234
const char *profile_uuid)
1238
for (pat = rec->pattern; pat != NULL; pat = pat->next) {
1242
uuid = bt_uuid2string(pat->data);
1246
ret = strcasecmp(uuid, profile_uuid);
1257
static GSList *device_match_pattern(struct btd_device *device,
1258
const char *match_uuid,
1261
GSList *l, *uuids = NULL;
1263
for (l = profiles; l; l = l->next) {
1264
char *profile_uuid = l->data;
1265
const sdp_record_t *rec;
1267
rec = btd_device_get_record(device, profile_uuid);
1271
if (record_has_uuid(rec, match_uuid))
1272
uuids = g_slist_append(uuids, profile_uuid);
1278
static GSList *device_match_driver(struct btd_device *device,
1279
struct btd_device_driver *driver,
1283
GSList *uuids = NULL;
1285
for (uuid = driver->uuids; *uuid; uuid++) {
1288
/* skip duplicated uuids */
1289
if (g_slist_find_custom(uuids, *uuid,
1290
(GCompareFunc) strcasecmp))
1293
/* match profile driver */
1294
match = g_slist_find_custom(profiles, *uuid,
1295
(GCompareFunc) strcasecmp);
1297
uuids = g_slist_append(uuids, match->data);
1301
/* match pattern driver */
1302
match = device_match_pattern(device, *uuid, profiles);
1303
uuids = g_slist_concat(uuids, match);
1309
void device_probe_drivers(struct btd_device *device, GSList *profiles)
1315
ba2str(&device->bdaddr, addr);
1317
if (device->blocked) {
1318
DBG("Skipping drivers for blocked device %s", addr);
1322
DBG("Probing drivers for %s", addr);
1324
for (list = device_drivers; list; list = list->next) {
1325
struct btd_device_driver *driver = list->data;
1326
GSList *probe_uuids;
1328
probe_uuids = device_match_driver(device, driver, profiles);
1333
err = driver->probe(device, probe_uuids);
1335
error("%s driver probe failed for device %s",
1336
driver->name, addr);
1337
g_slist_free(probe_uuids);
1341
device->drivers = g_slist_append(device->drivers, driver);
1342
g_slist_free(probe_uuids);
1346
for (list = profiles; list; list = list->next) {
1347
GSList *l = g_slist_find_custom(device->uuids, list->data,
1348
(GCompareFunc) strcasecmp);
1352
device->uuids = g_slist_insert_sorted(device->uuids,
1353
g_strdup(list->data),
1354
(GCompareFunc) strcasecmp);
1358
static void device_remove_drivers(struct btd_device *device, GSList *uuids)
1360
struct btd_adapter *adapter = device_get_adapter(device);
1361
GSList *list, *next;
1362
char srcaddr[18], dstaddr[18];
1364
sdp_list_t *records;
1366
adapter_get_address(adapter, &src);
1367
ba2str(&src, srcaddr);
1368
ba2str(&device->bdaddr, dstaddr);
1370
records = read_records(&src, &device->bdaddr);
1372
DBG("Removing drivers for %s", dstaddr);
1374
for (list = device->drivers; list; list = next) {
1375
struct btd_device_driver *driver = list->data;
1380
for (uuid = driver->uuids; *uuid; uuid++) {
1381
if (!g_slist_find_custom(uuids, *uuid,
1382
(GCompareFunc) strcasecmp))
1385
DBG("UUID %s was removed from device %s",
1388
driver->remove(device);
1389
device->drivers = g_slist_remove(device->drivers,
1395
for (list = uuids; list; list = list->next) {
1398
device->uuids = g_slist_remove(device->uuids, list->data);
1400
rec = find_record_in_list(records, list->data);
1404
delete_record(srcaddr, dstaddr, rec->handle);
1406
records = sdp_list_remove(records, rec);
1407
sdp_record_free(rec);
1412
sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
1415
static void services_changed(struct btd_device *device)
1417
DBusConnection *conn = get_dbus_connection();
1422
uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
1423
for (i = 0, l = device->uuids; l; l = l->next, i++)
1426
emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
1427
"UUIDs", DBUS_TYPE_STRING, &uuids, i);
1432
static int rec_cmp(const void *a, const void *b)
1434
const sdp_record_t *r1 = a;
1435
const sdp_record_t *r2 = b;
1437
return r1->handle - r2->handle;
1440
static void update_services(struct browse_req *req, sdp_list_t *recs)
1442
struct btd_device *device = req->device;
1443
struct btd_adapter *adapter = device_get_adapter(device);
1445
char srcaddr[18], dstaddr[18];
1448
adapter_get_address(adapter, &src);
1449
ba2str(&src, srcaddr);
1450
ba2str(&device->bdaddr, dstaddr);
1452
for (seq = recs; seq; seq = seq->next) {
1453
sdp_record_t *rec = (sdp_record_t *) seq->data;
1454
sdp_list_t *svcclass = NULL;
1455
gchar *profile_uuid;
1461
if (sdp_get_service_classes(rec, &svcclass) < 0)
1464
/* Check for empty service classes list */
1465
if (svcclass == NULL) {
1466
DBG("Skipping record with no service classes");
1470
/* Extract the first element and skip the remainning */
1471
profile_uuid = bt_uuid2string(svcclass->data);
1472
if (!profile_uuid) {
1473
sdp_list_free(svcclass, free);
1477
if (!strcasecmp(profile_uuid, PNP_UUID)) {
1478
uint16_t source, vendor, product, version;
1481
pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
1482
source = pdlist ? pdlist->val.uint16 : 0x0000;
1484
pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
1485
vendor = pdlist ? pdlist->val.uint16 : 0x0000;
1487
device_set_vendor(device, vendor);
1489
pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
1490
product = pdlist ? pdlist->val.uint16 : 0x0000;
1492
device_set_product(device, product);
1494
pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
1495
version = pdlist ? pdlist->val.uint16 : 0x0000;
1497
device_set_version(device, version);
1499
if (source || vendor || product || version)
1500
store_device_id(srcaddr, dstaddr, source,
1501
vendor, product, version);
1504
/* Check for duplicates */
1505
if (sdp_list_find(req->records, rec, rec_cmp)) {
1506
g_free(profile_uuid);
1507
sdp_list_free(svcclass, free);
1511
store_record(srcaddr, dstaddr, rec);
1514
req->records = sdp_list_append(req->records,
1515
sdp_copy_record(rec));
1517
l = g_slist_find_custom(device->uuids, profile_uuid,
1518
(GCompareFunc) strcmp);
1520
req->profiles_added =
1521
g_slist_append(req->profiles_added,
1524
req->profiles_removed =
1525
g_slist_remove(req->profiles_removed,
1527
g_free(profile_uuid);
1530
sdp_list_free(svcclass, free);
1534
static void store_profiles(struct btd_device *device)
1536
struct btd_adapter *adapter = device->adapter;
1540
adapter_get_address(adapter, &src);
1542
if (!device->uuids) {
1543
write_device_profiles(&src, &device->bdaddr, "");
1547
str = bt_list2string(device->uuids);
1548
write_device_profiles(&src, &device->bdaddr, str);
1552
static void create_device_reply(struct btd_device *device, struct browse_req *req)
1556
reply = dbus_message_new_method_return(req->msg);
1560
dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
1563
g_dbus_send_message(req->conn, reply);
1566
GSList *device_services_from_record(struct btd_device *device, GSList *profiles)
1568
GSList *l, *prim_list = NULL;
1572
sdp_uuid16_create(&proto_uuid, ATT_UUID);
1573
att_uuid = bt_uuid2string(&proto_uuid);
1575
for (l = profiles; l; l = l->next) {
1576
const char *profile_uuid = l->data;
1577
const sdp_record_t *rec;
1578
struct gatt_primary *prim;
1579
uint16_t start = 0, end = 0, psm = 0;
1582
rec = btd_device_get_record(device, profile_uuid);
1586
if (!record_has_uuid(rec, att_uuid))
1589
if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
1592
prim = g_new0(struct gatt_primary, 1);
1593
prim->range.start = start;
1594
prim->range.end = end;
1595
sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
1597
prim_list = g_slist_append(prim_list, prim);
1605
static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
1607
struct browse_req *req = user_data;
1608
struct btd_device *device = req->device;
1611
ba2str(&device->bdaddr, addr);
1614
error("%s: error updating services: %s (%d)",
1615
addr, strerror(-err), -err);
1619
update_services(req, recs);
1621
if (device->tmp_records)
1622
sdp_list_free(device->tmp_records,
1623
(sdp_free_func_t) sdp_record_free);
1625
device->tmp_records = req->records;
1626
req->records = NULL;
1628
if (!req->profiles_added && !req->profiles_removed) {
1629
DBG("%s: No service update", addr);
1633
/* Probe matching drivers for services added */
1634
if (req->profiles_added) {
1637
list = device_services_from_record(device, req->profiles_added);
1639
device_register_services(req->conn, device, list,
1642
device_probe_drivers(device, req->profiles_added);
1645
/* Remove drivers for services removed */
1646
if (req->profiles_removed)
1647
device_remove_drivers(device, req->profiles_removed);
1649
/* Propagate services changes */
1650
services_changed(req->device);
1656
if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
1657
"DiscoverServices"))
1658
discover_services_reply(req, err, device->tmp_records);
1659
else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
1660
"CreatePairedDevice"))
1661
create_device_reply(device, req);
1662
else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
1666
reply = btd_error_failed(req->msg, strerror(-err));
1667
g_dbus_send_message(req->conn, reply);
1671
create_device_reply(device, req);
1672
device_set_temporary(device, FALSE);
1676
if (!device->temporary) {
1679
adapter_get_address(device->adapter, &sba);
1680
device_get_address(device, &dba, NULL);
1682
store_profiles(device);
1685
device->browse = NULL;
1686
browse_request_free(req);
1689
static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
1691
struct browse_req *req = user_data;
1692
struct btd_device *device = req->device;
1693
struct btd_adapter *adapter = device->adapter;
1697
/* If we have a valid response and req->search_uuid == 2, then L2CAP
1698
* UUID & PNP searching was successful -- we are done */
1699
if (err < 0 || (req->search_uuid == 2 && req->records)) {
1700
if (err == -ECONNRESET && req->reconnect_attempt < 1) {
1702
req->reconnect_attempt++;
1707
update_services(req, recs);
1709
adapter_get_address(adapter, &src);
1711
/* Search for mandatory uuids */
1712
if (uuid_list[req->search_uuid]) {
1713
sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1714
bt_search_service(&src, &device->bdaddr, &uuid,
1715
browse_cb, user_data, NULL);
1720
search_cb(recs, err, user_data);
1723
static void init_browse(struct browse_req *req, gboolean reverse)
1727
/* If we are doing reverse-SDP don't try to detect removed profiles
1728
* since some devices hide their service records while they are
1734
for (l = req->device->uuids; l; l = l->next)
1735
req->profiles_removed = g_slist_append(req->profiles_removed,
1739
static char *primary_list_to_string(GSList *primary_list)
1744
services = g_string_new(NULL);
1746
for (l = primary_list; l; l = l->next) {
1747
struct gatt_primary *primary = l->data;
1750
memset(service, 0, sizeof(service));
1752
snprintf(service, sizeof(service), "%04X#%04X#%s ",
1753
primary->range.start, primary->range.end, primary->uuid);
1755
services = g_string_append(services, service);
1758
return g_string_free(services, FALSE);
1761
static void store_services(struct btd_device *device)
1763
struct btd_adapter *adapter = device->adapter;
1765
char *str = primary_list_to_string(device->primaries);
1767
adapter_get_address(adapter, &sba);
1768
device_get_address(device, &dba, NULL);
1770
write_device_services(&sba, &dba, device->bdaddr_type, str);
1775
static void attio_connected(gpointer data, gpointer user_data)
1777
struct attio_data *attio = data;
1778
GAttrib *attrib = user_data;
1781
attio->cfunc(attrib, attio->user_data);
1784
static void attio_disconnected(gpointer data, gpointer user_data)
1786
struct attio_data *attio = data;
1789
attio->dcfunc(attio->user_data);
1792
static void att_connect_dispatched(gpointer user_data)
1794
struct btd_device *device = user_data;
1796
device->auto_id = 0;
1799
static gboolean att_connect(gpointer user_data);
1801
static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
1804
struct btd_device *device = user_data;
1811
sock = g_io_channel_unix_get_fd(io);
1813
getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len);
1815
g_slist_foreach(device->attios, attio_disconnected, NULL);
1817
if (device->auto_connect == FALSE || err != ETIMEDOUT)
1820
device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
1821
AUTO_CONNECTION_INTERVAL,
1822
att_connect, device,
1823
att_connect_dispatched);
1826
att_cleanup(device);
1831
static void appearance_cb(guint8 status, const guint8 *pdu, guint16 plen,
1834
struct btd_device *device = user_data;
1835
struct btd_adapter *adapter = device->adapter;
1836
struct att_data_list *list = NULL;
1842
DBG("Read characteristics by UUID failed: %s\n",
1843
att_ecode2str(status));
1847
list = dec_read_by_type_resp(pdu, plen);
1851
if (list->len != 4) {
1852
DBG("Appearance value: invalid data");
1856
/* A device shall have only one instance of the
1857
Appearance characteristic. */
1858
atval = list->data[0] + 2; /* skip handle value */
1859
app = att_get_u16(atval);
1861
adapter_get_address(adapter, &src);
1862
write_remote_appearance(&src, &device->bdaddr, device->bdaddr_type,
1866
att_data_list_free(list);
1867
if (device->attios == NULL && device->attios_offline == NULL)
1868
att_cleanup(device);
1871
static void primary_cb(GSList *services, guint8 status, gpointer user_data)
1873
struct browse_req *req = user_data;
1874
struct btd_device *device = req->device;
1875
struct gatt_primary *gap_prim = NULL;
1876
GSList *l, *uuids = NULL;
1881
reply = btd_error_failed(req->msg,
1882
att_ecode2str(status));
1883
g_dbus_send_message(req->conn, reply);
1888
device_set_temporary(device, FALSE);
1890
for (l = services; l; l = l->next) {
1891
struct gatt_primary *prim = l->data;
1893
if (strcmp(prim->uuid, GAP_SVC_UUID) == 0)
1896
uuids = g_slist_append(uuids, prim->uuid);
1899
device_register_services(req->conn, device, g_slist_copy(services), -1);
1900
device_probe_drivers(device, uuids);
1903
/* Read appearance characteristic */
1906
bt_uuid16_create(&uuid, APPEARANCE_CHR_UUID);
1908
gatt_read_char_by_uuid(device->attrib, gap_prim->range.start,
1909
gap_prim->range.end, &uuid, appearance_cb, device);
1910
} else if (device->attios == NULL && device->attios_offline == NULL)
1911
att_cleanup(device);
1913
g_slist_free(uuids);
1915
services_changed(device);
1917
create_device_reply(device, req);
1919
store_services(device);
1922
device->browse = NULL;
1923
browse_request_free(req);
1926
static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
1928
struct att_callbacks *attcb = user_data;
1929
struct btd_device *device = attcb->user_data;
1932
g_io_channel_unref(device->att_io);
1933
device->att_io = NULL;
1936
DBG("%s", gerr->message);
1939
attcb->error(gerr, user_data);
1944
attrib = g_attrib_new(io);
1945
device->attachid = attrib_channel_attach(attrib);
1946
if (device->attachid == 0)
1947
error("Attribute server attach failure!");
1949
device->attrib = attrib;
1950
device->cleanup_id = g_io_add_watch(io, G_IO_HUP,
1951
attrib_disconnected_cb, device);
1954
attcb->success(user_data);
1959
static void att_error_cb(const GError *gerr, gpointer user_data)
1961
struct att_callbacks *attcb = user_data;
1962
struct btd_device *device = attcb->user_data;
1964
if (device->auto_connect == FALSE)
1967
device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
1968
AUTO_CONNECTION_INTERVAL,
1969
att_connect, device,
1970
att_connect_dispatched);
1972
DBG("Enabling automatic connections");
1975
static void att_success_cb(gpointer user_data)
1977
struct att_callbacks *attcb = user_data;
1978
struct btd_device *device = attcb->user_data;
1980
if (device->attios == NULL)
1983
g_slist_foreach(device->attios, attio_connected, device->attrib);
1986
static gboolean att_connect(gpointer user_data)
1988
struct btd_device *device = user_data;
1989
struct btd_adapter *adapter = device->adapter;
1990
struct att_callbacks *attcb;
1992
GError *gerr = NULL;
1996
adapter_get_address(adapter, &sba);
1997
ba2str(&device->bdaddr, addr);
1999
DBG("Connection attempt to: %s", addr);
2001
attcb = g_new0(struct att_callbacks, 1);
2002
attcb->error = att_error_cb;
2003
attcb->success = att_success_cb;
2004
attcb->user_data = device;
2006
if (device_is_bredr(device)) {
2007
io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2009
BT_IO_OPT_SOURCE_BDADDR, &sba,
2010
BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2011
BT_IO_OPT_PSM, ATT_PSM,
2012
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2015
io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2017
BT_IO_OPT_SOURCE_BDADDR, &sba,
2018
BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2019
BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
2020
BT_IO_OPT_CID, ATT_CID,
2021
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2026
error("ATT bt_io_connect(%s): %s", addr, gerr->message);
2032
device->att_io = io;
2037
static void att_browse_error_cb(const GError *gerr, gpointer user_data)
2039
struct att_callbacks *attcb = user_data;
2040
struct btd_device *device = attcb->user_data;
2041
struct browse_req *req = device->browse;
2046
reply = btd_error_failed(req->msg, gerr->message);
2047
g_dbus_send_message(req->conn, reply);
2050
device->browse = NULL;
2051
browse_request_free(req);
2054
static void att_browse_cb(gpointer user_data)
2056
struct att_callbacks *attcb = user_data;
2057
struct btd_device *device = attcb->user_data;
2059
gatt_discover_primary(device->attrib, NULL, primary_cb,
2063
int device_browse_primary(struct btd_device *device, DBusConnection *conn,
2064
DBusMessage *msg, gboolean secure)
2066
struct btd_adapter *adapter = device->adapter;
2067
struct att_callbacks *attcb;
2068
struct browse_req *req;
2069
BtIOSecLevel sec_level;
2075
/* FIXME: GATT service updates (implemented in update_services() for
2076
* SDP) are not supported yet. It will be supported once client side
2077
* "Services Changed" characteristic handling is implemented. */
2078
if (device->primaries) {
2079
error("Could not update GATT services");
2083
req = g_new0(struct browse_req, 1);
2084
req->device = btd_device_ref(device);
2085
adapter_get_address(adapter, &src);
2087
device->browse = req;
2089
if (device->attrib) {
2090
gatt_discover_primary(device->attrib, NULL, primary_cb, req);
2094
sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW;
2096
attcb = g_new0(struct att_callbacks, 1);
2097
attcb->error = att_browse_error_cb;
2098
attcb->success = att_browse_cb;
2099
attcb->user_data = device;
2101
device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2103
BT_IO_OPT_SOURCE_BDADDR, &src,
2104
BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2105
BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
2106
BT_IO_OPT_CID, ATT_CID,
2107
BT_IO_OPT_SEC_LEVEL, sec_level,
2110
if (device->att_io == NULL) {
2111
device->browse = NULL;
2112
browse_request_free(req);
2119
conn = get_dbus_connection();
2121
req->conn = dbus_connection_ref(conn);
2124
const char *sender = dbus_message_get_sender(msg);
2126
req->msg = dbus_message_ref(msg);
2127
/* Track the request owner to cancel it
2128
* automatically if the owner exits */
2129
req->listener_id = g_dbus_add_disconnect_watch(conn,
2131
discover_services_req_exit,
2138
int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
2139
DBusMessage *msg, uuid_t *search, gboolean reverse)
2141
struct btd_adapter *adapter = device->adapter;
2142
struct browse_req *req;
2151
adapter_get_address(adapter, &src);
2153
req = g_new0(struct browse_req, 1);
2154
req->device = btd_device_ref(device);
2156
memcpy(&uuid, search, sizeof(uuid_t));
2159
sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
2160
init_browse(req, reverse);
2164
err = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
2166
browse_request_free(req);
2171
conn = get_dbus_connection();
2173
req->conn = dbus_connection_ref(conn);
2174
device->browse = req;
2177
const char *sender = dbus_message_get_sender(msg);
2179
req->msg = dbus_message_ref(msg);
2180
/* Track the request owner to cancel it
2181
* automatically if the owner exits */
2182
req->listener_id = g_dbus_add_disconnect_watch(conn,
2184
discover_services_req_exit,
2191
struct btd_adapter *device_get_adapter(struct btd_device *device)
2196
return device->adapter;
2199
void device_get_address(struct btd_device *device, bdaddr_t *bdaddr,
2200
uint8_t *bdaddr_type)
2202
bacpy(bdaddr, &device->bdaddr);
2203
if (bdaddr_type != NULL)
2204
*bdaddr_type = device->bdaddr_type;
2207
void device_set_addr_type(struct btd_device *device, uint8_t bdaddr_type)
2212
device->bdaddr_type = bdaddr_type;
2215
uint8_t device_get_addr_type(struct btd_device *device)
2217
return device->bdaddr_type;
2220
const gchar *device_get_path(struct btd_device *device)
2225
return device->path;
2228
struct agent *device_get_agent(struct btd_device *device)
2234
return device->agent;
2236
return adapter_get_agent(device->adapter);
2239
gboolean device_is_busy(struct btd_device *device)
2241
return device->browse ? TRUE : FALSE;
2244
gboolean device_is_temporary(struct btd_device *device)
2246
return device->temporary;
2249
void device_set_temporary(struct btd_device *device, gboolean temporary)
2254
DBG("temporary %d", temporary);
2256
device->temporary = temporary;
2259
void device_set_bonded(struct btd_device *device, gboolean bonded)
2264
DBG("bonded %d", bonded);
2266
device->bonded = bonded;
2269
void device_set_auto_connect(struct btd_device *device, gboolean enable)
2276
ba2str(&device->bdaddr, addr);
2278
DBG("%s auto connect: %d", addr, enable);
2280
device->auto_connect = enable;
2282
/* Disabling auto connect */
2283
if (enable == FALSE) {
2284
if (device->auto_id)
2285
g_source_remove(device->auto_id);
2289
/* Enabling auto connect */
2290
if (device->auto_id != 0)
2293
if (device->attrib) {
2294
DBG("Already connected");
2298
if (device->attios == NULL && device->attios_offline == NULL)
2301
device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
2302
att_connect, device,
2303
att_connect_dispatched);
2306
static gboolean start_discovery(gpointer user_data)
2308
struct btd_device *device = user_data;
2310
if (device_is_bredr(device))
2311
device_browse_sdp(device, NULL, NULL, NULL, TRUE);
2313
device_browse_primary(device, NULL, NULL, FALSE);
2315
device->discov_timer = 0;
2320
static DBusMessage *new_authentication_return(DBusMessage *msg, int status)
2323
case 0x00: /* success */
2324
return dbus_message_new_method_return(msg);
2326
case 0x04: /* page timeout */
2327
return dbus_message_new_error(msg,
2328
ERROR_INTERFACE ".ConnectionAttemptFailed",
2330
case 0x08: /* connection timeout */
2331
return dbus_message_new_error(msg,
2332
ERROR_INTERFACE ".ConnectionAttemptFailed",
2333
"Connection Timeout");
2334
case 0x10: /* connection accept timeout */
2335
case 0x22: /* LMP response timeout */
2336
case 0x28: /* instant passed - is this a timeout? */
2337
return dbus_message_new_error(msg,
2338
ERROR_INTERFACE ".AuthenticationTimeout",
2339
"Authentication Timeout");
2340
case 0x17: /* too frequent pairing attempts */
2341
return dbus_message_new_error(msg,
2342
ERROR_INTERFACE ".RepeatedAttempts",
2343
"Repeated Attempts");
2346
case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */
2347
return dbus_message_new_error(msg,
2348
ERROR_INTERFACE ".AuthenticationRejected",
2349
"Authentication Rejected");
2351
case 0x07: /* memory capacity */
2352
case 0x09: /* connection limit */
2353
case 0x0a: /* synchronous connection limit */
2354
case 0x0d: /* limited resources */
2355
case 0x13: /* user ended the connection */
2356
case 0x14: /* terminated due to low resources */
2357
case 0x16: /* connection terminated */
2358
return dbus_message_new_error(msg,
2359
ERROR_INTERFACE ".AuthenticationCanceled",
2360
"Authentication Canceled");
2362
case 0x05: /* authentication failure */
2363
case 0x0E: /* rejected due to security reasons - is this auth failure? */
2364
case 0x25: /* encryption mode not acceptable - is this auth failure? */
2365
case 0x26: /* link key cannot be changed - is this auth failure? */
2366
case 0x29: /* pairing with unit key unsupported - is this auth failure? */
2367
case 0x2f: /* insufficient security - is this auth failure? */
2369
return dbus_message_new_error(msg,
2370
ERROR_INTERFACE ".AuthenticationFailed",
2371
"Authentication Failed");
2375
static void bonding_request_free(struct bonding_req *bonding)
2377
struct btd_device *device;
2382
if (bonding->listener_id)
2383
g_dbus_remove_watch(bonding->conn, bonding->listener_id);
2386
dbus_message_unref(bonding->msg);
2389
dbus_connection_unref(bonding->conn);
2391
device = bonding->device;
2397
device->bonding = NULL;
2402
agent_cancel(device->agent);
2403
agent_free(device->agent);
2404
device->agent = NULL;
2407
void device_set_paired(struct btd_device *device, gboolean value)
2409
DBusConnection *conn = get_dbus_connection();
2411
if (device->paired == value)
2415
btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
2416
device->bdaddr_type);
2418
device->paired = value;
2420
emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired",
2421
DBUS_TYPE_BOOLEAN, &value);
2424
static void device_agent_removed(struct agent *agent, void *user_data)
2426
struct btd_device *device = user_data;
2428
device->agent = NULL;
2431
device->authr->agent = NULL;
2434
static struct bonding_req *bonding_request_new(DBusConnection *conn,
2436
struct btd_device *device,
2437
const char *agent_path,
2440
struct bonding_req *bonding;
2441
const char *name = dbus_message_get_sender(msg);
2444
ba2str(&device->bdaddr, addr);
2445
DBG("Requesting bonding for %s", addr);
2450
device->agent = agent_create(device->adapter, name, agent_path,
2452
device_agent_removed,
2455
DBG("Temporary agent registered for %s at %s:%s",
2456
addr, name, agent_path);
2459
bonding = g_new0(struct bonding_req, 1);
2461
bonding->conn = dbus_connection_ref(conn);
2462
bonding->msg = dbus_message_ref(msg);
2467
static void create_bond_req_exit(DBusConnection *conn, void *user_data)
2469
struct btd_device *device = user_data;
2472
ba2str(&device->bdaddr, addr);
2473
DBG("%s: requestor exited before bonding was completed", addr);
2476
device_cancel_authentication(device, FALSE);
2478
if (device->bonding) {
2479
device->bonding->listener_id = 0;
2480
device_request_disconnect(device, NULL);
2484
DBusMessage *device_create_bonding(struct btd_device *device,
2485
DBusConnection *conn,
2487
const char *agent_path,
2490
struct btd_adapter *adapter = device->adapter;
2491
struct bonding_req *bonding;
2494
if (device->bonding)
2495
return btd_error_in_progress(msg);
2497
if (device_is_bonded(device))
2498
return btd_error_already_exists(msg);
2500
if (device_is_le(device)) {
2501
struct att_callbacks *attcb;
2502
GError *gerr = NULL;
2505
adapter_get_address(adapter, &sba);
2507
attcb = g_new0(struct att_callbacks, 1);
2508
attcb->user_data = device;
2510
device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2512
BT_IO_OPT_SOURCE_BDADDR, &sba,
2513
BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2514
BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
2515
BT_IO_OPT_CID, ATT_CID,
2516
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
2519
if (device->att_io == NULL) {
2520
DBusMessage *reply = btd_error_failed(msg,
2523
error("Bonding bt_io_connect(): %s", gerr->message);
2530
err = adapter_create_bonding(adapter, &device->bdaddr,
2531
device->bdaddr_type, capability);
2533
return btd_error_failed(msg, strerror(-err));
2535
bonding = bonding_request_new(conn, msg, device, agent_path,
2538
bonding->listener_id = g_dbus_add_disconnect_watch(conn,
2539
dbus_message_get_sender(msg),
2540
create_bond_req_exit, device,
2543
device->bonding = bonding;
2544
bonding->device = device;
2549
void device_simple_pairing_complete(struct btd_device *device, uint8_t status)
2551
struct authentication_req *auth = device->authr;
2553
if (auth && (auth->type == AUTH_TYPE_NOTIFY_PASSKEY
2554
|| auth->type == AUTH_TYPE_NOTIFY_PINCODE) && auth->agent)
2555
agent_cancel(auth->agent);
2558
static void device_auth_req_free(struct btd_device *device)
2561
g_free(device->authr->pincode);
2562
g_free(device->authr);
2563
device->authr = NULL;
2566
void device_bonding_complete(struct btd_device *device, uint8_t status)
2568
struct bonding_req *bonding = device->bonding;
2569
struct authentication_req *auth = device->authr;
2571
DBG("bonding %p status 0x%02x", bonding, status);
2573
if (auth && (auth->type == AUTH_TYPE_NOTIFY_PASSKEY
2574
|| auth->type == AUTH_TYPE_NOTIFY_PINCODE) && auth->agent)
2575
agent_cancel(auth->agent);
2578
device_cancel_authentication(device, TRUE);
2579
device_cancel_bonding(device, status);
2583
device_auth_req_free(device);
2585
/* If we're already paired nothing more is needed */
2589
device_set_paired(device, TRUE);
2591
/* If we were initiators start service discovery immediately.
2592
* However if the other end was the initator wait a few seconds
2593
* before SDP. This is due to potential IOP issues if the other
2594
* end starts doing SDP at the same time as us */
2596
DBG("Proceeding with service discovery");
2597
/* If we are initiators remove any discovery timer and just
2598
* start discovering services directly */
2599
if (device->discov_timer) {
2600
g_source_remove(device->discov_timer);
2601
device->discov_timer = 0;
2604
if (device_is_bredr(device))
2605
device_browse_sdp(device, bonding->conn, bonding->msg,
2608
device_browse_primary(device, bonding->conn,
2609
bonding->msg, FALSE);
2611
bonding_request_free(bonding);
2613
if (!device->browse && !device->discov_timer &&
2614
main_opts.reverse_sdp) {
2615
/* If we are not initiators and there is no currently
2616
* active discovery or discovery timer, set discovery
2618
DBG("setting timer for reverse service discovery");
2619
device->discov_timer = g_timeout_add_seconds(
2627
gboolean device_is_creating(struct btd_device *device, const char *sender)
2631
if (device->bonding && device->bonding->msg)
2632
msg = device->bonding->msg;
2633
else if (device->browse && device->browse->msg)
2634
msg = device->browse->msg;
2638
if (!dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2639
"CreatePairedDevice") &&
2640
!dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2647
return g_str_equal(sender, dbus_message_get_sender(msg));
2650
gboolean device_is_bonding(struct btd_device *device, const char *sender)
2652
struct bonding_req *bonding = device->bonding;
2654
if (!device->bonding)
2660
return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
2663
void device_cancel_bonding(struct btd_device *device, uint8_t status)
2665
struct bonding_req *bonding = device->bonding;
2672
ba2str(&device->bdaddr, addr);
2673
DBG("Canceling bonding request for %s", addr);
2676
device_cancel_authentication(device, FALSE);
2678
reply = new_authentication_return(bonding->msg, status);
2679
g_dbus_send_message(bonding->conn, reply);
2681
bonding_request_cancel(bonding);
2682
bonding_request_free(bonding);
2685
static void pincode_cb(struct agent *agent, DBusError *err,
2686
const char *pincode, void *data)
2688
struct authentication_req *auth = data;
2689
struct btd_device *device = auth->device;
2690
struct btd_adapter *adapter = device_get_adapter(device);
2691
struct agent *adapter_agent = adapter_get_agent(adapter);
2693
if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2694
g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2696
if (auth->agent == adapter_agent || adapter_agent == NULL)
2699
if (agent_request_pincode(adapter_agent, device, pincode_cb,
2700
auth->secure, auth, NULL) < 0)
2703
auth->agent = adapter_agent;
2708
/* No need to reply anything if the authentication already failed */
2709
if (auth->cb == NULL)
2712
((agent_pincode_cb) auth->cb)(agent, err, pincode, device);
2714
device->authr->cb = NULL;
2715
device->authr->agent = NULL;
2718
static void confirm_cb(struct agent *agent, DBusError *err, void *data)
2720
struct authentication_req *auth = data;
2721
struct btd_device *device = auth->device;
2722
struct btd_adapter *adapter = device_get_adapter(device);
2723
struct agent *adapter_agent = adapter_get_agent(adapter);
2725
if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2726
g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2728
if (auth->agent == adapter_agent || adapter_agent == NULL)
2731
if (agent_request_confirmation(adapter_agent, device,
2732
auth->passkey, confirm_cb,
2736
auth->agent = adapter_agent;
2741
/* No need to reply anything if the authentication already failed */
2742
if (auth->cb == NULL)
2745
((agent_cb) auth->cb)(agent, err, device);
2747
device->authr->cb = NULL;
2748
device->authr->agent = NULL;
2751
static void passkey_cb(struct agent *agent, DBusError *err,
2752
uint32_t passkey, void *data)
2754
struct authentication_req *auth = data;
2755
struct btd_device *device = auth->device;
2756
struct btd_adapter *adapter = device_get_adapter(device);
2757
struct agent *adapter_agent = adapter_get_agent(adapter);
2759
if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2760
g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2762
if (auth->agent == adapter_agent || adapter_agent == NULL)
2765
if (agent_request_passkey(adapter_agent, device, passkey_cb,
2769
auth->agent = adapter_agent;
2774
/* No need to reply anything if the authentication already failed */
2775
if (auth->cb == NULL)
2778
((agent_passkey_cb) auth->cb)(agent, err, passkey, device);
2780
device->authr->cb = NULL;
2781
device->authr->agent = NULL;
2784
static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
2786
struct authentication_req *auth = data;
2787
struct btd_device *device = auth->device;
2788
struct btd_adapter *adapter = device_get_adapter(device);
2789
struct agent *adapter_agent = adapter_get_agent(adapter);
2791
if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2792
g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2794
/* Request a pincode if we fail to display one */
2795
if (auth->agent == adapter_agent || adapter_agent == NULL) {
2796
if (agent_request_pincode(agent, device, pincode_cb,
2797
auth->secure, auth, NULL) < 0)
2802
if (agent_display_pincode(adapter_agent, device, auth->pincode,
2803
display_pincode_cb, auth, NULL) < 0)
2806
auth->agent = adapter_agent;
2811
/* No need to reply anything if the authentication already failed */
2812
if (auth->cb == NULL)
2815
((agent_pincode_cb) auth->cb)(agent, err, auth->pincode, device);
2817
g_free(device->authr->pincode);
2818
device->authr->pincode = NULL;
2819
device->authr->cb = NULL;
2820
device->authr->agent = NULL;
2824
static struct authentication_req *new_auth(struct btd_device *device,
2825
auth_type_t type, gboolean secure,
2828
struct authentication_req *auth;
2829
struct agent *agent;
2832
ba2str(&device->bdaddr, addr);
2833
DBG("Requesting agent authentication for %s", addr);
2835
if (device->authr) {
2836
error("Authentication already requested for %s", addr);
2840
agent = device_get_agent(device);
2842
error("No agent available for request type %d", type);
2846
auth = g_new0(struct authentication_req, 1);
2847
auth->agent = agent;
2848
auth->device = device;
2851
auth->secure = secure;
2852
device->authr = auth;
2857
int device_request_pincode(struct btd_device *device, gboolean secure,
2860
struct authentication_req *auth;
2863
auth = new_auth(device, AUTH_TYPE_PINCODE, secure, cb);
2867
err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
2870
error("Failed requesting authentication");
2871
device_auth_req_free(device);
2877
int device_request_passkey(struct btd_device *device, void *cb)
2879
struct authentication_req *auth;
2882
auth = new_auth(device, AUTH_TYPE_PASSKEY, FALSE, cb);
2886
err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
2889
error("Failed requesting authentication");
2890
device_auth_req_free(device);
2896
int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
2899
struct authentication_req *auth;
2902
auth = new_auth(device, AUTH_TYPE_CONFIRM, FALSE, cb);
2906
auth->passkey = passkey;
2908
err = agent_request_confirmation(auth->agent, device, passkey,
2909
confirm_cb, auth, NULL);
2911
error("Failed requesting authentication");
2912
device_auth_req_free(device);
2918
int device_notify_passkey(struct btd_device *device, uint32_t passkey,
2921
struct authentication_req *auth;
2924
if (device->authr) {
2925
auth = device->authr;
2926
if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
2929
auth = new_auth(device, AUTH_TYPE_NOTIFY_PASSKEY, FALSE, NULL);
2934
err = agent_display_passkey(auth->agent, device, passkey, entered);
2936
error("Failed requesting authentication");
2937
device_auth_req_free(device);
2943
int device_notify_pincode(struct btd_device *device, gboolean secure,
2944
const char *pincode, void *cb)
2946
struct authentication_req *auth;
2949
auth = new_auth(device, AUTH_TYPE_NOTIFY_PINCODE, secure, cb);
2953
auth->pincode = g_strdup(pincode);
2955
err = agent_display_pincode(auth->agent, device, pincode,
2956
display_pincode_cb, auth, NULL);
2958
error("Failed requesting authentication");
2959
device_auth_req_free(device);
2965
static void cancel_authentication(struct authentication_req *auth)
2967
struct btd_device *device;
2968
struct agent *agent;
2971
if (!auth || !auth->cb)
2974
device = auth->device;
2975
agent = auth->agent;
2977
dbus_error_init(&err);
2978
dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL);
2980
switch (auth->type) {
2981
case AUTH_TYPE_PINCODE:
2982
((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
2984
case AUTH_TYPE_CONFIRM:
2985
((agent_cb) auth->cb)(agent, &err, device);
2987
case AUTH_TYPE_PASSKEY:
2988
((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
2990
case AUTH_TYPE_NOTIFY_PASSKEY:
2991
/* User Notify doesn't require any reply */
2993
case AUTH_TYPE_NOTIFY_PINCODE:
2994
((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
2998
dbus_error_free(&err);
3002
void device_cancel_authentication(struct btd_device *device, gboolean aborted)
3004
struct authentication_req *auth = device->authr;
3010
ba2str(&device->bdaddr, addr);
3011
DBG("Canceling authentication request for %s", addr);
3014
agent_cancel(auth->agent);
3017
cancel_authentication(auth);
3019
device_auth_req_free(device);
3022
gboolean device_is_authenticating(struct btd_device *device)
3024
return (device->authr != NULL);
3027
gboolean device_is_authorizing(struct btd_device *device)
3029
return device->authorizing;
3032
void device_set_authorizing(struct btd_device *device, gboolean auth)
3034
device->authorizing = auth;
3037
void device_register_services(DBusConnection *conn, struct btd_device *device,
3038
GSList *prim_list, int psm)
3040
device->primaries = g_slist_concat(device->primaries, prim_list);
3041
device->services = attrib_client_register(conn, device, psm, NULL,
3045
GSList *btd_device_get_primaries(struct btd_device *device)
3047
return device->primaries;
3050
void btd_device_add_uuid(struct btd_device *device, const char *uuid)
3055
if (g_slist_find_custom(device->uuids, uuid,
3056
(GCompareFunc) strcasecmp))
3059
new_uuid = g_strdup(uuid);
3060
uuid_list = g_slist_append(NULL, new_uuid);
3062
device_probe_drivers(device, uuid_list);
3065
g_slist_free(uuid_list);
3067
store_profiles(device);
3068
services_changed(device);
3071
const sdp_record_t *btd_device_get_record(struct btd_device *device,
3076
if (device->tmp_records) {
3077
const sdp_record_t *record;
3079
record = find_record_in_list(device->tmp_records, uuid);
3084
adapter_get_address(device->adapter, &src);
3086
device->tmp_records = read_records(&src, &device->bdaddr);
3087
if (!device->tmp_records)
3090
return find_record_in_list(device->tmp_records, uuid);
3093
int btd_register_device_driver(struct btd_device_driver *driver)
3095
device_drivers = g_slist_append(device_drivers, driver);
3100
void btd_unregister_device_driver(struct btd_device_driver *driver)
3102
device_drivers = g_slist_remove(device_drivers, driver);
3105
struct btd_device *btd_device_ref(struct btd_device *device)
3109
DBG("%p: ref=%d", device, device->ref);
3114
void btd_device_unref(struct btd_device *device)
3116
DBusConnection *conn = get_dbus_connection();
3121
DBG("%p: ref=%d", device, device->ref);
3123
if (device->ref > 0)
3126
path = g_strdup(device->path);
3128
g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);
3133
void device_set_class(struct btd_device *device, uint32_t value)
3135
DBusConnection *conn = get_dbus_connection();
3137
emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Class",
3138
DBUS_TYPE_UINT32, &value);
3141
static gboolean notify_attios(gpointer user_data)
3143
struct btd_device *device = user_data;
3145
if (device->attrib == NULL)
3148
g_slist_foreach(device->attios_offline, attio_connected, device->attrib);
3149
device->attios = g_slist_concat(device->attios, device->attios_offline);
3150
device->attios_offline = NULL;
3155
guint btd_device_add_attio_callback(struct btd_device *device,
3156
attio_connect_cb cfunc,
3157
attio_disconnect_cb dcfunc,
3160
struct attio_data *attio;
3161
static guint attio_id = 0;
3163
DBG("%p registered ATT connection callback", device);
3165
attio = g_new0(struct attio_data, 1);
3166
attio->id = ++attio_id;
3167
attio->cfunc = cfunc;
3168
attio->dcfunc = dcfunc;
3169
attio->user_data = user_data;
3171
if (device->attrib && cfunc) {
3172
device->attios_offline = g_slist_append(device->attios_offline,
3174
g_idle_add(notify_attios, device);
3178
device->attios = g_slist_append(device->attios, attio);
3180
if (device->auto_id == 0)
3181
device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
3182
att_connect, device,
3183
att_connect_dispatched);
3188
static int attio_id_cmp(gconstpointer a, gconstpointer b)
3190
const struct attio_data *attio = a;
3191
guint id = GPOINTER_TO_UINT(b);
3193
return attio->id - id;
3196
gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
3198
struct attio_data *attio;
3201
l = g_slist_find_custom(device->attios, GUINT_TO_POINTER(id),
3205
device->attios = g_slist_remove(device->attios, attio);
3207
l = g_slist_find_custom(device->attios_offline,
3208
GUINT_TO_POINTER(id), attio_id_cmp);
3213
device->attios_offline = g_slist_remove(device->attios_offline,
3219
if (device->attios != NULL || device->attios_offline != NULL)
3222
if (device->auto_id) {
3223
g_source_remove(device->auto_id);
3224
device->auto_id = 0;
3227
att_cleanup(device);
3232
void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
3233
uint16_t vendor_id, uint16_t product_id,
3234
uint16_t product_ver)
3236
device_set_vendor(device, vendor_id);
3237
device_set_vendor_src(device, vendor_id_src);
3238
device_set_product(device, product_id);
3239
device_set_version(device, product_ver);