Initialize Tizen 2.3
[framework/connectivity/bluez.git] / wearable / src / device.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2006-2010  Nokia Corporation
6  *  Copyright (C) 2004-2010  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 <sys/ioctl.h>
35 #include <errno.h>
36
37 #include <bluetooth/bluetooth.h>
38 #include <bluetooth/uuid.h>
39 #include <bluetooth/sdp.h>
40 #include <bluetooth/sdp_lib.h>
41
42 #include <glib.h>
43 #include <dbus/dbus.h>
44 #include <gdbus.h>
45
46 #include "log.h"
47
48 #include "att.h"
49 #include "hcid.h"
50 #include "adapter.h"
51 #include "gattrib.h"
52 #include "attio.h"
53 #include "device.h"
54 #include "dbus-common.h"
55 #include "error.h"
56 #include "glib-helper.h"
57 #include "sdp-client.h"
58 #include "gatt.h"
59 #include "agent.h"
60 #include "sdp-xml.h"
61 #include "storage.h"
62 #include "btio.h"
63 #include "attrib-server.h"
64 #include "attrib/client.h"
65
66 #define DISCONNECT_TIMER        2
67 #define DISCOVERY_TIMER         2
68
69 #define AUTO_CONNECTION_INTERVAL        5 /* Next connection attempt */
70
71 /* When all services should trust a remote device */
72 #define GLOBAL_TRUST "[all]"
73
74 #define APPEARANCE_CHR_UUID 0x2a01
75
76 struct btd_disconnect_data {
77         guint id;
78         disconnect_watch watch;
79         void *user_data;
80         GDestroyNotify destroy;
81 };
82
83 struct bonding_req {
84         DBusConnection *conn;
85         DBusMessage *msg;
86         guint listener_id;
87         struct btd_device *device;
88 };
89
90 struct authentication_req {
91         auth_type_t type;
92         void *cb;
93         struct agent *agent;
94         struct btd_device *device;
95         uint32_t passkey;
96         char *pincode;
97         gboolean secure;
98 };
99
100 struct browse_req {
101         DBusConnection *conn;
102         DBusMessage *msg;
103         struct btd_device *device;
104         GSList *match_uuids;
105         GSList *profiles_added;
106         GSList *profiles_removed;
107         sdp_list_t *records;
108         int search_uuid;
109         int reconnect_attempt;
110         guint listener_id;
111 };
112
113 struct attio_data {
114         guint id;
115         attio_connect_cb cfunc;
116         attio_disconnect_cb dcfunc;
117         gpointer user_data;
118 };
119
120 typedef void (*attio_error_cb) (const GError *gerr, gpointer user_data);
121 typedef void (*attio_success_cb) (gpointer user_data);
122
123 struct att_callbacks {
124         attio_error_cb error;           /* Callback for error */
125         attio_success_cb success;       /* Callback for success */
126         gpointer user_data;
127 };
128
129 struct btd_device {
130         bdaddr_t        bdaddr;
131         uint8_t         bdaddr_type;
132         gchar           *path;
133         char            name[MAX_NAME_LENGTH + 1];
134         char            *alias;
135         uint16_t        vendor_src;
136         uint16_t        vendor;
137         uint16_t        product;
138         uint16_t        version;
139         struct btd_adapter      *adapter;
140         GSList          *uuids;
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 */
145         gboolean        temporary;
146         struct agent    *agent;
147         guint           disconn_timer;
148         guint           discov_timer;
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 */
153         GAttrib         *attrib;
154         GSList          *attios;
155         GSList          *attios_offline;
156         guint           attachid;               /* Attrib server attach */
157         guint           auto_id;                /* Auto connect source id */
158
159         gboolean        connected;
160
161         sdp_list_t      *tmp_records;
162
163         gboolean        trusted;
164         gboolean        paired;
165         gboolean        blocked;
166         gboolean        bonded;
167         gboolean        auto_connect;
168
169         gboolean        authorizing;
170         gint            ref;
171
172         GIOChannel      *att_io;
173         guint           cleanup_id;
174
175 #ifdef __TIZEN_PATCH__
176         guint           attio_id;
177         gboolean        gatt_connected;
178         uint8_t  disc_reason;
179 #endif
180 };
181
182 static uint16_t uuid_list[] = {
183         L2CAP_UUID,
184         PNP_INFO_SVCLASS_ID,
185         PUBLIC_BROWSE_GROUP,
186         0
187 };
188
189 static GSList *device_drivers = NULL;
190
191 static void browse_request_free(struct browse_req *req)
192 {
193         if (req->listener_id)
194                 g_dbus_remove_watch(req->conn, req->listener_id);
195         if (req->msg)
196                 dbus_message_unref(req->msg);
197         if (req->conn)
198                 dbus_connection_unref(req->conn);
199         if (req->device)
200                 btd_device_unref(req->device);
201         g_slist_free_full(req->profiles_added, g_free);
202         g_slist_free(req->profiles_removed);
203         if (req->records)
204                 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
205
206         g_free(req);
207 }
208
209 static void att_cleanup(struct btd_device *device)
210 {
211         if (device->attachid) {
212                 attrib_channel_detach(device->attrib, device->attachid);
213                 device->attachid = 0;
214         }
215
216         if (device->cleanup_id) {
217                 g_source_remove(device->cleanup_id);
218                 device->cleanup_id = 0;
219         }
220
221         if (device->att_io) {
222                 g_io_channel_shutdown(device->att_io, FALSE, NULL);
223                 g_io_channel_unref(device->att_io);
224                 device->att_io = NULL;
225         }
226
227         if (device->attrib) {
228                 g_attrib_unref(device->attrib);
229                 device->attrib = NULL;
230         }
231 }
232
233 static void browse_request_cancel(struct browse_req *req)
234 {
235         struct btd_device *device = req->device;
236         struct btd_adapter *adapter = device->adapter;
237         bdaddr_t src;
238
239         if (device_is_creating(device, NULL))
240                 device_set_temporary(device, TRUE);
241
242         adapter_get_address(adapter, &src);
243
244         bt_cancel_discovery(&src, &device->bdaddr);
245
246         att_cleanup(device);
247
248         device->browse = NULL;
249         browse_request_free(req);
250 }
251
252 static void device_free(gpointer user_data)
253 {
254         struct btd_device *device = user_data;
255         struct btd_adapter *adapter = device->adapter;
256         struct agent *agent = adapter_get_agent(adapter);
257
258         if (device->agent)
259                 agent_free(device->agent);
260
261         if (agent && (agent_is_busy(agent, device) ||
262                                 agent_is_busy(agent, device->authr)))
263                 agent_cancel(agent);
264
265         g_slist_free_full(device->services, g_free);
266         g_slist_free_full(device->uuids, g_free);
267         g_slist_free_full(device->primaries, g_free);
268         g_slist_free_full(device->attios, g_free);
269         g_slist_free_full(device->attios_offline, g_free);
270
271         att_cleanup(device);
272
273         if (device->tmp_records)
274                 sdp_list_free(device->tmp_records,
275                                         (sdp_free_func_t) sdp_record_free);
276
277         if (device->disconn_timer)
278                 g_source_remove(device->disconn_timer);
279
280         if (device->discov_timer)
281                 g_source_remove(device->discov_timer);
282
283         if (device->auto_id)
284                 g_source_remove(device->auto_id);
285
286         DBG("%p", device);
287
288         if (device->authr)
289                 g_free(device->authr->pincode);
290         g_free(device->authr);
291         g_free(device->path);
292         g_free(device->alias);
293         g_free(device);
294 }
295
296 gboolean device_is_bredr(struct btd_device *device)
297 {
298         return (device->bdaddr_type == BDADDR_BREDR);
299 }
300
301 gboolean device_is_le(struct btd_device *device)
302 {
303         return (device->bdaddr_type != BDADDR_BREDR);
304 }
305
306 gboolean device_is_paired(struct btd_device *device)
307 {
308         return device->paired;
309 }
310
311 gboolean device_is_bonded(struct btd_device *device)
312 {
313         return device->bonded;
314 }
315
316 gboolean device_is_trusted(struct btd_device *device)
317 {
318         return device->trusted;
319 }
320
321 static DBusMessage *get_properties(DBusConnection *conn,
322                                 DBusMessage *msg, void *user_data)
323 {
324         struct btd_device *device = user_data;
325         struct btd_adapter *adapter = device->adapter;
326         DBusMessage *reply;
327         DBusMessageIter iter;
328         DBusMessageIter dict;
329         bdaddr_t src;
330         char name[MAX_NAME_LENGTH + 1], srcaddr[18], dstaddr[18];
331         char **str;
332         const char *ptr, *icon = NULL;
333         dbus_bool_t boolean;
334         uint32_t class;
335         uint16_t app;
336         int i;
337         GSList *l;
338
339         ba2str(&device->bdaddr, dstaddr);
340
341         reply = dbus_message_new_method_return(msg);
342         if (!reply)
343                 return NULL;
344
345         dbus_message_iter_init_append(reply, &iter);
346
347         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
348                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
349                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
350                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
351
352         /* Address */
353         ptr = dstaddr;
354         dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr);
355
356         /* Name */
357         ptr = NULL;
358         memset(name, 0, sizeof(name));
359         adapter_get_address(adapter, &src);
360         ba2str(&src, srcaddr);
361
362         ptr = device->name;
363         dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr);
364
365         /* Alias (fallback to name or address) */
366         if (device->alias != NULL)
367                 ptr = device->alias;
368         else if (strlen(ptr) == 0) {
369                 g_strdelimit(dstaddr, ":", '-');
370                 ptr = dstaddr;
371         }
372
373         dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr);
374
375         /* Class */
376         if (read_remote_class(&src, &device->bdaddr, &class) == 0) {
377                 icon = class_to_icon(class);
378
379                 dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class);
380         } else if (read_remote_appearance(&src, &device->bdaddr,
381                                                 device->bdaddr_type, &app) == 0)
382                 /* Appearance */
383                 icon = gap_appearance_to_icon(app);
384
385         dict_append_entry(&dict, "Icon", DBUS_TYPE_STRING, &icon);
386
387         /* Vendor */
388         if (device->vendor)
389                 dict_append_entry(&dict, "Vendor", DBUS_TYPE_UINT16,
390                                                         &device->vendor);
391
392         /* Vendor Source*/
393         if (device->vendor_src)
394                 dict_append_entry(&dict, "VendorSource", DBUS_TYPE_UINT16,
395                                                         &device->vendor_src);
396
397         /* Product */
398         if (device->product)
399                 dict_append_entry(&dict, "Product", DBUS_TYPE_UINT16,
400                                                         &device->product);
401
402         /* Version */
403         if (device->version)
404                 dict_append_entry(&dict, "Version", DBUS_TYPE_UINT16,
405                                                         &device->version);
406
407         /* Paired */
408         boolean = device_is_paired(device);
409         dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean);
410
411         /* Trusted */
412         boolean = device_is_trusted(device);
413         dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);
414
415         /* Blocked */
416         boolean = device->blocked;
417         dict_append_entry(&dict, "Blocked", DBUS_TYPE_BOOLEAN, &boolean);
418
419         /* Connected */
420         dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,
421                                                         &device->connected);
422
423 #ifdef __TIZEN_PATCH__
424         /* GATT Connected */
425         dict_append_entry(&dict, "GattConnected", DBUS_TYPE_BOOLEAN,
426                                                         &device->gatt_connected);
427 #endif
428
429         /* UUIDs */
430         str = g_new0(char *, g_slist_length(device->uuids) + 1);
431         for (i = 0, l = device->uuids; l; l = l->next, i++)
432                 str[i] = l->data;
433         dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &str, i);
434         g_free(str);
435
436         /* Services */
437         str = g_new0(char *, g_slist_length(device->services) + 1);
438         for (i = 0, l = device->services; l; l = l->next, i++)
439                 str[i] = l->data;
440         dict_append_array(&dict, "Services", DBUS_TYPE_OBJECT_PATH, &str, i);
441         g_free(str);
442
443         /* Adapter */
444         ptr = adapter_get_path(adapter);
445         dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
446
447         dbus_message_iter_close_container(&iter, &dict);
448
449         return reply;
450 }
451
452 static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
453                                         const char *alias, void *data)
454 {
455         struct btd_device *device = data;
456         struct btd_adapter *adapter = device->adapter;
457         char srcaddr[18], dstaddr[18];
458         bdaddr_t src;
459         int err;
460
461         /* No change */
462         if ((device->alias == NULL && g_str_equal(alias, "")) ||
463                         g_strcmp0(device->alias, alias) == 0)
464                 return dbus_message_new_method_return(msg);
465
466         adapter_get_address(adapter, &src);
467         ba2str(&src, srcaddr);
468         ba2str(&device->bdaddr, dstaddr);
469
470         /* Remove alias if empty string */
471         err = write_device_alias(srcaddr, dstaddr,
472                         g_str_equal(alias, "") ? NULL : alias);
473         if (err < 0)
474                 return btd_error_failed(msg, strerror(-err));
475
476         g_free(device->alias);
477         device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
478
479         emit_property_changed(conn, dbus_message_get_path(msg),
480                                 DEVICE_INTERFACE, "Alias",
481                                 DBUS_TYPE_STRING, &alias);
482
483         return dbus_message_new_method_return(msg);
484 }
485
486 static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
487                                         gboolean value, void *data)
488 {
489         struct btd_device *device = data;
490         struct btd_adapter *adapter = device->adapter;
491         char srcaddr[18], dstaddr[18];
492         bdaddr_t src;
493         int err;
494
495         if (device->trusted == value)
496                 return dbus_message_new_method_return(msg);
497
498         adapter_get_address(adapter, &src);
499         ba2str(&src, srcaddr);
500         ba2str(&device->bdaddr, dstaddr);
501
502         err = write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
503         if (err < 0)
504                 return btd_error_failed(msg, strerror(-err));
505
506         device->trusted = value;
507
508         emit_property_changed(conn, dbus_message_get_path(msg),
509                                 DEVICE_INTERFACE, "Trusted",
510                                 DBUS_TYPE_BOOLEAN, &value);
511
512         return dbus_message_new_method_return(msg);
513 }
514
515 static void driver_remove(struct btd_device_driver *driver,
516                                                 struct btd_device *device)
517 {
518         driver->remove(device);
519
520         device->drivers = g_slist_remove(device->drivers, driver);
521 }
522
523 static gboolean do_disconnect(gpointer user_data)
524 {
525         struct btd_device *device = user_data;
526
527         device->disconn_timer = 0;
528
529         btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
530                                                         device->bdaddr_type);
531
532         return FALSE;
533 }
534
535 int device_block(DBusConnection *conn, struct btd_device *device,
536                                                 gboolean update_only)
537 {
538         int err = 0;
539         bdaddr_t src;
540
541         if (device->blocked)
542                 return 0;
543
544         if (device->connected)
545                 do_disconnect(device);
546
547         g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
548
549         if (!update_only)
550                 err = btd_adapter_block_address(device->adapter,
551                                         &device->bdaddr, device->bdaddr_type);
552
553         if (err < 0)
554                 return err;
555
556         device->blocked = TRUE;
557
558         adapter_get_address(device->adapter, &src);
559
560         err = write_blocked(&src, &device->bdaddr, TRUE);
561         if (err < 0)
562                 error("write_blocked(): %s (%d)", strerror(-err), -err);
563
564         device_set_temporary(device, FALSE);
565
566         emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Blocked",
567                                         DBUS_TYPE_BOOLEAN, &device->blocked);
568
569         return 0;
570 }
571
572 int device_unblock(DBusConnection *conn, struct btd_device *device,
573                                 gboolean silent, gboolean update_only)
574 {
575         int err = 0;
576         bdaddr_t src;
577
578         if (!device->blocked)
579                 return 0;
580
581         if (!update_only)
582                 err = btd_adapter_unblock_address(device->adapter,
583                                         &device->bdaddr, device->bdaddr_type);
584
585         if (err < 0)
586                 return err;
587
588         device->blocked = FALSE;
589
590         adapter_get_address(device->adapter, &src);
591
592         err = write_blocked(&src, &device->bdaddr, FALSE);
593         if (err < 0)
594                 error("write_blocked(): %s (%d)", strerror(-err), -err);
595
596         if (!silent) {
597                 emit_property_changed(conn, device->path,
598                                         DEVICE_INTERFACE, "Blocked",
599                                         DBUS_TYPE_BOOLEAN, &device->blocked);
600                 device_probe_drivers(device, device->uuids);
601         }
602
603         return 0;
604 }
605
606 static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
607                                                 gboolean value, void *data)
608 {
609         struct btd_device *device = data;
610         int err;
611
612         if (value)
613                 err = device_block(conn, device, FALSE);
614         else
615                 err = device_unblock(conn, device, FALSE, FALSE);
616
617         switch (-err) {
618         case 0:
619                 return dbus_message_new_method_return(msg);
620         case EINVAL:
621                 return btd_error_failed(msg, "Kernel lacks blacklist support");
622         default:
623                 return btd_error_failed(msg, strerror(-err));
624         }
625 }
626
627 static DBusMessage *set_property(DBusConnection *conn,
628                                 DBusMessage *msg, void *data)
629 {
630         DBusMessageIter iter;
631         DBusMessageIter sub;
632         const char *property;
633
634         if (!dbus_message_iter_init(msg, &iter))
635                 return btd_error_invalid_args(msg);
636
637         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
638                 return btd_error_invalid_args(msg);
639
640         dbus_message_iter_get_basic(&iter, &property);
641         dbus_message_iter_next(&iter);
642
643         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
644                 return btd_error_invalid_args(msg);
645         dbus_message_iter_recurse(&iter, &sub);
646
647         if (g_str_equal("Trusted", property)) {
648                 dbus_bool_t value;
649                 if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
650                         return btd_error_invalid_args(msg);
651                 dbus_message_iter_get_basic(&sub, &value);
652
653                 return set_trust(conn, msg, value, data);
654         } else if (g_str_equal("Alias", property)) {
655                 const char *alias;
656
657                 if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
658                         return btd_error_invalid_args(msg);
659                 dbus_message_iter_get_basic(&sub, &alias);
660
661                 return set_alias(conn, msg, alias, data);
662         } else if (g_str_equal("Blocked", property)) {
663                 dbus_bool_t value;
664
665                 if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
666                         return btd_error_invalid_args(msg);
667
668                 dbus_message_iter_get_basic(&sub, &value);
669
670                 return set_blocked(conn, msg, value, data);
671         }
672
673         return btd_error_invalid_args(msg);
674 }
675
676 static void discover_services_req_exit(DBusConnection *conn, void *user_data)
677 {
678         struct browse_req *req = user_data;
679
680         DBG("DiscoverServices requestor exited");
681
682         browse_request_cancel(req);
683 }
684
685 static DBusMessage *discover_services(DBusConnection *conn,
686                                         DBusMessage *msg, void *user_data)
687 {
688         struct btd_device *device = user_data;
689         const char *pattern;
690         int err;
691
692         if (device->browse)
693                 return btd_error_in_progress(msg);
694
695         if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
696                                                 DBUS_TYPE_INVALID) == FALSE)
697                 return btd_error_invalid_args(msg);
698
699         if (strlen(pattern) == 0) {
700                 err = device_browse_sdp(device, conn, msg, NULL, FALSE);
701                 if (err < 0)
702                         goto fail;
703         } else {
704                 uuid_t uuid;
705
706                 if (bt_string2uuid(&uuid, pattern) < 0)
707                         return btd_error_invalid_args(msg);
708
709                 sdp_uuid128_to_uuid(&uuid);
710
711                 err = device_browse_sdp(device, conn, msg, &uuid, FALSE);
712                 if (err < 0)
713                         goto fail;
714         }
715
716         return NULL;
717
718 fail:
719         return btd_error_failed(msg, strerror(-err));
720 }
721
722 static const char *browse_request_get_requestor(struct browse_req *req)
723 {
724         if (!req->msg)
725                 return NULL;
726
727         return dbus_message_get_sender(req->msg);
728 }
729
730 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
731                                                         const char *record)
732 {
733         DBusMessageIter entry;
734
735         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
736                                                         NULL, &entry);
737
738         dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
739
740         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
741
742         dbus_message_iter_close_container(dict, &entry);
743 }
744
745 static void discover_services_reply(struct browse_req *req, int err,
746                                                         sdp_list_t *recs)
747 {
748         DBusMessage *reply;
749         DBusMessageIter iter, dict;
750         sdp_list_t *seq;
751
752         if (!req->msg)
753                 return;
754
755         if (err) {
756                 const char *err_if;
757
758                 if (err == -EHOSTDOWN)
759                         err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
760                 else
761                         err_if = ERROR_INTERFACE ".Failed";
762
763                 reply = dbus_message_new_error(req->msg, err_if,
764                                                         strerror(-err));
765                 g_dbus_send_message(req->conn, reply);
766                 return;
767         }
768
769         reply = dbus_message_new_method_return(req->msg);
770         if (!reply)
771                 return;
772
773         dbus_message_iter_init_append(reply, &iter);
774
775         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
776                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
777                         DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
778                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
779
780         for (seq = recs; seq; seq = seq->next) {
781                 sdp_record_t *rec = (sdp_record_t *) seq->data;
782                 GString *result;
783
784                 if (!rec)
785                         break;
786
787                 result = g_string_new(NULL);
788
789                 convert_sdp_record_to_xml(rec, result,
790                                 (void *) g_string_append);
791
792                 if (result->len)
793                         iter_append_record(&dict, rec->handle, result->str);
794
795                 g_string_free(result, TRUE);
796         }
797
798         dbus_message_iter_close_container(&iter, &dict);
799
800         g_dbus_send_message(req->conn, reply);
801 }
802
803 static DBusMessage *cancel_discover(DBusConnection *conn,
804                                         DBusMessage *msg, void *user_data)
805 {
806         struct btd_device *device = user_data;
807         const char *sender = dbus_message_get_sender(msg);
808         const char *requestor;
809
810         if (!device->browse)
811                 return btd_error_does_not_exist(msg);
812
813         if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
814                                         "DiscoverServices"))
815                 return btd_error_not_authorized(msg);
816
817         requestor = browse_request_get_requestor(device->browse);
818
819         /* only the discover requestor can cancel the inquiry process */
820         if (!requestor || !g_str_equal(requestor, sender))
821                 return btd_error_not_authorized(msg);
822
823         discover_services_reply(device->browse, -ECANCELED, NULL);
824
825         browse_request_cancel(device->browse);
826
827         return dbus_message_new_method_return(msg);
828 }
829
830 static void bonding_request_cancel(struct bonding_req *bonding)
831 {
832         struct btd_device *device = bonding->device;
833         struct btd_adapter *adapter = device->adapter;
834
835         adapter_cancel_bonding(adapter, &device->bdaddr);
836 }
837
838 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
839 {
840         DBusConnection *conn = get_dbus_connection();
841
842         if (device->bonding)
843                 bonding_request_cancel(device->bonding);
844
845         if (device->browse) {
846                 discover_services_reply(device->browse, -ECANCELED, NULL);
847                 browse_request_cancel(device->browse);
848         }
849
850         if (msg)
851                 device->disconnects = g_slist_append(device->disconnects,
852                                                 dbus_message_ref(msg));
853
854         if (device->disconn_timer)
855                 return;
856
857         while (device->watches) {
858                 struct btd_disconnect_data *data = device->watches->data;
859
860                 if (data->watch)
861                         /* temporary is set if device is going to be removed */
862                         data->watch(device, device->temporary,
863                                                         data->user_data);
864
865                 /* Check if the watch has been removed by callback function */
866                 if (!g_slist_find(device->watches, data))
867                         continue;
868
869                 device->watches = g_slist_remove(device->watches, data);
870                 g_free(data);
871         }
872
873         device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
874                                                 do_disconnect, device);
875
876         g_dbus_emit_signal(conn, device->path,
877                         DEVICE_INTERFACE, "DisconnectRequested",
878                         DBUS_TYPE_INVALID);
879 }
880
881 static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
882                                                         void *user_data)
883 {
884         struct btd_device *device = user_data;
885
886         if (!device->connected)
887                 return btd_error_not_connected(msg);
888
889         device_request_disconnect(device, msg);
890
891         return NULL;
892 }
893
894 static void attio_connected(gpointer data, gpointer user_data)
895 {
896         struct attio_data *attio = data;
897         GAttrib *attrib = user_data;
898
899         if (attio->cfunc)
900                 attio->cfunc(attrib, attio->user_data);
901 }
902
903 static void attio_disconnected(gpointer data, gpointer user_data)
904 {
905         struct attio_data *attio = data;
906
907         if (attio->dcfunc)
908                 attio->dcfunc(attio->user_data);
909 }
910
911 #ifdef __TIZEN_PATCH__
912 void device_set_disconnect_reason(struct btd_device *device, uint8_t reason)
913 {
914         device->disc_reason = reason;
915 }
916
917 void device_set_attrib(struct btd_device *device, guint attachid, GAttrib *attrib)
918 {
919         if (device == NULL) {
920                 error("device is NULL");
921                 return;
922         }
923
924         device->attachid = attachid;
925         device->attrib = g_attrib_ref(attrib);
926 }
927
928 void device_set_gatt_connected(struct btd_device *device, gboolean connected)
929 {
930         DBusConnection *conn = get_dbus_connection();
931
932         if (device == NULL) {
933                 error("device is NULL");
934                 return;
935         }
936
937         if (device->gatt_connected == connected)
938                 return;
939
940         device->gatt_connected = connected;
941
942         DBG("GattConnected %d", connected);
943
944         emit_property_changed(conn, device->path,
945                         DEVICE_INTERFACE, "GattConnected",
946                         DBUS_TYPE_BOOLEAN, &device->gatt_connected);
947 }
948
949 static void gatt_connected_cb(GAttrib *attrib, gpointer user_data)
950 {
951         DBusConnection *conn = get_dbus_connection();
952         struct btd_device *device = user_data;
953
954         device->gatt_connected = TRUE;
955
956         emit_property_changed(conn, device->path,
957                 DEVICE_INTERFACE, "GattConnected",
958                 DBUS_TYPE_BOOLEAN, &device->gatt_connected);
959 }
960
961 static void gatt_disconnected_cb(gpointer user_data)
962 {
963         DBusConnection *conn = get_dbus_connection();
964         struct btd_device *device = user_data;
965
966         btd_device_remove_attio_callback(device, device->attio_id);
967
968         device->gatt_connected = FALSE;
969
970         emit_property_changed(conn, device->path,
971                 DEVICE_INTERFACE, "GattConnected",
972                 DBUS_TYPE_BOOLEAN, &device->gatt_connected);
973 }
974
975 static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
976                                                 void *user_data)
977 {
978         struct btd_device *device = user_data;
979
980         if (device == NULL) {
981                 error("device is NULL");
982                 return btd_error_invalid_args(msg);
983         }
984
985         if (!device_is_le(device))
986                 return btd_error_not_supported(msg);
987
988         if (device->gatt_connected)
989                 return btd_error_already_connected(msg);
990
991         device->auto_connect = FALSE;
992
993         if (device->att_io == NULL)
994                 device->attio_id = btd_device_add_attio_callback(device,
995                                         gatt_connected_cb,
996                                         gatt_disconnected_cb,
997                                         device);
998
999         return dbus_message_new_method_return(msg);
1000 }
1001
1002 static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
1003                                                 void *user_data)
1004 {
1005         struct btd_device *device = user_data;
1006
1007         if (device == NULL) {
1008                 error("device is NULL");
1009                 return btd_error_invalid_args(msg);
1010         }
1011
1012         if (!device_is_le(device))
1013                 return btd_error_not_supported(msg);
1014
1015         if(!device->gatt_connected)
1016                 return btd_error_not_connected(msg);
1017
1018         DBG("device->attrib : %p", device->attrib);
1019         if (device->attrib) {
1020                 GIOChannel *io = g_attrib_get_channel(device->attrib);
1021                 if (io) {
1022                         if (device->attachid) {
1023                                 attrib_channel_detach(device->attrib,
1024                                         device->attachid);
1025                                 device->attachid = 0;
1026                         }
1027                         g_io_channel_shutdown(io, FALSE, NULL);
1028                         g_io_channel_unref(io);
1029                         g_slist_foreach(device->attios,
1030                                         attio_disconnected, NULL);
1031                 }
1032         }
1033
1034         return dbus_message_new_method_return(msg);
1035 }
1036 #endif
1037
1038 static const GDBusMethodTable device_methods[] = {
1039         { GDBUS_METHOD("GetProperties",
1040                                 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
1041                                 get_properties) },
1042         { GDBUS_METHOD("SetProperty",
1043                         GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
1044                         set_property) },
1045         { GDBUS_ASYNC_METHOD("DiscoverServices",
1046                         GDBUS_ARGS({ "pattern", "s" }),
1047                         GDBUS_ARGS({ "services", "a{us}" }),
1048                         discover_services) },
1049         { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
1050         { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, disconnect) },
1051 #ifdef __TIZEN_PATCH__
1052         { GDBUS_METHOD("ConnectLE", NULL, NULL, connect_le) },
1053         { GDBUS_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
1054 #endif
1055         { }
1056 };
1057
1058 static const GDBusSignalTable device_signals[] = {
1059         { GDBUS_SIGNAL("PropertyChanged",
1060                         GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
1061         { GDBUS_SIGNAL("DisconnectRequested", NULL) },
1062 #ifdef __TIZEN_PATCH__
1063         { GDBUS_SIGNAL("Disconnected",
1064                         GDBUS_ARGS({ "reason", "y" })) },
1065 #endif
1066         { }
1067 };
1068
1069 gboolean device_is_connected(struct btd_device *device)
1070 {
1071         return device->connected;
1072 }
1073
1074 void device_add_connection(struct btd_device *device, DBusConnection *conn)
1075 {
1076         if (device->connected) {
1077                 char addr[18];
1078                 ba2str(&device->bdaddr, addr);
1079                 error("Device %s is already connected", addr);
1080                 return;
1081         }
1082
1083         device->connected = TRUE;
1084
1085         emit_property_changed(conn, device->path,
1086                                         DEVICE_INTERFACE, "Connected",
1087                                         DBUS_TYPE_BOOLEAN, &device->connected);
1088 }
1089
1090 void device_remove_connection(struct btd_device *device, DBusConnection *conn)
1091 {
1092         if (!device->connected) {
1093                 char addr[18];
1094                 ba2str(&device->bdaddr, addr);
1095                 error("Device %s isn't connected", addr);
1096                 return;
1097         }
1098
1099         device->connected = FALSE;
1100
1101         if (device->disconn_timer > 0) {
1102                 g_source_remove(device->disconn_timer);
1103                 device->disconn_timer = 0;
1104         }
1105
1106         while (device->disconnects) {
1107                 DBusMessage *msg = device->disconnects->data;
1108
1109                 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1110                 device->disconnects = g_slist_remove(device->disconnects, msg);
1111         }
1112
1113         if (device_is_paired(device) && !device_is_bonded(device))
1114                 device_set_paired(device, FALSE);
1115
1116         emit_property_changed(conn, device->path,
1117                                         DEVICE_INTERFACE, "Connected",
1118                                         DBUS_TYPE_BOOLEAN, &device->connected);
1119
1120 #ifdef __TIZEN_PATCH__
1121         g_dbus_emit_signal(conn, device->path,
1122                         DEVICE_INTERFACE, "Disconnected",
1123                         DBUS_TYPE_BYTE, &device->disc_reason,
1124                         DBUS_TYPE_INVALID);
1125 #endif
1126 }
1127
1128 guint device_add_disconnect_watch(struct btd_device *device,
1129                                 disconnect_watch watch, void *user_data,
1130                                 GDestroyNotify destroy)
1131 {
1132         struct btd_disconnect_data *data;
1133         static guint id = 0;
1134
1135         data = g_new0(struct btd_disconnect_data, 1);
1136         data->id = ++id;
1137         data->watch = watch;
1138         data->user_data = user_data;
1139         data->destroy = destroy;
1140
1141         device->watches = g_slist_append(device->watches, data);
1142
1143         return data->id;
1144 }
1145
1146 void device_remove_disconnect_watch(struct btd_device *device, guint id)
1147 {
1148         GSList *l;
1149
1150         for (l = device->watches; l; l = l->next) {
1151                 struct btd_disconnect_data *data = l->data;
1152
1153                 if (data->id == id) {
1154                         device->watches = g_slist_remove(device->watches,
1155                                                         data);
1156                         if (data->destroy)
1157                                 data->destroy(data->user_data);
1158                         g_free(data);
1159                         return;
1160                 }
1161         }
1162 }
1163
1164 static void device_set_vendor(struct btd_device *device, uint16_t value)
1165 {
1166         DBusConnection *conn = get_dbus_connection();
1167
1168         if (device->vendor == value)
1169                 return;
1170
1171         device->vendor = value;
1172
1173         emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Vendor",
1174                                 DBUS_TYPE_UINT16, &value);
1175 }
1176
1177 static void device_set_vendor_src(struct btd_device *device, uint16_t value)
1178 {
1179         DBusConnection *conn = get_dbus_connection();
1180
1181         if (device->vendor_src == value)
1182                 return;
1183
1184         device->vendor_src = value;
1185
1186         emit_property_changed(conn, device->path, DEVICE_INTERFACE,
1187                                 "VendorSource", DBUS_TYPE_UINT16, &value);
1188 }
1189
1190 static void device_set_product(struct btd_device *device, uint16_t value)
1191 {
1192         DBusConnection *conn = get_dbus_connection();
1193
1194         if (device->product == value)
1195                 return;
1196
1197         device->product = value;
1198
1199         emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Product",
1200                                 DBUS_TYPE_UINT16, &value);
1201 }
1202
1203 static void device_set_version(struct btd_device *device, uint16_t value)
1204 {
1205         DBusConnection *conn = get_dbus_connection();
1206
1207         if (device->version == value)
1208                 return;
1209
1210         device->version = value;
1211
1212         emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Version",
1213                                 DBUS_TYPE_UINT16, &value);
1214 }
1215
1216 struct btd_device *device_create(DBusConnection *conn,
1217                                 struct btd_adapter *adapter,
1218                                 const gchar *address, uint8_t bdaddr_type)
1219 {
1220         gchar *address_up;
1221         struct btd_device *device;
1222         const gchar *adapter_path = adapter_get_path(adapter);
1223         bdaddr_t src;
1224         char srcaddr[18], alias[MAX_NAME_LENGTH + 1];
1225         uint16_t vendor, product, version;
1226
1227         device = g_try_malloc0(sizeof(struct btd_device));
1228         if (device == NULL)
1229                 return NULL;
1230
1231         address_up = g_ascii_strup(address, -1);
1232         device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
1233         g_strdelimit(device->path, ":", '_');
1234         g_free(address_up);
1235
1236         DBG("Creating device %s", device->path);
1237
1238         if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
1239                                 device_methods, device_signals, NULL,
1240                                 device, device_free) == FALSE) {
1241                 device_free(device);
1242                 return NULL;
1243         }
1244
1245         str2ba(address, &device->bdaddr);
1246         device->adapter = adapter;
1247         device->bdaddr_type = bdaddr_type;
1248 #ifdef __TIZEN_PATCH__
1249         device->gatt_connected = FALSE;
1250 #endif
1251         adapter_get_address(adapter, &src);
1252         ba2str(&src, srcaddr);
1253         read_device_name(srcaddr, address, device->name);
1254         if (read_device_alias(srcaddr, address, alias, sizeof(alias)) == 0)
1255                 device->alias = g_strdup(alias);
1256         device->trusted = read_trust(&src, address, GLOBAL_TRUST);
1257
1258         if (read_blocked(&src, &device->bdaddr))
1259                 device_block(conn, device, FALSE);
1260
1261         if (read_link_key(&src, &device->bdaddr, NULL, NULL) == 0) {
1262                 device_set_paired(device, TRUE);
1263                 device_set_bonded(device, TRUE);
1264         }
1265
1266         if (device_is_le(device) && has_longtermkeys(&src, &device->bdaddr,
1267                                                         device->bdaddr_type)) {
1268                 device_set_paired(device, TRUE);
1269                 device_set_bonded(device, TRUE);
1270         }
1271
1272         if (read_device_id(srcaddr, address, NULL, &vendor, &product, &version)
1273                                                                         == 0) {
1274                 device_set_vendor(device, vendor);
1275                 device_set_product(device, product);
1276                 device_set_version(device, version);
1277         }
1278
1279         return btd_device_ref(device);
1280 }
1281
1282 void device_set_name(struct btd_device *device, const char *name)
1283 {
1284         DBusConnection *conn = get_dbus_connection();
1285
1286         if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
1287                 return;
1288
1289         strncpy(device->name, name, MAX_NAME_LENGTH);
1290
1291         emit_property_changed(conn, device->path,
1292                                 DEVICE_INTERFACE, "Name",
1293                                 DBUS_TYPE_STRING, &name);
1294
1295         if (device->alias != NULL)
1296                 return;
1297
1298         emit_property_changed(conn, device->path,
1299                                 DEVICE_INTERFACE, "Alias",
1300                                 DBUS_TYPE_STRING, &name);
1301 }
1302
1303 void device_get_name(struct btd_device *device, char *name, size_t len)
1304 {
1305         strncpy(name, device->name, len);
1306 }
1307
1308 uint16_t btd_device_get_vendor(struct btd_device *device)
1309 {
1310         return device->vendor;
1311 }
1312
1313 uint16_t btd_device_get_vendor_src(struct btd_device *device)
1314 {
1315         return device->vendor_src;
1316 }
1317
1318 uint16_t btd_device_get_product(struct btd_device *device)
1319 {
1320         return device->product;
1321 }
1322
1323 uint16_t btd_device_get_version(struct btd_device *device)
1324 {
1325         return device->version;
1326 }
1327
1328 static void device_remove_stored(struct btd_device *device)
1329 {
1330         bdaddr_t src;
1331         char key[20];
1332         DBusConnection *conn = get_dbus_connection();
1333
1334         adapter_get_address(device->adapter, &src);
1335         ba2str(&device->bdaddr, key);
1336
1337         /* key: address only */
1338         delete_entry(&src, "profiles", key);
1339         delete_entry(&src, "trusts", key);
1340
1341         if (device_is_bonded(device)) {
1342                 delete_entry(&src, "linkkeys", key);
1343                 delete_entry(&src, "aliases", key);
1344
1345                 /* key: address#type */
1346                 sprintf(&key[17], "#%hhu", device->bdaddr_type);
1347
1348                 delete_entry(&src, "longtermkeys", key);
1349
1350                 device_set_bonded(device, FALSE);
1351                 device->paired = FALSE;
1352                 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
1353                                                         device->bdaddr_type);
1354         }
1355
1356         delete_all_records(&src, &device->bdaddr);
1357         delete_device_service(&src, &device->bdaddr, device->bdaddr_type);
1358
1359         if (device->blocked)
1360                 device_unblock(conn, device, TRUE, FALSE);
1361 }
1362
1363 void device_remove(struct btd_device *device, gboolean remove_stored)
1364 {
1365
1366         DBG("Removing device %s", device->path);
1367
1368         if (device->agent)
1369                 agent_free(device->agent);
1370
1371         if (device->bonding) {
1372                 uint8_t status;
1373
1374                 if (device->connected)
1375                         status = HCI_OE_USER_ENDED_CONNECTION;
1376                 else
1377                         status = HCI_PAGE_TIMEOUT;
1378
1379                 device_cancel_bonding(device, status);
1380         }
1381
1382         if (device->browse) {
1383                 discover_services_reply(device->browse, -ECANCELED, NULL);
1384                 browse_request_cancel(device->browse);
1385         }
1386
1387         if (device->connected)
1388                 do_disconnect(device);
1389
1390         if (remove_stored)
1391                 device_remove_stored(device);
1392
1393         g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
1394         g_slist_free(device->drivers);
1395         device->drivers = NULL;
1396
1397         attrib_client_unregister(device->services);
1398
1399         btd_device_unref(device);
1400 }
1401
1402 gint device_address_cmp(struct btd_device *device, const gchar *address)
1403 {
1404         char addr[18];
1405
1406         ba2str(&device->bdaddr, addr);
1407         return strcasecmp(addr, address);
1408 }
1409
1410 static gboolean record_has_uuid(const sdp_record_t *rec,
1411                                 const char *profile_uuid)
1412 {
1413         sdp_list_t *pat;
1414
1415         for (pat = rec->pattern; pat != NULL; pat = pat->next) {
1416                 char *uuid;
1417                 int ret;
1418
1419                 uuid = bt_uuid2string(pat->data);
1420                 if (!uuid)
1421                         continue;
1422
1423                 ret = strcasecmp(uuid, profile_uuid);
1424
1425                 g_free(uuid);
1426
1427                 if (ret == 0)
1428                         return TRUE;
1429         }
1430
1431         return FALSE;
1432 }
1433
1434 static GSList *device_match_pattern(struct btd_device *device,
1435                                         const char *match_uuid,
1436                                         GSList *profiles)
1437 {
1438         GSList *l, *uuids = NULL;
1439
1440         for (l = profiles; l; l = l->next) {
1441                 char *profile_uuid = l->data;
1442                 const sdp_record_t *rec;
1443
1444                 rec = btd_device_get_record(device, profile_uuid);
1445                 if (!rec)
1446                         continue;
1447
1448                 if (record_has_uuid(rec, match_uuid))
1449                         uuids = g_slist_append(uuids, profile_uuid);
1450         }
1451
1452         return uuids;
1453 }
1454
1455 static GSList *device_match_driver(struct btd_device *device,
1456                                         struct btd_device_driver *driver,
1457                                         GSList *profiles)
1458 {
1459         const char **uuid;
1460         GSList *uuids = NULL;
1461
1462         for (uuid = driver->uuids; *uuid; uuid++) {
1463                 GSList *match;
1464
1465                 /* skip duplicated uuids */
1466                 if (g_slist_find_custom(uuids, *uuid,
1467                                 (GCompareFunc) strcasecmp))
1468                         continue;
1469
1470                 /* match profile driver */
1471                 match = g_slist_find_custom(profiles, *uuid,
1472                                         (GCompareFunc) strcasecmp);
1473                 if (match) {
1474                         uuids = g_slist_append(uuids, match->data);
1475                         continue;
1476                 }
1477
1478                 /* match pattern driver */
1479                 match = device_match_pattern(device, *uuid, profiles);
1480                 uuids = g_slist_concat(uuids, match);
1481         }
1482
1483         return uuids;
1484 }
1485
1486 void device_probe_drivers(struct btd_device *device, GSList *profiles)
1487 {
1488         GSList *list;
1489         char addr[18];
1490         int err;
1491
1492         ba2str(&device->bdaddr, addr);
1493
1494         if (device->blocked) {
1495                 DBG("Skipping drivers for blocked device %s", addr);
1496                 goto add_uuids;
1497         }
1498
1499         DBG("Probing drivers for %s", addr);
1500
1501         for (list = device_drivers; list; list = list->next) {
1502                 struct btd_device_driver *driver = list->data;
1503                 GSList *probe_uuids;
1504
1505                 probe_uuids = device_match_driver(device, driver, profiles);
1506
1507                 if (!probe_uuids)
1508                         continue;
1509
1510                 err = driver->probe(device, probe_uuids);
1511                 if (err < 0) {
1512                         error("%s driver probe failed for device %s",
1513                                                         driver->name, addr);
1514                         g_slist_free(probe_uuids);
1515                         continue;
1516                 }
1517
1518                 device->drivers = g_slist_append(device->drivers, driver);
1519                 g_slist_free(probe_uuids);
1520         }
1521
1522 add_uuids:
1523         for (list = profiles; list; list = list->next) {
1524                 GSList *l = g_slist_find_custom(device->uuids, list->data,
1525                                                 (GCompareFunc) strcasecmp);
1526                 if (l)
1527                         continue;
1528
1529                 device->uuids = g_slist_insert_sorted(device->uuids,
1530                                                 g_strdup(list->data),
1531                                                 (GCompareFunc) strcasecmp);
1532         }
1533 }
1534
1535 static void device_remove_drivers(struct btd_device *device, GSList *uuids)
1536 {
1537         struct btd_adapter *adapter = device_get_adapter(device);
1538         GSList *list, *next;
1539         char srcaddr[18], dstaddr[18];
1540         bdaddr_t src;
1541         sdp_list_t *records;
1542
1543         adapter_get_address(adapter, &src);
1544         ba2str(&src, srcaddr);
1545         ba2str(&device->bdaddr, dstaddr);
1546
1547         records = read_records(&src, &device->bdaddr);
1548
1549         DBG("Removing drivers for %s", dstaddr);
1550
1551         for (list = device->drivers; list; list = next) {
1552                 struct btd_device_driver *driver = list->data;
1553                 const char **uuid;
1554
1555                 next = list->next;
1556
1557                 for (uuid = driver->uuids; *uuid; uuid++) {
1558                         if (!g_slist_find_custom(uuids, *uuid,
1559                                                 (GCompareFunc) strcasecmp))
1560                                 continue;
1561
1562                         DBG("UUID %s was removed from device %s",
1563                                                         *uuid, dstaddr);
1564
1565                         driver->remove(device);
1566                         device->drivers = g_slist_remove(device->drivers,
1567                                                                 driver);
1568                         break;
1569                 }
1570         }
1571
1572         for (list = uuids; list; list = list->next) {
1573                 sdp_record_t *rec;
1574
1575                 device->uuids = g_slist_remove(device->uuids, list->data);
1576
1577                 rec = find_record_in_list(records, list->data);
1578                 if (!rec)
1579                         continue;
1580
1581                 delete_record(srcaddr, dstaddr, rec->handle);
1582
1583                 records = sdp_list_remove(records, rec);
1584                 sdp_record_free(rec);
1585
1586         }
1587
1588         if (records)
1589                 sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
1590 }
1591
1592 static void services_changed(struct btd_device *device)
1593 {
1594         DBusConnection *conn = get_dbus_connection();
1595         char **uuids;
1596         GSList *l;
1597         int i;
1598
1599         uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
1600         for (i = 0, l = device->uuids; l; l = l->next, i++)
1601                 uuids[i] = l->data;
1602
1603         emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
1604                                         "UUIDs", DBUS_TYPE_STRING, &uuids, i);
1605
1606         g_free(uuids);
1607 }
1608
1609 static int rec_cmp(const void *a, const void *b)
1610 {
1611         const sdp_record_t *r1 = a;
1612         const sdp_record_t *r2 = b;
1613
1614         return r1->handle - r2->handle;
1615 }
1616
1617 static void update_services(struct browse_req *req, sdp_list_t *recs)
1618 {
1619         struct btd_device *device = req->device;
1620         struct btd_adapter *adapter = device_get_adapter(device);
1621         sdp_list_t *seq;
1622         char srcaddr[18], dstaddr[18];
1623         bdaddr_t src;
1624
1625         adapter_get_address(adapter, &src);
1626         ba2str(&src, srcaddr);
1627         ba2str(&device->bdaddr, dstaddr);
1628
1629         for (seq = recs; seq; seq = seq->next) {
1630                 sdp_record_t *rec = (sdp_record_t *) seq->data;
1631                 sdp_list_t *svcclass = NULL;
1632                 gchar *profile_uuid;
1633                 GSList *l;
1634
1635                 if (!rec)
1636                         break;
1637
1638                 if (sdp_get_service_classes(rec, &svcclass) < 0)
1639                         continue;
1640
1641                 /* Check for empty service classes list */
1642                 if (svcclass == NULL) {
1643                         DBG("Skipping record with no service classes");
1644                         continue;
1645                 }
1646
1647                 /* Extract the first element and skip the remainning */
1648                 profile_uuid = bt_uuid2string(svcclass->data);
1649                 if (!profile_uuid) {
1650                         sdp_list_free(svcclass, free);
1651                         continue;
1652                 }
1653
1654                 if (!strcasecmp(profile_uuid, PNP_UUID)) {
1655                         uint16_t source, vendor, product, version;
1656                         sdp_data_t *pdlist;
1657
1658                         pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
1659                         source = pdlist ? pdlist->val.uint16 : 0x0000;
1660
1661                         pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
1662                         vendor = pdlist ? pdlist->val.uint16 : 0x0000;
1663
1664                         device_set_vendor(device, vendor);
1665
1666                         pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
1667                         product = pdlist ? pdlist->val.uint16 : 0x0000;
1668
1669                         device_set_product(device, product);
1670
1671                         pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
1672                         version = pdlist ? pdlist->val.uint16 : 0x0000;
1673
1674                         device_set_version(device, version);
1675
1676                         if (source || vendor || product || version)
1677                                 store_device_id(srcaddr, dstaddr, source,
1678                                                 vendor, product, version);
1679                 }
1680
1681                 /* Check for duplicates */
1682                 if (sdp_list_find(req->records, rec, rec_cmp)) {
1683                         g_free(profile_uuid);
1684                         sdp_list_free(svcclass, free);
1685                         continue;
1686                 }
1687
1688                 store_record(srcaddr, dstaddr, rec);
1689
1690                 /* Copy record */
1691                 req->records = sdp_list_append(req->records,
1692                                                         sdp_copy_record(rec));
1693
1694                 l = g_slist_find_custom(device->uuids, profile_uuid,
1695                                                         (GCompareFunc) strcmp);
1696                 if (!l)
1697                         req->profiles_added =
1698                                         g_slist_append(req->profiles_added,
1699                                                         profile_uuid);
1700                 else {
1701                         req->profiles_removed =
1702                                         g_slist_remove(req->profiles_removed,
1703                                                         l->data);
1704                         g_free(profile_uuid);
1705                 }
1706
1707                 sdp_list_free(svcclass, free);
1708         }
1709 }
1710
1711 static void store_profiles(struct btd_device *device)
1712 {
1713         struct btd_adapter *adapter = device->adapter;
1714         bdaddr_t src;
1715         char *str;
1716
1717         adapter_get_address(adapter, &src);
1718
1719         if (!device->uuids) {
1720                 write_device_profiles(&src, &device->bdaddr, "");
1721                 return;
1722         }
1723
1724         str = bt_list2string(device->uuids);
1725         write_device_profiles(&src, &device->bdaddr, str);
1726         g_free(str);
1727 }
1728
1729 static void create_device_reply(struct btd_device *device, struct browse_req *req)
1730 {
1731         DBusMessage *reply;
1732
1733         reply = dbus_message_new_method_return(req->msg);
1734         if (!reply)
1735                 return;
1736
1737         dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
1738                                         DBUS_TYPE_INVALID);
1739
1740         g_dbus_send_message(req->conn, reply);
1741 }
1742
1743 GSList *device_services_from_record(struct btd_device *device, GSList *profiles)
1744 {
1745         GSList *l, *prim_list = NULL;
1746         char *att_uuid;
1747         uuid_t proto_uuid;
1748
1749         sdp_uuid16_create(&proto_uuid, ATT_UUID);
1750         att_uuid = bt_uuid2string(&proto_uuid);
1751
1752         for (l = profiles; l; l = l->next) {
1753                 const char *profile_uuid = l->data;
1754                 const sdp_record_t *rec;
1755                 struct gatt_primary *prim;
1756                 uint16_t start = 0, end = 0, psm = 0;
1757                 uuid_t prim_uuid;
1758
1759                 rec = btd_device_get_record(device, profile_uuid);
1760                 if (!rec)
1761                         continue;
1762
1763                 if (!record_has_uuid(rec, att_uuid))
1764                         continue;
1765
1766                 if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
1767                         continue;
1768
1769                 prim = g_new0(struct gatt_primary, 1);
1770                 prim->range.start = start;
1771                 prim->range.end = end;
1772                 sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
1773
1774                 prim_list = g_slist_append(prim_list, prim);
1775         }
1776
1777         g_free(att_uuid);
1778
1779         return prim_list;
1780 }
1781
1782 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
1783 {
1784         struct browse_req *req = user_data;
1785         struct btd_device *device = req->device;
1786         char addr[18];
1787
1788         ba2str(&device->bdaddr, addr);
1789
1790         if (err < 0) {
1791                 error("%s: error updating services: %s (%d)",
1792                                 addr, strerror(-err), -err);
1793                 goto send_reply;
1794         }
1795
1796         update_services(req, recs);
1797
1798         if (device->tmp_records)
1799                 sdp_list_free(device->tmp_records,
1800                                         (sdp_free_func_t) sdp_record_free);
1801
1802         device->tmp_records = req->records;
1803         req->records = NULL;
1804
1805         if (!req->profiles_added && !req->profiles_removed) {
1806                 DBG("%s: No service update", addr);
1807                 goto send_reply;
1808         }
1809
1810         /* Probe matching drivers for services added */
1811         if (req->profiles_added) {
1812                 GSList *list;
1813
1814                 list = device_services_from_record(device, req->profiles_added);
1815                 if (list)
1816                         device_register_services(req->conn, device, list,
1817                                                                 ATT_PSM);
1818
1819                 device_probe_drivers(device, req->profiles_added);
1820         }
1821
1822         /* Remove drivers for services removed */
1823         if (req->profiles_removed)
1824                 device_remove_drivers(device, req->profiles_removed);
1825
1826         /* Propagate services changes */
1827         services_changed(req->device);
1828
1829 send_reply:
1830         if (!req->msg)
1831                 goto cleanup;
1832
1833         if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
1834                                         "DiscoverServices"))
1835                 discover_services_reply(req, err, device->tmp_records);
1836         else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
1837                                                 "CreatePairedDevice"))
1838                 create_device_reply(device, req);
1839         else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
1840                                                 "CreateDevice")) {
1841                 if (err < 0) {
1842                         DBusMessage *reply;
1843                         reply = btd_error_failed(req->msg, strerror(-err));
1844                         g_dbus_send_message(req->conn, reply);
1845                         goto cleanup;
1846                 }
1847
1848                 create_device_reply(device, req);
1849                 device_set_temporary(device, FALSE);
1850         }
1851
1852 cleanup:
1853         if (!device->temporary) {
1854                 bdaddr_t sba, dba;
1855
1856                 adapter_get_address(device->adapter, &sba);
1857                 device_get_address(device, &dba, NULL);
1858
1859                 store_profiles(device);
1860         }
1861
1862         device->browse = NULL;
1863         browse_request_free(req);
1864 }
1865
1866 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
1867 {
1868         struct browse_req *req = user_data;
1869         struct btd_device *device = req->device;
1870         struct btd_adapter *adapter = device->adapter;
1871         bdaddr_t src;
1872         uuid_t uuid;
1873
1874         /* If we have a valid response and req->search_uuid == 2, then L2CAP
1875          * UUID & PNP searching was successful -- we are done */
1876         if (err < 0 || (req->search_uuid == 2 && req->records)) {
1877                 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
1878                         req->search_uuid--;
1879                         req->reconnect_attempt++;
1880                 } else
1881                         goto done;
1882         }
1883
1884         update_services(req, recs);
1885
1886         adapter_get_address(adapter, &src);
1887
1888         /* Search for mandatory uuids */
1889         if (uuid_list[req->search_uuid]) {
1890                 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1891                 bt_search_service(&src, &device->bdaddr, &uuid,
1892                                                 browse_cb, user_data, NULL);
1893                 return;
1894         }
1895
1896 done:
1897         search_cb(recs, err, user_data);
1898 }
1899
1900 static void init_browse(struct browse_req *req, gboolean reverse)
1901 {
1902         GSList *l;
1903
1904         /* If we are doing reverse-SDP don't try to detect removed profiles
1905          * since some devices hide their service records while they are
1906          * connected
1907          */
1908         if (reverse)
1909                 return;
1910
1911         for (l = req->device->uuids; l; l = l->next)
1912                 req->profiles_removed = g_slist_append(req->profiles_removed,
1913                                                 l->data);
1914 }
1915
1916 static char *primary_list_to_string(GSList *primary_list)
1917 {
1918         GString *services;
1919         GSList *l;
1920
1921         services = g_string_new(NULL);
1922
1923         for (l = primary_list; l; l = l->next) {
1924                 struct gatt_primary *primary = l->data;
1925                 char service[64];
1926
1927                 memset(service, 0, sizeof(service));
1928
1929                 snprintf(service, sizeof(service), "%04X#%04X#%s ",
1930                                 primary->range.start, primary->range.end, primary->uuid);
1931
1932                 services = g_string_append(services, service);
1933         }
1934
1935         return g_string_free(services, FALSE);
1936 }
1937
1938 static void store_services(struct btd_device *device)
1939 {
1940         struct btd_adapter *adapter = device->adapter;
1941         bdaddr_t dba, sba;
1942         char *str = primary_list_to_string(device->primaries);
1943
1944         adapter_get_address(adapter, &sba);
1945         device_get_address(device, &dba, NULL);
1946
1947         write_device_services(&sba, &dba, device->bdaddr_type, str);
1948
1949         g_free(str);
1950 }
1951
1952 static void att_connect_dispatched(gpointer user_data)
1953 {
1954         struct btd_device *device = user_data;
1955
1956         device->auto_id = 0;
1957 }
1958
1959 static gboolean att_connect(gpointer user_data);
1960
1961 static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
1962                                                         gpointer user_data)
1963 {
1964         struct btd_device *device = user_data;
1965         int sock, err = 0;
1966         socklen_t len;
1967
1968         if (device->browse)
1969                 goto done;
1970
1971         sock = g_io_channel_unix_get_fd(io);
1972         len = sizeof(err);
1973         getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len);
1974
1975         g_slist_foreach(device->attios, attio_disconnected, NULL);
1976
1977         if (device->auto_connect == FALSE || err != ETIMEDOUT)
1978                 goto done;
1979
1980         device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
1981                                                 AUTO_CONNECTION_INTERVAL,
1982                                                 att_connect, device,
1983                                                 att_connect_dispatched);
1984
1985 done:
1986         att_cleanup(device);
1987
1988         return FALSE;
1989 }
1990
1991 static void appearance_cb(guint8 status, const guint8 *pdu, guint16 plen,
1992                                                         gpointer user_data)
1993 {
1994         struct btd_device *device = user_data;
1995         struct btd_adapter *adapter = device->adapter;
1996         struct att_data_list *list =  NULL;
1997         uint16_t app;
1998         bdaddr_t src;
1999         uint8_t *atval;
2000
2001         if (status != 0) {
2002                 DBG("Read characteristics by UUID failed: %s\n",
2003                                                         att_ecode2str(status));
2004                 goto done;
2005         }
2006
2007         list = dec_read_by_type_resp(pdu, plen);
2008         if (list == NULL)
2009                 goto done;
2010
2011         if (list->len != 4) {
2012                 DBG("Appearance value: invalid data");
2013                 goto done;
2014         }
2015
2016         /* A device shall have only one instance of the
2017         Appearance characteristic. */
2018         atval = list->data[0] + 2; /* skip handle value */
2019         app = att_get_u16(atval);
2020
2021         adapter_get_address(adapter, &src);
2022         write_remote_appearance(&src, &device->bdaddr, device->bdaddr_type,
2023                                                                         app);
2024
2025 done:
2026         att_data_list_free(list);
2027         if (device->attios == NULL && device->attios_offline == NULL)
2028                 att_cleanup(device);
2029 }
2030
2031 static void primary_cb(GSList *services, guint8 status, gpointer user_data)
2032 {
2033         struct browse_req *req = user_data;
2034         struct btd_device *device = req->device;
2035         struct gatt_primary *gap_prim = NULL;
2036         GSList *l, *uuids = NULL;
2037
2038         if (status) {
2039                 if (req->msg) {
2040                         DBusMessage *reply;
2041                         reply = btd_error_failed(req->msg,
2042                                                         att_ecode2str(status));
2043                         g_dbus_send_message(req->conn, reply);
2044                 }
2045                 goto done;
2046         }
2047
2048         device_set_temporary(device, FALSE);
2049
2050         for (l = services; l; l = l->next) {
2051                 struct gatt_primary *prim = l->data;
2052
2053                 if (strcmp(prim->uuid, GAP_SVC_UUID) == 0)
2054                         gap_prim = prim;
2055
2056                 uuids = g_slist_append(uuids, prim->uuid);
2057         }
2058
2059         device_register_services(req->conn, device, g_slist_copy(services), -1);
2060         device_probe_drivers(device, uuids);
2061
2062         if (gap_prim) {
2063                 /* Read appearance characteristic */
2064                 bt_uuid_t uuid;
2065
2066                 bt_uuid16_create(&uuid, APPEARANCE_CHR_UUID);
2067
2068                 gatt_read_char_by_uuid(device->attrib, gap_prim->range.start,
2069                         gap_prim->range.end, &uuid, appearance_cb, device);
2070         } else if (device->attios == NULL && device->attios_offline == NULL)
2071                 att_cleanup(device);
2072
2073         g_slist_free(uuids);
2074
2075         services_changed(device);
2076         if (req->msg)
2077                 create_device_reply(device, req);
2078
2079         store_services(device);
2080
2081 done:
2082         device->browse = NULL;
2083         browse_request_free(req);
2084 }
2085
2086 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
2087 {
2088         struct att_callbacks *attcb = user_data;
2089         struct btd_device *device = attcb->user_data;
2090         GAttrib *attrib;
2091
2092         g_io_channel_unref(device->att_io);
2093         device->att_io = NULL;
2094
2095         if (gerr) {
2096                 DBG("%s", gerr->message);
2097
2098                 if (attcb->error)
2099                         attcb->error(gerr, user_data);
2100
2101                 goto done;
2102         }
2103
2104         attrib = g_attrib_new(io);
2105         device->attachid = attrib_channel_attach(attrib);
2106         if (device->attachid == 0)
2107                 error("Attribute server attach failure!");
2108
2109         device->attrib = attrib;
2110         device->cleanup_id = g_io_add_watch(io, G_IO_HUP,
2111                                         attrib_disconnected_cb, device);
2112
2113         if (attcb->success)
2114                 attcb->success(user_data);
2115 done:
2116         g_free(attcb);
2117 }
2118
2119 static void att_error_cb(const GError *gerr, gpointer user_data)
2120 {
2121         struct att_callbacks *attcb = user_data;
2122         struct btd_device *device = attcb->user_data;
2123
2124         if (device->auto_connect == FALSE)
2125                 return;
2126
2127         device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
2128                                                 AUTO_CONNECTION_INTERVAL,
2129                                                 att_connect, device,
2130                                                 att_connect_dispatched);
2131
2132         DBG("Enabling automatic connections");
2133 }
2134
2135 static void att_success_cb(gpointer user_data)
2136 {
2137         struct att_callbacks *attcb = user_data;
2138         struct btd_device *device = attcb->user_data;
2139
2140         if (device->attios == NULL)
2141                 return;
2142
2143         g_slist_foreach(device->attios, attio_connected, device->attrib);
2144 }
2145
2146 static gboolean att_connect(gpointer user_data)
2147 {
2148         struct btd_device *device = user_data;
2149         struct btd_adapter *adapter = device->adapter;
2150         struct att_callbacks *attcb;
2151         GIOChannel *io;
2152         GError *gerr = NULL;
2153         char addr[18];
2154         bdaddr_t sba;
2155
2156         adapter_get_address(adapter, &sba);
2157         ba2str(&device->bdaddr, addr);
2158
2159         DBG("Connection attempt to: %s", addr);
2160
2161         attcb = g_new0(struct att_callbacks, 1);
2162         attcb->error = att_error_cb;
2163         attcb->success = att_success_cb;
2164         attcb->user_data = device;
2165
2166         if (device_is_bredr(device)) {
2167                 io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2168                                         attcb, NULL, &gerr,
2169                                         BT_IO_OPT_SOURCE_BDADDR, &sba,
2170                                         BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2171                                         BT_IO_OPT_PSM, ATT_PSM,
2172                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2173                                         BT_IO_OPT_INVALID);
2174         } else {
2175                 io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2176                                 attcb, NULL, &gerr,
2177                                 BT_IO_OPT_SOURCE_BDADDR, &sba,
2178                                 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2179                                 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
2180                                 BT_IO_OPT_CID, ATT_CID,
2181                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2182                                 BT_IO_OPT_INVALID);
2183         }
2184
2185         if (io == NULL) {
2186                 error("ATT bt_io_connect(%s): %s", addr, gerr->message);
2187                 g_error_free(gerr);
2188                 g_free(attcb);
2189                 return FALSE;
2190         }
2191
2192         device->att_io = io;
2193
2194         return FALSE;
2195 }
2196
2197 static void att_browse_error_cb(const GError *gerr, gpointer user_data)
2198 {
2199         struct att_callbacks *attcb = user_data;
2200         struct btd_device *device = attcb->user_data;
2201         struct browse_req *req = device->browse;
2202
2203         if (req->msg) {
2204                 DBusMessage *reply;
2205
2206                 reply = btd_error_failed(req->msg, gerr->message);
2207                 g_dbus_send_message(req->conn, reply);
2208         }
2209
2210         device->browse = NULL;
2211         browse_request_free(req);
2212 }
2213
2214 static void att_browse_cb(gpointer user_data)
2215 {
2216         struct att_callbacks *attcb = user_data;
2217         struct btd_device *device = attcb->user_data;
2218
2219         gatt_discover_primary(device->attrib, NULL, primary_cb,
2220                                                         device->browse);
2221 }
2222
2223 int device_browse_primary(struct btd_device *device, DBusConnection *conn,
2224                                 DBusMessage *msg, gboolean secure)
2225 {
2226         struct btd_adapter *adapter = device->adapter;
2227         struct att_callbacks *attcb;
2228         struct browse_req *req;
2229         BtIOSecLevel sec_level;
2230         bdaddr_t src;
2231
2232         if (device->browse)
2233                 return -EBUSY;
2234
2235         /* FIXME: GATT service updates (implemented in update_services() for
2236          * SDP) are not supported yet. It will be supported once client side
2237          * "Services Changed" characteristic handling is implemented. */
2238         if (device->primaries) {
2239                 error("Could not update GATT services");
2240                 return -ENOSYS;
2241         }
2242
2243         req = g_new0(struct browse_req, 1);
2244         req->device = btd_device_ref(device);
2245         adapter_get_address(adapter, &src);
2246
2247         device->browse = req;
2248
2249         if (device->attrib) {
2250                 gatt_discover_primary(device->attrib, NULL, primary_cb, req);
2251                 goto done;
2252         }
2253
2254         sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW;
2255
2256         attcb = g_new0(struct att_callbacks, 1);
2257         attcb->error = att_browse_error_cb;
2258         attcb->success = att_browse_cb;
2259         attcb->user_data = device;
2260
2261         device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2262                                 attcb, NULL, NULL,
2263                                 BT_IO_OPT_SOURCE_BDADDR, &src,
2264                                 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2265                                 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
2266                                 BT_IO_OPT_CID, ATT_CID,
2267                                 BT_IO_OPT_SEC_LEVEL, sec_level,
2268                                 BT_IO_OPT_INVALID);
2269
2270         if (device->att_io == NULL) {
2271                 device->browse = NULL;
2272                 browse_request_free(req);
2273                 g_free(attcb);
2274                 return -EIO;
2275         }
2276
2277 done:
2278         if (conn == NULL)
2279                 conn = get_dbus_connection();
2280
2281         req->conn = dbus_connection_ref(conn);
2282
2283         if (msg) {
2284                 const char *sender = dbus_message_get_sender(msg);
2285
2286                 req->msg = dbus_message_ref(msg);
2287                 /* Track the request owner to cancel it
2288                  * automatically if the owner exits */
2289                 req->listener_id = g_dbus_add_disconnect_watch(conn,
2290                                                 sender,
2291                                                 discover_services_req_exit,
2292                                                 req, NULL);
2293         }
2294
2295         return 0;
2296 }
2297
2298 int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
2299                         DBusMessage *msg, uuid_t *search, gboolean reverse)
2300 {
2301         struct btd_adapter *adapter = device->adapter;
2302         struct browse_req *req;
2303         bt_callback_t cb;
2304         bdaddr_t src;
2305         uuid_t uuid;
2306         int err;
2307
2308         if (device->browse)
2309                 return -EBUSY;
2310
2311         adapter_get_address(adapter, &src);
2312
2313         req = g_new0(struct browse_req, 1);
2314         req->device = btd_device_ref(device);
2315         if (search) {
2316                 memcpy(&uuid, search, sizeof(uuid_t));
2317                 cb = search_cb;
2318         } else {
2319                 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
2320                 init_browse(req, reverse);
2321                 cb = browse_cb;
2322         }
2323
2324         err = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
2325         if (err < 0) {
2326                 browse_request_free(req);
2327                 return err;
2328         }
2329
2330         if (conn == NULL)
2331                 conn = get_dbus_connection();
2332
2333         req->conn = dbus_connection_ref(conn);
2334         device->browse = req;
2335
2336         if (msg) {
2337                 const char *sender = dbus_message_get_sender(msg);
2338
2339                 req->msg = dbus_message_ref(msg);
2340                 /* Track the request owner to cancel it
2341                  * automatically if the owner exits */
2342                 req->listener_id = g_dbus_add_disconnect_watch(conn,
2343                                                 sender,
2344                                                 discover_services_req_exit,
2345                                                 req, NULL);
2346         }
2347
2348         return err;
2349 }
2350
2351 struct btd_adapter *device_get_adapter(struct btd_device *device)
2352 {
2353         if (!device)
2354                 return NULL;
2355
2356         return device->adapter;
2357 }
2358
2359 void device_get_address(struct btd_device *device, bdaddr_t *bdaddr,
2360                                                         uint8_t *bdaddr_type)
2361 {
2362         bacpy(bdaddr, &device->bdaddr);
2363         if (bdaddr_type != NULL)
2364                 *bdaddr_type = device->bdaddr_type;
2365 }
2366
2367 void device_set_addr_type(struct btd_device *device, uint8_t bdaddr_type)
2368 {
2369         if (device == NULL)
2370                 return;
2371
2372         device->bdaddr_type = bdaddr_type;
2373 }
2374
2375 uint8_t device_get_addr_type(struct btd_device *device)
2376 {
2377         return device->bdaddr_type;
2378 }
2379
2380 const gchar *device_get_path(struct btd_device *device)
2381 {
2382         if (!device)
2383                 return NULL;
2384
2385         return device->path;
2386 }
2387
2388 struct agent *device_get_agent(struct btd_device *device)
2389 {
2390         if (!device)
2391                 return NULL;
2392
2393         if (device->agent)
2394                 return device->agent;
2395
2396         return adapter_get_agent(device->adapter);
2397 }
2398
2399 gboolean device_is_busy(struct btd_device *device)
2400 {
2401         return device->browse ? TRUE : FALSE;
2402 }
2403
2404 gboolean device_is_temporary(struct btd_device *device)
2405 {
2406         return device->temporary;
2407 }
2408
2409 void device_set_temporary(struct btd_device *device, gboolean temporary)
2410 {
2411         if (!device)
2412                 return;
2413
2414         DBG("temporary %d", temporary);
2415
2416         device->temporary = temporary;
2417 }
2418
2419 void device_set_bonded(struct btd_device *device, gboolean bonded)
2420 {
2421         if (!device)
2422                 return;
2423
2424         DBG("bonded %d", bonded);
2425
2426         device->bonded = bonded;
2427 }
2428
2429 void device_set_auto_connect(struct btd_device *device, gboolean enable)
2430 {
2431         char addr[18];
2432
2433         if (!device)
2434                 return;
2435
2436         ba2str(&device->bdaddr, addr);
2437
2438         DBG("%s auto connect: %d", addr, enable);
2439
2440         device->auto_connect = enable;
2441
2442         /* Disabling auto connect */
2443         if (enable == FALSE) {
2444                 if (device->auto_id)
2445                         g_source_remove(device->auto_id);
2446                 return;
2447         }
2448
2449         /* Enabling auto connect */
2450         if (device->auto_id != 0)
2451                 return;
2452
2453         if (device->attrib) {
2454                 DBG("Already connected");
2455                 return;
2456         }
2457
2458         if (device->attios == NULL && device->attios_offline == NULL)
2459                 return;
2460
2461         device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
2462                                                 att_connect, device,
2463                                                 att_connect_dispatched);
2464 }
2465
2466 static gboolean start_discovery(gpointer user_data)
2467 {
2468         struct btd_device *device = user_data;
2469
2470         if (device_is_bredr(device))
2471                 device_browse_sdp(device, NULL, NULL, NULL, TRUE);
2472         else
2473                 device_browse_primary(device, NULL, NULL, FALSE);
2474
2475         device->discov_timer = 0;
2476
2477         return FALSE;
2478 }
2479
2480 static DBusMessage *new_authentication_return(DBusMessage *msg, int status)
2481 {
2482         switch (status) {
2483         case 0x00: /* success */
2484                 return dbus_message_new_method_return(msg);
2485
2486         case 0x04: /* page timeout */
2487                 return dbus_message_new_error(msg,
2488                                 ERROR_INTERFACE ".ConnectionAttemptFailed",
2489                                 "Page Timeout");
2490         case 0x08: /* connection timeout */
2491                 return dbus_message_new_error(msg,
2492                                 ERROR_INTERFACE ".ConnectionAttemptFailed",
2493                                 "Connection Timeout");
2494         case 0x10: /* connection accept timeout */
2495         case 0x22: /* LMP response timeout */
2496         case 0x28: /* instant passed - is this a timeout? */
2497                 return dbus_message_new_error(msg,
2498                                         ERROR_INTERFACE ".AuthenticationTimeout",
2499                                         "Authentication Timeout");
2500         case 0x17: /* too frequent pairing attempts */
2501                 return dbus_message_new_error(msg,
2502                                         ERROR_INTERFACE ".RepeatedAttempts",
2503                                         "Repeated Attempts");
2504
2505         case 0x06:
2506         case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */
2507                 return dbus_message_new_error(msg,
2508                                         ERROR_INTERFACE ".AuthenticationRejected",
2509                                         "Authentication Rejected");
2510
2511         case 0x07: /* memory capacity */
2512         case 0x09: /* connection limit */
2513         case 0x0a: /* synchronous connection limit */
2514         case 0x0d: /* limited resources */
2515         case 0x13: /* user ended the connection */
2516         case 0x14: /* terminated due to low resources */
2517         case 0x16: /* connection terminated */
2518                 return dbus_message_new_error(msg,
2519                                         ERROR_INTERFACE ".AuthenticationCanceled",
2520                                         "Authentication Canceled");
2521
2522         case 0x05: /* authentication failure */
2523         case 0x0E: /* rejected due to security reasons - is this auth failure? */
2524         case 0x25: /* encryption mode not acceptable - is this auth failure? */
2525         case 0x26: /* link key cannot be changed - is this auth failure? */
2526         case 0x29: /* pairing with unit key unsupported - is this auth failure? */
2527         case 0x2f: /* insufficient security - is this auth failure? */
2528         default:
2529                 return dbus_message_new_error(msg,
2530                                         ERROR_INTERFACE ".AuthenticationFailed",
2531                                         "Authentication Failed");
2532         }
2533 }
2534
2535 static void bonding_request_free(struct bonding_req *bonding)
2536 {
2537         struct btd_device *device;
2538
2539         if (!bonding)
2540                 return;
2541
2542         if (bonding->listener_id)
2543                 g_dbus_remove_watch(bonding->conn, bonding->listener_id);
2544
2545         if (bonding->msg)
2546                 dbus_message_unref(bonding->msg);
2547
2548         if (bonding->conn)
2549                 dbus_connection_unref(bonding->conn);
2550
2551         device = bonding->device;
2552         g_free(bonding);
2553
2554         if (!device)
2555                 return;
2556
2557         device->bonding = NULL;
2558
2559         if (!device->agent)
2560                 return;
2561
2562         agent_cancel(device->agent);
2563         agent_free(device->agent);
2564         device->agent = NULL;
2565 }
2566
2567 void device_set_paired(struct btd_device *device, gboolean value)
2568 {
2569         DBusConnection *conn = get_dbus_connection();
2570
2571         if (device->paired == value)
2572                 return;
2573
2574         if (!value)
2575                 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
2576                                                         device->bdaddr_type);
2577
2578         device->paired = value;
2579
2580         emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired",
2581                                 DBUS_TYPE_BOOLEAN, &value);
2582 }
2583
2584 static void device_agent_removed(struct agent *agent, void *user_data)
2585 {
2586         struct btd_device *device = user_data;
2587
2588         device->agent = NULL;
2589 #ifdef __TIZEN_PATCH__
2590         if (device->authr && (device->authr->agent == agent)) {
2591                 DBG("device->agent is the same with authr->agent");
2592                 device->authr->agent = NULL;
2593         }
2594 #else
2595         if (device->authr)
2596                 device->authr->agent = NULL;
2597 #endif
2598 }
2599
2600 static struct bonding_req *bonding_request_new(DBusConnection *conn,
2601                                                 DBusMessage *msg,
2602                                                 struct btd_device *device,
2603                                                 const char *agent_path,
2604                                                 uint8_t capability)
2605 {
2606         struct bonding_req *bonding;
2607         const char *name = dbus_message_get_sender(msg);
2608         char addr[18];
2609
2610         ba2str(&device->bdaddr, addr);
2611         DBG("Requesting bonding for %s", addr);
2612
2613         if (!agent_path)
2614                 goto proceed;
2615
2616         device->agent = agent_create(device->adapter, name, agent_path,
2617                                         capability,
2618                                         device_agent_removed,
2619                                         device);
2620
2621         DBG("Temporary agent registered for %s at %s:%s",
2622                         addr, name, agent_path);
2623
2624 proceed:
2625         bonding = g_new0(struct bonding_req, 1);
2626
2627         bonding->conn = dbus_connection_ref(conn);
2628         bonding->msg = dbus_message_ref(msg);
2629
2630         return bonding;
2631 }
2632
2633 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
2634 {
2635         struct btd_device *device = user_data;
2636         char addr[18];
2637
2638         ba2str(&device->bdaddr, addr);
2639         DBG("%s: requestor exited before bonding was completed", addr);
2640
2641         if (device->authr)
2642                 device_cancel_authentication(device, FALSE);
2643
2644         if (device->bonding) {
2645                 device->bonding->listener_id = 0;
2646                 device_request_disconnect(device, NULL);
2647         }
2648 }
2649
2650 DBusMessage *device_create_bonding(struct btd_device *device,
2651                                         DBusConnection *conn,
2652                                         DBusMessage *msg,
2653                                         const char *agent_path,
2654                                         uint8_t capability)
2655 {
2656         struct btd_adapter *adapter = device->adapter;
2657         struct bonding_req *bonding;
2658         int err;
2659
2660         if (device->bonding)
2661                 return btd_error_in_progress(msg);
2662
2663         if (device_is_bonded(device))
2664                 return btd_error_already_exists(msg);
2665
2666         if (device_is_le(device)) {
2667                 struct att_callbacks *attcb;
2668                 GError *gerr = NULL;
2669                 bdaddr_t sba;
2670
2671                 adapter_get_address(adapter, &sba);
2672
2673                 attcb = g_new0(struct att_callbacks, 1);
2674                 attcb->user_data = device;
2675
2676                 device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
2677                                 attcb, NULL, &gerr,
2678                                 BT_IO_OPT_SOURCE_BDADDR, &sba,
2679                                 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
2680                                 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
2681                                 BT_IO_OPT_CID, ATT_CID,
2682                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
2683                                 BT_IO_OPT_INVALID);
2684
2685                 if (device->att_io == NULL) {
2686                         DBusMessage *reply = btd_error_failed(msg,
2687                                                                 gerr->message);
2688
2689                         error("Bonding bt_io_connect(): %s", gerr->message);
2690                         g_error_free(gerr);
2691                         g_free(attcb);
2692                         return reply;
2693                 }
2694         }
2695
2696         err = adapter_create_bonding(adapter, &device->bdaddr,
2697                                         device->bdaddr_type, capability);
2698         if (err < 0)
2699                 return btd_error_failed(msg, strerror(-err));
2700
2701         bonding = bonding_request_new(conn, msg, device, agent_path,
2702                                         capability);
2703
2704         bonding->listener_id = g_dbus_add_disconnect_watch(conn,
2705                                                 dbus_message_get_sender(msg),
2706                                                 create_bond_req_exit, device,
2707                                                 NULL);
2708
2709         device->bonding = bonding;
2710         bonding->device = device;
2711
2712         return NULL;
2713 }
2714
2715 void device_simple_pairing_complete(struct btd_device *device, uint8_t status)
2716 {
2717         struct authentication_req *auth = device->authr;
2718
2719         if (auth && (auth->type == AUTH_TYPE_NOTIFY_PASSKEY
2720                      || auth->type == AUTH_TYPE_NOTIFY_PINCODE) && auth->agent)
2721                 agent_cancel(auth->agent);
2722 }
2723
2724 static void device_auth_req_free(struct btd_device *device)
2725 {
2726         if (device->authr)
2727                 g_free(device->authr->pincode);
2728         g_free(device->authr);
2729         device->authr = NULL;
2730 }
2731
2732 void device_bonding_complete(struct btd_device *device, uint8_t status)
2733 {
2734         struct bonding_req *bonding = device->bonding;
2735         struct authentication_req *auth = device->authr;
2736
2737         DBG("bonding %p status 0x%02x", bonding, status);
2738
2739         if (auth && (auth->type == AUTH_TYPE_NOTIFY_PASSKEY
2740                      || auth->type == AUTH_TYPE_NOTIFY_PINCODE) && auth->agent)
2741                 agent_cancel(auth->agent);
2742
2743         if (status) {
2744                 device_cancel_authentication(device, TRUE);
2745                 device_cancel_bonding(device, status);
2746                 return;
2747         }
2748
2749         device_auth_req_free(device);
2750
2751         /* If we're already paired nothing more is needed */
2752         if (device->paired)
2753                 return;
2754
2755         device_set_paired(device, TRUE);
2756
2757         /* If we were initiators start service discovery immediately.
2758          * However if the other end was the initator wait a few seconds
2759          * before SDP. This is due to potential IOP issues if the other
2760          * end starts doing SDP at the same time as us */
2761         if (bonding) {
2762                 DBG("Proceeding with service discovery");
2763                 /* If we are initiators remove any discovery timer and just
2764                  * start discovering services directly */
2765                 if (device->discov_timer) {
2766                         g_source_remove(device->discov_timer);
2767                         device->discov_timer = 0;
2768                 }
2769
2770                 if (device_is_bredr(device))
2771                         device_browse_sdp(device, bonding->conn, bonding->msg,
2772                                                                 NULL, FALSE);
2773                 else
2774                         device_browse_primary(device, bonding->conn,
2775                                                         bonding->msg, FALSE);
2776
2777                 bonding_request_free(bonding);
2778         } else {
2779                 if (!device->browse && !device->discov_timer &&
2780                                 main_opts.reverse_sdp) {
2781                         /* If we are not initiators and there is no currently
2782                          * active discovery or discovery timer, set discovery
2783                          * timer */
2784                         DBG("setting timer for reverse service discovery");
2785                         device->discov_timer = g_timeout_add_seconds(
2786                                                         DISCOVERY_TIMER,
2787                                                         start_discovery,
2788                                                         device);
2789                 }
2790         }
2791 }
2792
2793 gboolean device_is_creating(struct btd_device *device, const char *sender)
2794 {
2795         DBusMessage *msg;
2796
2797         if (device->bonding && device->bonding->msg)
2798                 msg = device->bonding->msg;
2799         else if (device->browse && device->browse->msg)
2800                 msg = device->browse->msg;
2801         else
2802                 return FALSE;
2803
2804         if (!dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2805                                                 "CreatePairedDevice") &&
2806                         !dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2807                                                         "CreateDevice"))
2808                 return FALSE;
2809
2810         if (sender == NULL)
2811                 return TRUE;
2812
2813         return g_str_equal(sender, dbus_message_get_sender(msg));
2814 }
2815
2816 gboolean device_is_bonding(struct btd_device *device, const char *sender)
2817 {
2818         struct bonding_req *bonding = device->bonding;
2819
2820         if (!device->bonding)
2821                 return FALSE;
2822
2823         if (!sender)
2824                 return TRUE;
2825
2826         return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
2827 }
2828
2829 void device_cancel_bonding(struct btd_device *device, uint8_t status)
2830 {
2831         struct bonding_req *bonding = device->bonding;
2832         DBusMessage *reply;
2833         char addr[18];
2834
2835         if (!bonding)
2836                 return;
2837
2838         ba2str(&device->bdaddr, addr);
2839         DBG("Canceling bonding request for %s", addr);
2840
2841         if (device->authr)
2842                 device_cancel_authentication(device, FALSE);
2843
2844         reply = new_authentication_return(bonding->msg, status);
2845         g_dbus_send_message(bonding->conn, reply);
2846
2847         bonding_request_cancel(bonding);
2848         bonding_request_free(bonding);
2849 }
2850
2851 static void pincode_cb(struct agent *agent, DBusError *err,
2852                                         const char *pincode, void *data)
2853 {
2854         struct authentication_req *auth = data;
2855         struct btd_device *device = auth->device;
2856         struct btd_adapter *adapter = device_get_adapter(device);
2857         struct agent *adapter_agent = adapter_get_agent(adapter);
2858
2859         if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2860                                 g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2861                 if (auth->agent == adapter_agent || adapter_agent == NULL)
2862                         goto done;
2863
2864                 if (agent_request_pincode(adapter_agent, device, pincode_cb,
2865                                                 auth->secure, auth, NULL) < 0)
2866                         goto done;
2867
2868                 auth->agent = adapter_agent;
2869                 return;
2870         }
2871
2872 done:
2873         /* No need to reply anything if the authentication already failed */
2874         if (auth->cb == NULL)
2875                 return;
2876
2877         ((agent_pincode_cb) auth->cb)(agent, err, pincode, device);
2878
2879         device->authr->cb = NULL;
2880         device->authr->agent = NULL;
2881 }
2882
2883 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
2884 {
2885         struct authentication_req *auth = data;
2886         struct btd_device *device = auth->device;
2887         struct btd_adapter *adapter = device_get_adapter(device);
2888         struct agent *adapter_agent = adapter_get_agent(adapter);
2889
2890         if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2891                                 g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2892                 if (auth->agent == adapter_agent || adapter_agent == NULL)
2893                         goto done;
2894
2895                 if (agent_request_confirmation(adapter_agent, device,
2896                                                 auth->passkey, confirm_cb,
2897                                                 auth, NULL) < 0)
2898                         goto done;
2899
2900                 auth->agent = adapter_agent;
2901                 return;
2902         }
2903
2904 done:
2905         /* No need to reply anything if the authentication already failed */
2906         if (auth->cb == NULL)
2907                 return;
2908
2909         ((agent_cb) auth->cb)(agent, err, device);
2910
2911         device->authr->cb = NULL;
2912         device->authr->agent = NULL;
2913 }
2914
2915 static void passkey_cb(struct agent *agent, DBusError *err,
2916                                                 uint32_t passkey, void *data)
2917 {
2918         struct authentication_req *auth = data;
2919         struct btd_device *device = auth->device;
2920         struct btd_adapter *adapter = device_get_adapter(device);
2921         struct agent *adapter_agent = adapter_get_agent(adapter);
2922
2923         if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2924                                 g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2925                 if (auth->agent == adapter_agent || adapter_agent == NULL)
2926                         goto done;
2927
2928                 if (agent_request_passkey(adapter_agent, device, passkey_cb,
2929                                                         auth, NULL) < 0)
2930                         goto done;
2931
2932                 auth->agent = adapter_agent;
2933                 return;
2934         }
2935
2936 done:
2937         /* No need to reply anything if the authentication already failed */
2938         if (auth->cb == NULL)
2939                 return;
2940
2941         ((agent_passkey_cb) auth->cb)(agent, err, passkey, device);
2942
2943         device->authr->cb = NULL;
2944         device->authr->agent = NULL;
2945 }
2946
2947 static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
2948 {
2949         struct authentication_req *auth = data;
2950         struct btd_device *device = auth->device;
2951         struct btd_adapter *adapter = device_get_adapter(device);
2952         struct agent *adapter_agent = adapter_get_agent(adapter);
2953
2954         if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
2955                                 g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
2956                 /* Request a pincode if we fail to display one */
2957                 if (auth->agent == adapter_agent || adapter_agent == NULL) {
2958                         if (agent_request_pincode(agent, device, pincode_cb,
2959                                                 auth->secure, auth, NULL) < 0)
2960                                 goto done;
2961                         return;
2962                 }
2963
2964                 if (agent_display_pincode(adapter_agent, device, auth->pincode,
2965                                         display_pincode_cb, auth, NULL) < 0)
2966                         goto done;
2967
2968                 auth->agent = adapter_agent;
2969                 return;
2970         }
2971
2972 done:
2973         /* No need to reply anything if the authentication already failed */
2974         if (auth->cb == NULL)
2975                 return;
2976
2977         ((agent_pincode_cb) auth->cb)(agent, err, auth->pincode, device);
2978
2979         g_free(device->authr->pincode);
2980         device->authr->pincode = NULL;
2981         device->authr->cb = NULL;
2982         device->authr->agent = NULL;
2983 }
2984
2985 int device_request_authentication(struct btd_device *device, auth_type_t type,
2986                                         void *data, gboolean secure, void *cb)
2987 {
2988         struct authentication_req *auth;
2989         struct agent *agent;
2990         char addr[18];
2991         int err;
2992
2993         ba2str(&device->bdaddr, addr);
2994         DBG("Requesting agent authentication for %s", addr);
2995
2996         if (device->authr) {
2997                 error("Authentication already requested for %s", addr);
2998                 return -EALREADY;
2999         }
3000
3001         agent = device_get_agent(device);
3002         if (!agent) {
3003                 error("No agent available for request type %d", type);
3004                 return -EPERM;
3005         }
3006
3007         auth = g_new0(struct authentication_req, 1);
3008         auth->agent = agent;
3009         auth->device = device;
3010         auth->cb = cb;
3011         auth->type = type;
3012         auth->secure = secure;
3013         device->authr = auth;
3014
3015         switch (type) {
3016         case AUTH_TYPE_PINCODE:
3017                 err = agent_request_pincode(agent, device, pincode_cb, secure,
3018                                                                 auth, NULL);
3019                 break;
3020         case AUTH_TYPE_PASSKEY:
3021                 err = agent_request_passkey(agent, device, passkey_cb,
3022                                                                 auth, NULL);
3023                 break;
3024         case AUTH_TYPE_CONFIRM:
3025                 auth->passkey = *((uint32_t *) data);
3026                 err = agent_request_confirmation(agent, device, auth->passkey,
3027                                                 confirm_cb, auth, NULL);
3028                 break;
3029         case AUTH_TYPE_NOTIFY_PASSKEY:
3030                 auth->passkey = *((uint32_t *) data);
3031                 err = agent_display_passkey(agent, device, auth->passkey);
3032                 break;
3033         case AUTH_TYPE_NOTIFY_PINCODE:
3034                 auth->pincode = g_strdup((const char *) data);
3035                 err = agent_display_pincode(agent, device, auth->pincode,
3036                                                 display_pincode_cb, auth, NULL);
3037                 break;
3038         default:
3039                 err = -EINVAL;
3040         }
3041
3042         if (err < 0) {
3043                 error("Failed requesting authentication");
3044                 device_auth_req_free(device);
3045         }
3046
3047         return err;
3048 }
3049
3050 static void cancel_authentication(struct authentication_req *auth)
3051 {
3052         struct btd_device *device;
3053         struct agent *agent;
3054         DBusError err;
3055
3056         if (!auth || !auth->cb)
3057                 return;
3058
3059         device = auth->device;
3060         agent = auth->agent;
3061
3062         dbus_error_init(&err);
3063         dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL);
3064
3065         switch (auth->type) {
3066         case AUTH_TYPE_PINCODE:
3067                 ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
3068                 break;
3069         case AUTH_TYPE_CONFIRM:
3070                 ((agent_cb) auth->cb)(agent, &err, device);
3071                 break;
3072         case AUTH_TYPE_PASSKEY:
3073                 ((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
3074                 break;
3075         case AUTH_TYPE_NOTIFY_PASSKEY:
3076                 /* User Notify doesn't require any reply */
3077                 break;
3078         case AUTH_TYPE_NOTIFY_PINCODE:
3079                 ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
3080                 break;
3081         }
3082
3083         dbus_error_free(&err);
3084         auth->cb = NULL;
3085 }
3086
3087 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
3088 {
3089         struct authentication_req *auth = device->authr;
3090         char addr[18];
3091
3092         if (!auth)
3093                 return;
3094
3095         ba2str(&device->bdaddr, addr);
3096         DBG("Canceling authentication request for %s", addr);
3097
3098         if (auth->agent)
3099                 agent_cancel(auth->agent);
3100
3101         if (!aborted)
3102                 cancel_authentication(auth);
3103
3104         device_auth_req_free(device);
3105 }
3106
3107 gboolean device_is_authenticating(struct btd_device *device)
3108 {
3109         return (device->authr != NULL);
3110 }
3111
3112 gboolean device_is_authorizing(struct btd_device *device)
3113 {
3114         return device->authorizing;
3115 }
3116
3117 void device_set_authorizing(struct btd_device *device, gboolean auth)
3118 {
3119         device->authorizing = auth;
3120 }
3121
3122 void device_register_services(DBusConnection *conn, struct btd_device *device,
3123                                                 GSList *prim_list, int psm)
3124 {
3125         device->primaries = g_slist_concat(device->primaries, prim_list);
3126         device->services = attrib_client_register(conn, device, psm, NULL,
3127                                                                 prim_list);
3128 }
3129
3130 GSList *btd_device_get_primaries(struct btd_device *device)
3131 {
3132         return device->primaries;
3133 }
3134
3135 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
3136 {
3137         GSList *uuid_list;
3138         char *new_uuid;
3139
3140         if (g_slist_find_custom(device->uuids, uuid,
3141                                 (GCompareFunc) strcasecmp))
3142                 return;
3143
3144         new_uuid = g_strdup(uuid);
3145         uuid_list = g_slist_append(NULL, new_uuid);
3146
3147         device_probe_drivers(device, uuid_list);
3148
3149         g_free(new_uuid);
3150         g_slist_free(uuid_list);
3151
3152         store_profiles(device);
3153         services_changed(device);
3154 }
3155
3156 const sdp_record_t *btd_device_get_record(struct btd_device *device,
3157                                                         const char *uuid)
3158 {
3159         bdaddr_t src;
3160
3161         if (device->tmp_records) {
3162                 const sdp_record_t *record;
3163
3164                 record = find_record_in_list(device->tmp_records, uuid);
3165                 if (record != NULL)
3166                         return record;
3167         }
3168
3169         adapter_get_address(device->adapter, &src);
3170
3171         device->tmp_records = read_records(&src, &device->bdaddr);
3172         if (!device->tmp_records)
3173                 return NULL;
3174
3175         return find_record_in_list(device->tmp_records, uuid);
3176 }
3177
3178 int btd_register_device_driver(struct btd_device_driver *driver)
3179 {
3180         device_drivers = g_slist_append(device_drivers, driver);
3181
3182         return 0;
3183 }
3184
3185 void btd_unregister_device_driver(struct btd_device_driver *driver)
3186 {
3187         device_drivers = g_slist_remove(device_drivers, driver);
3188 }
3189
3190 struct btd_device *btd_device_ref(struct btd_device *device)
3191 {
3192         device->ref++;
3193
3194         DBG("%p: ref=%d", device, device->ref);
3195
3196         return device;
3197 }
3198
3199 void btd_device_unref(struct btd_device *device)
3200 {
3201         DBusConnection *conn = get_dbus_connection();
3202         gchar *path;
3203
3204         device->ref--;
3205
3206         DBG("%p: ref=%d", device, device->ref);
3207
3208         if (device->ref > 0)
3209                 return;
3210
3211         path = g_strdup(device->path);
3212
3213         g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);
3214
3215         g_free(path);
3216 }
3217
3218 void device_set_class(struct btd_device *device, uint32_t value)
3219 {
3220         DBusConnection *conn = get_dbus_connection();
3221
3222         emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Class",
3223                                 DBUS_TYPE_UINT32, &value);
3224 }
3225
3226 static gboolean notify_attios(gpointer user_data)
3227 {
3228         struct btd_device *device = user_data;
3229
3230         if (device->attrib == NULL)
3231                 return FALSE;
3232
3233         g_slist_foreach(device->attios_offline, attio_connected, device->attrib);
3234         device->attios = g_slist_concat(device->attios, device->attios_offline);
3235         device->attios_offline = NULL;
3236
3237         return FALSE;
3238 }
3239
3240 guint btd_device_add_attio_callback(struct btd_device *device,
3241                                                 attio_connect_cb cfunc,
3242                                                 attio_disconnect_cb dcfunc,
3243                                                 gpointer user_data)
3244 {
3245         struct attio_data *attio;
3246         static guint attio_id = 0;
3247
3248         DBG("%p registered ATT connection callback", device);
3249
3250         attio = g_new0(struct attio_data, 1);
3251         attio->id = ++attio_id;
3252         attio->cfunc = cfunc;
3253         attio->dcfunc = dcfunc;
3254         attio->user_data = user_data;
3255
3256         if (device->attrib && cfunc) {
3257                 device->attios_offline = g_slist_append(device->attios_offline,
3258                                                                         attio);
3259                 g_idle_add(notify_attios, device);
3260                 return attio->id;
3261         }
3262
3263         device->attios = g_slist_append(device->attios, attio);
3264
3265         if (device->auto_id == 0)
3266                 device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
3267                                                 att_connect, device,
3268                                                 att_connect_dispatched);
3269
3270         return attio->id;
3271 }
3272
3273 static int attio_id_cmp(gconstpointer a, gconstpointer b)
3274 {
3275         const struct attio_data *attio = a;
3276         guint id = GPOINTER_TO_UINT(b);
3277
3278         return attio->id - id;
3279 }
3280
3281 gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
3282 {
3283         struct attio_data *attio;
3284         GSList *l;
3285
3286         l = g_slist_find_custom(device->attios, GUINT_TO_POINTER(id),
3287                                                                 attio_id_cmp);
3288         if (l) {
3289                 attio = l->data;
3290                 device->attios = g_slist_remove(device->attios, attio);
3291         } else {
3292                 l = g_slist_find_custom(device->attios_offline,
3293                                         GUINT_TO_POINTER(id), attio_id_cmp);
3294                 if (!l)
3295                         return FALSE;
3296
3297                 attio = l->data;
3298                 device->attios_offline = g_slist_remove(device->attios_offline,
3299                                                                         attio);
3300         }
3301
3302         g_free(attio);
3303
3304         if (device->attios != NULL || device->attios_offline != NULL)
3305                 return TRUE;
3306
3307         if (device->auto_id) {
3308                 g_source_remove(device->auto_id);
3309                 device->auto_id = 0;
3310         }
3311
3312         att_cleanup(device);
3313
3314         return TRUE;
3315 }
3316
3317 void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
3318                         uint16_t vendor_id, uint16_t product_id,
3319                         uint16_t product_ver)
3320 {
3321         device_set_vendor(device, vendor_id);
3322         device_set_vendor_src(device, vendor_id_src);
3323         device_set_product(device, product_id);
3324         device_set_version(device, product_ver);
3325 }