device: Add DA logic to restrict the connection to only one mobile device
[platform/upstream/bluez.git] / src / device.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *
4  *  BlueZ - Bluetooth protocol stack for Linux
5  *
6  *  Copyright (C) 2006-2010  Nokia Corporation
7  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
8  *
9  *
10  */
11
12 #ifdef HAVE_CONFIG_H
13 #include <config.h>
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <stdbool.h>
21 #include <errno.h>
22 #include <dirent.h>
23 #include <time.h>
24 #include <sys/stat.h>
25
26 #include <glib.h>
27 #include <dbus/dbus.h>
28
29 #include "lib/bluetooth.h"
30 #include "lib/sdp.h"
31 #include "lib/sdp_lib.h"
32 #include "lib/uuid.h"
33
34 #include "gdbus/gdbus.h"
35
36 #include "log.h"
37 #include "src/shared/util.h"
38 #include "src/shared/att.h"
39 #include "src/shared/queue.h"
40 #include "src/shared/gatt-db.h"
41 #include "src/shared/gatt-client.h"
42 #include "src/shared/gatt-server.h"
43 #include "src/shared/ad.h"
44 #include "src/shared/timeout.h"
45 #include "btio/btio.h"
46 #include "lib/mgmt.h"
47 #include "attrib/att.h"
48 #include "btd.h"
49 #include "adapter.h"
50 #include "gatt-database.h"
51 #include "attrib/gattrib.h"
52 #include "device.h"
53 #include "gatt-client.h"
54 #include "profile.h"
55 #include "service.h"
56 #include "dbus-common.h"
57 #include "error.h"
58 #include "uuid-helper.h"
59 #include "sdp-client.h"
60 #include "attrib/gatt.h"
61 #include "agent.h"
62 #include "textfile.h"
63 #include "storage.h"
64 #include "attrib-server.h"
65 #include "eir.h"
66
67 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
68 #include "sdp-xml.h"
69 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
70 #include <sys/ioctl.h>
71 #endif  /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
72 #endif
73
74 #define DISCONNECT_TIMER        2
75 #define DISCOVERY_TIMER         1
76 #define INVALID_FLAGS           0xff
77
78 #ifndef MIN
79 #define MIN(a, b) ((a) < (b) ? (a) : (b))
80 #endif
81
82 #define RSSI_THRESHOLD          8
83
84 #define GATT_PRIM_SVC_UUID_STR "2800"
85 #define GATT_SND_SVC_UUID_STR  "2801"
86 #define GATT_INCLUDE_UUID_STR "2802"
87 #define GATT_CHARAC_UUID_STR "2803"
88
89 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
90 #define DEV_MAX_MANUFACTURER_DATA_LEN   248
91 #endif
92
93 static DBusConnection *dbus_conn = NULL;
94 static unsigned service_state_cb_id;
95
96 struct btd_disconnect_data {
97         guint id;
98         disconnect_watch watch;
99         void *user_data;
100         GDestroyNotify destroy;
101 };
102
103 struct bonding_req {
104         DBusMessage *msg;
105         guint listener_id;
106         struct btd_device *device;
107         uint8_t bdaddr_type;
108         struct agent *agent;
109         struct btd_adapter_pin_cb_iter *cb_iter;
110         uint8_t status;
111         guint retry_timer;
112         struct timespec attempt_start_time;
113         long last_attempt_duration_ms;
114 };
115
116 typedef enum {
117         AUTH_TYPE_PINCODE,
118         AUTH_TYPE_PASSKEY,
119         AUTH_TYPE_CONFIRM,
120         AUTH_TYPE_NOTIFY_PASSKEY,
121         AUTH_TYPE_NOTIFY_PINCODE,
122 } auth_type_t;
123
124 struct authentication_req {
125         auth_type_t type;
126         struct agent *agent;
127         struct btd_device *device;
128         uint8_t addr_type;
129         uint32_t passkey;
130         char *pincode;
131         gboolean secure;
132 };
133
134 enum {
135         BROWSE_SDP,
136         BROWSE_GATT
137 };
138
139 struct browse_req {
140         DBusMessage *msg;
141         struct btd_device *device;
142         uint8_t type;
143         GSList *match_uuids;
144         GSList *profiles_added;
145         sdp_list_t *records;
146         int search_uuid;
147         int reconnect_attempt;
148         guint listener_id;
149         uint16_t sdp_flags;
150 };
151
152 struct included_search {
153         struct browse_req *req;
154         GSList *services;
155         GSList *current;
156 };
157
158 struct svc_callback {
159         unsigned int id;
160         guint idle_id;
161         struct btd_device *dev;
162         device_svc_cb_t func;
163         void *user_data;
164 };
165
166 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
167 struct le_adv_report_info {
168         uint8_t flags;
169         char manufacturer_data[DEV_MAX_MANUFACTURER_DATA_LEN];
170         uint8_t manufacturer_data_len;
171 };
172 #endif
173
174 /* Per-bearer (LE or BR/EDR) device state */
175 struct bearer_state {
176         bool paired;
177         bool bonded;
178         bool connected;
179         bool svc_resolved;
180 };
181
182 struct csrk_info {
183         uint8_t key[16];
184         uint32_t counter;
185 };
186
187 enum {
188         WAKE_FLAG_DEFAULT = 0,
189         WAKE_FLAG_ENABLED,
190         WAKE_FLAG_DISABLED,
191 };
192
193
194 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
195 typedef enum {
196         DEV_PAIRED_NONE = 0,
197         DEV_PAIRED_BREDR = 1,
198         DEV_PAIRED_LE,
199         DEV_PAIRED_BREDR_LE,
200 } dev_paired_state;
201
202 typedef enum {
203         DEV_CONNECTED_NONE = 0,
204         DEV_CONNECTED_BREDR = 1,
205         DEV_CONNECTED_LE,
206         DEV_CONNECTED_BREDR_LE,
207 } dev_connected_state;
208
209 struct trusted_profile_t {
210         uint32_t        pbap:2;
211         uint32_t        map:2;
212         uint32_t        sap:2;
213         uint32_t        hfp_hs:2;
214         uint32_t        a2dp:2;
215 } __packed;
216 #endif
217
218 struct btd_device {
219         int ref_count;
220
221         bdaddr_t        conn_bdaddr;
222         uint8_t         conn_bdaddr_type;
223         bdaddr_t        bdaddr;
224         uint8_t         bdaddr_type;
225         char            *path;
226         bool            bredr;
227         bool            le;
228         bool            pending_paired;         /* "Paired" waiting for SDP */
229         bool            svc_refreshed;
230         bool            refresh_discovery;
231
232         /* Manage whether this device can wake the system from suspend.
233          * - wake_support: Requires a profile that supports wake (i.e. HID)
234          * - wake_allowed: Is wake currently allowed?
235          * - pending_wake_allowed - Wake flag sent via set_device_flags
236          * - wake_override - User configured wake setting
237          */
238         bool            wake_support;
239         bool            wake_allowed;
240         bool            pending_wake_allowed;
241         uint8_t         wake_override;
242         GDBusPendingPropertySet wake_id;
243
244         uint32_t        supported_flags;
245         uint32_t        current_flags;
246         GSList          *svc_callbacks;
247         GSList          *eir_uuids;
248         struct bt_ad    *ad;
249         uint8_t         ad_flags[1];
250         char            name[MAX_NAME_LENGTH + 1];
251         char            *alias;
252         uint32_t        class;
253         uint16_t        vendor_src;
254         uint16_t        vendor;
255         uint16_t        product;
256         uint16_t        version;
257         uint16_t        appearance;
258         char            *modalias;
259         struct btd_adapter      *adapter;
260         GSList          *uuids;
261         GSList          *primaries;             /* List of primary services */
262         GSList          *services;              /* List of btd_service */
263         GSList          *pending;               /* Pending services */
264         GSList          *watches;               /* List of disconnect_data */
265         bool            temporary;
266         bool            connectable;
267         unsigned int    disconn_timer;
268         unsigned int    discov_timer;
269         unsigned int    temporary_timer;        /* Temporary/disappear timer */
270         struct browse_req *browse;              /* service discover request */
271         struct bonding_req *bonding;
272         struct authentication_req *authr;       /* authentication request */
273         GSList          *disconnects;           /* disconnects message */
274         DBusMessage     *connect;               /* connect message */
275         DBusMessage     *disconnect;            /* disconnect message */
276         GAttrib         *attrib;
277
278         struct bt_att *att;                     /* The new ATT transport */
279         uint16_t att_mtu;                       /* The ATT MTU */
280         unsigned int att_disconn_id;
281
282         /*
283          * TODO: For now, device creates and owns the client-role gatt_db, but
284          * this needs to be persisted in a more central place so that proper
285          * attribute cache support can be built.
286          */
287         struct gatt_db *db;                     /* GATT db cache */
288         unsigned int db_id;
289         struct bt_gatt_client *client;          /* GATT client instance */
290         struct bt_gatt_server *server;          /* GATT server instance */
291         unsigned int gatt_ready_id;
292
293         struct btd_gatt_client *client_dbus;
294
295         struct bearer_state bredr_state;
296         struct bearer_state le_state;
297
298         struct csrk_info *local_csrk;
299         struct csrk_info *remote_csrk;
300         uint8_t ltk_enc_size;
301
302         sdp_list_t      *tmp_records;
303
304         time_t          bredr_seen;
305         time_t          le_seen;
306
307         gboolean        trusted;
308 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
309         struct trusted_profile_t trusted_profiles;
310 #endif
311         gboolean        blocked;
312         gboolean        auto_connect;
313         gboolean        disable_auto_connect;
314         gboolean        general_connect;
315
316         bool            legacy;
317         int8_t          rssi;
318         int8_t          tx_power;
319
320         GIOChannel      *att_io;
321         guint           store_id;
322
323         time_t          name_resolve_failed_time;
324 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
325         bool    legacy_pairing;
326         char            *manufacturer_data;
327         int             manufacturer_data_len;
328         struct le_adv_report_info le_adv_data;
329         int     remote_feature_flags;
330         guint   attio_id;
331         gboolean        gatt_connected;
332         uint16_t        auth_payload_timeout;
333         uint8_t disc_reason;
334         uint8_t         last_bdaddr_type;
335         uint8_t         auth_bdaddr_type;
336         gboolean        ipsp_connected; /* IPSP Connection state */
337         char            if_name[16 + 1]; /* BT interface UP after IPSP connection */
338         uint8_t         rpa_res_support; /* RPA Resolution capability of device */
339         uint16_t        max_tx_octets;
340         uint16_t        max_tx_time;
341         uint16_t        max_rx_octets;
342         uint16_t        max_rx_time;
343         bdaddr_t        *rpa;
344         DBusMessage *req_att_mtu;       /* Attribute MTU request message */
345         uint8_t         irk_val[16];
346         bool pending_conn_update;
347         bool le_connectable;
348 #endif
349 };
350
351 static const uint16_t uuid_list[] = {
352         L2CAP_UUID,
353         PNP_INFO_SVCLASS_ID,
354         PUBLIC_BROWSE_GROUP,
355         0
356 };
357
358 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
359 typedef enum {
360         SHOW_AUTHORIZATION = 0x0, /* 0b00 */
361         SUPPORTED_BLOCKED = 0x1, /* 0b01 */
362         SUPPORTED_TRUSTED= 0x2, /* 0b10 */
363 } bt_profile_trusted_states;
364
365 #define PBAP_SHIFT_OFFSET 0
366 #define MAP_SHIFT_OFFSET 2
367 #define SAP_SHIFT_OFFSET 4
368 #define HFP_HS_SHIFT_OFFSET 6
369 #define A2DP_SHIFT_OFFSET 8
370
371 #define PROFILE_SUPPORTED 0x3 /* This corresponds to binary 0b11*/
372
373 #endif
374
375 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
376 #define OTP_PSM 0x0025
377
378 /* OTP Client */
379 #define BT_OTC_SERVICE_NAME     "org.otp.client"
380 #define BT_OTC_OBJECT_PATH      "/org/otp/client"
381 #define BT_OTC_INTERFACE_NAME   "org.otp.otc_channel"
382
383 /* OTP Server */
384 #define BT_OTS_SERVICE_NAME     "org.projectx.otp"
385 #define BT_OTS_OBJECT_PATH      "/org/projectx/otp"
386 #define BT_OTS_INTERFACE_NAME   "org.projectx.otp_service"
387
388 typedef enum {
389         BT_OTP_CLIENT_ROLE = 0x00,
390         BT_OTP_SERVER_ROLE,
391 } bt_otp_role_e;
392
393 struct otc_conn_info {
394         const char *dev_path;
395         bt_otp_role_e role;
396         GIOChannel *io;
397         bool otc_connected;
398 };
399
400 GSList *otc_connection_list = NULL;
401 #endif
402
403 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
404 #define BT_L2CAP_LE_INTERFACE_NAME "org.bluez.l2cap_le"
405 #define BTD_L2CAP_LE_PSM_MAX 0xFFFF
406 #define UUID_LEN 37
407
408 typedef enum {
409         BT_L2CAP_LE_CLIENT_ROLE = 0x00,
410         BT_L2CAP_LE_SERVER_ROLE,
411 } bt_l2cap_le_role_e;
412
413 struct l2cap_le_conn_info {
414         struct l2cap_le_profile_info *profile_info;
415         GIOChannel *io;
416         guint io_id;
417         bool connected;
418         const char *dev_path;
419         int psm;
420         guint auth_id;
421         char *auth_uuid;
422 };
423
424 struct l2cap_le_profile_info {
425         char *name;
426         char *owner;
427         char *path;
428         bt_l2cap_le_role_e role;
429         int psm;
430         BtIOSecLevel sec_level;
431         bool authorize;
432         guint id;
433         struct l2cap_le_conn_info *server;
434         GSList *conn;
435 };
436
437 GSList *l2cap_le_socket_list = NULL;
438 #endif
439
440
441 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
442 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
443
444 static struct bearer_state *get_state(struct btd_device *dev,
445                                                         uint8_t bdaddr_type)
446 {
447         if (bdaddr_type == BDADDR_BREDR)
448                 return &dev->bredr_state;
449         else
450                 return &dev->le_state;
451 }
452
453 static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
454 {
455         GSList *l;
456
457         for (l = list; l != NULL; l = g_slist_next(l)) {
458                 struct btd_service *service = l->data;
459
460                 if (btd_service_get_profile(service) == p)
461                         return l;
462         }
463
464         return NULL;
465 }
466
467 static GSList *find_service_with_state(GSList *list,
468                                                 btd_service_state_t state)
469 {
470         GSList *l;
471
472         for (l = list; l != NULL; l = g_slist_next(l)) {
473                 struct btd_service *service = l->data;
474
475                 if (btd_service_get_state(service) == state)
476                         return l;
477         }
478
479         return NULL;
480 }
481
482 static GSList *find_service_with_uuid(GSList *list, char *uuid)
483 {
484         GSList *l;
485
486         for (l = list; l != NULL; l = g_slist_next(l)) {
487                 struct btd_service *service = l->data;
488                 struct btd_profile *profile = btd_service_get_profile(service);
489
490                 if (bt_uuid_strcmp(profile->remote_uuid, uuid) == 0)
491                         return l;
492         }
493
494         return NULL;
495 }
496
497 static void update_technologies(GKeyFile *file, struct btd_device *dev)
498 {
499         const char *list[2];
500         size_t len = 0;
501
502         if (dev->bredr)
503                 list[len++] = "BR/EDR";
504
505         if (dev->le) {
506                 const char *type;
507
508                 if (dev->bdaddr_type == BDADDR_LE_PUBLIC)
509                         type = "public";
510                 else
511                         type = "static";
512
513                 g_key_file_set_string(file, "General", "AddressType", type);
514
515                 list[len++] = "LE";
516         }
517
518         g_key_file_set_string_list(file, "General", "SupportedTechnologies",
519                                                                 list, len);
520 }
521
522 static void store_csrk(struct csrk_info *csrk, GKeyFile *key_file,
523                                                         const char *group)
524 {
525         char key[33];
526         int i;
527
528         for (i = 0; i < 16; i++)
529                 sprintf(key + (i * 2), "%2.2X", csrk->key[i]);
530
531         g_key_file_set_string(key_file, group, "Key", key);
532         g_key_file_set_integer(key_file, group, "Counter", csrk->counter);
533 }
534
535 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
536 static char *manufacturer_data2str(char *data, int size)
537 {
538         char str[DEV_MAX_MANUFACTURER_DATA_LEN * 3 + 1];
539         char tmp[5];
540         int i;
541
542         str[0] = '\0';
543         for(i = 0; i < size; i++) {
544                 snprintf(tmp, sizeof(tmp), "%d ", data[i]);
545                 g_strlcat(str, tmp, sizeof(str));
546         }
547
548         return g_strdup(str);
549 }
550
551 static void load_manufacturer_data_2digit(char *data, int len, char *buf)
552 {
553         int i;
554         char **split;
555
556         split = g_strsplit(data, " ", 0);
557
558         for (i = 0; i < len; i++) {
559                 if (split[i] == NULL)
560                         break;
561
562                 buf[i] = (char)g_ascii_strtoull(split[i], NULL, 10);
563         }
564
565         g_strfreev(split);
566
567         return;
568 }
569 #endif
570
571 static gboolean store_device_info_cb(gpointer user_data)
572 {
573         struct btd_device *device = user_data;
574         GKeyFile *key_file;
575         GError *gerr = NULL;
576         char filename[PATH_MAX];
577         char device_addr[18];
578         char *str;
579         char class[9];
580         char **uuids = NULL;
581         gsize length = 0;
582 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
583         gboolean svc_change_regd = false;
584 #endif
585
586         device->store_id = 0;
587
588         ba2str(&device->bdaddr, device_addr);
589
590 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
591         if (device->rpa)
592                 ba2str(device->rpa, device_addr);
593 #endif
594         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
595                                 btd_adapter_get_storage_dir(device->adapter),
596                                 device_addr);
597         create_file(filename, 0600);
598
599         key_file = g_key_file_new();
600         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
601                 error("Unable to load key file from %s: (%s)", filename,
602                                                                 gerr->message);
603                 g_error_free(gerr);
604                 g_key_file_free(key_file);
605                 return FALSE;
606         }
607
608         g_key_file_set_string(key_file, "General", "Name", device->name);
609
610         if (device->alias != NULL)
611                 g_key_file_set_string(key_file, "General", "Alias",
612                                                                 device->alias);
613         else
614                 g_key_file_remove_key(key_file, "General", "Alias", NULL);
615
616         if (device->class) {
617                 sprintf(class, "0x%6.6x", device->class & 0xffffff);
618                 g_key_file_set_string(key_file, "General", "Class", class);
619         } else {
620                 g_key_file_remove_key(key_file, "General", "Class", NULL);
621         }
622
623         if (device->appearance) {
624                 sprintf(class, "0x%4.4x", device->appearance);
625                 g_key_file_set_string(key_file, "General", "Appearance", class);
626         } else {
627                 g_key_file_remove_key(key_file, "General", "Appearance", NULL);
628         }
629
630 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
631         if (device->rpa_res_support) {
632                 g_key_file_set_integer(key_file, "General", "RPAResSupport",
633                                         device->rpa_res_support);
634         } else {
635                 g_key_file_remove_key(key_file, "General", "RPAResSupport", NULL);
636         }
637 #endif
638
639         update_technologies(key_file, device);
640
641         g_key_file_set_boolean(key_file, "General", "Trusted",
642                                                         device->trusted);
643 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
644         struct trusted_profile_t trust_profile = device->trusted_profiles;
645         int trusted_profiles = (trust_profile.pbap << PBAP_SHIFT_OFFSET) |
646                         (trust_profile.map << MAP_SHIFT_OFFSET) |
647                         (trust_profile.sap << SAP_SHIFT_OFFSET) |
648                         (trust_profile.hfp_hs << HFP_HS_SHIFT_OFFSET) |
649                         (trust_profile.a2dp << A2DP_SHIFT_OFFSET);
650         DBG("Storing TrustedProfiles %d", trusted_profiles);
651         g_key_file_set_integer(key_file, "General", "TrustedProfiles",
652                                                         trusted_profiles);
653 #endif
654         g_key_file_set_boolean(key_file, "General", "Blocked",
655                                                         device->blocked);
656
657         if (device->wake_override != WAKE_FLAG_DEFAULT) {
658                 g_key_file_set_boolean(key_file, "General", "WakeAllowed",
659                                        device->wake_override ==
660                                                WAKE_FLAG_ENABLED);
661         }
662
663         if (device->uuids) {
664                 GSList *l;
665                 int i;
666
667                 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
668                 for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
669                         uuids[i] = l->data;
670                 g_key_file_set_string_list(key_file, "General", "Services",
671                                                 (const char **)uuids, i);
672         } else {
673                 g_key_file_remove_key(key_file, "General", "Services", NULL);
674         }
675
676 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
677         if (device->le_adv_data.flags) {
678                 g_key_file_set_integer(key_file, "General", "Flags",
679                                         device->le_adv_data.flags);
680         } else {
681                 g_key_file_remove_key(key_file, "General", "Flags", NULL);
682         }
683
684         if (device->manufacturer_data) {
685                 str = manufacturer_data2str(device->manufacturer_data,
686                                         device->manufacturer_data_len);
687                 g_key_file_set_string(key_file, "General",
688                                 "LegacyManufacturerData",
689                                 str);
690                 g_free(str);
691                 g_key_file_set_integer(key_file, "General",
692                                 "LegacyManufacturerDataLen",
693                                 device->manufacturer_data_len);
694         } else {
695                 g_key_file_remove_key(key_file, "General",
696                                                 "LegacyManufacturerData", NULL);
697                 g_key_file_remove_key(key_file, "General",
698                                                 "LegacyManufacturerDataLen", NULL);
699         }
700
701         if (device->rpa) {
702                 char irk_addr[18];
703
704                 ba2str(&device->bdaddr, irk_addr);
705                 g_key_file_set_string(key_file, "General", "IdentityAddress",
706                                                                 irk_addr);
707         } else {
708                 g_key_file_remove_key(key_file, "General", "IdentityAddress",
709                                                                 NULL);
710         }
711 #endif
712
713         if (device->vendor_src) {
714                 g_key_file_set_integer(key_file, "DeviceID", "Source",
715                                         device->vendor_src);
716                 g_key_file_set_integer(key_file, "DeviceID", "Vendor",
717                                         device->vendor);
718                 g_key_file_set_integer(key_file, "DeviceID", "Product",
719                                         device->product);
720                 g_key_file_set_integer(key_file, "DeviceID", "Version",
721                                         device->version);
722         } else {
723                 g_key_file_remove_group(key_file, "DeviceID", NULL);
724         }
725
726 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
727         svc_change_regd = bt_att_get_svc_changed_indication_registered(device->att);
728         g_key_file_set_boolean(key_file, "Att", "SvcChangeRegd",
729                                                 svc_change_regd);
730 #endif
731
732         if (device->local_csrk)
733                 store_csrk(device->local_csrk, key_file, "LocalSignatureKey");
734
735         if (device->remote_csrk)
736                 store_csrk(device->remote_csrk, key_file, "RemoteSignatureKey");
737
738         str = g_key_file_to_data(key_file, &length, NULL);
739         if (!g_file_set_contents(filename, str, length, &gerr)) {
740                 error("Unable set contents for %s: (%s)", filename,
741                                                                 gerr->message);
742                 g_error_free(gerr);
743         }
744
745         g_free(str);
746
747         g_key_file_free(key_file);
748         g_free(uuids);
749
750         return FALSE;
751 }
752
753 static bool device_address_is_private(struct btd_device *dev)
754 {
755         if (dev->bdaddr_type != BDADDR_LE_RANDOM)
756                 return false;
757
758         switch (dev->bdaddr.b[5] >> 6) {
759         case 0x00:      /* Private non-resolvable */
760         case 0x01:      /* Private resolvable */
761                 return true;
762         default:
763                 return false;
764         }
765 }
766
767 static void store_device_info(struct btd_device *device)
768 {
769         if (device->temporary || device->store_id > 0)
770                 return;
771
772         if (device_address_is_private(device)) {
773                 DBG("Can't store info for private addressed device %s",
774                                                                 device->path);
775                 return;
776         }
777
778         device->store_id = g_idle_add(store_device_info_cb, device);
779 }
780
781 void device_store_cached_name(struct btd_device *dev, const char *name)
782 {
783         char filename[PATH_MAX];
784         char d_addr[18];
785         GKeyFile *key_file;
786         GError *gerr = NULL;
787         char *data;
788         char *data_old;
789         gsize length = 0;
790         gsize length_old = 0;
791
792         if (device_address_is_private(dev)) {
793                 DBG("Can't store name for private addressed device %s",
794                                                                 dev->path);
795                 return;
796         }
797
798         ba2str(&dev->bdaddr, d_addr);
799
800 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
801         if (dev->rpa)
802                 ba2str(dev->rpa, d_addr);
803 #endif
804
805         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
806                         btd_adapter_get_storage_dir(dev->adapter), d_addr);
807         create_file(filename, 0600);
808
809         key_file = g_key_file_new();
810         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
811                 error("Unable to load key file from %s: (%s)", filename,
812                                                                 gerr->message);
813                 g_error_free(gerr);
814         }
815
816         data_old = g_key_file_to_data(key_file, &length_old, NULL);
817
818         g_key_file_set_string(key_file, "General", "Name", name);
819
820         data = g_key_file_to_data(key_file, &length, NULL);
821
822         if ((length != length_old) || (memcmp(data, data_old, length))) {
823                 if (!g_file_set_contents(filename, data, length, &gerr)) {
824                         error("Unable set contents for %s: (%s)", filename,
825                                                                 gerr->message);
826                         g_error_free(gerr);
827                 }
828         }
829         g_free(data);
830         g_free(data_old);
831
832         g_key_file_free(key_file);
833 }
834
835 static void device_store_cached_name_resolve(struct btd_device *dev)
836 {
837         char filename[PATH_MAX];
838         char d_addr[18];
839         GKeyFile *key_file;
840         GError *gerr = NULL;
841         char *data;
842         char *data_old;
843         gsize length = 0;
844         gsize length_old = 0;
845         uint64_t failed_time;
846
847         if (device_address_is_private(dev)) {
848                 DBG("Can't store name resolve for private addressed device %s",
849                                                                 dev->path);
850                 return;
851         }
852
853         ba2str(&dev->bdaddr, d_addr);
854         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
855                         btd_adapter_get_storage_dir(dev->adapter), d_addr);
856         create_file(filename, 0600);
857
858         key_file = g_key_file_new();
859         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
860                 error("Unable to load key file from %s: (%s)", filename,
861                                                                 gerr->message);
862                 g_error_free(gerr);
863         }
864
865         failed_time = (uint64_t) dev->name_resolve_failed_time;
866
867         data_old = g_key_file_to_data(key_file, &length_old, NULL);
868
869         g_key_file_set_uint64(key_file, "NameResolving", "FailedTime",
870                                                                 failed_time);
871
872         data = g_key_file_to_data(key_file, &length, NULL);
873
874         if ((length != length_old) || (memcmp(data, data_old, length))) {
875                 if (!g_file_set_contents(filename, data, length, &gerr)) {
876                         error("Unable set contents for %s: (%s)", filename,
877                                                                 gerr->message);
878                         g_error_free(gerr);
879                 }
880         }
881
882         g_free(data);
883         g_free(data_old);
884
885         g_key_file_free(key_file);
886 }
887
888 static void browse_request_free(struct browse_req *req)
889 {
890 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
891         DBG("");
892 #endif
893         struct btd_device *device = req->device;
894
895         if (device->browse == req)
896                 device->browse = NULL;
897
898         if (req->listener_id)
899                 g_dbus_remove_watch(dbus_conn, req->listener_id);
900         if (req->msg)
901                 dbus_message_unref(req->msg);
902         g_slist_free_full(req->profiles_added, g_free);
903         if (req->records)
904                 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
905
906         g_free(req);
907 }
908
909 static bool gatt_cache_is_enabled(struct btd_device *device)
910 {
911         switch (btd_opts.gatt_cache) {
912         case BT_GATT_CACHE_YES:
913                 return device_is_paired(device, device->bdaddr_type);
914         case BT_GATT_CACHE_NO:
915                 return false;
916         case BT_GATT_CACHE_ALWAYS:
917         default:
918                 return true;
919         }
920 }
921
922 static void gatt_cache_cleanup(struct btd_device *device)
923 {
924         if (gatt_cache_is_enabled(device))
925                 return;
926
927         bt_gatt_client_cancel_all(device->client);
928         gatt_db_clear(device->db);
929         device->le_state.svc_resolved = false;
930 }
931
932 static void gatt_client_cleanup(struct btd_device *device)
933 {
934         if (!device->client)
935                 return;
936
937         gatt_cache_cleanup(device);
938         bt_gatt_client_set_service_changed(device->client, NULL, NULL, NULL);
939
940         if (device->gatt_ready_id > 0) {
941                 bt_gatt_client_ready_unregister(device->client,
942                                                 device->gatt_ready_id);
943                 device->gatt_ready_id = 0;
944         }
945
946         bt_gatt_client_unref(device->client);
947         device->client = NULL;
948 }
949
950 static void gatt_server_cleanup(struct btd_device *device)
951 {
952         if (!device->server)
953                 return;
954
955         btd_gatt_database_att_disconnected(
956                         btd_adapter_get_database(device->adapter), device);
957
958         bt_gatt_server_unref(device->server);
959         device->server = NULL;
960 }
961
962 static void attio_cleanup(struct btd_device *device)
963 {
964         if (device->att_disconn_id)
965                 bt_att_unregister_disconnect(device->att,
966                                                         device->att_disconn_id);
967
968         if (device->att_io) {
969                 g_io_channel_shutdown(device->att_io, FALSE, NULL);
970                 g_io_channel_unref(device->att_io);
971                 device->att_io = NULL;
972         }
973
974         gatt_client_cleanup(device);
975         gatt_server_cleanup(device);
976
977         if (device->att) {
978                 bt_att_unref(device->att);
979                 device->att = NULL;
980         }
981
982         if (device->attrib) {
983                 GAttrib *attrib = device->attrib;
984
985                 device->attrib = NULL;
986                 g_attrib_cancel_all(attrib);
987                 g_attrib_unref(attrib);
988         }
989 }
990
991 static void browse_request_cancel(struct browse_req *req)
992 {
993         struct btd_device *device = req->device;
994         struct btd_adapter *adapter = device->adapter;
995
996         DBG("");
997
998         bt_cancel_discovery(btd_adapter_get_address(adapter), &device->bdaddr);
999
1000         attio_cleanup(device);
1001
1002         browse_request_free(req);
1003 }
1004
1005 static void svc_dev_remove(gpointer user_data)
1006 {
1007         struct svc_callback *cb = user_data;
1008
1009         if (cb->idle_id > 0)
1010                 g_source_remove(cb->idle_id);
1011
1012         cb->func(cb->dev, -ENODEV, cb->user_data);
1013
1014         g_free(cb);
1015 }
1016
1017 static void device_free(gpointer user_data)
1018 {
1019         struct btd_device *device = user_data;
1020
1021         btd_gatt_client_destroy(device->client_dbus);
1022         device->client_dbus = NULL;
1023
1024         g_slist_free_full(device->uuids, g_free);
1025         g_slist_free_full(device->primaries, g_free);
1026         g_slist_free_full(device->svc_callbacks, svc_dev_remove);
1027
1028         /* Reset callbacks since the device is going to be freed */
1029         gatt_db_unregister(device->db, device->db_id);
1030
1031         attio_cleanup(device);
1032
1033         gatt_db_unref(device->db);
1034
1035         bt_ad_unref(device->ad);
1036
1037         if (device->tmp_records)
1038                 sdp_list_free(device->tmp_records,
1039                                         (sdp_free_func_t) sdp_record_free);
1040
1041         if (device->disconn_timer)
1042                 timeout_remove(device->disconn_timer);
1043
1044         if (device->discov_timer)
1045                 timeout_remove(device->discov_timer);
1046
1047         if (device->temporary_timer)
1048                 timeout_remove(device->temporary_timer);
1049
1050         if (device->connect)
1051                 dbus_message_unref(device->connect);
1052
1053         if (device->disconnect)
1054                 dbus_message_unref(device->disconnect);
1055
1056         DBG("%p", device);
1057
1058         if (device->authr) {
1059                 if (device->authr->agent)
1060                         agent_unref(device->authr->agent);
1061                 g_free(device->authr->pincode);
1062                 g_free(device->authr);
1063         }
1064
1065         if (device->eir_uuids)
1066                 g_slist_free_full(device->eir_uuids, g_free);
1067
1068 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1069         g_free(device->rpa);
1070 #endif
1071         g_free(device->local_csrk);
1072         g_free(device->remote_csrk);
1073         g_free(device->path);
1074         g_free(device->alias);
1075         free(device->modalias);
1076         g_free(device);
1077 }
1078
1079 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1080 void device_set_remote_feature_flag(struct btd_device *device, int flags)
1081 {
1082         device->remote_feature_flags = flags;
1083 }
1084
1085 gboolean device_is_bredrle(struct btd_device *device)
1086 {
1087         return (device->remote_feature_flags & (EIR_CONTROLLER | EIR_SIM_HOST));
1088 }
1089 #endif
1090
1091 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type)
1092 {
1093         struct bearer_state *state = get_state(device, bdaddr_type);
1094
1095         return state->paired;
1096 }
1097
1098 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type)
1099 {
1100         struct bearer_state *state = get_state(device, bdaddr_type);
1101
1102         return state->bonded;
1103 }
1104
1105 gboolean device_is_trusted(struct btd_device *device)
1106 {
1107         return device->trusted;
1108 }
1109
1110 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1111 gboolean device_is_profile_trusted(struct btd_device *device,
1112                 const char *uuid)
1113 {
1114         if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1115                 if (device->trusted_profiles.pbap == SUPPORTED_TRUSTED)
1116                         return TRUE;
1117         } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1118                 if (device->trusted_profiles.map == SUPPORTED_TRUSTED)
1119                         return TRUE;
1120         } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1121                 if (device->trusted_profiles.sap == SUPPORTED_TRUSTED)
1122                         return TRUE;
1123         } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1124                 if (device->trusted_profiles.hfp_hs == SUPPORTED_TRUSTED)
1125                         return TRUE;
1126         } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1127                 if (device->trusted_profiles.a2dp == SUPPORTED_TRUSTED)
1128                         return TRUE;
1129         }
1130         return FALSE;
1131 }
1132
1133 gboolean device_is_profile_blocked(struct btd_device *device,
1134                 const char *uuid)
1135 {
1136         if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1137                 if (device->trusted_profiles.pbap == SUPPORTED_BLOCKED)
1138                         return TRUE;
1139         } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1140                 if (device->trusted_profiles.map == SUPPORTED_BLOCKED)
1141                         return TRUE;
1142         } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1143                 if (device->trusted_profiles.sap == SUPPORTED_BLOCKED)
1144                         return TRUE;
1145         } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1146                 if (device->trusted_profiles.hfp_hs == SUPPORTED_BLOCKED)
1147                         return TRUE;
1148         } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1149                 if (device->trusted_profiles.a2dp == SUPPORTED_BLOCKED)
1150                         return TRUE;
1151         }
1152         return FALSE;
1153 }
1154 #endif
1155
1156 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
1157                                         DBusMessageIter *iter, void *data)
1158 {
1159         struct btd_device *device = data;
1160         char dstaddr[18];
1161         const char *ptr = dstaddr;
1162
1163 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1164         if (device->rpa)
1165                 ba2str(device->rpa, dstaddr);
1166         else
1167 #endif
1168         ba2str(&device->bdaddr, dstaddr);
1169         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1170
1171         return TRUE;
1172 }
1173
1174 static gboolean property_get_address_type(const GDBusPropertyTable *property,
1175                                         DBusMessageIter *iter, void *user_data)
1176 {
1177         struct btd_device *device = user_data;
1178         const char *str;
1179
1180         if (device->le && device->bdaddr_type == BDADDR_LE_RANDOM)
1181                 str = "random";
1182         else
1183                 str = "public";
1184
1185         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
1186
1187         return TRUE;
1188 }
1189
1190 static gboolean dev_property_get_name(const GDBusPropertyTable *property,
1191                                         DBusMessageIter *iter, void *data)
1192 {
1193         struct btd_device *device = data;
1194         const char *ptr = device->name;
1195
1196         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1197
1198         return TRUE;
1199 }
1200
1201 static gboolean dev_property_exists_name(const GDBusPropertyTable *property,
1202                                                                 void *data)
1203 {
1204         struct btd_device *dev = data;
1205
1206         return device_name_known(dev);
1207 }
1208
1209 static gboolean dev_property_get_alias(const GDBusPropertyTable *property,
1210                                         DBusMessageIter *iter, void *data)
1211 {
1212         struct btd_device *device = data;
1213         char dstaddr[18];
1214         const char *ptr;
1215
1216         /* Alias (fallback to name or address) */
1217         if (device->alias != NULL)
1218                 ptr = device->alias;
1219         else if (strlen(device->name) > 0) {
1220                 ptr = device->name;
1221         } else {
1222                 ba2str(&device->bdaddr, dstaddr);
1223 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
1224                 g_strdelimit(dstaddr, ":", '-');
1225 #endif
1226                 ptr = dstaddr;
1227         }
1228
1229         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1230
1231         return TRUE;
1232 }
1233
1234 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1235 static gboolean dev_property_get_alias_set(const GDBusPropertyTable *property,
1236                                         DBusMessageIter *iter, void *data)
1237 {
1238         struct btd_device *device = data;
1239         dbus_bool_t val;
1240
1241         if (device->alias != NULL)
1242                 val = TRUE;
1243         else
1244                 val = FALSE;
1245
1246         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1247
1248         return TRUE;
1249 }
1250 #endif
1251
1252 static void set_alias(GDBusPendingPropertySet id, const char *alias,
1253                                                                 void *data)
1254 {
1255         struct btd_device *device = data;
1256
1257         /* No change */
1258         if ((device->alias == NULL && g_str_equal(alias, "")) ||
1259                                         g_strcmp0(device->alias, alias) == 0) {
1260                 g_dbus_pending_property_success(id);
1261                 return;
1262         }
1263
1264         g_free(device->alias);
1265         device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
1266
1267         store_device_info(device);
1268
1269         g_dbus_emit_property_changed(dbus_conn, device->path,
1270                                                 DEVICE_INTERFACE, "Alias");
1271
1272         g_dbus_pending_property_success(id);
1273 }
1274
1275 static void dev_property_set_alias(const GDBusPropertyTable *property,
1276                                         DBusMessageIter *value,
1277                                         GDBusPendingPropertySet id, void *data)
1278 {
1279         const char *alias;
1280
1281         if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING) {
1282                 g_dbus_pending_property_error(id,
1283                                         ERROR_INTERFACE ".InvalidArguments",
1284                                         "Invalid arguments in method call");
1285                 return;
1286         }
1287
1288         dbus_message_iter_get_basic(value, &alias);
1289
1290         set_alias(id, alias, data);
1291 }
1292
1293 static gboolean dev_property_exists_class(const GDBusPropertyTable *property,
1294                                                                 void *data)
1295 {
1296         struct btd_device *device = data;
1297
1298         return device->class != 0;
1299 }
1300
1301 static gboolean dev_property_get_class(const GDBusPropertyTable *property,
1302                                         DBusMessageIter *iter, void *data)
1303 {
1304         struct btd_device *device = data;
1305
1306         if (device->class == 0)
1307                 return FALSE;
1308
1309         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &device->class);
1310
1311         return TRUE;
1312 }
1313
1314 static gboolean get_appearance(const GDBusPropertyTable *property, void *data,
1315                                                         uint16_t *appearance)
1316 {
1317         struct btd_device *device = data;
1318
1319         if (dev_property_exists_class(property, data))
1320                 return FALSE;
1321
1322         if (device->appearance) {
1323                 *appearance = device->appearance;
1324                 return TRUE;
1325         }
1326
1327         return FALSE;
1328 }
1329
1330 static gboolean dev_property_exists_appearance(
1331                         const GDBusPropertyTable *property, void *data)
1332 {
1333         uint16_t appearance;
1334
1335         return get_appearance(property, data, &appearance);
1336 }
1337
1338 static gboolean dev_property_get_appearance(const GDBusPropertyTable *property,
1339                                         DBusMessageIter *iter, void *data)
1340 {
1341         uint16_t appearance;
1342
1343         if (!get_appearance(property, data, &appearance))
1344                 return FALSE;
1345
1346         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &appearance);
1347
1348         return TRUE;
1349 }
1350
1351 static const char *get_icon(const GDBusPropertyTable *property, void *data)
1352 {
1353         struct btd_device *device = data;
1354         const char *icon = NULL;
1355         uint16_t appearance;
1356
1357         if (device->class != 0)
1358                 icon = class_to_icon(device->class);
1359         else if (get_appearance(property, data, &appearance))
1360                 icon = gap_appearance_to_icon(appearance);
1361
1362         return icon;
1363 }
1364
1365 static gboolean dev_property_exists_icon(
1366                         const GDBusPropertyTable *property, void *data)
1367 {
1368         return get_icon(property, data) != NULL;
1369 }
1370
1371 static gboolean dev_property_get_icon(const GDBusPropertyTable *property,
1372                                         DBusMessageIter *iter, void *data)
1373 {
1374         const char *icon;
1375
1376         icon = get_icon(property, data);
1377         if (icon == NULL)
1378                 return FALSE;
1379
1380         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &icon);
1381
1382         return TRUE;
1383 }
1384
1385 static gboolean dev_property_get_paired(const GDBusPropertyTable *property,
1386                                         DBusMessageIter *iter, void *data)
1387 {
1388         struct btd_device *dev = data;
1389         dbus_bool_t val;
1390
1391         if (dev->bredr_state.paired || dev->le_state.paired)
1392                 val = TRUE;
1393         else
1394                 val = FALSE;
1395
1396         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1397
1398         return TRUE;
1399 }
1400
1401 static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
1402                                         DBusMessageIter *iter, void *data)
1403 {
1404         struct btd_device *device = data;
1405         dbus_bool_t val = device->legacy;
1406
1407         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1408
1409         return TRUE;
1410 }
1411
1412 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
1413                                         DBusMessageIter *iter, void *data)
1414 {
1415         struct btd_device *dev = data;
1416         dbus_int16_t val = dev->rssi;
1417
1418         dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1419
1420         return TRUE;
1421 }
1422
1423 static gboolean dev_property_exists_rssi(const GDBusPropertyTable *property,
1424                                                                 void *data)
1425 {
1426         struct btd_device *dev = data;
1427
1428         if (dev->rssi == 0)
1429                 return FALSE;
1430
1431         return TRUE;
1432 }
1433
1434 static gboolean dev_property_get_tx_power(const GDBusPropertyTable *property,
1435                                         DBusMessageIter *iter, void *data)
1436 {
1437         struct btd_device *dev = data;
1438         dbus_int16_t val = dev->tx_power;
1439
1440         dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1441
1442         return TRUE;
1443 }
1444
1445 static gboolean dev_property_exists_tx_power(const GDBusPropertyTable *property,
1446                                                                 void *data)
1447 {
1448         struct btd_device *dev = data;
1449
1450         if (dev->tx_power == 127)
1451                 return FALSE;
1452
1453         return TRUE;
1454 }
1455
1456 static gboolean
1457 dev_property_get_svc_resolved(const GDBusPropertyTable *property,
1458                                         DBusMessageIter *iter, void *data)
1459 {
1460         struct btd_device *device = data;
1461         gboolean val = device->svc_refreshed;
1462
1463         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1464
1465         return TRUE;
1466 }
1467
1468 static gboolean dev_property_flags_exist(const GDBusPropertyTable *property,
1469                                                                 void *data)
1470 {
1471         struct btd_device *device = data;
1472
1473         return device->ad_flags[0] != INVALID_FLAGS;
1474 }
1475
1476 static gboolean
1477 dev_property_get_flags(const GDBusPropertyTable *property,
1478                                         DBusMessageIter *iter, void *data)
1479 {
1480         struct btd_device *device = data;
1481         uint8_t *flags = device->ad_flags;
1482         DBusMessageIter array;
1483
1484         dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1485                                         DBUS_TYPE_BYTE_AS_STRING, &array);
1486         dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1487                                         &flags, sizeof(device->ad_flags));
1488         dbus_message_iter_close_container(iter, &array);
1489
1490         return TRUE;
1491 }
1492
1493 static gboolean dev_property_get_trusted(const GDBusPropertyTable *property,
1494                                         DBusMessageIter *iter, void *data)
1495 {
1496         struct btd_device *device = data;
1497         gboolean val = device_is_trusted(device);
1498
1499         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1500
1501         return TRUE;
1502 }
1503
1504 static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
1505 {
1506         struct btd_device *device = data;
1507
1508         btd_device_set_trusted(device, value);
1509
1510         g_dbus_pending_property_success(id);
1511 }
1512
1513 static void dev_property_set_trusted(const GDBusPropertyTable *property,
1514                                         DBusMessageIter *value,
1515                                         GDBusPendingPropertySet id, void *data)
1516 {
1517         dbus_bool_t b;
1518
1519         if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1520                 g_dbus_pending_property_error(id,
1521                                         ERROR_INTERFACE ".InvalidArguments",
1522                                         "Invalid arguments in method call");
1523                 return;
1524         }
1525
1526         dbus_message_iter_get_basic(value, &b);
1527
1528         set_trust(id, b, data);
1529 }
1530
1531 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1532 static gboolean dev_property_get_trusted_profiles(const GDBusPropertyTable *property,
1533                                         DBusMessageIter *iter, void *data)
1534 {
1535         struct btd_device *device = data;
1536         uint32_t pbap = device->trusted_profiles.pbap;
1537         uint32_t map = device->trusted_profiles.map;
1538         uint32_t sap = device->trusted_profiles.sap;
1539         uint32_t hfp_hs = device->trusted_profiles.hfp_hs;
1540         uint32_t a2dp = device->trusted_profiles.a2dp;
1541
1542         unsigned int val = (pbap << PBAP_SHIFT_OFFSET) |
1543                         (map << MAP_SHIFT_OFFSET) |
1544                         (sap << SAP_SHIFT_OFFSET) |
1545                         (hfp_hs << HFP_HS_SHIFT_OFFSET) |
1546                         (a2dp << A2DP_SHIFT_OFFSET);
1547
1548         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val);
1549
1550         return TRUE;
1551 }
1552 #endif
1553
1554 static gboolean dev_property_get_blocked(const GDBusPropertyTable *property,
1555                                         DBusMessageIter *iter, void *data)
1556 {
1557         struct btd_device *device = data;
1558
1559         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1560                                                         &device->blocked);
1561
1562         return TRUE;
1563 }
1564
1565 static void set_blocked(GDBusPendingPropertySet id, gboolean value, void *data)
1566 {
1567         struct btd_device *device = data;
1568         int err;
1569
1570         if (value)
1571                 err = device_block(device, FALSE);
1572         else
1573                 err = device_unblock(device, FALSE, FALSE);
1574
1575         switch (-err) {
1576         case 0:
1577                 g_dbus_pending_property_success(id);
1578                 break;
1579         case EINVAL:
1580                 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1581                                         "Kernel lacks reject list support");
1582                 break;
1583         default:
1584                 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1585                                                         strerror(-err));
1586                 break;
1587         }
1588 }
1589
1590
1591 static void dev_property_set_blocked(const GDBusPropertyTable *property,
1592                                         DBusMessageIter *value,
1593                                         GDBusPendingPropertySet id, void *data)
1594 {
1595         dbus_bool_t b;
1596
1597         if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1598                 g_dbus_pending_property_error(id,
1599                                         ERROR_INTERFACE ".InvalidArguments",
1600                                         "Invalid arguments in method call");
1601                 return;
1602         }
1603
1604         dbus_message_iter_get_basic(value, &b);
1605
1606         set_blocked(id, b, data);
1607 }
1608
1609 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1610 static uint8_t device_get_connected_state(struct btd_device *device)
1611 {
1612         if (device->bredr_state.connected && device->le_state.connected)
1613                 return DEV_CONNECTED_BREDR_LE;
1614         else if (device->bredr_state.connected)
1615                 return DEV_CONNECTED_BREDR;
1616         else if (device->le_state.connected)
1617                 return DEV_CONNECTED_LE;
1618         else
1619                 return DEV_CONNECTED_NONE;
1620 }
1621
1622 static gboolean dev_property_get_payload(const GDBusPropertyTable *property,
1623                                         DBusMessageIter *iter, void *data)
1624 {
1625         struct btd_device *dev = data;
1626         dbus_uint16_t payload_timeout = dev->auth_payload_timeout;
1627
1628         dbus_message_iter_append_basic(iter,
1629                         DBUS_TYPE_UINT16, &payload_timeout);
1630
1631         return TRUE;
1632 }
1633
1634 static gboolean dev_property_get_last_addr_type(const GDBusPropertyTable *property,
1635                                         DBusMessageIter *iter, void *data)
1636 {
1637         struct btd_device *dev = data;
1638         uint8_t last_addr_type = dev->last_bdaddr_type;
1639
1640         dbus_message_iter_append_basic(iter,
1641                         DBUS_TYPE_BYTE, &last_addr_type);
1642
1643         return TRUE;
1644 }
1645
1646 static gboolean dev_property_get_att_mtu(const GDBusPropertyTable *property,
1647                                         DBusMessageIter *iter, void *data)
1648 {
1649         struct btd_device *device = data;
1650         dbus_uint16_t mtu = bt_gatt_client_get_mtu(device->client);
1651
1652         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &mtu);
1653
1654         return TRUE;
1655 }
1656
1657 static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
1658                                         DBusMessageIter *iter, void *data)
1659 {
1660         struct btd_device *device = data;
1661         dbus_bool_t gatt_connected;
1662
1663         if (device->gatt_connected)
1664                 gatt_connected = TRUE;
1665         else
1666                 gatt_connected = FALSE;
1667
1668         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1669                                         &gatt_connected);
1670
1671         return TRUE;
1672 }
1673
1674 static gboolean dev_property_get_ipsp_conn_state(const GDBusPropertyTable *property,
1675                                         DBusMessageIter *iter, void *data)
1676 {
1677         struct btd_device *dev = data;
1678         dbus_bool_t ipsp_connected;
1679
1680         if (dev->ipsp_connected)
1681                 ipsp_connected = TRUE;
1682         else
1683                 ipsp_connected = FALSE;
1684
1685         dbus_message_iter_append_basic(iter,
1686                         DBUS_TYPE_BOOLEAN, &ipsp_connected);
1687
1688         return TRUE;
1689 }
1690
1691 static gboolean dev_property_get_ipsp_conn_bt_iface_name(const GDBusPropertyTable *property,
1692                                 DBusMessageIter *iter, void *data)
1693 {
1694         struct btd_device *dev = data;
1695         char *ptr = g_strdup(dev->if_name);
1696
1697         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, (const char **)&ptr);
1698
1699         g_free(ptr);
1700
1701         return TRUE;
1702 }
1703 #endif
1704
1705 static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
1706                                         DBusMessageIter *iter, void *data)
1707 {
1708         struct btd_device *dev = data;
1709
1710 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1711         uint8_t connected = device_get_connected_state(dev);
1712
1713         dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &connected);
1714 #else
1715         dbus_bool_t connected;
1716
1717         if (dev->bredr_state.connected || dev->le_state.connected)
1718                 connected = TRUE;
1719         else
1720                 connected = FALSE;
1721
1722         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1723 #endif
1724
1725         return TRUE;
1726 }
1727
1728 static gboolean dev_property_get_uuids(const GDBusPropertyTable *property,
1729                                         DBusMessageIter *iter, void *data)
1730 {
1731         struct btd_device *dev = data;
1732         DBusMessageIter entry;
1733         GSList *l;
1734
1735         dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1736                                 DBUS_TYPE_STRING_AS_STRING, &entry);
1737
1738         if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
1739                 l = dev->uuids;
1740         else if (dev->eir_uuids)
1741                 l = dev->eir_uuids;
1742         else
1743                 l = dev->uuids;
1744
1745         for (; l != NULL; l = l->next)
1746                 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1747                                                         &l->data);
1748
1749         dbus_message_iter_close_container(iter, &entry);
1750
1751         return TRUE;
1752 }
1753
1754 static gboolean dev_property_get_modalias(const GDBusPropertyTable *property,
1755                                         DBusMessageIter *iter, void *data)
1756 {
1757         struct btd_device *device = data;
1758
1759         if (!device->modalias)
1760                 return FALSE;
1761
1762         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1763                                                         &device->modalias);
1764
1765         return TRUE;
1766 }
1767
1768 static gboolean dev_property_exists_modalias(const GDBusPropertyTable *property,
1769                                                                 void *data)
1770 {
1771         struct btd_device *device = data;
1772
1773         return device->modalias ? TRUE : FALSE;
1774 }
1775
1776 static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
1777                                         DBusMessageIter *iter, void *data)
1778 {
1779         struct btd_device *device = data;
1780         const char *str = adapter_get_path(device->adapter);
1781
1782         dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &str);
1783
1784         return TRUE;
1785 }
1786
1787 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1788 static gboolean property_get_manufacturer_data_len(const GDBusPropertyTable *property,
1789                                         DBusMessageIter *iter, void *user_data)
1790 {
1791         struct btd_device *device = user_data;
1792         dbus_uint16_t val = device->manufacturer_data_len;
1793
1794         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
1795
1796         return TRUE;
1797 }
1798
1799 static gboolean property_get_manufacturer_data(const GDBusPropertyTable *property,
1800                                         DBusMessageIter *iter, void *user_data)
1801 {
1802         struct btd_device *device = user_data;
1803         char str[DEV_MAX_MANUFACTURER_DATA_LEN] = {0};
1804         DBusMessageIter array;
1805
1806         memset(str, 0, DEV_MAX_MANUFACTURER_DATA_LEN);
1807         if (device->manufacturer_data_len)
1808                 memcpy(str, device->manufacturer_data,
1809                                         device->manufacturer_data_len);
1810
1811         dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1812                                         DBUS_TYPE_BYTE_AS_STRING, &array);
1813
1814         dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1815                                                 &device->manufacturer_data,
1816                                                 device->manufacturer_data_len);
1817
1818         dbus_message_iter_close_container(iter, &array);
1819
1820         return TRUE;
1821 }
1822
1823 gboolean device_get_gatt_connected(const struct btd_device *device)
1824 {
1825         return device->gatt_connected;
1826 }
1827 #endif
1828
1829 static void append_manufacturer_data(void *data, void *user_data)
1830 {
1831         struct bt_ad_manufacturer_data *md = data;
1832         DBusMessageIter *dict = user_data;
1833
1834         g_dbus_dict_append_basic_array(dict,
1835                                 DBUS_TYPE_UINT16, &md->manufacturer_id,
1836                                 DBUS_TYPE_BYTE, &md->data, md->len);
1837 }
1838
1839 static gboolean
1840 dev_property_get_manufacturer_data(const GDBusPropertyTable *property,
1841                                         DBusMessageIter *iter, void *data)
1842 {
1843         struct btd_device *device = data;
1844         DBusMessageIter dict;
1845
1846         dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1847                                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1848                                         DBUS_TYPE_UINT16_AS_STRING
1849                                         DBUS_TYPE_VARIANT_AS_STRING
1850                                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1851                                         &dict);
1852
1853         bt_ad_foreach_manufacturer_data(device->ad, append_manufacturer_data,
1854                                                                         &dict);
1855
1856         dbus_message_iter_close_container(iter, &dict);
1857
1858         return TRUE;
1859 }
1860
1861 static gboolean
1862 dev_property_manufacturer_data_exist(const GDBusPropertyTable *property,
1863                                                                 void *data)
1864 {
1865         struct btd_device *device = data;
1866
1867         return bt_ad_has_manufacturer_data(device->ad, NULL);
1868 }
1869
1870 static void append_service_data(void *data, void *user_data)
1871 {
1872         struct bt_ad_service_data *sd = data;
1873         DBusMessageIter *dict = user_data;
1874         char uuid_str[MAX_LEN_UUID_STR];
1875
1876         bt_uuid_to_string(&sd->uuid, uuid_str, sizeof(uuid_str));
1877
1878         dict_append_array(dict, uuid_str, DBUS_TYPE_BYTE, &sd->data, sd->len);
1879 }
1880
1881 static gboolean
1882 dev_property_get_service_data(const GDBusPropertyTable *property,
1883                                         DBusMessageIter *iter, void *data)
1884 {
1885         struct btd_device *device = data;
1886         DBusMessageIter dict;
1887
1888         dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1889                                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1890                                         DBUS_TYPE_STRING_AS_STRING
1891                                         DBUS_TYPE_VARIANT_AS_STRING
1892                                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1893                                         &dict);
1894
1895         bt_ad_foreach_service_data(device->ad, append_service_data, &dict);
1896
1897         dbus_message_iter_close_container(iter, &dict);
1898
1899         return TRUE;
1900 }
1901
1902 static gboolean
1903 dev_property_service_data_exist(const GDBusPropertyTable *property,
1904                                                                 void *data)
1905 {
1906         struct btd_device *device = data;
1907
1908         return bt_ad_has_service_data(device->ad, NULL);
1909 }
1910
1911 static void append_advertising_data(void *data, void *user_data)
1912 {
1913         struct bt_ad_data *ad = data;
1914         DBusMessageIter *dict = user_data;
1915
1916         g_dbus_dict_append_basic_array(dict,
1917                                 DBUS_TYPE_BYTE, &ad->type,
1918                                 DBUS_TYPE_BYTE, &ad->data, ad->len);
1919 }
1920
1921 static gboolean
1922 dev_property_get_advertising_data(const GDBusPropertyTable *property,
1923                                         DBusMessageIter *iter, void *data)
1924 {
1925         struct btd_device *device = data;
1926         DBusMessageIter dict;
1927
1928         dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1929                                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1930                                         DBUS_TYPE_BYTE_AS_STRING
1931                                         DBUS_TYPE_VARIANT_AS_STRING
1932                                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1933                                         &dict);
1934
1935         bt_ad_foreach_data(device->ad, append_advertising_data, &dict);
1936
1937         dbus_message_iter_close_container(iter, &dict);
1938
1939         return TRUE;
1940 }
1941
1942 static gboolean
1943 dev_property_advertising_data_exist(const GDBusPropertyTable *property,
1944                                                                 void *data)
1945 {
1946         struct btd_device *device = data;
1947
1948         return bt_ad_has_data(device->ad, NULL);
1949 }
1950
1951 static bool device_get_wake_support(struct btd_device *device)
1952 {
1953         return device->wake_support;
1954 }
1955
1956 void device_set_wake_support(struct btd_device *device, bool wake_support)
1957 {
1958         device->wake_support = wake_support;
1959
1960         /* If wake configuration has not been made yet, set the initial
1961          * configuration.
1962          */
1963         if (device->wake_override == WAKE_FLAG_DEFAULT) {
1964                 device_set_wake_override(device, wake_support);
1965                 device_set_wake_allowed(device, wake_support, -1U);
1966         }
1967 }
1968
1969 static bool device_get_wake_allowed(struct btd_device *device)
1970 {
1971         return device->wake_allowed;
1972 }
1973
1974 void device_set_wake_override(struct btd_device *device, bool wake_override)
1975 {
1976         if (wake_override) {
1977                 device->wake_override = WAKE_FLAG_ENABLED;
1978                 device->current_flags |= DEVICE_FLAG_REMOTE_WAKEUP;
1979         } else {
1980                 device->wake_override = WAKE_FLAG_DISABLED;
1981                 device->current_flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
1982         }
1983 }
1984
1985 static void device_set_wake_allowed_complete(struct btd_device *device)
1986 {
1987         if (device->wake_id != -1U) {
1988                 g_dbus_pending_property_success(device->wake_id);
1989                 device->wake_id = -1U;
1990         }
1991
1992         device->wake_allowed = device->pending_wake_allowed;
1993         g_dbus_emit_property_changed(dbus_conn, device->path,
1994                                         DEVICE_INTERFACE, "WakeAllowed");
1995
1996         store_device_info(device);
1997 }
1998
1999 static void set_wake_allowed_complete(uint8_t status, uint16_t length,
2000                                          const void *param, void *user_data)
2001 {
2002         const struct mgmt_rp_set_device_flags *rp = param;
2003         struct btd_device *dev = user_data;
2004
2005         if (status != MGMT_STATUS_SUCCESS) {
2006                 error("Set device flags return status: %s",
2007                                         mgmt_errstr(status));
2008                 return;
2009         }
2010
2011         if (length < sizeof(*rp)) {
2012                 error("Too small Set Device Flags complete event: %d", length);
2013                 return;
2014         }
2015
2016         device_set_wake_allowed_complete(dev);
2017 }
2018
2019 void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
2020                              GDBusPendingPropertySet id)
2021 {
2022         uint32_t flags;
2023         /* Pending and current value are the same unless there is a change in
2024          * progress. Only update wake allowed if pending value doesn't match the
2025          * new value.
2026          */
2027         if (wake_allowed == device->pending_wake_allowed)
2028                 return;
2029
2030         device->wake_id = id;
2031         device->pending_wake_allowed = wake_allowed;
2032         flags = device->current_flags;
2033         if (wake_allowed)
2034                 flags |= DEVICE_FLAG_REMOTE_WAKEUP;
2035         else
2036                 flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
2037
2038         adapter_set_device_flags(device->adapter, device, flags,
2039                                         set_wake_allowed_complete, device);
2040 }
2041
2042
2043 static gboolean
2044 dev_property_get_wake_allowed(const GDBusPropertyTable *property,
2045                              DBusMessageIter *iter, void *data)
2046 {
2047         struct btd_device *device = data;
2048         dbus_bool_t wake_allowed = device_get_wake_allowed(device);
2049
2050         dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &wake_allowed);
2051
2052         return TRUE;
2053 }
2054
2055 static void dev_property_set_wake_allowed(const GDBusPropertyTable *property,
2056                                          DBusMessageIter *value,
2057                                          GDBusPendingPropertySet id, void *data)
2058 {
2059         struct btd_device *device = data;
2060         dbus_bool_t b;
2061
2062         if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
2063                 g_dbus_pending_property_error(id,
2064                                         ERROR_INTERFACE ".InvalidArguments",
2065                                         "Invalid arguments in method call");
2066                 return;
2067         }
2068
2069         if (device->temporary) {
2070                 g_dbus_pending_property_error(id,
2071                                         ERROR_INTERFACE ".Unsupported",
2072                                         "Cannot set property while temporary");
2073                 return;
2074         }
2075
2076         /* Emit busy or success depending on current value. */
2077         if (b == device->pending_wake_allowed) {
2078                 if (device->wake_allowed == device->pending_wake_allowed)
2079                         g_dbus_pending_property_success(id);
2080                 else
2081                         g_dbus_pending_property_error(
2082                                 id, ERROR_INTERFACE ".Busy",
2083                                 "Property change in progress");
2084
2085                 return;
2086         }
2087
2088         dbus_message_iter_get_basic(value, &b);
2089         device_set_wake_override(device, b);
2090         device_set_wake_allowed(device, b, id);
2091 }
2092
2093 static gboolean dev_property_wake_allowed_exist(
2094                 const GDBusPropertyTable *property, void *data)
2095 {
2096         struct btd_device *device = data;
2097
2098         return device_get_wake_support(device);
2099 }
2100
2101
2102 static bool disconnect_all(gpointer user_data)
2103 {
2104         struct btd_device *device = user_data;
2105
2106         device->disconn_timer = 0;
2107
2108         if (device->bredr_state.connected)
2109                 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2110                                                                 BDADDR_BREDR);
2111
2112         if (device->le_state.connected)
2113                 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2114                                                         device->bdaddr_type);
2115
2116         return FALSE;
2117 }
2118
2119 int device_block(struct btd_device *device, gboolean update_only)
2120 {
2121         int err = 0;
2122
2123         if (device->blocked)
2124                 return 0;
2125
2126         if (device->disconn_timer > 0)
2127                 timeout_remove(device->disconn_timer);
2128
2129         disconnect_all(device);
2130
2131         while (device->services != NULL) {
2132                 struct btd_service *service = device->services->data;
2133
2134                 device->services = g_slist_remove(device->services, service);
2135                 service_remove(service);
2136         }
2137
2138         if (!update_only) {
2139                 if (device->le)
2140                         err = btd_adapter_block_address(device->adapter,
2141                                                         &device->bdaddr,
2142                                                         device->bdaddr_type);
2143                 if (!err && device->bredr)
2144                         err = btd_adapter_block_address(device->adapter,
2145                                                         &device->bdaddr,
2146                                                         BDADDR_BREDR);
2147         }
2148
2149         if (err < 0)
2150                 return err;
2151
2152         device->blocked = TRUE;
2153
2154         store_device_info(device);
2155
2156         btd_device_set_temporary(device, false);
2157
2158         g_dbus_emit_property_changed(dbus_conn, device->path,
2159                                                 DEVICE_INTERFACE, "Blocked");
2160
2161         return 0;
2162 }
2163
2164 int device_unblock(struct btd_device *device, gboolean silent,
2165                                                         gboolean update_only)
2166 {
2167         int err = 0;
2168
2169         if (!device->blocked)
2170                 return 0;
2171
2172         if (!update_only) {
2173                 if (device->le)
2174                         err = btd_adapter_unblock_address(device->adapter,
2175                                                         &device->bdaddr,
2176                                                         device->bdaddr_type);
2177                 if (!err && device->bredr)
2178                         err = btd_adapter_unblock_address(device->adapter,
2179                                                         &device->bdaddr,
2180                                                         BDADDR_BREDR);
2181         }
2182
2183         if (err < 0)
2184                 return err;
2185
2186         device->blocked = FALSE;
2187
2188         store_device_info(device);
2189
2190         if (!silent) {
2191                 g_dbus_emit_property_changed(dbus_conn, device->path,
2192                                                 DEVICE_INTERFACE, "Blocked");
2193                 device_probe_profiles(device, device->uuids);
2194         }
2195
2196         return 0;
2197 }
2198
2199 static void browse_request_exit(DBusConnection *conn, void *user_data)
2200 {
2201         struct browse_req *req = user_data;
2202
2203         DBG("Requestor exited");
2204
2205         browse_request_cancel(req);
2206 }
2207
2208 static void bonding_request_cancel(struct bonding_req *bonding)
2209 {
2210         struct btd_device *device = bonding->device;
2211         struct btd_adapter *adapter = device->adapter;
2212
2213         adapter_cancel_bonding(adapter, &device->bdaddr, device->bdaddr_type);
2214 }
2215
2216 static void dev_disconn_service(gpointer a, gpointer b)
2217 {
2218         btd_service_disconnect(a);
2219 }
2220
2221 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
2222 {
2223         if (device->bonding)
2224                 bonding_request_cancel(device->bonding);
2225
2226         if (device->browse)
2227                 browse_request_cancel(device->browse);
2228
2229         if (device->att_io) {
2230                 g_io_channel_shutdown(device->att_io, FALSE, NULL);
2231                 g_io_channel_unref(device->att_io);
2232                 device->att_io = NULL;
2233         }
2234
2235         if (device->connect) {
2236                 DBusMessage *reply = btd_error_failed(device->connect,
2237                                                 ERR_BREDR_CONN_CANCELED);
2238                 g_dbus_send_message(dbus_conn, reply);
2239                 dbus_message_unref(device->connect);
2240                 device->connect = NULL;
2241         }
2242
2243         if (btd_device_is_connected(device) && msg)
2244                 device->disconnects = g_slist_append(device->disconnects,
2245                                                 dbus_message_ref(msg));
2246
2247         if (device->disconn_timer)
2248                 return;
2249
2250         g_slist_foreach(device->services, dev_disconn_service, NULL);
2251
2252         g_slist_free(device->pending);
2253         device->pending = NULL;
2254
2255         while (device->watches) {
2256                 struct btd_disconnect_data *data = device->watches->data;
2257
2258                 if (data->watch)
2259                         /* temporary is set if device is going to be removed */
2260                         data->watch(device, device->temporary,
2261                                                         data->user_data);
2262
2263                 /* Check if the watch has been removed by callback function */
2264                 if (!g_slist_find(device->watches, data))
2265                         continue;
2266
2267                 device->watches = g_slist_remove(device->watches, data);
2268                 g_free(data);
2269         }
2270
2271         if (!btd_device_is_connected(device)) {
2272                 if (msg)
2273                         g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
2274                 return;
2275         }
2276
2277         device->disconn_timer = timeout_add_seconds(DISCONNECT_TIMER,
2278                                                         disconnect_all,
2279                                                         device, NULL);
2280 }
2281
2282 bool device_is_disconnecting(struct btd_device *device)
2283 {
2284         return device->disconn_timer > 0;
2285 }
2286
2287 void device_set_ltk_enc_size(struct btd_device *device, uint8_t enc_size)
2288 {
2289         device->ltk_enc_size = enc_size;
2290         bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
2291 }
2292
2293 static void device_set_auto_connect(struct btd_device *device, gboolean enable)
2294 {
2295         char addr[18];
2296
2297         if (!device || !device->le)
2298                 return;
2299
2300         ba2str(&device->bdaddr, addr);
2301
2302         DBG("%s auto connect: %d", addr, enable);
2303
2304         if (device->auto_connect == enable)
2305                 return;
2306
2307         device->auto_connect = enable;
2308
2309         /* Disabling auto connect */
2310         if (enable == FALSE) {
2311                 adapter_connect_list_remove(device->adapter, device);
2312                 adapter_auto_connect_remove(device->adapter, device);
2313                 return;
2314         }
2315
2316         /* Enabling auto connect */
2317         adapter_auto_connect_add(device->adapter, device);
2318
2319         if (device->attrib) {
2320                 DBG("Already connected");
2321                 return;
2322         }
2323
2324         adapter_connect_list_add(device->adapter, device);
2325 }
2326
2327 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
2328                                                         void *user_data)
2329 {
2330         struct btd_device *device = user_data;
2331
2332         /*
2333          * If device is not trusted disable connections through passive
2334          * scanning until Device1.Connect is called
2335          */
2336         if (device->auto_connect && !device->trusted) {
2337                 device->disable_auto_connect = TRUE;
2338                 device_set_auto_connect(device, FALSE);
2339         }
2340
2341         device_request_disconnect(device, msg);
2342
2343         return NULL;
2344 }
2345
2346 static int connect_next(struct btd_device *dev)
2347 {
2348         struct btd_service *service;
2349         int err = -ENOENT;
2350
2351         while (dev->pending) {
2352                 service = dev->pending->data;
2353
2354                 err = btd_service_connect(service);
2355                 if (!err)
2356                         return 0;
2357
2358                 dev->pending = g_slist_delete_link(dev->pending, dev->pending);
2359         }
2360
2361         return err;
2362 }
2363
2364 static void device_profile_connected(struct btd_device *dev,
2365                                         struct btd_profile *profile, int err)
2366 {
2367         struct btd_service *pending;
2368         GSList *l;
2369
2370         DBG("%s %s (%d)", profile->name, strerror(-err), -err);
2371
2372         if (!err)
2373                 btd_device_set_temporary(dev, false);
2374
2375         if (dev->pending == NULL)
2376                 goto done;
2377
2378         if (!btd_device_is_connected(dev)) {
2379                 switch (-err) {
2380                 case EHOSTDOWN: /* page timeout */
2381                 case EHOSTUNREACH: /* adapter not powered */
2382                 case ECONNABORTED: /* adapter powered down */
2383                         goto done;
2384                 }
2385         }
2386
2387         pending = dev->pending->data;
2388         l = find_service_with_profile(dev->pending, profile);
2389         if (l != NULL)
2390                 dev->pending = g_slist_delete_link(dev->pending, l);
2391
2392         /* Only continue connecting the next profile if it matches the first
2393          * pending, otherwise it will trigger another connect to the same
2394          * profile
2395          */
2396         if (profile != btd_service_get_profile(pending))
2397                 return;
2398
2399         if (connect_next(dev) == 0)
2400                 return;
2401
2402 done:
2403         g_slist_free(dev->pending);
2404         dev->pending = NULL;
2405
2406         if (!dev->connect)
2407                 return;
2408
2409         if (dbus_message_is_method_call(dev->connect, DEVICE_INTERFACE,
2410                                                         "Connect")) {
2411                 if (!err)
2412                         dev->general_connect = TRUE;
2413                 else if (find_service_with_state(dev->services,
2414                                                 BTD_SERVICE_STATE_CONNECTED))
2415                         /* Reset error if there are services connected */
2416                         err = 0;
2417         }
2418
2419         DBG("returning response to %s", dbus_message_get_sender(dev->connect));
2420
2421         if (err) {
2422                 /* Fallback to LE bearer if supported */
2423                 if (err == -EHOSTDOWN && dev->le && !dev->le_state.connected) {
2424                         err = device_connect_le(dev);
2425                         if (err == 0)
2426                                 return;
2427                 }
2428
2429                 g_dbus_send_message(dbus_conn,
2430                         btd_error_failed(dev->connect,
2431                                         btd_error_bredr_conn_from_errno(err)));
2432         } else {
2433 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2434                 /* SDP is not required for Samsung TV Power on */
2435                 if (g_strcmp0(profile->name, "hid-device") == 0) {
2436                         DBG("Skip SDP discovery.");
2437                 } else {
2438 #endif
2439                 /* Start passive SDP discovery to update known services */
2440                 if (dev->bredr && !dev->svc_refreshed && dev->refresh_discovery)
2441                         device_browse_sdp(dev, NULL);
2442 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2443                 }
2444 #endif
2445
2446                 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
2447         }
2448
2449         dbus_message_unref(dev->connect);
2450         dev->connect = NULL;
2451 }
2452
2453 void device_add_eir_uuids(struct btd_device *dev, GSList *uuids)
2454 {
2455         GSList *l;
2456         bool added = false;
2457
2458         if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
2459                 return;
2460
2461         for (l = uuids; l != NULL; l = l->next) {
2462                 const char *str = l->data;
2463                 if (g_slist_find_custom(dev->eir_uuids, str, bt_uuid_strcmp))
2464                         continue;
2465                 added = true;
2466                 dev->eir_uuids = g_slist_append(dev->eir_uuids, g_strdup(str));
2467         }
2468
2469         if (added)
2470                 g_dbus_emit_property_changed(dbus_conn, dev->path,
2471                                                 DEVICE_INTERFACE, "UUIDs");
2472 }
2473
2474 static void add_manufacturer_data(void *data, void *user_data)
2475 {
2476         struct eir_msd *msd = data;
2477         struct btd_device *dev = user_data;
2478
2479         if (!bt_ad_add_manufacturer_data(dev->ad, msd->company, msd->data,
2480                                                                 msd->data_len))
2481                 return;
2482
2483         g_dbus_emit_property_changed(dbus_conn, dev->path,
2484                                         DEVICE_INTERFACE, "ManufacturerData");
2485 }
2486
2487 void device_set_manufacturer_data(struct btd_device *dev, GSList *list,
2488                                                                 bool duplicate)
2489 {
2490         if (duplicate)
2491                 bt_ad_clear_manufacturer_data(dev->ad);
2492
2493         g_slist_foreach(list, add_manufacturer_data, dev);
2494 }
2495
2496 static void add_service_data(void *data, void *user_data)
2497 {
2498         struct eir_sd *sd = data;
2499         struct btd_device *dev = user_data;
2500         bt_uuid_t uuid;
2501
2502         if (bt_string_to_uuid(&uuid, sd->uuid) < 0)
2503                 return;
2504
2505         if (!bt_ad_add_service_data(dev->ad, &uuid, sd->data, sd->data_len))
2506                 return;
2507
2508         g_dbus_emit_property_changed(dbus_conn, dev->path,
2509                                         DEVICE_INTERFACE, "ServiceData");
2510 }
2511
2512 void device_set_service_data(struct btd_device *dev, GSList *list,
2513                                                         bool duplicate)
2514 {
2515         if (duplicate)
2516                 bt_ad_clear_service_data(dev->ad);
2517
2518         g_slist_foreach(list, add_service_data, dev);
2519 }
2520
2521 static void add_data(void *data, void *user_data)
2522 {
2523         struct eir_ad *ad = data;
2524         struct btd_device *dev = user_data;
2525
2526         if (!bt_ad_add_data(dev->ad, ad->type, ad->data, ad->len))
2527                 return;
2528
2529         if (ad->type == EIR_TRANSPORT_DISCOVERY)
2530                 g_dbus_emit_property_changed(dbus_conn, dev->path,
2531                                                 DEVICE_INTERFACE,
2532                                                 "AdvertisingData");
2533 }
2534
2535 void device_set_data(struct btd_device *dev, GSList *list,
2536                                                         bool duplicate)
2537 {
2538         if (duplicate)
2539                 bt_ad_clear_data(dev->ad);
2540
2541         g_slist_foreach(list, add_data, dev);
2542 }
2543
2544 static struct btd_service *find_connectable_service(struct btd_device *dev,
2545                                                         const char *uuid)
2546 {
2547         GSList *l;
2548 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2549         struct btd_service *s = NULL;
2550 #endif
2551         for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2552                 struct btd_service *service = l->data;
2553                 struct btd_profile *p = btd_service_get_profile(service);
2554
2555                 if (!p->connect || !p->remote_uuid)
2556                         continue;
2557
2558 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
2559                 if (strcasecmp(uuid, p->remote_uuid) == 0)
2560                         return service;
2561 #else
2562                 if (strcasecmp(uuid, p->remote_uuid) == 0) {
2563                         s = service;
2564                         if (ext_profile_is_registered_as_client_role(p) == TRUE) {
2565                                 return service;
2566                         } else {
2567                                 continue;
2568                         }
2569                 }
2570 #endif
2571         }
2572 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2573         if (s)
2574                 return s;
2575 #endif
2576
2577         return NULL;
2578 }
2579
2580 static int service_prio_cmp(gconstpointer a, gconstpointer b)
2581 {
2582         struct btd_profile *p1 = btd_service_get_profile(a);
2583         struct btd_profile *p2 = btd_service_get_profile(b);
2584
2585         return p2->priority - p1->priority;
2586 }
2587
2588 bool btd_device_all_services_allowed(struct btd_device *dev)
2589 {
2590         GSList *l;
2591         struct btd_adapter *adapter = dev->adapter;
2592         struct btd_service *service;
2593         struct btd_profile *profile;
2594
2595         for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2596                 service = l->data;
2597                 profile = btd_service_get_profile(service);
2598
2599                 if (!profile || !profile->auto_connect)
2600                         continue;
2601
2602                 if (!btd_adapter_is_uuid_allowed(adapter, profile->remote_uuid))
2603                         return false;
2604         }
2605
2606         return true;
2607 }
2608
2609 void btd_device_update_allowed_services(struct btd_device *dev)
2610 {
2611         struct btd_adapter *adapter = dev->adapter;
2612         struct btd_service *service;
2613         struct btd_profile *profile;
2614         GSList *l;
2615         bool is_allowed;
2616         char addr[18];
2617
2618         /* If service discovery is ongoing, let the service discovery complete
2619          * callback call this function.
2620          */
2621         if (dev->browse) {
2622                 ba2str(&dev->bdaddr, addr);
2623                 DBG("service discovery of %s is ongoing. Skip updating allowed "
2624                                                         "services", addr);
2625                 return;
2626         }
2627
2628         for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2629                 service = l->data;
2630                 profile = btd_service_get_profile(service);
2631
2632                 is_allowed = btd_adapter_is_uuid_allowed(adapter,
2633                                                         profile->remote_uuid);
2634                 btd_service_set_allowed(service, is_allowed);
2635         }
2636 }
2637
2638 static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
2639 {
2640         struct btd_service *service;
2641         struct btd_profile *p;
2642         GSList *l;
2643 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2644         bool hs_hf_verify = FALSE;
2645 #endif
2646
2647         if (uuid) {
2648                 service = find_connectable_service(dev, uuid);
2649                 if (!service)
2650                         return dev->pending;
2651
2652                 if (btd_service_is_allowed(service))
2653                         return g_slist_prepend(dev->pending, service);
2654
2655 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2656                 else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
2657                         DBG("HFP service not found check for HSP service");
2658                         service = find_connectable_service(dev, HSP_HS_UUID);
2659                         if (service)
2660                                 return g_slist_prepend(dev->pending, service);
2661                 } else if (g_strcmp0(uuid, HID_UUID) == 0) {
2662                         DBG("HID service not found, add HID service");
2663                         btd_device_add_uuid(dev, uuid);
2664                         service = find_connectable_service(dev, HID_UUID);
2665                         if (service)
2666                                 return g_slist_prepend(dev->pending, service);
2667                 }
2668 #endif
2669                 return dev->pending;
2670         }
2671
2672         for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2673                 service = l->data;
2674                 p = btd_service_get_profile(service);
2675
2676 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2677                 DBG("profile uuid %s", p->remote_uuid);
2678                 if (g_strcmp0(p->remote_uuid, HSP_HS_UUID) == 0) {
2679                         DBG("HSP service is found check for HFP service");
2680                         struct btd_service *service;
2681                         struct btd_profile *p;
2682                         GSList *h;
2683
2684                         for (h = dev->services; h != NULL; h = g_slist_next(h)) {
2685                                 service = h->data;
2686                                 p = btd_service_get_profile(service);
2687
2688                                 if (g_strcmp0(p->remote_uuid, HFP_HS_UUID) == 0) {
2689                                         DBG("HFP found,ignore HSP ");
2690                                         hs_hf_verify = TRUE;
2691                                         break;
2692                                 }
2693                         }
2694                         if (hs_hf_verify)
2695                                 continue;
2696                 }
2697 #endif
2698                 if (!p->auto_connect)
2699                         continue;
2700
2701                 if (!btd_service_is_allowed(service)) {
2702                         info("service %s is blocked", p->remote_uuid);
2703                         continue;
2704                 }
2705
2706                 if (g_slist_find(dev->pending, service))
2707                         continue;
2708
2709                 if (btd_service_get_state(service) !=
2710                                                 BTD_SERVICE_STATE_DISCONNECTED)
2711                         continue;
2712
2713                 dev->pending = g_slist_insert_sorted(dev->pending, service,
2714                                                         service_prio_cmp);
2715         }
2716
2717         return dev->pending;
2718 }
2719
2720 int btd_device_connect_services(struct btd_device *dev, GSList *services)
2721 {
2722         GSList *l;
2723
2724         if (dev->pending || dev->connect || dev->browse)
2725                 return -EBUSY;
2726
2727         if (!btd_adapter_get_powered(dev->adapter))
2728                 return -ENETDOWN;
2729
2730         if (!dev->bredr_state.svc_resolved)
2731                 return -ENOENT;
2732
2733         if (services) {
2734                 for (l = services; l; l = g_slist_next(l)) {
2735                         struct btd_service *service = l->data;
2736
2737                         dev->pending = g_slist_append(dev->pending, service);
2738                 }
2739         } else {
2740                 dev->pending = create_pending_list(dev, NULL);
2741         }
2742
2743         return connect_next(dev);
2744 }
2745
2746 static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
2747                                         DBusMessage *msg, const char *uuid)
2748 {
2749         struct bearer_state *state = get_state(dev, bdaddr_type);
2750         int err;
2751
2752         DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
2753                                                 dbus_message_get_sender(msg));
2754
2755 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2756         if (dev->pending || dev->connect)
2757                 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2758 #else
2759         if (dev->pending || dev->connect || dev->browse)
2760                 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2761 #endif
2762
2763         if (!btd_adapter_get_powered(dev->adapter)) {
2764                 return btd_error_not_ready_str(msg,
2765                                         ERR_BREDR_CONN_ADAPTER_NOT_POWERED);
2766         }
2767
2768         btd_device_set_temporary(dev, false);
2769
2770         if (!state->svc_resolved)
2771                 goto resolve_services;
2772
2773         dev->pending = create_pending_list(dev, uuid);
2774         if (!dev->pending) {
2775                 if (dev->svc_refreshed) {
2776 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2777                         if (!uuid && dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2778                                                         "Connect") &&
2779                                 find_service_with_state(dev->services,
2780                                                 BTD_SERVICE_STATE_CONNECTED)) {
2781 #else
2782                         if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2783                                                         "Connect") &&
2784                                 find_service_with_state(dev->services,
2785                                                 BTD_SERVICE_STATE_CONNECTED)) {
2786 #endif
2787                                 return dbus_message_new_method_return(msg);
2788                         } else {
2789                                 return btd_error_not_available_str(msg,
2790                                         ERR_BREDR_CONN_PROFILE_UNAVAILABLE);
2791                         }
2792                 }
2793
2794                 goto resolve_services;
2795         }
2796
2797         err = connect_next(dev);
2798         if (err < 0) {
2799                 if (err == -EALREADY)
2800 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2801                         return btd_error_already_connected(msg);
2802 #else
2803                         return dbus_message_new_method_return(msg);
2804 #endif
2805                 return btd_error_failed(msg,
2806                                         btd_error_bredr_conn_from_errno(err));
2807         }
2808
2809         dev->connect = dbus_message_ref(msg);
2810
2811         return NULL;
2812
2813 resolve_services:
2814         DBG("Resolving services for %s", dev->path);
2815
2816         if (bdaddr_type == BDADDR_BREDR)
2817                 err = device_browse_sdp(dev, msg);
2818         else
2819                 err = device_browse_gatt(dev, msg);
2820         if (err < 0) {
2821                 return btd_error_failed(msg, bdaddr_type == BDADDR_BREDR ?
2822                         ERR_BREDR_CONN_SDP_SEARCH : ERR_LE_CONN_GATT_BROWSE);
2823         }
2824
2825         return NULL;
2826 }
2827
2828 #define NVAL_TIME ((time_t) -1)
2829 #define SEEN_TRESHHOLD 300
2830
2831 static uint8_t select_conn_bearer(struct btd_device *dev)
2832 {
2833         time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME;
2834         time_t current = time(NULL);
2835
2836         /* Prefer bonded bearer in case only one is bonded */
2837         if (dev->bredr_state.bonded && !dev->le_state.bonded )
2838                 return BDADDR_BREDR;
2839         else if (!dev->bredr_state.bonded && dev->le_state.bonded)
2840                 return dev->bdaddr_type;
2841
2842         /* If the address is random it can only be connected over LE */
2843         if (dev->bdaddr_type == BDADDR_LE_RANDOM)
2844                 return dev->bdaddr_type;
2845
2846         if (dev->bredr_seen) {
2847                 bredr_last = current - dev->bredr_seen;
2848                 if (bredr_last > SEEN_TRESHHOLD)
2849                         bredr_last = NVAL_TIME;
2850         }
2851
2852         if (dev->le_seen) {
2853                 le_last = current - dev->le_seen;
2854                 if (le_last > SEEN_TRESHHOLD)
2855                         le_last = NVAL_TIME;
2856         }
2857
2858         if (le_last == NVAL_TIME && bredr_last == NVAL_TIME)
2859                 return dev->bdaddr_type;
2860
2861         if (dev->bredr && (!dev->le || le_last == NVAL_TIME))
2862                 return BDADDR_BREDR;
2863
2864         if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME))
2865                 return dev->bdaddr_type;
2866
2867         /*
2868          * Prefer BR/EDR if time is the same since it might be from an
2869          * advertisement with BR/EDR flag set.
2870          */
2871         if (bredr_last <= le_last && btd_adapter_get_bredr(dev->adapter))
2872                 return BDADDR_BREDR;
2873
2874         return dev->bdaddr_type;
2875 }
2876
2877 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
2878                                                         void *user_data)
2879 {
2880         struct btd_device *dev = user_data;
2881         uint8_t bdaddr_type;
2882
2883         if (dev->bredr_state.connected) {
2884                 /*
2885                  * Check if services have been resolved and there is at least
2886                  * one connected before switching to connect LE.
2887                  */
2888                 if (dev->bredr_state.svc_resolved &&
2889                         find_service_with_state(dev->services,
2890                                                 BTD_SERVICE_STATE_CONNECTED))
2891                         bdaddr_type = dev->bdaddr_type;
2892                 else
2893                         bdaddr_type = BDADDR_BREDR;
2894         } else if (dev->le_state.connected && dev->bredr)
2895                 bdaddr_type = BDADDR_BREDR;
2896         else
2897                 bdaddr_type = select_conn_bearer(dev);
2898
2899         if (bdaddr_type != BDADDR_BREDR) {
2900                 int err;
2901
2902                 if (dev->le_state.connected)
2903                         return dbus_message_new_method_return(msg);
2904
2905                 btd_device_set_temporary(dev, false);
2906
2907                 if (dev->disable_auto_connect) {
2908                         dev->disable_auto_connect = FALSE;
2909                         device_set_auto_connect(dev, TRUE);
2910                 }
2911
2912                 err = device_connect_le(dev);
2913                 if (err < 0)
2914                         return btd_error_failed(msg, strerror(-err));
2915
2916                 dev->connect = dbus_message_ref(msg);
2917
2918                 return NULL;
2919         }
2920
2921         return connect_profiles(dev, bdaddr_type, msg, NULL);
2922 }
2923
2924 static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
2925                                                         void *user_data)
2926 {
2927         struct btd_device *dev = user_data;
2928         const char *pattern;
2929         char *uuid;
2930         DBusMessage *reply;
2931
2932         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2933                                                         DBUS_TYPE_INVALID)) {
2934                 return btd_error_invalid_args_str(msg,
2935                                         ERR_BREDR_CONN_INVALID_ARGUMENTS);
2936         }
2937
2938         uuid = bt_name2string(pattern);
2939         reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
2940         free(uuid);
2941
2942         return reply;
2943 }
2944
2945 static void device_profile_disconnected(struct btd_device *dev,
2946                                         struct btd_profile *profile, int err)
2947 {
2948         if (!dev->disconnect)
2949                 return;
2950
2951         if (err)
2952                 g_dbus_send_message(dbus_conn,
2953                                         btd_error_failed(dev->disconnect,
2954                                                         strerror(-err)));
2955         else
2956                 g_dbus_send_reply(dbus_conn, dev->disconnect,
2957                                                         DBUS_TYPE_INVALID);
2958
2959         dbus_message_unref(dev->disconnect);
2960         dev->disconnect = NULL;
2961 }
2962
2963 static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
2964                                                         void *user_data)
2965 {
2966         struct btd_device *dev = user_data;
2967         struct btd_service *service;
2968         const char *pattern;
2969         char *uuid;
2970         int err;
2971
2972         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2973                                                         DBUS_TYPE_INVALID))
2974                 return btd_error_invalid_args(msg);
2975
2976         uuid = bt_name2string(pattern);
2977         if (uuid == NULL)
2978                 return btd_error_invalid_args(msg);
2979
2980         service = find_connectable_service(dev, uuid);
2981 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2982         if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2983                 DBG("HFP service is not found check for HSP service");
2984                 service = find_connectable_service(dev, HSP_HS_UUID);
2985         }
2986 #endif
2987         free(uuid);
2988
2989         if (!service)
2990                 return btd_error_invalid_args(msg);
2991
2992         if (dev->disconnect)
2993                 return btd_error_in_progress(msg);
2994
2995         if (btd_service_get_state(service) == BTD_SERVICE_STATE_DISCONNECTED)
2996                 return dbus_message_new_method_return(msg);
2997
2998         dev->disconnect = dbus_message_ref(msg);
2999
3000         err = btd_service_disconnect(service);
3001         if (err == 0)
3002                 return NULL;
3003
3004 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3005         if (dev->disconnect)
3006 #endif
3007         dbus_message_unref(dev->disconnect);
3008         dev->disconnect = NULL;
3009
3010         if (err == -ENOTSUP)
3011                 return btd_error_not_supported(msg);
3012         else if (err == -EALREADY)
3013                 return dbus_message_new_method_return(msg);
3014
3015         return btd_error_failed(msg, strerror(-err));
3016 }
3017
3018 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3019 static DBusMessage *disconnect_ext_profile(DBusConnection *conn,
3020                                            DBusMessage *msg, void *user_data)
3021 {
3022         struct btd_device *dev = user_data;
3023         struct btd_profile *profile;
3024         struct btd_service *service;
3025         const char *sender, *path;
3026         GSList *l;
3027         int err;
3028
3029         sender = dbus_message_get_sender(msg);
3030
3031         DBG("sender %s", sender);
3032
3033         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
3034                                                         DBUS_TYPE_INVALID))
3035                 return btd_error_invalid_args(msg);
3036
3037         profile = btd_profile_find_ext(sender, path);
3038         if (!profile)
3039                 return btd_error_invalid_args(msg);
3040
3041         l = find_service_with_profile(dev->services, profile);
3042         if (!l)
3043                 return btd_error_invalid_args(msg);
3044
3045         service = l->data;
3046
3047         if (dev->disconnect)
3048                 return btd_error_in_progress(msg);
3049
3050         dev->disconnect = dbus_message_ref(msg);
3051
3052         err = btd_service_disconnect(service);
3053         if (err == 0)
3054                 return NULL;
3055
3056         if (dev->disconnect)
3057                 dbus_message_unref(dev->disconnect);
3058         dev->disconnect = NULL;
3059
3060         if (err == -ENOTSUP)
3061                 return btd_error_not_supported(msg);
3062
3063         return btd_error_failed(msg, strerror(-err));
3064 }
3065 #endif
3066
3067 static void store_services(struct btd_device *device)
3068 {
3069         char filename[PATH_MAX];
3070         char dst_addr[18];
3071         uuid_t uuid;
3072         char *prim_uuid;
3073         GKeyFile *key_file;
3074         GError *gerr = NULL;
3075         GSList *l;
3076         char *data;
3077         gsize length = 0;
3078
3079         if (device_address_is_private(device)) {
3080                 DBG("Can't store services for private addressed device %s",
3081                                                                 device->path);
3082                 return;
3083         }
3084
3085         sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
3086         prim_uuid = bt_uuid2string(&uuid);
3087         if (prim_uuid == NULL)
3088                 return;
3089
3090         ba2str(&device->bdaddr, dst_addr);
3091
3092 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3093         if (device->rpa)
3094                 ba2str(device->rpa, dst_addr);
3095 #endif
3096
3097         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes",
3098                                 btd_adapter_get_storage_dir(device->adapter),
3099                                 dst_addr);
3100         key_file = g_key_file_new();
3101
3102         for (l = device->primaries; l; l = l->next) {
3103                 struct gatt_primary *primary = l->data;
3104                 char handle[6], uuid_str[33];
3105                 int i;
3106
3107                 sprintf(handle, "%hu", primary->range.start);
3108
3109                 bt_string2uuid(&uuid, primary->uuid);
3110                 sdp_uuid128_to_uuid(&uuid);
3111
3112                 switch (uuid.type) {
3113                 case SDP_UUID16:
3114                         sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
3115                         break;
3116                 case SDP_UUID32:
3117                         sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
3118                         break;
3119                 case SDP_UUID128:
3120                         for (i = 0; i < 16; i++)
3121                                 sprintf(uuid_str + (i * 2), "%2.2X",
3122                                                 uuid.value.uuid128.data[i]);
3123                         break;
3124                 default:
3125                         uuid_str[0] = '\0';
3126                 }
3127
3128                 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
3129                 g_key_file_set_string(key_file, handle, "Value", uuid_str);
3130                 g_key_file_set_integer(key_file, handle, "EndGroupHandle",
3131                                         primary->range.end);
3132         }
3133
3134         data = g_key_file_to_data(key_file, &length, NULL);
3135         if (length > 0) {
3136                 create_file(filename, 0600);
3137                 if (!g_file_set_contents(filename, data, length, &gerr)) {
3138                         error("Unable set contents for %s: (%s)", filename,
3139                                                                 gerr->message);
3140                         g_error_free(gerr);
3141                 }
3142         }
3143
3144         free(prim_uuid);
3145         g_free(data);
3146         g_key_file_free(key_file);
3147 }
3148
3149 struct gatt_saver {
3150         struct btd_device *device;
3151         uint16_t ext_props;
3152         GKeyFile *key_file;
3153 };
3154
3155 static void db_hash_read_value_cb(struct gatt_db_attribute *attrib,
3156                                                 int err, const uint8_t *value,
3157                                                 size_t length, void *user_data)
3158 {
3159         const uint8_t **hash = user_data;
3160
3161         if (err || (length != 16))
3162                 return;
3163
3164         *hash = value;
3165 }
3166
3167 static void store_desc(struct gatt_db_attribute *attr, void *user_data)
3168 {
3169         struct gatt_saver *saver = user_data;
3170         GKeyFile *key_file = saver->key_file;
3171         char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3172         const bt_uuid_t *uuid;
3173         bt_uuid_t ext_uuid;
3174         uint16_t handle_num;
3175
3176         handle_num = gatt_db_attribute_get_handle(attr);
3177         sprintf(handle, "%04hx", handle_num);
3178
3179         uuid = gatt_db_attribute_get_type(attr);
3180         bt_uuid_to_string(uuid, uuid_str, sizeof(uuid_str));
3181
3182         bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
3183         if (!bt_uuid_cmp(uuid, &ext_uuid) && saver->ext_props)
3184                 sprintf(value, "%04hx:%s", saver->ext_props, uuid_str);
3185         else
3186                 sprintf(value, "%s", uuid_str);
3187
3188         g_key_file_set_string(key_file, "Attributes", handle, value);
3189 }
3190
3191 static void store_chrc(struct gatt_db_attribute *attr, void *user_data)
3192 {
3193         struct gatt_saver *saver = user_data;
3194         GKeyFile *key_file = saver->key_file;
3195         char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3196         uint16_t handle_num, value_handle;
3197         uint8_t properties;
3198         bt_uuid_t uuid, hash_uuid;
3199
3200         if (!gatt_db_attribute_get_char_data(attr, &handle_num, &value_handle,
3201                                                 &properties, &saver->ext_props,
3202                                                 &uuid)) {
3203                 warn("Error storing characteristic - can't get data");
3204                 return;
3205         }
3206
3207         sprintf(handle, "%04hx", handle_num);
3208         bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3209
3210         /* Store Database Hash  value if available */
3211         bt_uuid16_create(&hash_uuid, GATT_CHARAC_DB_HASH);
3212         if (!bt_uuid_cmp(&uuid, &hash_uuid)) {
3213                 const uint8_t *hash = NULL;
3214
3215                 attr = gatt_db_get_attribute(saver->device->db, value_handle);
3216
3217                 gatt_db_attribute_read(attr, 0, BT_ATT_OP_READ_REQ, NULL,
3218                                         db_hash_read_value_cb, &hash);
3219                 if (hash)
3220                         sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:"
3221                                 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3222                                 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3223                                 "%02hhx%02hhx:%s", value_handle, properties,
3224                                 hash[0], hash[1], hash[2], hash[3],
3225                                 hash[4], hash[5], hash[6], hash[7],
3226                                 hash[8], hash[9], hash[10], hash[11],
3227                                 hash[12], hash[13], hash[14], hash[15],
3228                                 uuid_str);
3229                 else
3230                         sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3231                                 value_handle, properties, uuid_str);
3232
3233         } else
3234                 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3235                                 value_handle, properties, uuid_str);
3236
3237         g_key_file_set_string(key_file, "Attributes", handle, value);
3238
3239         gatt_db_service_foreach_desc(attr, store_desc, saver);
3240 }
3241
3242 static void store_incl(struct gatt_db_attribute *attr, void *user_data)
3243 {
3244         struct gatt_saver *saver = user_data;
3245         GKeyFile *key_file = saver->key_file;
3246         struct gatt_db_attribute *service;
3247         char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3248         uint16_t handle_num, start, end;
3249         bt_uuid_t uuid;
3250
3251         if (!gatt_db_attribute_get_incl_data(attr, &handle_num, &start, &end)) {
3252                 warn("Error storing included service - can't get data");
3253                 return;
3254         }
3255
3256         service = gatt_db_get_attribute(saver->device->db, start);
3257         if (!service) {
3258                 warn("Error storing included service - can't find it");
3259                 return;
3260         }
3261
3262         sprintf(handle, "%04hx", handle_num);
3263
3264         gatt_db_attribute_get_service_uuid(service, &uuid);
3265         bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3266         sprintf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", start,
3267                                                                 end, uuid_str);
3268
3269         g_key_file_set_string(key_file, "Attributes", handle, value);
3270 }
3271
3272 static void store_service(struct gatt_db_attribute *attr, void *user_data)
3273 {
3274         struct gatt_saver *saver = user_data;
3275         GKeyFile *key_file = saver->key_file;
3276         char uuid_str[MAX_LEN_UUID_STR], handle[6], value[256];
3277         uint16_t start, end;
3278         bt_uuid_t uuid;
3279         bool primary;
3280         char *type;
3281
3282         if (!gatt_db_attribute_get_service_data(attr, &start, &end, &primary,
3283                                                                 &uuid)) {
3284                 warn("Error storing service - can't get data");
3285                 return;
3286         }
3287
3288         sprintf(handle, "%04hx", start);
3289
3290         bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3291
3292         if (primary)
3293                 type = GATT_PRIM_SVC_UUID_STR;
3294         else
3295                 type = GATT_SND_SVC_UUID_STR;
3296
3297         sprintf(value, "%s:%04hx:%s", type, end, uuid_str);
3298
3299         g_key_file_set_string(key_file, "Attributes", handle, value);
3300
3301         gatt_db_service_foreach_incl(attr, store_incl, saver);
3302         gatt_db_service_foreach_char(attr, store_chrc, saver);
3303 }
3304
3305 static void store_gatt_db(struct btd_device *device)
3306 {
3307         char filename[PATH_MAX];
3308         char dst_addr[18];
3309         GKeyFile *key_file;
3310         GError *gerr = NULL;
3311         char *data;
3312         gsize length = 0;
3313         struct gatt_saver saver;
3314
3315         if (device_address_is_private(device)) {
3316                 DBG("Can't store GATT db for private addressed device %s",
3317                                                                 device->path);
3318                 return;
3319         }
3320
3321         if (!gatt_cache_is_enabled(device))
3322                 return;
3323
3324         ba2str(&device->bdaddr, dst_addr);
3325
3326         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
3327                                 btd_adapter_get_storage_dir(device->adapter),
3328                                 dst_addr);
3329         create_file(filename, 0600);
3330
3331         key_file = g_key_file_new();
3332         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
3333                 error("Unable to load key file from %s: (%s)", filename,
3334                                                                 gerr->message);
3335                 g_error_free(gerr);
3336         }
3337
3338         /* Remove current attributes since it might have changed */
3339         g_key_file_remove_group(key_file, "Attributes", NULL);
3340
3341         saver.key_file = key_file;
3342         saver.device = device;
3343
3344         gatt_db_foreach_service(device->db, NULL, store_service, &saver);
3345
3346         data = g_key_file_to_data(key_file, &length, NULL);
3347         if (!g_file_set_contents(filename, data, length, &gerr)) {
3348                 error("Unable set contents for %s: (%s)", filename,
3349                                                                 gerr->message);
3350                 g_error_free(gerr);
3351         }
3352
3353         g_free(data);
3354         g_key_file_free(key_file);
3355 }
3356
3357
3358 static void browse_request_complete(struct browse_req *req, uint8_t type,
3359                                                 uint8_t bdaddr_type, int err)
3360 {
3361         struct btd_device *dev = req->device;
3362         DBusMessage *reply = NULL;
3363         DBusMessage *msg;
3364
3365         if (req->type != type)
3366                 return;
3367
3368         if (!req->msg)
3369                 goto done;
3370
3371         if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Pair")) {
3372                 if (!device_is_paired(dev, bdaddr_type)) {
3373                         reply = btd_error_failed(req->msg, "Not paired");
3374                         goto done;
3375                 }
3376
3377                 if (dev->pending_paired) {
3378                         g_dbus_emit_property_changed(dbus_conn, dev->path,
3379                                                 DEVICE_INTERFACE, "Paired");
3380                         dev->pending_paired = false;
3381                 }
3382
3383                 /* Disregard browse errors in case of Pair */
3384                 reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
3385                 goto done;
3386         }
3387
3388         if (err) {
3389                 /* Fallback to LE bearer if supported */
3390                 if (err == -EHOSTDOWN && bdaddr_type == BDADDR_BREDR &&
3391                                 dev->le && !dev->le_state.connected) {
3392                         err = device_connect_le(dev);
3393                         if (err == 0)
3394                                 goto done;
3395                 }
3396                 reply = btd_error_failed(req->msg,
3397                                 bdaddr_type == BDADDR_BREDR ?
3398                                 btd_error_bredr_conn_from_errno(err) :
3399                                 btd_error_le_conn_from_errno(err));
3400                 goto done;
3401         }
3402
3403         /* if successfully resolved services we need to free browsing request
3404          * before passing message back to connect functions, otherwise
3405          * device->browse is set and "InProgress" error is returned instead
3406          * of actually connecting services
3407          */
3408         msg = dbus_message_ref(req->msg);
3409         browse_request_free(req);
3410         req = NULL;
3411
3412         if (dbus_message_is_method_call(msg, DEVICE_INTERFACE, "Connect"))
3413                 reply = dev_connect(dbus_conn, msg, dev);
3414         else if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
3415                                                         "ConnectProfile"))
3416                 reply = connect_profile(dbus_conn, msg, dev);
3417         else
3418                 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
3419
3420         dbus_message_unref(msg);
3421
3422 done:
3423         if (reply)
3424                 g_dbus_send_message(dbus_conn, reply);
3425
3426         if (req)
3427                 browse_request_free(req);
3428 }
3429
3430 void device_set_refresh_discovery(struct btd_device *dev, bool refresh)
3431 {
3432         dev->refresh_discovery = refresh;
3433 }
3434
3435 static void device_set_svc_refreshed(struct btd_device *device, bool value)
3436 {
3437         if (device->svc_refreshed == value)
3438                 return;
3439
3440         device->svc_refreshed = value;
3441
3442         g_dbus_emit_property_changed(dbus_conn, device->path,
3443                                         DEVICE_INTERFACE, "ServicesResolved");
3444 }
3445
3446 static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type,
3447                                                 uint8_t bdaddr_type, int err)
3448 {
3449         struct bearer_state *state = get_state(dev, bdaddr_type);
3450         struct browse_req *req = dev->browse;
3451
3452 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3453         DBG("%s bdaddr_type %d err %d", dev->path, bdaddr_type, err);
3454 #else
3455         DBG("%s err %d", dev->path, err);
3456 #endif
3457
3458 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3459         state->svc_resolved = true;
3460 #else
3461         if (err == 0)
3462                 state->svc_resolved = true;
3463 #endif
3464
3465         /* Disconnection notification can happen before this function
3466          * gets called, so don't set svc_refreshed for a disconnected
3467          * device.
3468          */
3469         if (state->connected)
3470                 device_set_svc_refreshed(dev, true);
3471
3472         g_slist_free_full(dev->eir_uuids, g_free);
3473         dev->eir_uuids = NULL;
3474
3475         if (dev->pending_paired) {
3476                 g_dbus_emit_property_changed(dbus_conn, dev->path,
3477                                                 DEVICE_INTERFACE, "Paired");
3478                 dev->pending_paired = false;
3479         }
3480
3481         if (!dev->temporary) {
3482                 store_device_info(dev);
3483
3484                 if (bdaddr_type != BDADDR_BREDR && err == 0)
3485                         store_services(dev);
3486         }
3487
3488 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3489         if (req)
3490                 browse_request_complete(req, browse_type, bdaddr_type, err);
3491 #endif
3492
3493         while (dev->svc_callbacks) {
3494                 struct svc_callback *cb = dev->svc_callbacks->data;
3495
3496                 if (cb->idle_id > 0)
3497                         g_source_remove(cb->idle_id);
3498
3499                 cb->func(dev, err, cb->user_data);
3500
3501                 dev->svc_callbacks = g_slist_delete_link(dev->svc_callbacks,
3502                                                         dev->svc_callbacks);
3503                 g_free(cb);
3504         }
3505
3506 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3507         if (!req) 
3508                 return;
3509
3510         /* If bdaddr_type is LE but req is for SDP, don't complete browse req. */
3511         if (bdaddr_type != BDADDR_BREDR && req->search_uuid) {
3512                 DBG("Discover comp. is for LE but browse req. is for SDP.");
3513                 return;
3514         }
3515
3516         browse_request_complete(req, browse_type, bdaddr_type, err);
3517 #endif
3518         btd_device_update_allowed_services(dev);
3519         device_resolved_drivers(dev->adapter, dev);
3520 }
3521
3522 static struct bonding_req *bonding_request_new(DBusMessage *msg,
3523                                                 struct btd_device *device,
3524                                                 uint8_t bdaddr_type,
3525                                                 struct agent *agent)
3526 {
3527         struct bonding_req *bonding;
3528         char addr[18];
3529
3530         ba2str(&device->bdaddr, addr);
3531         DBG("Requesting bonding for %s", addr);
3532
3533         bonding = g_new0(struct bonding_req, 1);
3534
3535         bonding->msg = dbus_message_ref(msg);
3536         bonding->bdaddr_type = bdaddr_type;
3537
3538         bonding->cb_iter = btd_adapter_pin_cb_iter_new(device->adapter);
3539
3540         /* Marks the bonding start time for the first attempt on request
3541          * construction. The following attempts will be updated on
3542          * device_bonding_retry. */
3543         clock_gettime(CLOCK_MONOTONIC, &bonding->attempt_start_time);
3544
3545         if (agent)
3546                 bonding->agent = agent_ref(agent);
3547
3548         return bonding;
3549 }
3550
3551 void device_bonding_restart_timer(struct btd_device *device)
3552 {
3553         if (!device || !device->bonding)
3554                 return;
3555
3556         clock_gettime(CLOCK_MONOTONIC, &device->bonding->attempt_start_time);
3557 }
3558
3559 static void bonding_request_stop_timer(struct bonding_req *bonding)
3560 {
3561         struct timespec current;
3562
3563         clock_gettime(CLOCK_MONOTONIC, &current);
3564
3565         /* Compute the time difference in ms. */
3566         bonding->last_attempt_duration_ms =
3567                 (current.tv_sec - bonding->attempt_start_time.tv_sec) * 1000L +
3568                 (current.tv_nsec - bonding->attempt_start_time.tv_nsec)
3569                                                                 / 1000000L;
3570 }
3571
3572 /* Returns the duration of the last bonding attempt in milliseconds. The
3573  * duration is measured starting from the latest of the following three
3574  * events and finishing when the Command complete event is received for the
3575  * authentication request:
3576  *  - MGMT_OP_PAIR_DEVICE is sent,
3577  *  - MGMT_OP_PIN_CODE_REPLY is sent and
3578  *  - Command complete event is received for the sent MGMT_OP_PIN_CODE_REPLY.
3579  */
3580 long device_bonding_last_duration(struct btd_device *device)
3581 {
3582         struct bonding_req *bonding = device->bonding;
3583
3584         if (!bonding)
3585                 return 0;
3586
3587         return bonding->last_attempt_duration_ms;
3588 }
3589
3590 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
3591 {
3592         struct btd_device *device = user_data;
3593         char addr[18];
3594
3595         ba2str(&device->bdaddr, addr);
3596         DBG("%s: requestor exited before bonding was completed", addr);
3597
3598         if (device->authr)
3599                 device_cancel_authentication(device, FALSE);
3600
3601         if (device->bonding) {
3602                 device->bonding->listener_id = 0;
3603                 device_request_disconnect(device, NULL);
3604         }
3605 }
3606
3607 static void bonding_request_free(struct bonding_req *bonding)
3608 {
3609         if (!bonding)
3610                 return;
3611
3612         if (bonding->listener_id)
3613                 g_dbus_remove_watch(dbus_conn, bonding->listener_id);
3614
3615         if (bonding->msg)
3616                 dbus_message_unref(bonding->msg);
3617
3618         if (bonding->cb_iter)
3619                 g_free(bonding->cb_iter);
3620
3621         if (bonding->agent) {
3622                 agent_cancel(bonding->agent);
3623                 agent_unref(bonding->agent);
3624                 bonding->agent = NULL;
3625         }
3626
3627         if (bonding->retry_timer)
3628                 g_source_remove(bonding->retry_timer);
3629
3630         if (bonding->device)
3631                 bonding->device->bonding = NULL;
3632
3633         g_free(bonding);
3634 }
3635
3636 static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg,
3637                                                                 void *data)
3638 {
3639         struct btd_device *device = data;
3640         struct btd_adapter *adapter = device->adapter;
3641 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3642         struct bearer_state *state;
3643 #endif
3644         uint8_t bdaddr_type;
3645         const char *sender;
3646         struct agent *agent;
3647         struct bonding_req *bonding;
3648         uint8_t io_cap;
3649 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3650         uint8_t conn_type;
3651         bool connect_le = FALSE;
3652         uint8_t link_type = DEV_CONNECTED_NONE;
3653 #endif
3654         int err;
3655
3656         btd_device_set_temporary(device, false);
3657
3658 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3659         if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &conn_type,
3660                                         DBUS_TYPE_INVALID) == FALSE)
3661 #else
3662         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
3663 #endif
3664                 return btd_error_invalid_args(msg);
3665
3666         if (device->bonding)
3667                 return btd_error_in_progress(msg);
3668
3669 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3670         if (conn_type == DEV_CONN_DEFAULT) {
3671                 link_type = device_get_connected_state(device);
3672
3673                 if (link_type == DEV_CONNECTED_BREDR) {
3674                         if (device_is_bonded(device, DEV_CONN_BREDR))
3675                                 return btd_error_already_exists(msg);
3676                         conn_type = DEV_CONN_BREDR;
3677                 } else if (link_type == DEV_CONNECTED_LE) {
3678                          if (device_is_bonded(device, DEV_CONN_LE))
3679                                 return btd_error_already_exists(msg);
3680                          conn_type = DEV_CONN_LE;
3681                 } else {
3682                         if (device_is_bonded(device, DEV_CONN_BREDR))
3683                                 return btd_error_already_exists(msg);
3684                         else if (device_is_bonded(device, DEV_CONN_LE))
3685                                 return btd_error_already_exists(msg);
3686
3687                         if (device->bredr)
3688                                 conn_type = DEV_CONN_BREDR;
3689                         else if (device->le)
3690                                 conn_type = DEV_CONN_LE;
3691                         else
3692                                 conn_type = DEV_CONN_BREDR;
3693                 }
3694         } else {
3695                 if (device_is_bonded(device, conn_type))
3696                         return btd_error_already_exists(msg);
3697         }
3698         bdaddr_type = device->bdaddr_type;
3699 #else
3700         if (device->bredr_state.bonded)
3701                 bdaddr_type = device->bdaddr_type;
3702         else if (device->le_state.bonded)
3703                 bdaddr_type = BDADDR_BREDR;
3704         else
3705                 bdaddr_type = select_conn_bearer(device);
3706
3707         state = get_state(device, bdaddr_type);
3708
3709         if (state->bonded)
3710                 return btd_error_already_exists(msg);
3711 #endif
3712
3713 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3714         DBG("conn_type %d, link_type %d, bdaddr_type %d, device->bredr %d",
3715                         conn_type, link_type, bdaddr_type, device->bredr);
3716         if (conn_type == DEV_CONN_LE &&
3717             (device_is_bredrle(device) || bdaddr_type != BDADDR_BREDR)) {
3718                 DBG("LE Connect request");
3719                 connect_le = TRUE;
3720         }
3721 #endif
3722
3723         sender = dbus_message_get_sender(msg);
3724
3725         agent = agent_get(sender);
3726         if (agent)
3727                 io_cap = agent_get_io_capability(agent);
3728         else
3729                 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
3730
3731 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3732         if ((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3733                         connect_le)
3734                 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3735         else
3736                 bonding = bonding_request_new(msg, device, BDADDR_BREDR, agent);
3737 #else
3738         bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3739 #endif
3740
3741         if (agent)
3742                 agent_unref(agent);
3743
3744         bonding->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
3745                                                 sender, create_bond_req_exit,
3746                                                 device, NULL);
3747
3748         device->bonding = bonding;
3749         bonding->device = device;
3750
3751         /* Due to a bug in the kernel we might loose out on ATT commands
3752          * that arrive during the SMP procedure, so connect the ATT
3753          * channel first and only then start pairing (there's code for
3754          * this in the ATT connect callback)
3755          */
3756 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3757         if (((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3758                 (connect_le)) && !device->le_state.connected)
3759                 err = device_connect_le(device);
3760         else if (connect_le) /* Send bonding request if LE is already connected*/
3761                 err = adapter_create_bonding(adapter, &device->bdaddr,
3762                                                         bdaddr_type, io_cap);
3763         else
3764                 err = adapter_create_bonding(adapter, &device->bdaddr,
3765                                                         BDADDR_BREDR, io_cap);
3766 #else
3767         if (bdaddr_type != BDADDR_BREDR) {
3768                 if (!state->connected && btd_le_connect_before_pairing())
3769                         err = device_connect_le(device);
3770                 else
3771                         err = adapter_create_bonding(adapter, &device->bdaddr,
3772                                                         device->bdaddr_type,
3773                                                         io_cap);
3774         } else {
3775                 err = adapter_create_bonding(adapter, &device->bdaddr,
3776                                                         BDADDR_BREDR, io_cap);
3777         }
3778 #endif
3779
3780         if (err < 0) {
3781                 bonding_request_free(device->bonding);
3782                 return btd_error_failed(msg, strerror(-err));
3783         }
3784
3785         return NULL;
3786 }
3787
3788 static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
3789 {
3790         switch (status) {
3791         case MGMT_STATUS_SUCCESS:
3792                 return dbus_message_new_method_return(msg);
3793
3794         case MGMT_STATUS_CONNECT_FAILED:
3795                 return dbus_message_new_error(msg,
3796                                 ERROR_INTERFACE ".ConnectionAttemptFailed",
3797                                 "Page Timeout");
3798         case MGMT_STATUS_TIMEOUT:
3799                 return dbus_message_new_error(msg,
3800                                 ERROR_INTERFACE ".AuthenticationTimeout",
3801                                 "Authentication Timeout");
3802         case MGMT_STATUS_BUSY:
3803         case MGMT_STATUS_REJECTED:
3804                 return dbus_message_new_error(msg,
3805                                 ERROR_INTERFACE ".AuthenticationRejected",
3806                                 "Authentication Rejected");
3807         case MGMT_STATUS_CANCELLED:
3808         case MGMT_STATUS_NO_RESOURCES:
3809 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3810         case MGMT_STATUS_DISCONNECTED:
3811 #endif
3812                 return dbus_message_new_error(msg,
3813                                 ERROR_INTERFACE ".AuthenticationCanceled",
3814                                 "Authentication Canceled");
3815         case MGMT_STATUS_ALREADY_PAIRED:
3816                 return dbus_message_new_error(msg,
3817                                 ERROR_INTERFACE ".AlreadyExists",
3818                                 "Already Paired");
3819         default:
3820                 return dbus_message_new_error(msg,
3821                                 ERROR_INTERFACE ".AuthenticationFailed",
3822                                 "Authentication Failed");
3823         }
3824 }
3825
3826 static void device_cancel_bonding(struct btd_device *device, uint8_t status)
3827 {
3828         struct bonding_req *bonding = device->bonding;
3829         DBusMessage *reply;
3830         char addr[18];
3831
3832         if (!bonding)
3833                 return;
3834
3835         ba2str(&device->bdaddr, addr);
3836         DBG("Canceling bonding request for %s", addr);
3837
3838         if (device->authr)
3839                 device_cancel_authentication(device, FALSE);
3840
3841         reply = new_authentication_return(bonding->msg, status);
3842         g_dbus_send_message(dbus_conn, reply);
3843
3844         bonding_request_cancel(bonding);
3845         bonding_request_free(bonding);
3846 }
3847
3848 static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
3849                                                                 void *data)
3850 {
3851         struct btd_device *device = data;
3852         struct bonding_req *req = device->bonding;
3853
3854         DBG("");
3855
3856         if (!req)
3857                 return btd_error_does_not_exist(msg);
3858
3859         device_cancel_bonding(device, MGMT_STATUS_CANCELLED);
3860
3861         return dbus_message_new_method_return(msg);
3862 }
3863
3864 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3865 static DBusMessage *discover_services(DBusConnection *conn,
3866                                         DBusMessage *msg, void *user_data)
3867 {
3868         struct btd_device *device = user_data;
3869         const char *pattern;
3870         int err;
3871
3872         if (device->browse)
3873                 return btd_error_in_progress(msg);
3874
3875         if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
3876                                                 DBUS_TYPE_INVALID) == FALSE)
3877                 return btd_error_invalid_args(msg);
3878
3879         err = device_browse_sdp(device, msg);
3880         if (err < 0)
3881                 goto fail;
3882
3883         return NULL;
3884
3885 fail:
3886         return btd_error_failed(msg,
3887                         "Unable to search the SDP services");
3888 }
3889
3890 static const char *browse_request_get_requestor(struct browse_req *req)
3891 {
3892         if (!req->msg)
3893                 return NULL;
3894
3895         return dbus_message_get_sender(req->msg);
3896 }
3897
3898 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
3899                                                         const char *record)
3900 {
3901         DBusMessageIter entry;
3902
3903         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
3904                                                         NULL, &entry);
3905
3906         dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
3907
3908         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
3909
3910         dbus_message_iter_close_container(dict, &entry);
3911 }
3912
3913 static void discover_services_reply(struct browse_req *req, int err,
3914                                                         sdp_list_t *recs)
3915 {
3916         DBusMessage *reply;
3917         DBusMessageIter iter, dict;
3918         sdp_list_t *seq;
3919
3920         if (!req->msg)
3921                 return;
3922
3923         if (err) {
3924                 const char *err_if;
3925
3926                 if (err == -EHOSTDOWN)
3927                         err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
3928                 else
3929                         err_if = ERROR_INTERFACE ".Failed";
3930
3931                 reply = dbus_message_new_error(req->msg, err_if,
3932                                                         strerror(-err));
3933                 g_dbus_send_message(dbus_conn, reply);
3934                 return;
3935         }
3936
3937         reply = dbus_message_new_method_return(req->msg);
3938         if (!reply)
3939                 return;
3940
3941         dbus_message_iter_init_append(reply, &iter);
3942
3943         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3944                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3945                         DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
3946                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
3947
3948         for (seq = recs; seq; seq = seq->next) {
3949                 sdp_record_t *rec = (sdp_record_t *) seq->data;
3950                 GString *result;
3951
3952                 if (!rec)
3953                         break;
3954
3955                 result = g_string_new(NULL);
3956
3957                 convert_sdp_record_to_xml(rec, result,
3958                                 (void *) g_string_append);
3959
3960                 if (result->len) {
3961                         if (!g_utf8_validate(result->str, -1, NULL)) {
3962                                 gchar *ptr = NULL;
3963
3964                                 DBG("UTF8 invalid string, make valid");
3965                                 ptr = g_utf8_make_valid(result->str, -1);
3966                                 iter_append_record(&dict, rec->handle, ptr);
3967                                 g_free(ptr);
3968                         } else {
3969                                 iter_append_record(&dict, rec->handle, result->str);
3970                         }
3971                 }
3972
3973                 g_string_free(result, TRUE);
3974         }
3975
3976         dbus_message_iter_close_container(&iter, &dict);
3977
3978         g_dbus_send_message(dbus_conn, reply);
3979 }
3980
3981 static DBusMessage *cancel_discover(DBusConnection *conn,
3982                                         DBusMessage *msg, void *user_data)
3983 {
3984         struct btd_device *device = user_data;
3985         const char *sender = dbus_message_get_sender(msg);
3986         const char *requestor;
3987
3988         if (!device->browse)
3989                 return btd_error_does_not_exist(msg);
3990
3991         if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
3992                                         "DiscoverServices"))
3993                 return btd_error_not_authorized(msg);
3994
3995         requestor = browse_request_get_requestor(device->browse);
3996
3997         /* only the discover requestor can cancel the inquiry process */
3998         if (!requestor || !g_str_equal(requestor, sender))
3999                 return btd_error_not_authorized(msg);
4000
4001         discover_services_reply(device->browse, -ECANCELED, NULL);
4002
4003         if (device->browse)
4004                 browse_request_cancel(device->browse);
4005
4006         return dbus_message_new_method_return(msg);
4007 }
4008
4009 void device_set_gatt_connected(struct btd_device *device, gboolean connected)
4010 {
4011         if (device == NULL) {
4012                 error("device is NULL");
4013                 return;
4014         }
4015
4016         if (device->gatt_connected == connected) {
4017                 error("same state change for gatt_connected : %d", connected);
4018                 return;
4019         }
4020         DBG("GattConnected %d", connected);
4021
4022         device->gatt_connected = connected;
4023         g_dbus_emit_property_changed(dbus_conn, device->path,
4024                         DEVICE_INTERFACE, "GattConnected");
4025 }
4026
4027 static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
4028                                                         void *user_data)
4029 {
4030         struct btd_device *dev = user_data;
4031         dbus_bool_t auto_connect = FALSE;
4032         int err;
4033
4034         if (!dev->le) {
4035                 /*
4036                  * If a LE connection is requested without device discovery,
4037                  * we try to get device object. Here, technology can be updated
4038                  * if there is matched device object. Or, a new device object
4039                  * will be created.
4040                  */
4041                 dev = btd_adapter_get_device(dev->adapter, &dev->bdaddr,
4042                                 BDADDR_LE_PUBLIC);
4043                 if (dev == NULL) {
4044                         error("Unable to get device object");
4045                         return btd_error_not_supported(msg);
4046                 }
4047         }
4048
4049         if (dev->le_state.connected)
4050                 return dbus_message_new_method_return(msg);
4051
4052         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &auto_connect,
4053                                 DBUS_TYPE_INVALID))
4054                 return btd_error_invalid_args(msg);
4055
4056         btd_device_set_temporary(dev, false);
4057
4058         if (auto_connect) {
4059                 DBG("Start BLE auto connection");
4060                 dev->disable_auto_connect = FALSE;
4061                 device_set_auto_connect(dev, TRUE);
4062
4063                 return dbus_message_new_method_return(msg);
4064         }
4065
4066         err = device_connect_le(dev);
4067         if (err < 0)
4068                 return btd_error_failed(msg, strerror(-err));
4069
4070         dev->connect = dbus_message_ref(msg);
4071
4072         return NULL;
4073 }
4074
4075 static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
4076                                                         void *user_data)
4077 {
4078         struct btd_device *dev = user_data;
4079
4080         if (!dev->le)
4081                 return btd_error_not_supported(msg);
4082
4083         /*
4084          * Disable connections through passive sccanning
4085          */
4086         if (dev->auto_connect) {
4087                 DBG("Stop BLE auto connection");
4088                 dev->disable_auto_connect = FALSE;
4089                 device_set_auto_connect(dev, FALSE);
4090
4091                 if (!dev->le_state.connected) {
4092                         g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
4093                         return NULL;
4094                 }
4095         }
4096
4097         device_request_disconnect(dev, msg);
4098
4099         return NULL;
4100 }
4101
4102 static DBusMessage *connect_ipsp(DBusConnection *conn, DBusMessage *msg,
4103                                                         void *user_data)
4104 {
4105         struct btd_device *device = user_data;
4106
4107         DBG("bdaddr_type  %d", device->bdaddr_type);
4108
4109         if (device->bdaddr_type == BDADDR_BREDR) {
4110                 if(device->le)
4111                         device->bdaddr_type = BDADDR_LE_PUBLIC;
4112                 else {
4113                         device = btd_adapter_get_device(device->adapter,
4114                                         &device->bdaddr, BDADDR_LE_PUBLIC);
4115                         if (device == NULL)
4116                                 return btd_error_no_such_adapter(msg);
4117                 }
4118         }
4119
4120         if (device->ipsp_connected)
4121                 return btd_error_already_connected(msg);
4122
4123         /* Initiate Connection for 6Lowan*/
4124         if (btd_adapter_connect_ipsp(device->adapter, &device->bdaddr,
4125                                         device->bdaddr_type) != 0)
4126                 return btd_error_failed(msg, "ConnectFailed");
4127
4128         return dbus_message_new_method_return(msg);;
4129 }
4130
4131 static DBusMessage *disconnect_ipsp(DBusConnection *conn, DBusMessage *msg,
4132                                                         void *user_data)
4133 {
4134         struct btd_device *device = user_data;
4135         DBG("bdaddr_type  %d", device->bdaddr_type);
4136
4137         if (device->bdaddr_type == BDADDR_BREDR)
4138                 return btd_error_not_supported(msg);
4139
4140         if (!device->ipsp_connected)
4141                 return btd_error_not_connected(msg);
4142
4143         /* Disconnect the 6Lowpan connection */
4144         if (btd_adapter_disconnect_ipsp(device->adapter, &device->bdaddr,
4145                                         device->bdaddr_type) != 0)
4146                 return btd_error_failed(msg, "DisconnectFailed");
4147
4148         /* TODO: Handle disconnection of GATT connection, If the connection
4149          * is established as part of IPSP connection. */
4150
4151         return dbus_message_new_method_return(msg);;
4152 }
4153
4154 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4155 static GSList *find_otc_conn_info(GSList *list, const char *path)
4156 {
4157         GSList *l;
4158
4159         for (l = list; l != NULL; l = g_slist_next(l)) {
4160                 struct otc_conn_info *info = l->data;
4161
4162                 if (g_strcmp0(info->dev_path, path) == 0)
4163                         return l;
4164         }
4165
4166         return NULL;
4167 }
4168
4169 static gboolean otc_disconnected_cb(GIOChannel *chan, GIOCondition cond,
4170                                                         gpointer user_data)
4171 {
4172         struct otc_conn_info *conn_info;
4173         const char *dev_path = (const char *) user_data;
4174         GSList *l;
4175
4176         DBG("OTC Disconnected");
4177
4178         l = find_otc_conn_info(otc_connection_list, dev_path);
4179         if (!l)
4180                 return FALSE;
4181
4182         conn_info = l->data;
4183         conn_info->otc_connected = false;
4184
4185         g_dbus_emit_signal(dbus_conn, dev_path,
4186                                 DEVICE_INTERFACE, "OtcDisconnected",
4187                                 DBUS_TYPE_INVALID);
4188
4189         if (conn_info->io) {
4190                 g_io_channel_shutdown(conn_info->io, TRUE, NULL);
4191                 g_io_channel_unref(conn_info->io);
4192         }
4193
4194         otc_connection_list = g_slist_remove(otc_connection_list, conn_info);
4195         g_free(conn_info);
4196
4197         return FALSE;
4198 }
4199
4200 static void otc_connect_cb(GIOChannel *chan, GError *gerr,
4201                                                 gpointer user_data)
4202 {
4203         const char *dev_path;
4204         GSList *l;
4205         struct otc_conn_info *conn_info = NULL;
4206         DBusMessage *msg = NULL;
4207         DBusMessageIter iter;
4208         int fd;
4209
4210         if (gerr)
4211                 return;
4212
4213         dev_path = (const char *) user_data;
4214         l = find_otc_conn_info(otc_connection_list, dev_path);
4215
4216         if (!l)
4217                 return;
4218
4219         conn_info = l->data;
4220         conn_info->otc_connected = true;
4221
4222         fd = g_io_channel_unix_get_fd(chan);
4223
4224         DBG("OTC Connected fd [%d], role [%s]",
4225                         fd, conn_info->role ? "server" : "client");
4226         DBG("dev_path [%s]", dev_path);
4227
4228         g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4229                         otc_disconnected_cb, (gpointer) dev_path);
4230
4231         if (conn_info->role == BT_OTP_CLIENT_ROLE) {
4232                 msg = dbus_message_new_method_call(BT_OTC_SERVICE_NAME,
4233                                                         BT_OTC_OBJECT_PATH,
4234                                                         BT_OTC_INTERFACE_NAME,
4235                                                         "NewConnection");
4236         } else if (conn_info->role == BT_OTP_SERVER_ROLE) {
4237                 msg = dbus_message_new_method_call(BT_OTS_SERVICE_NAME,
4238                                                         BT_OTS_OBJECT_PATH,
4239                                                         BT_OTS_INTERFACE_NAME,
4240                                                         "NewConnection");
4241         }
4242
4243         if (!msg) {
4244                 error("Unable to create NewConnection call");
4245                 return;
4246         }
4247
4248         dbus_message_iter_init_append(msg, &iter);
4249
4250         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4251
4252         dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4253
4254         if (!g_dbus_send_message(dbus_conn, msg)) {
4255                 error("sending NewConnection failed");
4256                 dbus_message_unref(msg);
4257         }
4258 }
4259
4260 int btd_adapter_connect_otc(struct btd_device *device)
4261 {
4262         struct btd_adapter *adapter = device_get_adapter(device);
4263         const bdaddr_t *src = btd_adapter_get_address(adapter);
4264         uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4265         const bdaddr_t *dest = device_get_address(device);
4266         uint8_t dest_type = device->bdaddr_type;
4267         struct otc_conn_info *conn_info = NULL;
4268         const char *dev_path = device_get_path(device);
4269         GError *gerr = NULL;
4270
4271         conn_info = g_malloc0(sizeof(struct otc_conn_info));
4272
4273         conn_info->io = bt_io_connect(otc_connect_cb,
4274                                         (gpointer) dev_path, NULL, &gerr,
4275                                         BT_IO_OPT_SOURCE_BDADDR, src,
4276                                         BT_IO_OPT_SOURCE_TYPE, src_type,
4277                                         BT_IO_OPT_DEST_BDADDR, dest,
4278                                         BT_IO_OPT_DEST_TYPE, dest_type,
4279                                         BT_IO_OPT_PSM, OTP_PSM,
4280                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4281                                         BT_IO_OPT_INVALID);
4282
4283         if (!conn_info->io) {
4284                 error("OTC Connect failed : %s", gerr->message);
4285                 g_error_free(gerr);
4286                 g_free(conn_info);
4287                 return -EIO;
4288         }
4289
4290         conn_info->dev_path = dev_path;
4291         conn_info->role = BT_OTP_CLIENT_ROLE;
4292         conn_info->otc_connected = false;
4293         g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4294
4295         otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4296         return 0;
4297 }
4298
4299 static DBusMessage *connect_otc(DBusConnection *conn, DBusMessage *msg,
4300                                                         void *user_data)
4301 {
4302         struct btd_device *device = user_data;
4303         GSList *l;
4304
4305         if (device == NULL)
4306                 return btd_error_invalid_args(msg);
4307
4308         l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4309
4310         if (l) {
4311                 struct otc_conn_info *info = l->data;
4312                 if (info->otc_connected)
4313                         return btd_error_already_connected(msg);
4314                 else
4315                         return btd_error_busy(msg);
4316         }
4317
4318         if (btd_adapter_connect_otc(device) != 0)
4319                 return btd_error_failed(msg, "ConnectFailed");
4320
4321         return dbus_message_new_method_return(msg);
4322 }
4323
4324 static DBusMessage *disconnect_otc(DBusConnection *conn, DBusMessage *msg,
4325                                                         void *user_data)
4326 {
4327         struct btd_device *device = user_data;
4328         struct otc_conn_info *info = NULL;
4329         GSList *l;
4330         int sock;
4331
4332         l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4333
4334         if (!l)
4335                 return btd_error_does_not_exist(msg);
4336
4337         info = l->data;
4338
4339         if (!info->otc_connected)
4340                 return btd_error_not_connected(msg);
4341
4342         sock = g_io_channel_unix_get_fd(info->io);
4343
4344         shutdown(sock, SHUT_RDWR);
4345
4346         g_io_channel_shutdown(info->io, FALSE, NULL);
4347
4348         g_io_channel_unref(info->io);
4349         info->io = NULL;
4350
4351         return dbus_message_new_method_return(msg);
4352 }
4353
4354 int btd_adapter_listen_otc(struct btd_device *device)
4355 {
4356         struct btd_adapter *adapter = device_get_adapter(device);
4357         const bdaddr_t *src = btd_adapter_get_address(adapter);
4358         uint8_t type = btd_adapter_get_le_address_type(adapter);
4359         struct otc_conn_info *conn_info = NULL;
4360         const char *dev_path = device_get_path(device);
4361         GError *gerr = NULL;
4362
4363         conn_info = g_malloc0(sizeof(struct otc_conn_info));
4364
4365         conn_info->io = bt_io_listen(otc_connect_cb, NULL, (gpointer) dev_path,
4366                                 NULL, &gerr,
4367                                 BT_IO_OPT_SOURCE_BDADDR, src,
4368                                 BT_IO_OPT_SOURCE_TYPE, type,
4369                                 BT_IO_OPT_PSM, OTP_PSM,
4370                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4371                                 BT_IO_OPT_INVALID);
4372
4373         if (!conn_info->io) {
4374                 error("OTC Listen failed : %s", gerr->message);
4375                 g_error_free(gerr);
4376                 g_free(conn_info);
4377                 return -EIO;
4378         }
4379
4380         conn_info->dev_path = dev_path;
4381         conn_info->otc_connected = false;
4382         conn_info->role = BT_OTP_SERVER_ROLE;
4383         g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4384
4385         otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4386         return 0;
4387 }
4388
4389 static DBusMessage *listen_otc(DBusConnection *conn, DBusMessage *msg,
4390                                                         void *user_data)
4391 {
4392         struct btd_device *device = user_data;
4393         GSList *l;
4394
4395         if (device == NULL)
4396                 return btd_error_invalid_args(msg);
4397
4398         l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4399
4400         if (l) {
4401                 struct otc_conn_info *info = l->data;
4402                 if (info->otc_connected)
4403                         return btd_error_already_connected(msg);
4404                 else
4405                         return btd_error_busy(msg);
4406         }
4407
4408         if (btd_adapter_listen_otc(device) != 0)
4409                 return btd_error_failed(msg, "ListenFailed");
4410
4411         return dbus_message_new_method_return(msg);
4412 }
4413 #endif
4414
4415 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4416 /********************* L2CAP LE SOCKET IMPLEMENTATION *************************/
4417 static GSList *find_l2cap_le_profile_info(GSList *list, const char *owner,
4418                                                 const char *path)
4419 {
4420         GSList *l;
4421         for (l = list; l != NULL; l = g_slist_next(l)) {
4422                 struct l2cap_le_profile_info *info = l->data;
4423
4424                 if (!info)
4425                         continue;
4426
4427                 if (g_strcmp0(info->owner, owner))
4428                         continue;
4429
4430                 if (!g_strcmp0(info->path, path))
4431                         return l;
4432         }
4433
4434         return NULL;
4435 }
4436
4437 static int parse_l2cap_le_opt(struct l2cap_le_profile_info *info,
4438                                                 const char *key, DBusMessageIter *value)
4439 {
4440         int type = dbus_message_iter_get_arg_type(value);
4441         dbus_bool_t b;
4442
4443         if (strcasecmp(key, "RequireAuthentication") == 0) {
4444                 if (type != DBUS_TYPE_BOOLEAN)
4445                         return -EINVAL;
4446
4447                 dbus_message_iter_get_basic(value, &b);
4448
4449                 if (b)
4450                         info->sec_level = BT_IO_SEC_MEDIUM;
4451                 else
4452                         info->sec_level = BT_IO_SEC_LOW;
4453         } else if (strcasecmp(key, "RequireAuthorization") == 0) {
4454                 if (type != DBUS_TYPE_BOOLEAN)
4455                         return -EINVAL;
4456                 dbus_message_iter_get_basic(value, &b);
4457                 info->authorize = b;
4458         }
4459
4460         return 0;
4461 }
4462
4463 static struct l2cap_le_profile_info *create_l2cap_le_socket(const char *owner,
4464                                                 const char *path, int psm, DBusMessageIter *opts)
4465 {
4466         struct l2cap_le_profile_info *info = NULL;
4467
4468         if (psm < 0 || psm > BTD_L2CAP_LE_PSM_MAX)
4469                 return NULL;
4470
4471         info = g_malloc0(sizeof(struct l2cap_le_profile_info));
4472
4473         info->owner = g_strdup(owner);
4474         info->path = g_strdup(path);
4475         info->psm = psm;
4476
4477         while (dbus_message_iter_get_arg_type(opts) == DBUS_TYPE_DICT_ENTRY) {
4478                 DBusMessageIter value, entry;
4479                 const char *key;
4480
4481                 dbus_message_iter_recurse(opts, &entry);
4482                 dbus_message_iter_get_basic(&entry, &key);
4483
4484                 dbus_message_iter_next(&entry);
4485                 dbus_message_iter_recurse(&entry, &value);
4486
4487                 if (parse_l2cap_le_opt(info, key, &value) < 0)
4488                         error("Invalid value for l2cap_le_socket option %s", key);
4489
4490                 dbus_message_iter_next(opts);
4491         }
4492
4493         if (!info->name)
4494                 info->name = g_strdup_printf("%s%s/%d", owner, path, psm);
4495
4496         return info;
4497 }
4498
4499 static void l2cap_le_io_destroy(gpointer p)
4500 {
4501         struct l2cap_le_conn_info *conn = p;
4502
4503         if (conn->io_id > 0)
4504                 g_source_remove(conn->io_id);
4505
4506         if (conn->io) {
4507                 g_io_channel_shutdown(conn->io, FALSE, NULL);
4508                 g_io_channel_unref(conn->io);
4509         }
4510
4511         if (conn->auth_id != 0)
4512                 btd_cancel_authorization(conn->auth_id);
4513
4514         if (conn->auth_uuid)
4515                 free(conn->auth_uuid);
4516
4517         g_free(conn);
4518 }
4519
4520 static gboolean l2cap_le_disconnected_cb(GIOChannel *chan,
4521                                                 GIOCondition cond, gpointer user_data)
4522 {
4523         struct l2cap_le_conn_info *conn = user_data;
4524         struct l2cap_le_profile_info *info = conn->profile_info;
4525
4526         DBG(" L2CAP LE socket disconnected role [%s] ",
4527                         info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4528
4529         g_dbus_emit_signal(dbus_conn, conn->dev_path,
4530                         DEVICE_INTERFACE, "L2CAPLEDisconnected",
4531                         DBUS_TYPE_INVALID);
4532
4533         conn->connected = false;
4534
4535         info->conn = g_slist_remove(info->conn, conn);
4536         l2cap_le_io_destroy(conn);
4537         return FALSE;
4538 }
4539
4540 static void l2cap_le_connect_cb(GIOChannel *chan, GError *gerr,
4541                                                 gpointer user_data)
4542 {
4543         struct l2cap_le_conn_info *conn = (struct l2cap_le_conn_info *) user_data;
4544         struct l2cap_le_profile_info *info = conn->profile_info;
4545         DBusMessage *msg = NULL;
4546         DBusMessageIter iter;
4547         const char *dev_path;
4548         int fd;
4549         GError *io_err = NULL;
4550         char addr[18];
4551
4552         if (!bt_io_get(chan, &io_err,
4553                                 BT_IO_OPT_DEST, addr,
4554                                 BT_IO_OPT_INVALID)) {
4555                 if (gerr) {
4556                         error("%s failed %s", info->name, gerr->message);
4557                         g_error_free(io_err);
4558                         io_err = NULL;
4559                 } else {
4560                         error("Unable to get connect data for %s: %s",
4561                                 info->name, io_err->message);
4562                         gerr = io_err;
4563                 }
4564                 goto drop;
4565         }
4566
4567         if (gerr != NULL) {
4568                 error("%s failed to connect to %s: %s", info->name, addr,
4569                                                                 gerr->message);
4570                 goto drop;
4571         }
4572
4573         conn->connected = true;
4574
4575         fd = g_io_channel_unix_get_fd(chan);
4576
4577         if (conn->io_id == 0)
4578                 conn->io_id = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4579                         l2cap_le_disconnected_cb, conn);
4580
4581         msg = dbus_message_new_method_call(info->owner,
4582                                                         info->path,
4583                                                         BT_L2CAP_LE_INTERFACE_NAME,
4584                                                         "NewConnection");
4585
4586         if (!msg) {
4587                 error("Unable to create NewConnection call");
4588                 goto drop;
4589         }
4590
4591         dev_path = conn->dev_path;
4592
4593         dbus_message_iter_init_append(msg, &iter);
4594
4595         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4596
4597         dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4598
4599         if (!g_dbus_send_message(dbus_conn, msg)) {
4600                 error("sending NewConnection failed");
4601                 dbus_message_unref(msg);
4602                 goto drop;
4603         }
4604
4605         DBG("L2CAP_LE Connected fd [%d] addr [%s], role [%s]",fd, addr,
4606                         info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4607         return;
4608
4609 drop:
4610         if (io_err)
4611                 g_error_free(io_err);
4612
4613         info->conn = g_slist_remove(info->conn, conn);
4614         l2cap_le_io_destroy(conn);
4615 }
4616
4617 static struct l2cap_le_conn_info *create_l2cap_le_conn(
4618                                                 struct l2cap_le_conn_info *server, GIOChannel *io,
4619                                                 bdaddr_t *src, bdaddr_t *dst, uint8_t dst_type)
4620 {
4621         struct l2cap_le_conn_info *conn;
4622         GIOCondition cond;
4623         struct btd_device *device;
4624         struct btd_adapter *adapter = adapter_find(src);
4625
4626         if (!adapter) {
4627                 error("could not find adapter");
4628                 return NULL;
4629         }
4630
4631         device = btd_adapter_get_device(adapter, dst, dst_type);
4632         if (!device) {
4633                 error("could not find Device");
4634                 return NULL;
4635         }
4636
4637         conn = g_new0(struct l2cap_le_conn_info, 1);
4638         conn->io = g_io_channel_ref(io);
4639         conn->profile_info = server->profile_info;
4640         conn->dev_path = device_get_path(device);
4641
4642         cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
4643         conn->io_id = g_io_add_watch(io, cond, l2cap_le_disconnected_cb, conn);
4644
4645         return conn;
4646 }
4647
4648 static void l2cap_le_auth(DBusError *err, void *user_data)
4649 {
4650         struct l2cap_le_conn_info *conn = user_data;
4651         struct l2cap_le_profile_info *info = conn->profile_info;
4652         GError *gerr = NULL;
4653         char addr[18];
4654
4655         conn->auth_id = 0;
4656
4657         bt_io_get(conn->io, &gerr, BT_IO_OPT_DEST, addr, BT_IO_OPT_INVALID);
4658         if (gerr != NULL) {
4659                 error("Unable to get connect data for %s: %s",
4660                                                 info->name, gerr->message);
4661                 g_error_free(gerr);
4662                 goto drop;
4663         }
4664
4665         if (err && dbus_error_is_set(err)) {
4666                 error("%s rejected %s: %s", info->name, addr, err->message);
4667                 goto drop;
4668         }
4669
4670         if (!bt_io_accept(conn->io, l2cap_le_connect_cb, conn, NULL, &gerr)) {
4671                 error("bt_io_accept: %s", gerr->message);
4672                 g_error_free(gerr);
4673                 goto drop;
4674         }
4675
4676         DBG("%s authorized to connect to %s", addr, info->name);
4677         return;
4678
4679 drop:
4680         info->conn = g_slist_remove(info->conn, conn);
4681         l2cap_le_io_destroy(conn);
4682 }
4683
4684 static void l2cap_le_confirm(GIOChannel *io, gpointer user_data)
4685 {
4686         struct l2cap_le_conn_info *server = user_data;
4687         struct l2cap_le_profile_info *info = server->profile_info;
4688         struct l2cap_le_conn_info *conn;
4689         GError *gerr = NULL;
4690         uint8_t dst_type;
4691         bdaddr_t src, dst;
4692         char addr[18];
4693         char *uuid = g_malloc0(UUID_LEN * sizeof(char));
4694
4695         bt_io_get(io, &gerr,
4696                         BT_IO_OPT_SOURCE_BDADDR, &src,
4697                         BT_IO_OPT_DEST_BDADDR, &dst,
4698                         BT_IO_OPT_DEST_TYPE, &dst_type,
4699                         BT_IO_OPT_DEST, addr,
4700                         BT_IO_OPT_INVALID);
4701         if (gerr != NULL) {
4702                 error("%s failed to get connect data: %s", info->name,
4703                                                         gerr->message);
4704                 g_error_free(gerr);
4705                 return;
4706         }
4707
4708         DBG("incoming connect from %s for authorization", addr);
4709
4710         conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4711         if (conn == NULL)
4712                 return;
4713
4714         /* Use custom uuid of the form "FFFFFFFF-FFFF-FFFF-FFFF-<psm in 12 digits>"
4715         *  for authorizing l2cap_le socket using existing flow.
4716         *  This custom uuid will be used in the BT-OAL layer to identify the
4717         *  l2cap_le socket authorization and extracting psm from it.
4718         */
4719         snprintf(uuid, UUID_LEN, "%s%012d", L2CAP_LE_UUID_SUBSTR, server->psm);
4720         conn->auth_uuid = uuid;
4721
4722         conn->auth_id = btd_request_authorization(&src, &dst,
4723                                         (const char *)conn->auth_uuid, l2cap_le_auth, conn);
4724         if (conn->auth_id == 0) {
4725                 error("%s authorization failure", info->name);
4726                 l2cap_le_io_destroy(conn);
4727                 return;
4728         }
4729
4730         info->conn = g_slist_append(info->conn, conn);
4731
4732         DBG("%s authorizing connection from %s", info->name, addr);
4733 }
4734
4735 static void l2cap_le_direct_connect(GIOChannel *io, GError *err,
4736                                                 gpointer user_data)
4737 {
4738         struct l2cap_le_conn_info *server = user_data;
4739         struct l2cap_le_profile_info *info = server->profile_info;
4740         struct l2cap_le_conn_info *conn;
4741         GError *gerr = NULL;
4742         uint8_t dst_type;
4743         bdaddr_t src, dst;
4744
4745         bt_io_get(io, &gerr,
4746                         BT_IO_OPT_SOURCE_BDADDR, &src,
4747                         BT_IO_OPT_DEST_BDADDR, &dst,
4748                         BT_IO_OPT_DEST_TYPE, &dst_type,
4749                         BT_IO_OPT_INVALID);
4750         if (gerr != NULL) {
4751                 error("%s failed to get connect data: %s", info->name,
4752                                                                 gerr->message);
4753                 g_error_free(gerr);
4754                 return;
4755         }
4756
4757         conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4758         if (conn == NULL)
4759                 return;
4760
4761         info->conn = g_slist_append(info->conn, conn);
4762
4763         l2cap_le_connect_cb(io, err, conn);
4764 }
4765
4766 static void _remove_l2cap_le_socket(struct l2cap_le_profile_info *info)
4767 {
4768         l2cap_le_socket_list = g_slist_remove(l2cap_le_socket_list, info);
4769
4770         DBG("Removed \"%s\"", info->name);
4771
4772         if (info->server)
4773                 l2cap_le_io_destroy((gpointer)info->server);
4774         g_slist_free_full(info->conn, l2cap_le_io_destroy);
4775
4776         g_free(info->name);
4777         g_free(info->owner);
4778         g_free(info->path);
4779
4780         g_free(info);
4781 }
4782
4783 static void l2cap_le_socket_exited(DBusConnection *conn, void *user_data)
4784 {
4785         struct l2cap_le_profile_info *info = user_data;
4786
4787         DBG("l2cap le server \"%s\" exited", info->name);
4788
4789         _remove_l2cap_le_socket(info);
4790 }
4791
4792 static int _connect_l2cap_le(struct btd_device *device,
4793                                                 struct l2cap_le_profile_info *info)
4794 {
4795         struct btd_adapter *adapter = device_get_adapter(device);
4796         const bdaddr_t *src = btd_adapter_get_address(adapter);
4797         uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4798         const bdaddr_t *dest = device_get_address(device);
4799         uint8_t dest_type = device->bdaddr_type;
4800         const char *dev_path = device_get_path(device);
4801         GError *gerr = NULL;
4802         struct l2cap_le_conn_info *conn = NULL;
4803
4804         conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4805         info->conn = g_slist_append(info->conn, conn);
4806
4807         conn->io = bt_io_connect(l2cap_le_connect_cb,
4808                                         conn, NULL, &gerr,
4809                                         BT_IO_OPT_SOURCE_BDADDR, src,
4810                                         BT_IO_OPT_SOURCE_TYPE, src_type,
4811                                         BT_IO_OPT_DEST_BDADDR, dest,
4812                                         BT_IO_OPT_DEST_TYPE, dest_type,
4813                                         BT_IO_OPT_PSM, info->psm,
4814                                         BT_IO_OPT_SEC_LEVEL, info->sec_level,
4815                                         BT_IO_OPT_INVALID);
4816
4817         if (!conn->io) {
4818                 error("L2CAP_LE Connect failed : %s", gerr->message);
4819                 g_error_free(gerr);
4820                 _remove_l2cap_le_socket(info);
4821                 return -EIO;
4822         }
4823
4824         info->role = BT_L2CAP_LE_CLIENT_ROLE;
4825         conn->dev_path = dev_path;
4826         conn->profile_info = info;
4827         conn->connected = false;
4828         g_io_channel_set_close_on_unref(conn->io, FALSE);
4829
4830         l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4831         return 0;
4832 }
4833
4834 static int _listen_l2cap_le(struct btd_adapter *adapter,
4835                                                 struct l2cap_le_profile_info *info)
4836 {
4837         const bdaddr_t *src = btd_adapter_get_address(adapter);
4838         uint8_t type = btd_adapter_get_le_address_type(adapter);
4839         GError *gerr = NULL;
4840         struct l2cap_le_conn_info *conn = NULL;
4841         BtIOConfirm confirm;
4842         BtIOConnect connect;
4843         int psm = 0;
4844
4845         if (info->authorize) {
4846                 confirm = l2cap_le_confirm;
4847                 connect = NULL;
4848         } else {
4849                 confirm = NULL;
4850                 connect = l2cap_le_direct_connect;
4851         }
4852
4853         conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4854         info->server = conn;
4855
4856         conn->io = bt_io_listen(connect, confirm, (gpointer)conn,
4857                                                         NULL, &gerr,
4858                                                         BT_IO_OPT_SOURCE_BDADDR, src,
4859                                                         BT_IO_OPT_SOURCE_TYPE, type,
4860                                                         BT_IO_OPT_PSM, info->psm,
4861                                                         BT_IO_OPT_SEC_LEVEL, info->sec_level,
4862                                                         BT_IO_OPT_INVALID);
4863
4864     if (!conn->io) {
4865                 error("L2cap_LE Listen failed : %s", gerr->message);
4866                 g_error_free(gerr);
4867                 _remove_l2cap_le_socket(info);
4868                 return -EIO;
4869     }
4870
4871         bt_io_get(conn->io, &gerr, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID);
4872
4873         DBG("L2CAP LE Socket listen to PSM %d successful", psm);
4874
4875         conn->connected = false;
4876         info->role = BT_L2CAP_LE_SERVER_ROLE;
4877         conn->psm = psm;
4878         conn->profile_info = info;
4879         g_io_channel_set_close_on_unref(conn->io, FALSE);
4880
4881         l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4882
4883         return 0;
4884 }
4885
4886 static DBusMessage *connect_l2cap_le_socket(DBusConnection *conn,
4887                                                 DBusMessage *msg, void *user_data)
4888 {
4889         struct btd_device *device = user_data;
4890         GSList *l;
4891         const char *path, *sender;
4892         dbus_int32_t psm;
4893         DBusMessageIter args, opts;
4894         struct l2cap_le_profile_info *info = NULL;
4895
4896         if (device == NULL)
4897                 return btd_error_invalid_args(msg);
4898
4899         sender = dbus_message_get_sender(msg);
4900
4901         dbus_message_iter_init(msg, &args);
4902         dbus_message_iter_get_basic(&args, &path);
4903         dbus_message_iter_next(&args);
4904
4905         dbus_message_iter_get_basic(&args, &psm);
4906         dbus_message_iter_next(&args);
4907
4908         l = find_l2cap_le_profile_info(l2cap_le_socket_list,  sender, path);
4909
4910         if (l) {
4911                 struct l2cap_le_profile_info *info = l->data;
4912                 if (info->conn) {
4913                         struct l2cap_le_conn_info *conn_info = info->conn->data;
4914                         if (conn_info && conn_info->connected)
4915                                 return btd_error_already_connected(msg);
4916                         else
4917                                 return btd_error_busy(msg);
4918                 } else {
4919                         error("Something is wrong!!!");
4920                         return btd_error_failed(msg, "ConnectFailed due to some internal error");
4921                 }
4922         }
4923
4924         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4925                 return btd_error_invalid_args(msg);
4926
4927         dbus_message_iter_recurse(&args, &opts);
4928
4929         info = create_l2cap_le_socket(sender, path, psm, &opts);
4930         if (!info)
4931                 return btd_error_invalid_args(msg);
4932
4933         info->role = BT_L2CAP_LE_CLIENT_ROLE;
4934
4935         DBG("connect l2cap l2 socket channel %d", (int)psm);
4936
4937         if (_connect_l2cap_le(device, info) != 0)
4938                 return btd_error_failed(msg, "ConnectFailed");
4939
4940         info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4941                                                         info, NULL);
4942
4943         return dbus_message_new_method_return(msg);
4944 }
4945
4946 DBusMessage *listen_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg,
4947                                                 void *user_data)
4948 {
4949         struct btd_adapter *adapter = user_data;
4950         GSList *l;
4951         const char *path, *sender;
4952         dbus_int32_t psm;
4953         DBusMessageIter args, opts;
4954         struct l2cap_le_profile_info *info = NULL;
4955
4956         sender = dbus_message_get_sender(msg);
4957
4958         dbus_message_iter_init(msg, &args);
4959         dbus_message_iter_get_basic(&args, &path);
4960         dbus_message_iter_next(&args);
4961
4962         dbus_message_iter_get_basic(&args, &psm);
4963         dbus_message_iter_next(&args);
4964
4965         l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4966
4967         if (l)
4968                 return btd_error_already_exists(msg);
4969
4970         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4971                 return btd_error_invalid_args(msg);
4972
4973         dbus_message_iter_recurse(&args, &opts);
4974
4975         info = create_l2cap_le_socket(sender, path, psm, &opts);
4976         if (!info)
4977                 return btd_error_invalid_args(msg);
4978
4979         info->role = BT_L2CAP_LE_SERVER_ROLE;
4980
4981         DBG("listen l2cap_le socket to psm %d", (int)psm);
4982
4983         if (_listen_l2cap_le(adapter, info) != 0)
4984                 return btd_error_failed(msg, "ListenFailed");
4985
4986         info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4987                                                         info, NULL);
4988
4989         return dbus_message_new_method_return(msg);
4990 }
4991
4992 DBusMessage *get_psm_l2cap_le(DBusConnection *conn, DBusMessage *msg)
4993 {
4994         const char *path, *sender;
4995         int psm;
4996         GSList *l;
4997         DBusMessage *reply;
4998         DBusMessageIter args;
4999         struct l2cap_le_profile_info *info;
5000
5001         sender = dbus_message_get_sender(msg);
5002
5003         DBG("sender %s", sender);
5004
5005         dbus_message_iter_init(msg, &args);
5006
5007         dbus_message_iter_get_basic(&args, &path);
5008         dbus_message_iter_next(&args);
5009
5010         l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
5011
5012         if (!l) {
5013                 DBG("L2cap LE socket not exist");
5014                 return btd_error_does_not_exist(msg);
5015         }
5016
5017         info = l->data;
5018
5019         if(info->server)
5020                 psm = info->server->psm;
5021         else
5022                 return btd_error_does_not_exist(msg);
5023
5024         reply = dbus_message_new_method_return(msg);
5025         if (!reply)
5026                 return btd_error_failed(msg,
5027                                         "Failed to create reply.");
5028
5029         dbus_message_append_args(reply,
5030                         DBUS_TYPE_UINT32, &psm,
5031                         DBUS_TYPE_INVALID);
5032
5033         return reply;
5034 }
5035
5036 DBusMessage *remove_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg)
5037 {
5038         const char *path, *sender;
5039         struct l2cap_le_profile_info *info = NULL;
5040         GSList *l;
5041
5042         sender = dbus_message_get_sender(msg);
5043
5044         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
5045                                                         DBUS_TYPE_INVALID))
5046                 return btd_error_invalid_args(msg);
5047
5048         DBG("remove socket sender %s path %s", sender, path);
5049
5050         l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
5051
5052         if (!l) {
5053                 DBG("L2cap LE socket not exist");
5054                 return btd_error_does_not_exist(msg);
5055         }
5056
5057         info = l->data;
5058
5059         g_dbus_remove_watch(conn, info->id);
5060         _remove_l2cap_le_socket(info);
5061
5062         return dbus_message_new_method_return(msg);
5063 }
5064 #endif
5065
5066 static DBusMessage *le_set_data_length(
5067                         DBusConnection *conn, DBusMessage *msg,
5068                         void *user_data)
5069 {
5070         dbus_uint16_t max_tx_octets;
5071         dbus_uint16_t max_tx_time;
5072         struct btd_device *device = user_data;
5073         int status;
5074         char addr[18];
5075
5076         if (!dbus_message_get_args(msg, NULL,
5077                                 DBUS_TYPE_UINT16, &max_tx_octets,
5078                                 DBUS_TYPE_UINT16, &max_tx_time,
5079                                 DBUS_TYPE_INVALID)) {
5080                 DBG("error in retrieving values");
5081                 return btd_error_invalid_args(msg);
5082         }
5083
5084         if (device->bdaddr_type == BDADDR_BREDR)
5085                 return btd_error_not_supported(msg);
5086
5087         ba2str(&device->bdaddr, addr);
5088
5089         DBG("Remote device address: %s", addr);
5090         DBG("Max tx octets: %u, Max tx time: %u",
5091                                 max_tx_octets, max_tx_time);
5092
5093         status = btd_adapter_le_set_data_length(device->adapter,
5094                                 &device->bdaddr, max_tx_octets,
5095                                 max_tx_time);
5096
5097         if (status != 0)
5098                 return btd_error_failed(msg, "Unable to set le data length values");
5099         else
5100                 return dbus_message_new_method_return(msg);
5101 }
5102
5103 static DBusMessage *set_trusted_profile(DBusConnection *conn,
5104                                                 DBusMessage *msg, void *data)
5105 {
5106         struct btd_device *dev = data;
5107         dbus_bool_t profile_trusted;
5108         const char *pattern;
5109         char *uuid;
5110         uint32_t pbap = dev->trusted_profiles.pbap;
5111         uint32_t map = dev->trusted_profiles.map;
5112         uint32_t sap = dev->trusted_profiles.sap;
5113         uint32_t hfp_hs = dev->trusted_profiles.hfp_hs;
5114         uint32_t a2dp = dev->trusted_profiles.a2dp;
5115
5116         if (!dbus_message_get_args(msg, NULL,
5117                                 DBUS_TYPE_STRING, &pattern,
5118                                 DBUS_TYPE_BOOLEAN, &profile_trusted,
5119                                 DBUS_TYPE_INVALID))
5120                 return btd_error_invalid_args(msg);
5121
5122         DBG("Pattern : %s", pattern);
5123         uuid = bt_name2string(pattern);
5124         DBG("UUID : %s", uuid);
5125         DBG("profile Trusted : %d %d %d", dev->trusted_profiles.pbap,
5126                         dev->trusted_profiles.map, dev->trusted_profiles.sap);
5127         DBG("profile Restricted : %d %d", dev->trusted_profiles.hfp_hs,
5128                         dev->trusted_profiles.a2dp);
5129         if (g_strcmp0(uuid, OBEX_PBAP_UUID) == 0) {
5130                 if (profile_trusted)
5131                         pbap = SUPPORTED_TRUSTED;
5132                 else
5133                         pbap = SUPPORTED_BLOCKED;
5134         } else if (g_strcmp0(uuid, OBEX_MAP_UUID) == 0) {
5135                 if (profile_trusted)
5136                         map = SUPPORTED_TRUSTED;
5137                 else
5138                         map = SUPPORTED_BLOCKED;
5139         } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
5140                 if (profile_trusted)
5141                         sap = SUPPORTED_TRUSTED;
5142                 else
5143                         sap = SUPPORTED_BLOCKED;
5144         } else  if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
5145                 if (profile_trusted)
5146                         hfp_hs = SUPPORTED_TRUSTED;
5147                 else
5148                         hfp_hs = SUPPORTED_BLOCKED;
5149         } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
5150                 if (profile_trusted)
5151                         a2dp = SUPPORTED_TRUSTED;
5152                 else
5153                         a2dp = SUPPORTED_BLOCKED;
5154         } else {
5155                 free(uuid);
5156                 return btd_error_invalid_args(msg);
5157         }
5158
5159         free(uuid);
5160         btd_device_set_trusted_profiles(dev, pbap, map, sap, hfp_hs, a2dp);
5161         return dbus_message_new_method_return(msg);
5162 }
5163
5164 static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
5165                                                                         void *user_data)
5166 {
5167         struct btd_device *dev = user_data;
5168         struct btd_service *service;
5169         btd_service_state_t state;
5170         const char *pattern;
5171         char *uuid;
5172         DBusMessage *reply;
5173         dbus_bool_t val;
5174
5175         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
5176                                                         DBUS_TYPE_INVALID))
5177                 return btd_error_invalid_args(msg);
5178
5179         reply = dbus_message_new_method_return(msg);
5180         if (!reply)
5181                 return btd_error_invalid_args(reply);
5182
5183         uuid = bt_name2string(pattern);
5184         DBG("is_connected_profile_uuid : %s", uuid);
5185         service = btd_device_get_service(dev, uuid);
5186
5187         if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
5188                 DBG("HFP  service is not found check for HSP service");
5189                 service = btd_device_get_service(dev, HSP_HS_UUID);
5190         }
5191         if (uuid)
5192                 free(uuid);
5193
5194         if (!service)
5195                 return btd_error_not_connected(msg);
5196
5197         state = btd_service_get_state(service);
5198         DBG("Connected State : %d", state);
5199
5200         if (state == BTD_SERVICE_STATE_CONNECTED)
5201                 val = TRUE;
5202         else
5203                 val = FALSE;
5204
5205         dbus_message_append_args(reply,
5206                         DBUS_TYPE_BOOLEAN, &val,
5207                         DBUS_TYPE_INVALID);
5208
5209         return reply;
5210 }
5211
5212 static DBusMessage *update_le_conn_parm(DBusConnection *conn, DBusMessage *msg,
5213                                         void *user_data)
5214 {
5215         struct btd_device *device = user_data;
5216         GIOChannel *io;
5217         int fd;
5218         struct le_conn_param param = {0, 0, 0, 0};
5219         uint32_t min, max, latency, to_multiplier;
5220
5221         DBG("");
5222
5223         if (device == NULL) {
5224                 error("device is NULL");
5225                 return btd_error_invalid_args(msg);
5226         }
5227
5228         if (!device->le) {
5229                 error("le is not supported");
5230                 return btd_error_not_supported(msg);
5231         }
5232
5233         if (!device->gatt_connected || !device->attrib)
5234                 return btd_error_not_connected(msg);
5235
5236         io = g_attrib_get_channel(device->attrib);
5237         if (!io)
5238                 return btd_error_not_connected(msg);
5239
5240         fd = g_io_channel_unix_get_fd(io);
5241         if (fd < 0)
5242                 return btd_error_not_connected(msg);
5243
5244         if (device_get_conn_update_state(device))
5245                 return btd_error_in_progress(msg);
5246         else
5247                 device_set_conn_update_state(device, true);
5248
5249         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &min,
5250                                         DBUS_TYPE_UINT32, &max,
5251                                         DBUS_TYPE_UINT32, &latency,
5252                                         DBUS_TYPE_UINT32, &to_multiplier,
5253                                         DBUS_TYPE_INVALID)) {
5254                 error("Invalid args");
5255                 return btd_error_invalid_args(msg);
5256         }
5257
5258         if (min > UINT16_MAX || max > UINT16_MAX ||
5259                         latency > UINT16_MAX || to_multiplier > UINT16_MAX) {
5260                 error("Invalid args");
5261                 return btd_error_invalid_args(msg);
5262         }
5263         param.min = (uint16_t)min;
5264         param.max = (uint16_t)max;
5265         param.latency = (uint16_t)latency;
5266         param.to_multiplier = (uint16_t)to_multiplier;
5267
5268         if (setsockopt(fd, SOL_BLUETOOTH, BT_LE_CONN_PARAM,
5269                                 &param, sizeof(param)) < 0) {
5270                 error("Can't Update LE conn param : %s (%d)",
5271                                 strerror(errno), errno);
5272                 return btd_error_failed(msg, strerror(errno));
5273         }
5274
5275         return dbus_message_new_method_return(msg);
5276 }
5277
5278 static void device_request_att_mtu_reponse_cb(bool success, uint8_t att_ecode,
5279                                         void *user_data)
5280 {
5281         struct btd_device *device = user_data;
5282         DBusMessage *reply;
5283         DBusMessageIter iter;
5284         uint16_t mtu;
5285
5286         if (!device->req_att_mtu)
5287                 return;
5288
5289         mtu = bt_gatt_client_get_mtu(device->client);
5290
5291         if (!success) {
5292                 const char *err_if;
5293                 err_if = ERROR_INTERFACE ".Failed";
5294
5295                 reply = dbus_message_new_error(device->req_att_mtu, err_if,
5296                                                         "Request Att MTU failed");
5297                 g_dbus_send_message(dbus_conn, reply);
5298                 return;
5299         }
5300
5301         DBG("MTU exchange complete, with MTU: %u", mtu);
5302
5303         reply = dbus_message_new_method_return(device->req_att_mtu);
5304         if (!reply)
5305                 return;
5306
5307         dbus_message_iter_init_append(reply, &iter);
5308
5309         dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
5310                                                         &mtu);
5311         dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
5312                                                         &att_ecode);
5313         g_dbus_send_message(dbus_conn, reply);
5314
5315         dbus_message_unref(device->req_att_mtu);
5316         device->req_att_mtu = NULL;
5317 }
5318
5319 static DBusMessage *request_att_mtu(DBusConnection *conn, DBusMessage *msg,
5320                                         void *user_data)
5321 {
5322         struct btd_device *device = user_data;
5323         uint16_t mtu;
5324
5325         DBG("");
5326
5327         if (device == NULL) {
5328                 error("device is NULL");
5329                 return btd_error_invalid_args(msg);
5330         }
5331
5332         if (!device->le) {
5333                 error("le is not supported");
5334                 return btd_error_not_supported(msg);
5335         }
5336
5337         if (!device->gatt_connected || !device->attrib)
5338                 return btd_error_not_connected(msg);
5339
5340         if (!dbus_message_get_args(msg, NULL,
5341                                                 DBUS_TYPE_UINT16, &mtu,
5342                                                 DBUS_TYPE_INVALID)) {
5343                 error("Invalid args");
5344                 return btd_error_invalid_args(msg);
5345         }
5346
5347         DBG("MTU %d", mtu);
5348
5349         if (!bt_gatt_request_att_mtu(device->client, mtu,
5350                                 device_request_att_mtu_reponse_cb, device))
5351                 return btd_error_failed(msg, "Unable to Request MTU");
5352
5353         device->req_att_mtu = dbus_message_ref(msg);
5354         return NULL;
5355 }
5356
5357 static DBusMessage *device_get_ida(DBusConnection *conn, DBusMessage *msg,
5358                                                         void *user_data)
5359 {
5360         struct btd_device *device = user_data;
5361         char device_idaddr[18] = { 0 };
5362         DBusMessage *reply;
5363         const gchar *id_address = device_idaddr;
5364
5365         DBG("");
5366
5367         if (device == NULL)
5368                 return btd_error_invalid_args(msg);
5369
5370         if (!device->le) {
5371                 error("It doesn't support LE");
5372                 return btd_error_not_supported(msg);
5373         }
5374
5375         if (device->rpa) {
5376                 // There is the first RPA. So it's paired device.
5377                 if (device->bredr)
5378                         ba2str(device->rpa, device_idaddr);
5379                 else
5380                         ba2str(&device->bdaddr, device_idaddr);
5381         } else if (device->bdaddr_type != BDADDR_LE_RANDOM) {
5382                 // device->bdaddr is identity address.
5383                 ba2str(&device->bdaddr, device_idaddr);
5384         } else if ((device->bdaddr.b[5] >> 6) == 0x01) {
5385                 // RPA but it's not paired
5386                 return btd_error_does_not_exist(msg);
5387         } else if ((device->bdaddr.b[5] >> 6) == 0x03) {
5388                 // Static Random address
5389                 ba2str(&device->bdaddr, device_idaddr);
5390         } else {
5391                 // Non-RPA case
5392                 return btd_error_not_supported(msg);
5393         }
5394
5395         reply = dbus_message_new_method_return(msg);
5396         if (!reply)
5397                 return NULL;
5398
5399         dbus_message_append_args(reply, DBUS_TYPE_STRING, &id_address,
5400                                                         DBUS_TYPE_INVALID);
5401
5402         return reply;
5403 }
5404
5405 void device_set_conn_update_state(struct btd_device *device, bool state)
5406 {
5407         if (!device)
5408                 return;
5409
5410         device->pending_conn_update = state;
5411 }
5412
5413 bool device_get_conn_update_state(struct btd_device *device)
5414 {
5415         return device->pending_conn_update;
5416 }
5417 #endif
5418
5419 static const GDBusMethodTable device_methods[] = {
5420         { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
5421         { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
5422         { GDBUS_ASYNC_METHOD("ConnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5423                                                 NULL, connect_profile) },
5424         { GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5425                                                 NULL, disconnect_profile) },
5426 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5427         { GDBUS_ASYNC_METHOD("DisconnectExtProfile",
5428                                         GDBUS_ARGS({ "profile", "o" }), NULL,
5429                                         disconnect_ext_profile) },
5430         { GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL,
5431                         pair_device) },
5432 #else
5433         { GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
5434 #endif
5435         { GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
5436 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5437         { GDBUS_ASYNC_METHOD("ConnectLE", GDBUS_ARGS({ "auto_connect", "b"}),
5438                                                 NULL, connect_le) },
5439         { GDBUS_ASYNC_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
5440         { GDBUS_METHOD("IsConnectedProfile", GDBUS_ARGS({ "UUID", "s" }),
5441                         GDBUS_ARGS({ "IsConnected", "b" }),
5442                         is_connected_profile)},
5443         { GDBUS_METHOD("LeConnUpdate", GDBUS_ARGS({ "interval_min", "u" },
5444                                 { "interval_max", "u" }, { "latency", "u" },
5445                                 { "time_out", "u" }), NULL,
5446                         update_le_conn_parm) },
5447         { GDBUS_ASYNC_METHOD("DiscoverServices", GDBUS_ARGS({ "pattern", "s" }),
5448                         NULL, discover_services) },
5449         { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
5450         { GDBUS_ASYNC_METHOD("ConnectIpsp", NULL, NULL, connect_ipsp) },
5451         { GDBUS_ASYNC_METHOD("DisconnectIpsp", NULL, NULL, disconnect_ipsp) },
5452 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5453         { GDBUS_METHOD("ConnectOtc", NULL, NULL, connect_otc) },
5454         { GDBUS_METHOD("DisconnectOtc", NULL, NULL, disconnect_otc) },
5455         { GDBUS_METHOD("ListenOtc", NULL, NULL, listen_otc) },
5456         { GDBUS_ASYNC_METHOD("ConnectL2capLESocket",
5457                         GDBUS_ARGS({ "path", "o"}, { "psm", "i" }, { "options", "a{sv}" }),
5458                                                 NULL, connect_l2cap_le_socket) },
5459 #endif
5460         { GDBUS_ASYNC_METHOD("LESetDataLength",
5461                         GDBUS_ARGS({"max_tx_octets", "q" },
5462                         { "max_tx_time", "q" }), NULL,
5463                         le_set_data_length)},
5464         { GDBUS_ASYNC_METHOD("RequestAttMtu", GDBUS_ARGS({ "mtu", "q" }),
5465                         GDBUS_ARGS({ "mtu", "q" }, { "status", "y"}),
5466                         request_att_mtu) },
5467         { GDBUS_METHOD("GetIDAddress", NULL, GDBUS_ARGS({ "IDAdress", "s" }),
5468                         device_get_ida) },
5469         { GDBUS_METHOD("SetTrustedProfile",
5470                         GDBUS_ARGS({ "uuid", "s"}, { "trusted", "b"}), NULL,
5471                         set_trusted_profile) },
5472 #endif
5473         { }
5474 };
5475
5476 static const GDBusPropertyTable device_properties[] = {
5477         { "Address", "s", dev_property_get_address },
5478         { "AddressType", "s", property_get_address_type },
5479         { "Name", "s", dev_property_get_name, NULL, dev_property_exists_name },
5480         { "Alias", "s", dev_property_get_alias, dev_property_set_alias },
5481         { "Class", "u", dev_property_get_class, NULL,
5482                                         dev_property_exists_class },
5483         { "Appearance", "q", dev_property_get_appearance, NULL,
5484                                         dev_property_exists_appearance },
5485         { "Icon", "s", dev_property_get_icon, NULL,
5486                                         dev_property_exists_icon },
5487         { "Paired", "b", dev_property_get_paired },
5488         { "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
5489         { "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
5490         { "LegacyPairing", "b", dev_property_get_legacy },
5491         { "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
5492 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5493         {"IsAliasSet", "b", dev_property_get_alias_set },
5494         { "Connected", "y", dev_property_get_connected },
5495 #else
5496         { "Connected", "b", dev_property_get_connected },
5497 #endif
5498         { "UUIDs", "as", dev_property_get_uuids },
5499         { "Modalias", "s", dev_property_get_modalias, NULL,
5500                                                 dev_property_exists_modalias },
5501         { "Adapter", "o", dev_property_get_adapter },
5502 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5503          /* To handle Failed Legacy Pairing when initiated from Remote device*/
5504         { "LegacyPaired", "b", dev_property_get_paired },
5505         { "LegacyManufacturerDataLen", "q", property_get_manufacturer_data_len },
5506         { "LegacyManufacturerData", "ay", property_get_manufacturer_data },
5507         { "GattConnected", "b", dev_property_get_gatt_connected },
5508         { "PayloadTimeout", "q", dev_property_get_payload},
5509         { "LastAddrType", "y", dev_property_get_last_addr_type},
5510         { "IpspConnected", "b", dev_property_get_ipsp_conn_state },
5511         { "IpspBtInterfaceInfo", "s", dev_property_get_ipsp_conn_bt_iface_name },
5512         { "AttMtu", "q", dev_property_get_att_mtu },
5513         { "TrustedProfiles", "u", dev_property_get_trusted_profiles},
5514 #endif
5515         { "ManufacturerData", "a{qv}", dev_property_get_manufacturer_data,
5516                                 NULL, dev_property_manufacturer_data_exist },
5517         { "ServiceData", "a{sv}", dev_property_get_service_data,
5518                                 NULL, dev_property_service_data_exist },
5519         { "TxPower", "n", dev_property_get_tx_power, NULL,
5520                                         dev_property_exists_tx_power },
5521         { "ServicesResolved", "b", dev_property_get_svc_resolved, NULL, NULL },
5522         { "AdvertisingFlags", "ay", dev_property_get_flags, NULL,
5523                                         dev_property_flags_exist,
5524                                         G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
5525         { "AdvertisingData", "a{yv}", dev_property_get_advertising_data,
5526                                 NULL, dev_property_advertising_data_exist,
5527                                 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
5528         { "WakeAllowed", "b", dev_property_get_wake_allowed,
5529                                 dev_property_set_wake_allowed,
5530                                 dev_property_wake_allowed_exist },
5531         { }
5532 };
5533
5534 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5535 static const GDBusSignalTable device_signals[] = {
5536         { GDBUS_SIGNAL("Disconnected",
5537                         GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" },
5538                                 { "name", "s" })) },
5539         { GDBUS_SIGNAL("DeviceConnected", GDBUS_ARGS({ "bdaddr_type", "y"})) },
5540         { GDBUS_SIGNAL("ProfileStateChanged",
5541                         GDBUS_ARGS({ "profile", "s"}, {"state", "i"})) },
5542         { GDBUS_SIGNAL("AdvReport",
5543                         GDBUS_ARGS({"Address","s"}, { "Address Type", "y" },
5544                                 { "Adv Type", "y"}, { "RSSI", "i"},
5545                                 { "AdvDataLen", "i"}, { "AdvData", "ay"})) },
5546         { GDBUS_SIGNAL("LEDataLengthChanged",
5547                         GDBUS_ARGS({"max_tx_octets","q"},
5548                                 { "max_tx_time", "q" },
5549                                 { "max_rx_octets", "q"},
5550                                 { "max_rx_time", "q"}))},
5551         { GDBUS_SIGNAL("IpspStateChanged",
5552                         GDBUS_ARGS({"connected","b"}, {"if_name","s"}))},
5553         { GDBUS_SIGNAL("OtcDisconnected", NULL)},
5554         { GDBUS_SIGNAL("AttMtuChanged",
5555                         GDBUS_ARGS({"mtu", "q"})) },
5556         { }
5557 };
5558 #endif
5559
5560 uint8_t btd_device_get_bdaddr_type(struct btd_device *dev)
5561 {
5562         return dev->bdaddr_type;
5563 }
5564
5565 bool btd_device_is_connected(struct btd_device *dev)
5566 {
5567         return dev->bredr_state.connected || dev->le_state.connected;
5568 }
5569
5570 static void clear_temporary_timer(struct btd_device *dev)
5571 {
5572         if (dev->temporary_timer) {
5573                 timeout_remove(dev->temporary_timer);
5574                 dev->temporary_timer = 0;
5575         }
5576 }
5577
5578 void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
5579 {
5580         struct bearer_state *state = get_state(dev, bdaddr_type);
5581
5582         device_update_last_seen(dev, bdaddr_type);
5583
5584         if (state->connected) {
5585                 char addr[18];
5586                 ba2str(&dev->bdaddr, addr);
5587                 error("Device %s is already connected", addr);
5588                 return;
5589         }
5590
5591         bacpy(&dev->conn_bdaddr, &dev->bdaddr);
5592         dev->conn_bdaddr_type = dev->bdaddr_type;
5593
5594         /* If this is the first connection over this bearer */
5595         if (bdaddr_type == BDADDR_BREDR)
5596                 device_set_bredr_support(dev);
5597         else
5598                 device_set_le_support(dev, bdaddr_type);
5599
5600         state->connected = true;
5601
5602 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5603         if (dev->le_state.connected && dev->bredr_state.connected)
5604                 return;
5605
5606         /* Remove temporary timer while connected */
5607         clear_temporary_timer(dev);
5608
5609         g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
5610                                                                 "Connected");
5611 #else
5612 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
5613         if (bdaddr_type == BDADDR_BREDR &&
5614             get_charging_state(dev->adapter) == WIRELESS_CHARGING) {
5615                 int br_pkt_type = ACL_PTYPE_MASK |
5616                         HCI_2DH1 | HCI_2DH3 | HCI_2DH5 |
5617                         HCI_3DH1 | HCI_3DH3 | HCI_3DH5;
5618
5619                 DBG("During wireless charging... Change packet type");
5620                 device_change_pkt_type(dev, (gpointer)br_pkt_type);
5621         }
5622 #endif  /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
5623
5624         g_dbus_emit_signal(dbus_conn, dev->path,
5625                 DEVICE_INTERFACE, "DeviceConnected",
5626                 DBUS_TYPE_BYTE, &bdaddr_type,
5627                 DBUS_TYPE_INVALID);
5628 #endif
5629 }
5630
5631 void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
5632 {
5633         struct bearer_state *state = get_state(device, bdaddr_type);
5634         DBusMessage *reply;
5635 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5636         bool remove_device = false;
5637 #endif
5638         bool paired_status_updated = false;
5639 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5640         char *dev_name = device->name;
5641 #endif
5642
5643         if (!state->connected)
5644                 return;
5645
5646         state->connected = false;
5647         device->general_connect = FALSE;
5648
5649         device_set_svc_refreshed(device, false);
5650
5651         if (device->disconn_timer > 0) {
5652                 timeout_remove(device->disconn_timer);
5653                 device->disconn_timer = 0;
5654         }
5655
5656 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5657         if (device->browse) {
5658                 struct browse_req *req = device->browse;
5659
5660                 if ((bdaddr_type == BDADDR_BREDR && req->search_uuid != 0) ||
5661                     (bdaddr_type != BDADDR_BREDR && req->search_uuid == 0))
5662                         device->browse = NULL;
5663                 else
5664                         DBG("device->browse is for other link");
5665         }
5666 #endif
5667
5668         /* This could be executed while the client is waiting for Connect() but
5669          * att_connect_cb has not been invoked.
5670          * In that case reply the client that the connection failed.
5671          */
5672         if (device->connect) {
5673                 DBG("connection removed while Connect() is waiting reply");
5674                 reply = btd_error_failed(device->connect,
5675                                                 ERR_BREDR_CONN_CANCELED);
5676                 g_dbus_send_message(dbus_conn, reply);
5677                 dbus_message_unref(device->connect);
5678                 device->connect = NULL;
5679         }
5680
5681         while (device->disconnects) {
5682                 DBusMessage *msg = device->disconnects->data;
5683
5684 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5685                 if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
5686                                                                 "RemoveDevice"))
5687                         remove_device = true;
5688 #endif
5689                 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
5690                 device->disconnects = g_slist_remove(device->disconnects, msg);
5691                 dbus_message_unref(msg);
5692         }
5693
5694         /* Check paired status of both bearers since it's possible to be
5695          * paired but not connected via link key to LTK conversion.
5696          */
5697         if (!device->bredr_state.connected && device->bredr_state.paired &&
5698                                                 !device->bredr_state.bonded) {
5699                 btd_adapter_remove_bonding(device->adapter,
5700                                                 &device->bdaddr,
5701                                                 BDADDR_BREDR);
5702                 device->bredr_state.paired = false;
5703                 paired_status_updated = true;
5704         }
5705
5706         if (!device->le_state.connected && device->le_state.paired &&
5707                                                 !device->le_state.bonded) {
5708                 btd_adapter_remove_bonding(device->adapter,
5709                                                 &device->bdaddr,
5710                                                 device->bdaddr_type);
5711                 device->le_state.paired = false;
5712                 paired_status_updated = true;
5713         }
5714
5715         /* report change only if both bearers are unpaired */
5716         if (!device->bredr_state.paired && !device->le_state.paired &&
5717                                                         paired_status_updated)
5718                 g_dbus_emit_property_changed(dbus_conn, device->path,
5719                                                 DEVICE_INTERFACE,
5720                                                 "Paired");
5721
5722
5723 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5724         if (device->bredr_state.connected || device->le_state.connected)
5725                 return;
5726
5727         device_update_last_seen(device, bdaddr_type);
5728
5729         g_slist_free_full(device->eir_uuids, g_free);
5730         device->eir_uuids = NULL;
5731
5732         g_dbus_emit_property_changed(dbus_conn, device->path,
5733                                                 DEVICE_INTERFACE, "Connected");
5734
5735         if (remove_device)
5736                 btd_adapter_remove_device(device->adapter, device);
5737 #else
5738         g_dbus_emit_signal(dbus_conn, device->path,
5739                 DEVICE_INTERFACE, "Disconnected",
5740                 DBUS_TYPE_BYTE, &bdaddr_type,
5741                 DBUS_TYPE_BYTE, &device->disc_reason,
5742                 DBUS_TYPE_STRING, &dev_name,
5743                 DBUS_TYPE_INVALID);
5744 #endif
5745 }
5746
5747 guint device_add_disconnect_watch(struct btd_device *device,
5748                                 disconnect_watch watch, void *user_data,
5749                                 GDestroyNotify destroy)
5750 {
5751         struct btd_disconnect_data *data;
5752         static guint id = 0;
5753
5754         data = g_new0(struct btd_disconnect_data, 1);
5755         data->id = ++id;
5756         data->watch = watch;
5757         data->user_data = user_data;
5758         data->destroy = destroy;
5759
5760         device->watches = g_slist_append(device->watches, data);
5761
5762         return data->id;
5763 }
5764
5765 void device_remove_disconnect_watch(struct btd_device *device, guint id)
5766 {
5767         GSList *l;
5768
5769         for (l = device->watches; l; l = l->next) {
5770                 struct btd_disconnect_data *data = l->data;
5771
5772                 if (data->id == id) {
5773                         device->watches = g_slist_remove(device->watches,
5774                                                         data);
5775                         if (data->destroy)
5776                                 data->destroy(data->user_data);
5777                         g_free(data);
5778                         return;
5779                 }
5780         }
5781 }
5782
5783 static char *load_cached_name(struct btd_device *device, const char *local,
5784                                 const char *peer)
5785 {
5786         char filename[PATH_MAX];
5787         GKeyFile *key_file;
5788         char *str = NULL;
5789         int len;
5790
5791         if (device_address_is_private(device))
5792                 return NULL;
5793
5794         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
5795
5796         key_file = g_key_file_new();
5797
5798         if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
5799                 goto failed;
5800
5801         str = g_key_file_get_string(key_file, "General", "Name", NULL);
5802         if (str) {
5803                 len = strlen(str);
5804                 if (len > HCI_MAX_NAME_LENGTH)
5805                         str[HCI_MAX_NAME_LENGTH] = '\0';
5806         }
5807
5808 failed:
5809         g_key_file_free(key_file);
5810
5811         return str;
5812 }
5813
5814 static void load_cached_name_resolve(struct btd_device *device,
5815                                         const char *local, const char *peer)
5816 {
5817         char filename[PATH_MAX];
5818         GKeyFile *key_file;
5819         uint64_t failed_time;
5820
5821         if (device_address_is_private(device))
5822                 return;
5823
5824         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
5825
5826         key_file = g_key_file_new();
5827
5828         if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
5829                 goto failed;
5830
5831         failed_time = g_key_file_get_uint64(key_file, "NameResolving",
5832                                                         "FailedTime", NULL);
5833
5834         device->name_resolve_failed_time = failed_time;
5835
5836 failed:
5837         g_key_file_free(key_file);
5838 }
5839
5840 static struct csrk_info *load_csrk(GKeyFile *key_file, const char *group)
5841 {
5842         struct csrk_info *csrk;
5843         char *str;
5844         int i;
5845
5846         str = g_key_file_get_string(key_file, group, "Key", NULL);
5847         if (!str)
5848                 return NULL;
5849
5850         csrk = g_new0(struct csrk_info, 1);
5851
5852         for (i = 0; i < 16; i++) {
5853                 if (sscanf(str + (i * 2), "%2hhx", &csrk->key[i]) != 1)
5854                         goto fail;
5855         }
5856
5857         /*
5858          * In case of older storage this will return 0 which is fine since it
5859          * didn't support signing at that point the counter should never have
5860          * been used.
5861          */
5862         csrk->counter = g_key_file_get_integer(key_file, group, "Counter",
5863                                                                         NULL);
5864         g_free(str);
5865
5866         return csrk;
5867
5868 fail:
5869         g_free(str);
5870         g_free(csrk);
5871         return NULL;
5872 }
5873
5874 static void load_services(struct btd_device *device, char **uuids)
5875 {
5876         char **uuid;
5877
5878         for (uuid = uuids; *uuid; uuid++) {
5879                 if (g_slist_find_custom(device->uuids, *uuid, bt_uuid_strcmp))
5880                         continue;
5881
5882                 device->uuids = g_slist_insert_sorted(device->uuids,
5883                                                         g_strdup(*uuid),
5884                                                         bt_uuid_strcmp);
5885         }
5886
5887         g_strfreev(uuids);
5888 }
5889
5890 static void convert_info(struct btd_device *device, GKeyFile *key_file)
5891 {
5892         char filename[PATH_MAX];
5893         char adapter_addr[18];
5894         char device_addr[18];
5895         char **uuids;
5896         char *str;
5897         gsize length = 0;
5898         GError *gerr = NULL;
5899
5900         /* Load device profile list from legacy properties */
5901         uuids = g_key_file_get_string_list(key_file, "General", "SDPServices",
5902                                                                 NULL, NULL);
5903         if (uuids)
5904                 load_services(device, uuids);
5905
5906         uuids = g_key_file_get_string_list(key_file, "General", "GATTServices",
5907                                                                 NULL, NULL);
5908         if (uuids)
5909                 load_services(device, uuids);
5910
5911         if (!device->uuids)
5912                 return;
5913
5914         /* Remove old entries so they are not loaded again */
5915         g_key_file_remove_key(key_file, "General", "SDPServices", NULL);
5916         g_key_file_remove_key(key_file, "General", "GATTServices", NULL);
5917
5918         ba2str(btd_adapter_get_address(device->adapter), adapter_addr);
5919         ba2str(&device->bdaddr, device_addr);
5920         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
5921                         device_addr);
5922
5923         str = g_key_file_to_data(key_file, &length, NULL);
5924         if (!g_file_set_contents(filename, str, length, &gerr)) {
5925                 error("Unable set contents for %s: (%s)", filename,
5926                                                                 gerr->message);
5927                 g_error_free(gerr);
5928         }
5929         g_free(str);
5930
5931         store_device_info(device);
5932 }
5933
5934 static void load_info(struct btd_device *device, const char *local,
5935                         const char *peer, GKeyFile *key_file)
5936 {
5937         GError *gerr = NULL;
5938         char *str;
5939         gboolean store_needed = FALSE;
5940         gboolean blocked;
5941         gboolean wake_allowed;
5942         char **uuids;
5943         int source, vendor, product, version;
5944         char **techno, **t;
5945 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5946         gboolean svc_change_regd;
5947         char buf[DEV_MAX_MANUFACTURER_DATA_LEN] = { 0, };
5948 #endif
5949         /* Load device name from storage info file, if that fails fall back to
5950          * the cache.
5951          */
5952         str = g_key_file_get_string(key_file, "General", "Name", NULL);
5953         if (str == NULL) {
5954                 str = load_cached_name(device, local, peer);
5955                 if (str)
5956                         store_needed = TRUE;
5957         }
5958
5959         if (str) {
5960                 strcpy(device->name, str);
5961                 g_free(str);
5962         }
5963
5964         /* Load alias */
5965         device->alias = g_key_file_get_string(key_file, "General", "Alias",
5966                                                                         NULL);
5967
5968         /* Load class */
5969         str = g_key_file_get_string(key_file, "General", "Class", NULL);
5970         if (str) {
5971                 uint32_t class;
5972
5973                 if (sscanf(str, "%x", &class) == 1)
5974                         device->class = class;
5975                 g_free(str);
5976         }
5977
5978         /* Load appearance */
5979         str = g_key_file_get_string(key_file, "General", "Appearance", NULL);
5980         if (str) {
5981                 device->appearance = strtol(str, NULL, 16);
5982                 g_free(str);
5983         }
5984
5985 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5986         /* Load RPA Resolution Support value */
5987         device->rpa_res_support = g_key_file_get_integer(key_file,
5988                                                         "General", "RPAResSupport", NULL);
5989
5990         str = g_key_file_get_string(key_file, "General", "LegacyManufacturerDataLen", NULL);
5991         if (str) {
5992                 device->manufacturer_data_len = strtol(str, NULL, 10);
5993                 g_free(str);
5994
5995                 if (0 > device->manufacturer_data_len) {
5996                         error("Invalid manufacturer_data_len: %d",
5997                                         device->manufacturer_data_len);
5998                         device->manufacturer_data_len = 0;
5999                 }
6000
6001                 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerData", NULL);
6002                 if (str) {
6003                         if (device->manufacturer_data_len < DEV_MAX_MANUFACTURER_DATA_LEN) {
6004                                 load_manufacturer_data_2digit(str,
6005                                                         device->manufacturer_data_len,  buf);
6006                                 device->manufacturer_data = g_memdup(buf,
6007                                                         device->manufacturer_data_len);
6008                         }
6009                         g_free(str);
6010                 }
6011         }
6012
6013         str = g_key_file_get_string(key_file, "General", "IdentityAddress",
6014                                                                 NULL);
6015
6016         if (str) {
6017                 device->rpa = g_malloc0(sizeof(bdaddr_t));
6018                 bacpy(device->rpa, &device->bdaddr);
6019                 str2ba(str, &device->bdaddr);
6020                 g_free(str);
6021         }
6022 #endif
6023
6024         /* Load device technology */
6025         techno = g_key_file_get_string_list(key_file, "General",
6026                                         "SupportedTechnologies", NULL, NULL);
6027         if (!techno)
6028                 goto next;
6029
6030         for (t = techno; *t; t++) {
6031                 if (g_str_equal(*t, "BR/EDR"))
6032                         device->bredr = true;
6033                 else if (g_str_equal(*t, "LE"))
6034                         device->le = true;
6035                 else
6036                         error("Unknown device technology");
6037         }
6038
6039         if (!device->le) {
6040                 device->bdaddr_type = BDADDR_BREDR;
6041         } else {
6042                 str = g_key_file_get_string(key_file, "General",
6043                                                 "AddressType", NULL);
6044
6045                 if (str && g_str_equal(str, "public"))
6046                         device->bdaddr_type = BDADDR_LE_PUBLIC;
6047                 else if (str && g_str_equal(str, "static"))
6048                         device->bdaddr_type = BDADDR_LE_RANDOM;
6049                 else
6050                         error("Unknown LE device technology");
6051
6052                 g_free(str);
6053
6054                 device->local_csrk = load_csrk(key_file, "LocalSignatureKey");
6055                 device->remote_csrk = load_csrk(key_file, "RemoteSignatureKey");
6056         }
6057
6058         g_strfreev(techno);
6059
6060 next:
6061         /* Load trust */
6062         device->trusted = g_key_file_get_boolean(key_file, "General",
6063                                                         "Trusted", NULL);
6064
6065 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6066         /* Load Trusted Profiles*/
6067         int trusted_profiles = g_key_file_get_integer(key_file, "General",
6068                                                         "TrustedProfiles", NULL);
6069         DBG("Loading TrustedProfiles %d", trusted_profiles);
6070         device->trusted_profiles.pbap = ((trusted_profiles &
6071                         (PROFILE_SUPPORTED << PBAP_SHIFT_OFFSET)) >> PBAP_SHIFT_OFFSET);
6072         device->trusted_profiles.map = ((trusted_profiles &
6073                         (PROFILE_SUPPORTED << MAP_SHIFT_OFFSET)) >> MAP_SHIFT_OFFSET);
6074         device->trusted_profiles.sap = ((trusted_profiles &
6075                         (PROFILE_SUPPORTED << SAP_SHIFT_OFFSET)) >> SAP_SHIFT_OFFSET);
6076         device->trusted_profiles.hfp_hs = ((trusted_profiles &
6077                         (PROFILE_SUPPORTED << HFP_HS_SHIFT_OFFSET)) >> HFP_HS_SHIFT_OFFSET);
6078         device->trusted_profiles.a2dp = ((trusted_profiles &
6079                         (PROFILE_SUPPORTED << A2DP_SHIFT_OFFSET)) >> A2DP_SHIFT_OFFSET);
6080
6081 #endif
6082
6083         /* Load device blocked */
6084         blocked = g_key_file_get_boolean(key_file, "General", "Blocked", NULL);
6085         if (blocked)
6086                 device_block(device, FALSE);
6087
6088         /* Load device profile list */
6089         uuids = g_key_file_get_string_list(key_file, "General", "Services",
6090                                                 NULL, NULL);
6091         if (uuids) {
6092                 load_services(device, uuids);
6093
6094                 /* Discovered services restored from storage */
6095                 device->bredr_state.svc_resolved = true;
6096         }
6097
6098         /* Load device id */
6099         source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
6100         if (source) {
6101                 vendor = g_key_file_get_integer(key_file, "DeviceID",
6102                                                         "Vendor", NULL);
6103
6104                 product = g_key_file_get_integer(key_file, "DeviceID",
6105                                                         "Product", NULL);
6106
6107                 version = g_key_file_get_integer(key_file, "DeviceID",
6108                                                         "Version", NULL);
6109
6110                 btd_device_set_pnpid(device, source, vendor, product, version);
6111         }
6112
6113         /* Wake allowed is only configured and stored if user changed it.
6114          * Otherwise, we enable if profile supports it.
6115          */
6116         wake_allowed = g_key_file_get_boolean(key_file, "General",
6117                                               "WakeAllowed", &gerr);
6118         if (!gerr) {
6119                 device_set_wake_override(device, wake_allowed);
6120         } else {
6121                 g_error_free(gerr);
6122                 gerr = NULL;
6123         }
6124
6125 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6126         /* Load Service changed Registered flag */
6127         svc_change_regd = g_key_file_get_boolean(key_file, "Att",
6128                                                 "SvcChangeRegd", NULL);
6129
6130         bt_att_set_svc_changed_indication_registered(device->att,
6131                                                 svc_change_regd);
6132 #endif
6133
6134         if (store_needed)
6135                 store_device_info(device);
6136 }
6137
6138 static void load_att_info(struct btd_device *device, const char *local,
6139                                 const char *peer)
6140 {
6141         char filename[PATH_MAX];
6142         struct stat st;
6143         GKeyFile *key_file;
6144         GError *gerr = NULL;
6145         char *prim_uuid, *str;
6146         char **groups, **handle, *service_uuid;
6147         struct gatt_primary *prim;
6148         uuid_t uuid;
6149         char tmp[3];
6150         int i;
6151
6152         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", local,
6153                         peer);
6154
6155         /* Check if attributes file exists */
6156         if (stat(filename, &st) < 0)
6157                 return;
6158
6159         key_file = g_key_file_new();
6160         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6161                 error("Unable to load key file from %s: (%s)", filename,
6162                                                                 gerr->message);
6163                 g_error_free(gerr);
6164         }
6165         groups = g_key_file_get_groups(key_file, NULL);
6166
6167         sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
6168         prim_uuid = bt_uuid2string(&uuid);
6169
6170         for (handle = groups; *handle; handle++) {
6171                 gboolean uuid_ok;
6172                 int end;
6173
6174                 str = g_key_file_get_string(key_file, *handle, "UUID", NULL);
6175                 if (!str)
6176                         continue;
6177
6178                 uuid_ok = g_str_equal(str, prim_uuid);
6179                 g_free(str);
6180
6181                 if (!uuid_ok)
6182                         continue;
6183
6184                 str = g_key_file_get_string(key_file, *handle, "Value", NULL);
6185                 if (!str)
6186                         continue;
6187
6188                 end = g_key_file_get_integer(key_file, *handle,
6189                                                 "EndGroupHandle", NULL);
6190                 if (end == 0) {
6191                         g_free(str);
6192                         continue;
6193                 }
6194
6195                 prim = g_new0(struct gatt_primary, 1);
6196                 prim->range.start = atoi(*handle);
6197                 prim->range.end = end;
6198
6199                 switch (strlen(str)) {
6200                 case 4:
6201                         uuid.type = SDP_UUID16;
6202                         sscanf(str, "%04hx", &uuid.value.uuid16);
6203                 break;
6204                 case 8:
6205                         uuid.type = SDP_UUID32;
6206                         sscanf(str, "%08x", &uuid.value.uuid32);
6207                         break;
6208                 case 32:
6209                         uuid.type = SDP_UUID128;
6210                         memset(tmp, 0, sizeof(tmp));
6211                         for (i = 0; i < 16; i++) {
6212                                 memcpy(tmp, str + (i * 2), 2);
6213                                 uuid.value.uuid128.data[i] =
6214                                                 (uint8_t) strtol(tmp, NULL, 16);
6215                         }
6216                         break;
6217                 default:
6218                         g_free(str);
6219                         g_free(prim);
6220                         continue;
6221                 }
6222
6223                 service_uuid = bt_uuid2string(&uuid);
6224                 memcpy(prim->uuid, service_uuid, MAX_LEN_UUID_STR);
6225                 free(service_uuid);
6226                 g_free(str);
6227
6228                 device->primaries = g_slist_append(device->primaries, prim);
6229         }
6230
6231         g_strfreev(groups);
6232         g_key_file_free(key_file);
6233         free(prim_uuid);
6234 }
6235
6236 static void device_register_primaries(struct btd_device *device,
6237                                                 GSList *prim_list, int psm)
6238 {
6239         device->primaries = g_slist_concat(device->primaries, prim_list);
6240 }
6241
6242 static void add_primary(struct gatt_db_attribute *attr, void *user_data)
6243 {
6244         GSList **new_services = user_data;
6245         struct gatt_primary *prim;
6246         bt_uuid_t uuid;
6247
6248         prim = g_new0(struct gatt_primary, 1);
6249         if (!prim) {
6250                 DBG("Failed to allocate gatt_primary structure");
6251                 return;
6252         }
6253
6254         gatt_db_attribute_get_service_handles(attr, &prim->range.start,
6255                                                         &prim->range.end);
6256         gatt_db_attribute_get_service_uuid(attr, &uuid);
6257         bt_uuid_to_string(&uuid, prim->uuid, sizeof(prim->uuid));
6258
6259         *new_services = g_slist_append(*new_services, prim);
6260 }
6261
6262 static void load_desc_value(struct gatt_db_attribute *attrib,
6263                                                 int err, void *user_data)
6264 {
6265         if (err)
6266                 warn("loading descriptor value to db failed");
6267 }
6268
6269 static ssize_t str2val(const char *str, uint8_t *val, size_t len)
6270 {
6271         const char *pos = str;
6272         size_t i;
6273
6274         for (i = 0; i < len; i++) {
6275                 if (sscanf(pos, "%2hhx", &val[i]) != 1)
6276                         break;
6277                 pos += 2;
6278         }
6279
6280         return i;
6281 }
6282
6283 static int load_desc(char *handle, char *value,
6284                                         struct gatt_db_attribute *service)
6285 {
6286         char uuid_str[MAX_LEN_UUID_STR];
6287         struct gatt_db_attribute *att;
6288         uint16_t handle_int;
6289         uint16_t val;
6290         bt_uuid_t uuid, ext_uuid;
6291
6292         if (sscanf(handle, "%04hx", &handle_int) != 1)
6293                 return -EIO;
6294
6295         /* Check if there is any value stored, otherwise it is just the UUID */
6296         if (sscanf(value, "%04hx:%s", &val, uuid_str) != 2) {
6297                 if (sscanf(value, "%s", uuid_str) != 1)
6298                         return -EIO;
6299                 val = 0;
6300         }
6301
6302         DBG("loading descriptor handle: 0x%04x, value: 0x%04x, value uuid: %s",
6303                                 handle_int, val, uuid_str);
6304
6305         bt_string_to_uuid(&uuid, uuid_str);
6306         bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
6307
6308         /* If it is CEP then it must contain the value */
6309         if (!bt_uuid_cmp(&uuid, &ext_uuid) && !val) {
6310                 warn("cannot load CEP descriptor without value");
6311                 return -EIO;
6312         }
6313
6314         att = gatt_db_service_insert_descriptor(service, handle_int, &uuid,
6315                                                         0, NULL, NULL, NULL);
6316         if (!att || gatt_db_attribute_get_handle(att) != handle_int) {
6317                 warn("loading descriptor to db failed");
6318                 return -EIO;
6319         }
6320
6321         if (val) {
6322                 if (!gatt_db_attribute_write(att, 0, (uint8_t *)&val,
6323                                                 sizeof(val), 0, NULL,
6324                                                 load_desc_value, NULL))
6325                         return -EIO;
6326         }
6327
6328         return 0;
6329 }
6330
6331 static int load_chrc(char *handle, char *value,
6332                                         struct gatt_db_attribute *service)
6333 {
6334         uint16_t properties, value_handle, handle_int;
6335         char uuid_str[MAX_LEN_UUID_STR];
6336         struct gatt_db_attribute *att;
6337         char val_str[32];
6338         uint8_t val[16];
6339         size_t val_len;
6340         bt_uuid_t uuid;
6341
6342         if (sscanf(handle, "%04hx", &handle_int) != 1)
6343                 return -EIO;
6344
6345         /* Check if there is any value stored */
6346         if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%32s:%s",
6347                         &value_handle, &properties, val_str, uuid_str) != 4) {
6348                 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%s",
6349                                 &value_handle, &properties, uuid_str) != 3)
6350                         return -EIO;
6351                 val_len = 0;
6352         } else
6353                 val_len = str2val(val_str, val, sizeof(val));
6354
6355         bt_string_to_uuid(&uuid, uuid_str);
6356
6357         /* Log debug message. */
6358         DBG("loading characteristic handle: 0x%04x, value handle: 0x%04x,"
6359                                 " properties 0x%04x value: %s uuid: %s",
6360                                 handle_int, value_handle, properties,
6361                                 val_len ? val_str : "", uuid_str);
6362
6363         att = gatt_db_service_insert_characteristic(service, value_handle,
6364                                                         &uuid, 0, properties,
6365                                                         NULL, NULL, NULL);
6366         if (!att || gatt_db_attribute_get_handle(att) != value_handle) {
6367                 warn("loading characteristic to db failed");
6368                 return -EIO;
6369         }
6370
6371         if (val_len) {
6372                 if (!gatt_db_attribute_write(att, 0, val, val_len, 0, NULL,
6373                                                 load_desc_value, NULL))
6374                         return -EIO;
6375         }
6376
6377         return 0;
6378 }
6379
6380 static int load_incl(struct gatt_db *db, char *handle, char *value,
6381                                         struct gatt_db_attribute *service)
6382 {
6383         char uuid_str[MAX_LEN_UUID_STR];
6384         struct gatt_db_attribute *att;
6385         uint16_t start, end;
6386
6387         if (sscanf(handle, "%04hx", &start) != 1)
6388                 return -EIO;
6389
6390         if (sscanf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", &start, &end,
6391                                                                 uuid_str) != 3)
6392                 return -EIO;
6393
6394         /* Log debug message. */
6395         DBG("loading included service: 0x%04x, end: 0x%04x, uuid: %s", start,
6396                                                                 end, uuid_str);
6397
6398         att = gatt_db_get_attribute(db, start);
6399         if (!att) {
6400                 warn("loading included service to db failed - no such service");
6401                 return -EIO;
6402         }
6403
6404         att = gatt_db_service_add_included(service, att);
6405         if (!att) {
6406                 warn("loading included service to db failed");
6407                 return -EIO;
6408         }
6409
6410         return 0;
6411 }
6412
6413 static int load_service(struct gatt_db *db, char *handle, char *value)
6414 {
6415         struct gatt_db_attribute *att;
6416         uint16_t start, end;
6417         char type[MAX_LEN_UUID_STR], uuid_str[MAX_LEN_UUID_STR];
6418         bt_uuid_t uuid;
6419         bool primary;
6420
6421         if (sscanf(handle, "%04hx", &start) != 1)
6422                 return -EIO;
6423
6424         if (sscanf(value, "%[^:]:%04hx:%s", type, &end, uuid_str) != 3)
6425                 return -EIO;
6426
6427         if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR))
6428                 primary = true;
6429         else if (g_str_equal(type, GATT_SND_SVC_UUID_STR))
6430                 primary = false;
6431         else
6432                 return -EIO;
6433
6434         bt_string_to_uuid(&uuid, uuid_str);
6435
6436         /* Log debug message. */
6437         DBG("loading service: 0x%04x, end: 0x%04x, uuid: %s",
6438                                                         start, end, uuid_str);
6439
6440         att = gatt_db_insert_service(db, start, &uuid, primary,
6441                                                         end - start + 1);
6442         if (!att) {
6443                 error("Unable load service into db!");
6444                 return -EIO;
6445         }
6446
6447         return 0;
6448 }
6449
6450 static int load_gatt_db_impl(GKeyFile *key_file, char **keys,
6451                                                         struct gatt_db *db)
6452 {
6453         struct gatt_db_attribute *current_service;
6454         char **handle, *value, type[MAX_LEN_UUID_STR];
6455         int ret;
6456
6457         /* first load service definitions */
6458         for (handle = keys; *handle; handle++) {
6459                 value = g_key_file_get_string(key_file, "Attributes", *handle,
6460                                                                         NULL);
6461
6462                 if (sscanf(value, "%[^:]:", type) != 1) {
6463                         warn("Missing Type in attribute definition");
6464                         g_free(value);
6465                         return -EIO;
6466                 }
6467
6468                 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6469                                 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6470                         ret = load_service(db, *handle, value);
6471                         if (ret) {
6472                                 g_free(value);
6473                                 return ret;
6474                         }
6475                 }
6476
6477                 g_free(value);
6478         }
6479
6480         current_service = NULL;
6481         /* then fill them with data*/
6482         for (handle = keys; *handle; handle++) {
6483                 value = g_key_file_get_string(key_file, "Attributes", *handle,
6484                                                                         NULL);
6485
6486                 if (sscanf(value, "%[^:]:", type) != 1) {
6487                         warn("Missing Type in attribute definition");
6488                         g_free(value);
6489                         return -EIO;
6490                 }
6491
6492                 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6493                                 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6494                         uint16_t tmp;
6495                         uint16_t start, end;
6496                         bool primary;
6497                         bt_uuid_t uuid;
6498                         char uuid_str[MAX_LEN_UUID_STR];
6499
6500                         if (sscanf(*handle, "%04hx", &tmp) != 1) {
6501                                 warn("Unable to parse attribute handle");
6502                                 g_free(value);
6503                                 return -EIO;
6504                         }
6505
6506                         if (current_service)
6507                                 gatt_db_service_set_active(current_service,
6508                                                                         true);
6509
6510                         current_service = gatt_db_get_attribute(db, tmp);
6511
6512                         gatt_db_attribute_get_service_data(current_service,
6513                                                         &start, &end,
6514                                                         &primary, &uuid);
6515
6516                         bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6517                 } else if (g_str_equal(type, GATT_INCLUDE_UUID_STR)) {
6518                         ret = load_incl(db, *handle, value, current_service);
6519                 } else if (g_str_equal(type, GATT_CHARAC_UUID_STR)) {
6520                         ret = load_chrc(*handle, value, current_service);
6521                 } else {
6522                         ret = load_desc(*handle, value, current_service);
6523                 }
6524
6525                 g_free(value);
6526                 if (ret) {
6527                         gatt_db_clear(db);
6528                         return ret;
6529                 }
6530         }
6531
6532         if (current_service)
6533                 gatt_db_service_set_active(current_service, true);
6534
6535         return 0;
6536 }
6537
6538 static void load_gatt_db(struct btd_device *device, const char *local,
6539                                                         const char *peer)
6540 {
6541         char **keys, filename[PATH_MAX];
6542         GKeyFile *key_file;
6543         GError *gerr = NULL;
6544
6545         if (!gatt_cache_is_enabled(device))
6546                 return;
6547
6548         DBG("Restoring %s gatt database from file", peer);
6549
6550         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
6551
6552         key_file = g_key_file_new();
6553         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6554                 error("Unable to load key file from %s: (%s)", filename,
6555                                                                 gerr->message);
6556                 g_error_free(gerr);
6557         }
6558         keys = g_key_file_get_keys(key_file, "Attributes", NULL, NULL);
6559
6560         if (!keys) {
6561                 warn("No cache for %s", peer);
6562                 g_key_file_free(key_file);
6563                 return;
6564         }
6565
6566         if (load_gatt_db_impl(key_file, keys, device->db))
6567                 warn("Unable to load gatt db from file for %s", peer);
6568
6569         g_strfreev(keys);
6570         g_key_file_free(key_file);
6571
6572         g_slist_free_full(device->primaries, g_free);
6573         device->primaries = NULL;
6574         gatt_db_foreach_service(device->db, NULL, add_primary,
6575                                                         &device->primaries);
6576 }
6577
6578 static void device_add_uuids(struct btd_device *device, GSList *uuids)
6579 {
6580         GSList *l;
6581         bool changed = false;
6582
6583         for (l = uuids; l != NULL; l = g_slist_next(l)) {
6584                 GSList *match = g_slist_find_custom(device->uuids, l->data,
6585                                                         bt_uuid_strcmp);
6586                 if (match)
6587                         continue;
6588
6589                 changed = true;
6590                 device->uuids = g_slist_insert_sorted(device->uuids,
6591                                                 g_strdup(l->data),
6592                                                 bt_uuid_strcmp);
6593         }
6594
6595         if (changed)
6596                 g_dbus_emit_property_changed(dbus_conn, device->path,
6597                                                 DEVICE_INTERFACE, "UUIDs");
6598 }
6599
6600 static bool device_match_profile(struct btd_device *device,
6601                                         struct btd_profile *profile,
6602                                         GSList *uuids)
6603 {
6604         if (profile->remote_uuid == NULL)
6605                 return false;
6606
6607         if (g_slist_find_custom(uuids, profile->remote_uuid,
6608                                                         bt_uuid_strcmp) == NULL) {
6609 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
6610                 if (strcmp(profile->name, "hid-device") == 0)
6611                         return true;
6612 #endif
6613                 return false;
6614         }
6615
6616         return true;
6617 }
6618
6619 static void add_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6620 {
6621         struct btd_device *device = user_data;
6622         struct btd_service *service;
6623         struct btd_profile *profile;
6624         bt_uuid_t uuid;
6625         char uuid_str[MAX_LEN_UUID_STR];
6626         GSList *l;
6627
6628         gatt_db_attribute_get_service_uuid(attr, &uuid);
6629         bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6630
6631         /* Check if service was already probed */
6632         l = find_service_with_uuid(device->services, uuid_str);
6633         if (l)
6634                 goto done;
6635
6636         /* Add UUID and probe service */
6637         btd_device_add_uuid(device, uuid_str);
6638
6639         /* Check if service was probed */
6640         l = find_service_with_uuid(device->services, uuid_str);
6641         if (!l)
6642                 return;
6643
6644 done:
6645         /* Mark service as active to skip discovering it again */
6646         gatt_db_service_set_active(attr, true);
6647
6648         service = l->data;
6649         profile = btd_service_get_profile(service);
6650
6651         /* Claim attributes of internal profiles */
6652         if (!profile->external) {
6653                 /* Mark the service as claimed by the existing profile. */
6654                 gatt_db_service_set_claimed(attr, true);
6655         }
6656
6657         /* Notify driver about the new connection */
6658         service_accept(service);
6659 }
6660
6661 static void device_add_gatt_services(struct btd_device *device)
6662 {
6663         char addr[18];
6664
6665         ba2str(&device->bdaddr, addr);
6666
6667         if (device->blocked) {
6668                 DBG("Skipping profiles for blocked device %s", addr);
6669                 return;
6670         }
6671
6672         gatt_db_foreach_service(device->db, NULL, add_gatt_service, device);
6673 }
6674
6675 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6676 static void accept_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6677 {
6678         struct btd_device *device = user_data;
6679         GSList *l;
6680         bt_uuid_t uuid;
6681         char uuid_str[MAX_LEN_UUID_STR];
6682
6683         gatt_db_attribute_get_service_uuid(attr, &uuid);
6684         bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6685
6686         l = find_service_with_uuid(device->services, uuid_str);
6687         if (!l)
6688                 return;
6689
6690         service_accept(l->data);
6691 }
6692 #endif
6693
6694 static void device_accept_gatt_profiles(struct btd_device *device)
6695 {
6696 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6697         GSList *l;
6698
6699         for (l = device->services; l != NULL; l = g_slist_next(l))
6700                 service_accept(l->data);
6701 #else
6702         gatt_db_foreach_service(device->db, NULL, accept_gatt_service, device);
6703 #endif
6704 }
6705
6706 static void device_remove_gatt_service(struct btd_device *device,
6707                                                 struct gatt_db_attribute *attr)
6708 {
6709         struct btd_service *service;
6710         bt_uuid_t uuid;
6711         char uuid_str[MAX_LEN_UUID_STR];
6712         GSList *l;
6713
6714         gatt_db_attribute_get_service_uuid(attr, &uuid);
6715         bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6716
6717         l = find_service_with_uuid(device->services, uuid_str);
6718         if (!l)
6719                 return;
6720
6721         service = l->data;
6722         device->services = g_slist_delete_link(device->services, l);
6723         device->pending = g_slist_remove(device->pending, service);
6724         service_remove(service);
6725 }
6726
6727 static gboolean gatt_services_changed(gpointer user_data)
6728 {
6729         struct btd_device *device = user_data;
6730
6731         store_gatt_db(device);
6732
6733         return FALSE;
6734 }
6735
6736 static void gatt_service_added(struct gatt_db_attribute *attr, void *user_data)
6737 {
6738         struct btd_device *device = user_data;
6739         GSList *new_service = NULL;
6740         uint16_t start, end;
6741
6742         if (!bt_gatt_client_is_ready(device->client))
6743                 return;
6744
6745         gatt_db_attribute_get_service_data(attr, &start, &end, NULL, NULL);
6746
6747         DBG("start: 0x%04x, end: 0x%04x", start, end);
6748
6749         /*
6750          * TODO: Remove the primaries list entirely once all profiles use
6751          * shared/gatt.
6752          */
6753         add_primary(attr, &new_service);
6754         if (!new_service)
6755                 return;
6756
6757         device_register_primaries(device, new_service, -1);
6758
6759         add_gatt_service(attr, device);
6760
6761         btd_gatt_client_service_added(device->client_dbus, attr);
6762
6763         gatt_services_changed(device);
6764 }
6765
6766 static gint prim_attr_cmp(gconstpointer a, gconstpointer b)
6767 {
6768         const struct gatt_primary *prim = a;
6769         const struct gatt_db_attribute *attr = b;
6770         uint16_t start, end;
6771
6772         gatt_db_attribute_get_service_handles(attr, &start, &end);
6773
6774         return !(prim->range.start == start && prim->range.end == end);
6775 }
6776
6777 static gint prim_uuid_cmp(gconstpointer a, gconstpointer b)
6778 {
6779         const struct gatt_primary *prim = a;
6780         const char *uuid = b;
6781
6782         return bt_uuid_strcmp(prim->uuid, uuid);
6783 }
6784
6785 static void gatt_service_removed(struct gatt_db_attribute *attr,
6786                                                                 void *user_data)
6787 {
6788         struct btd_device *device = user_data;
6789         GSList *l;
6790         struct gatt_primary *prim;
6791         uint16_t start, end;
6792
6793         /*
6794          * NOTE: shared/gatt-client clears the database in case of failure. This
6795          * triggers the service_removed callback for all affected services.
6796          * Hence, this function will be called in the following cases:
6797          *
6798          *    1. When a GATT service gets removed due to "Service Changed".
6799          *
6800          *    2. When a GATT service gets removed when the database get cleared
6801          *       upon disconnection with a non-bonded device.
6802          *
6803          *    3. When a GATT service gets removed when the database get cleared
6804          *       by shared/gatt-client when its initialization procedure fails,
6805          *       e.g. due to an ATT protocol error or an unexpected disconnect.
6806          *       In this case the gatt-client will not be ready.
6807          */
6808
6809         gatt_db_attribute_get_service_handles(attr, &start, &end);
6810
6811         DBG("start: 0x%04x, end: 0x%04x", start, end);
6812
6813         /* Remove the corresponding gatt_primary */
6814         l = g_slist_find_custom(device->primaries, attr, prim_attr_cmp);
6815         if (!l)
6816                 return;
6817
6818         prim = l->data;
6819         device->primaries = g_slist_delete_link(device->primaries, l);
6820
6821         /*
6822          * Remove the corresponding UUIDs entry and profile, only if this is
6823          * the last service with this UUID.
6824          */
6825         l = g_slist_find_custom(device->uuids, prim->uuid, bt_uuid_strcmp);
6826
6827         if (l && !g_slist_find_custom(device->primaries, prim->uuid,
6828                                                         prim_uuid_cmp)) {
6829                 /*
6830                  * If this happend since the db was cleared for a non-bonded
6831                  * device, then don't remove the btd_service just yet. We do
6832                  * this so that we can avoid re-probing the profile if the same
6833                  * GATT service is found on the device on re-connection.
6834                  * However, if the device is marked as temporary, then we
6835                  * remove it anyway.
6836                  */
6837                 if (device->client || device->temporary == TRUE)
6838                         device_remove_gatt_service(device, attr);
6839
6840                 g_free(l->data);
6841                 device->uuids = g_slist_delete_link(device->uuids, l);
6842                 g_dbus_emit_property_changed(dbus_conn, device->path,
6843                                                 DEVICE_INTERFACE, "UUIDs");
6844         }
6845
6846         g_free(prim);
6847
6848         store_device_info(device);
6849
6850         btd_gatt_client_service_removed(device->client_dbus, attr);
6851
6852         gatt_services_changed(device);
6853 }
6854
6855 static struct btd_device *device_new(struct btd_adapter *adapter,
6856                                 const char *address)
6857 {
6858         char *address_up;
6859         struct btd_device *device;
6860         const char *adapter_path = adapter_get_path(adapter);
6861
6862 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6863         DBG("address %s", address);
6864 #endif
6865
6866         device = g_try_malloc0(sizeof(struct btd_device));
6867         if (device == NULL)
6868                 return NULL;
6869
6870         device->tx_power = 127;
6871
6872         device->db = gatt_db_new();
6873         if (!device->db) {
6874                 g_free(device);
6875                 return NULL;
6876         }
6877
6878         memset(device->ad_flags, INVALID_FLAGS, sizeof(device->ad_flags));
6879
6880         device->ad = bt_ad_new();
6881         if (!device->ad) {
6882                 device_free(device);
6883                 return NULL;
6884         }
6885
6886         address_up = g_ascii_strup(address, -1);
6887         device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
6888         g_strdelimit(device->path, ":", '_');
6889         g_free(address_up);
6890
6891         str2ba(address, &device->bdaddr);
6892
6893         device->client_dbus = btd_gatt_client_new(device);
6894         if (!device->client_dbus) {
6895                 error("Failed to create btd_gatt_client");
6896                 device_free(device);
6897                 return NULL;
6898         }
6899
6900         DBG("Creating device %s", device->path);
6901
6902         if (g_dbus_register_interface(dbus_conn,
6903                                         device->path, DEVICE_INTERFACE,
6904 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6905                                         device_methods, device_signals,
6906 #else
6907                                         device_methods, NULL,
6908 #endif
6909                                         device_properties, device,
6910                                         device_free) == FALSE) {
6911                 error("Unable to register device interface for %s", address);
6912                 device_free(device);
6913                 return NULL;
6914         }
6915
6916         device->adapter = adapter;
6917         device->temporary = true;
6918
6919         device->db_id = gatt_db_register(device->db, gatt_service_added,
6920                                         gatt_service_removed, device, NULL);
6921
6922         device->refresh_discovery = btd_opts.refresh_discovery;
6923
6924         return btd_device_ref(device);
6925 }
6926
6927 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6928 void device_print_addr(struct btd_device *dev)
6929 {
6930         char ida[18];
6931         char rpa[18];
6932
6933         ba2str(&dev->bdaddr, ida);
6934
6935         if (dev->rpa) {
6936                 ba2str(dev->rpa, rpa);
6937
6938                 DBG("IDA %s [%d] : RPA [%s], BREDR [%d], LE [%d]",
6939                                 ida, dev->bdaddr_type, rpa,
6940                                 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6941         } else {
6942                 DBG("ADDR %s [%d] : BREDR [%d], LE [%d]",
6943                                 ida, dev->bdaddr_type,
6944                                 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6945         }
6946 }
6947 #endif
6948
6949 struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
6950                                 const char *address, GKeyFile *key_file)
6951 {
6952         struct btd_device *device;
6953         const char *src_dir;
6954
6955         DBG("address %s", address);
6956
6957         device = device_new(adapter, address);
6958         if (device == NULL)
6959                 return NULL;
6960
6961         convert_info(device, key_file);
6962
6963         src_dir = btd_adapter_get_storage_dir(adapter);
6964
6965         load_info(device, src_dir, address, key_file);
6966         load_att_info(device, src_dir, address);
6967
6968         return device;
6969 }
6970
6971 struct btd_device *device_create(struct btd_adapter *adapter,
6972                                 const bdaddr_t *bdaddr, uint8_t bdaddr_type)
6973 {
6974         struct btd_device *device;
6975         char dst[18];
6976         char *str;
6977         const char *storage_dir;
6978
6979         ba2str(bdaddr, dst);
6980         DBG("dst %s", dst);
6981
6982         device = device_new(adapter, dst);
6983         if (device == NULL)
6984                 return NULL;
6985
6986         device->bdaddr_type = bdaddr_type;
6987
6988         if (bdaddr_type == BDADDR_BREDR)
6989                 device->bredr = true;
6990         else
6991                 device->le = true;
6992
6993         storage_dir = btd_adapter_get_storage_dir(adapter);
6994         str = load_cached_name(device, storage_dir, dst);
6995         if (str) {
6996                 strcpy(device->name, str);
6997                 g_free(str);
6998         }
6999
7000         load_cached_name_resolve(device, storage_dir, dst);
7001
7002         return device;
7003 }
7004
7005 char *btd_device_get_storage_path(struct btd_device *device,
7006                                 const char *filename)
7007 {
7008         char dstaddr[18];
7009
7010         if (device_address_is_private(device)) {
7011                 warn("Refusing storage path for private addressed device %s",
7012                                                                 device->path);
7013                 return NULL;
7014         }
7015
7016         ba2str(&device->bdaddr, dstaddr);
7017
7018 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7019         if (device->rpa)
7020                 ba2str(device->rpa, dstaddr);
7021 #endif
7022
7023         if (!filename)
7024                 return g_strdup_printf(STORAGEDIR "/%s/%s",
7025                                 btd_adapter_get_storage_dir(device->adapter),
7026                                 dstaddr);
7027
7028         return g_strdup_printf(STORAGEDIR "/%s/%s/%s",
7029                                 btd_adapter_get_storage_dir(device->adapter),
7030                                 dstaddr, filename);
7031 }
7032
7033 void btd_device_device_set_name(struct btd_device *device, const char *name)
7034 {
7035         if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
7036                 return;
7037
7038         DBG("%s %s", device->path, name);
7039
7040         strncpy(device->name, name, MAX_NAME_LENGTH);
7041
7042         store_device_info(device);
7043
7044         g_dbus_emit_property_changed(dbus_conn, device->path,
7045                                                 DEVICE_INTERFACE, "Name");
7046
7047         if (device->alias != NULL)
7048                 return;
7049
7050         g_dbus_emit_property_changed(dbus_conn, device->path,
7051                                                 DEVICE_INTERFACE, "Alias");
7052 }
7053
7054 void device_get_name(struct btd_device *device, char *name, size_t len)
7055 {
7056         if (name != NULL && len > 0) {
7057                 strncpy(name, device->name, len - 1);
7058                 name[len - 1] = '\0';
7059         }
7060 }
7061
7062 bool device_name_known(struct btd_device *device)
7063 {
7064         return device->name[0] != '\0';
7065 }
7066
7067 bool device_is_name_resolve_allowed(struct btd_device *device)
7068 {
7069         struct timespec now;
7070
7071         if (!device)
7072                 return false;
7073
7074         clock_gettime(CLOCK_MONOTONIC, &now);
7075
7076         /* If now < failed_time, it means the clock has somehow turned back,
7077          * possibly because of system restart. Allow name request in this case.
7078          */
7079         return now.tv_sec < device->name_resolve_failed_time ||
7080                 now.tv_sec >= device->name_resolve_failed_time +
7081                                         btd_opts.name_request_retry_delay;
7082 }
7083
7084 void device_name_resolve_fail(struct btd_device *device)
7085 {
7086         struct timespec now;
7087
7088         if (!device)
7089                 return;
7090
7091         clock_gettime(CLOCK_MONOTONIC, &now);
7092         device->name_resolve_failed_time = now.tv_sec;
7093         device_store_cached_name_resolve(device);
7094 }
7095
7096 void device_set_class(struct btd_device *device, uint32_t class)
7097 {
7098         if (device->class == class)
7099                 return;
7100
7101         DBG("%s 0x%06X", device->path, class);
7102
7103         device->class = class;
7104
7105         store_device_info(device);
7106
7107         g_dbus_emit_property_changed(dbus_conn, device->path,
7108                                                 DEVICE_INTERFACE, "Class");
7109         g_dbus_emit_property_changed(dbus_conn, device->path,
7110                                                 DEVICE_INTERFACE, "Icon");
7111 }
7112
7113 void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
7114                                                         uint8_t bdaddr_type)
7115 {
7116         bool auto_connect = device->auto_connect;
7117
7118         if (!bacmp(bdaddr, &device->bdaddr) &&
7119                                         bdaddr_type == device->bdaddr_type)
7120                 return;
7121
7122         /* Since this function is only used for LE SMP Identity
7123          * Resolving purposes we can now assume LE is supported.
7124          */
7125         device->le = true;
7126
7127         /* Remove old address from accept/auto-connect list since its address
7128          * will be changed.
7129          */
7130         if (auto_connect)
7131                 device_set_auto_connect(device, FALSE);
7132
7133         bacpy(&device->bdaddr, bdaddr);
7134         device->bdaddr_type = bdaddr_type;
7135
7136         store_device_info(device);
7137
7138         g_dbus_emit_property_changed(dbus_conn, device->path,
7139                                                 DEVICE_INTERFACE, "Address");
7140         g_dbus_emit_property_changed(dbus_conn, device->path,
7141                                         DEVICE_INTERFACE, "AddressType");
7142
7143         if (auto_connect)
7144                 device_set_auto_connect(device, TRUE);
7145 }
7146
7147 void device_set_bredr_support(struct btd_device *device)
7148 {
7149 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7150         char addr_str[18];
7151
7152         if (device->rpa) {
7153                 ba2str(device->rpa, addr_str);
7154                 error("Cannot set bredr support to RPA device [%s]", addr_str);
7155                 return;
7156         }
7157
7158         if (device->bdaddr_type == BDADDR_LE_RANDOM) {
7159                 ba2str(&device->bdaddr, addr_str);
7160                 error("Cannot set bredr support to LE random device [%s]",
7161                                                                 addr_str);
7162                 return;
7163         }
7164 #endif
7165
7166         if (device->bredr)
7167                 return;
7168
7169         device->bredr = true;
7170         store_device_info(device);
7171 }
7172
7173 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7174 void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa)
7175 {
7176         if (device->rpa == NULL) {
7177                 device->rpa = g_malloc0(sizeof(bdaddr_t));
7178                 bacpy(device->rpa, rpa);
7179         } else
7180                 error("RPA is already set");
7181 }
7182
7183 void device_set_irk_value(struct btd_device *device, const uint8_t *val)
7184 {
7185         memcpy(&device->irk_val, val, sizeof(device->irk_val));
7186 }
7187 #endif
7188
7189 void device_set_le_support(struct btd_device *device, uint8_t bdaddr_type)
7190 {
7191         if (device->le)
7192                 return;
7193
7194         device->le = true;
7195         device->bdaddr_type = bdaddr_type;
7196
7197         store_device_info(device);
7198 }
7199
7200 static bool device_disappeared(gpointer user_data)
7201 {
7202         struct btd_device *dev = user_data;
7203
7204 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7205         if (dev->le_state.connected) {
7206                 DBG("GATT connection exists, don't remove the device");
7207                 return FALSE;
7208         }
7209 #endif
7210
7211         dev->temporary_timer = 0;
7212
7213         btd_adapter_remove_device(dev->adapter, dev);
7214
7215         return FALSE;
7216 }
7217
7218 static void set_temporary_timer(struct btd_device *dev, unsigned int timeout)
7219 {
7220         clear_temporary_timer(dev);
7221
7222         if (!timeout)
7223                 return;
7224
7225         dev->temporary_timer = timeout_add_seconds(timeout, device_disappeared,
7226                                                                 dev, NULL);
7227 }
7228
7229 void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type)
7230 {
7231         if (bdaddr_type == BDADDR_BREDR)
7232                 device->bredr_seen = time(NULL);
7233         else
7234                 device->le_seen = time(NULL);
7235
7236         if (!device_is_temporary(device))
7237                 return;
7238
7239         /* Restart temporary timer */
7240         set_temporary_timer(device, btd_opts.tmpto);
7241 }
7242
7243 /* It is possible that we have two device objects for the same device in
7244  * case it has first been discovered over BR/EDR and has a private
7245  * address when discovered over LE for the first time. In such a case we
7246  * need to inherit critical values from the duplicate so that we don't
7247  * ovewrite them when writing to storage. The next time bluetoothd
7248  * starts the device will show up as a single instance.
7249  */
7250 void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup)
7251 {
7252         GSList *l;
7253
7254         DBG("");
7255
7256         dev->bredr = dup->bredr;
7257
7258         dev->trusted = dup->trusted;
7259         dev->blocked = dup->blocked;
7260
7261         for (l = dup->uuids; l; l = g_slist_next(l))
7262                 dev->uuids = g_slist_append(dev->uuids, g_strdup(l->data));
7263
7264         if (dev->name[0] == '\0')
7265                 strcpy(dev->name, dup->name);
7266
7267         if (!dev->alias)
7268                 dev->alias = g_strdup(dup->alias);
7269
7270         dev->class = dup->class;
7271
7272         dev->vendor_src = dup->vendor_src;
7273         dev->vendor = dup->vendor;
7274         dev->product = dup->product;
7275         dev->version = dup->version;
7276 }
7277
7278 uint32_t btd_device_get_class(struct btd_device *device)
7279 {
7280         return device->class;
7281 }
7282
7283 uint16_t btd_device_get_vendor(struct btd_device *device)
7284 {
7285         return device->vendor;
7286 }
7287
7288 uint16_t btd_device_get_vendor_src(struct btd_device *device)
7289 {
7290         return device->vendor_src;
7291 }
7292
7293 uint16_t btd_device_get_product(struct btd_device *device)
7294 {
7295         return device->product;
7296 }
7297
7298 uint16_t btd_device_get_version(struct btd_device *device)
7299 {
7300         return device->version;
7301 }
7302
7303 static void delete_folder_tree(const char *dirname)
7304 {
7305         DIR *dir;
7306         struct dirent *entry;
7307         char filename[PATH_MAX];
7308
7309         dir = opendir(dirname);
7310         if (dir == NULL)
7311                 return;
7312
7313         while ((entry = readdir(dir)) != NULL) {
7314                 if (g_str_equal(entry->d_name, ".") ||
7315                                 g_str_equal(entry->d_name, ".."))
7316                         continue;
7317
7318                 if (entry->d_type == DT_UNKNOWN)
7319                         entry->d_type = util_get_dt(dirname, entry->d_name);
7320
7321                 snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
7322
7323                 if (entry->d_type == DT_DIR)
7324                         delete_folder_tree(filename);
7325                 else
7326                         unlink(filename);
7327         }
7328         closedir(dir);
7329
7330         rmdir(dirname);
7331 }
7332
7333 void device_remove_bonding(struct btd_device *device, uint8_t bdaddr_type)
7334 {
7335         if (bdaddr_type == BDADDR_BREDR)
7336                 device->bredr_state.bonded = false;
7337         else
7338                 device->le_state.bonded = false;
7339
7340         if (!device->bredr_state.bonded && !device->le_state.bonded)
7341                 btd_device_set_temporary(device, true);
7342
7343         btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
7344                                                         bdaddr_type);
7345 }
7346
7347 static void device_remove_stored(struct btd_device *device)
7348 {
7349         char device_addr[18];
7350         char filename[PATH_MAX];
7351         GKeyFile *key_file;
7352         GError *gerr = NULL;
7353         char *data;
7354         gsize length = 0;
7355
7356         if (device->bredr_state.bonded)
7357                 device_remove_bonding(device, BDADDR_BREDR);
7358
7359         if (device->le_state.bonded)
7360                 device_remove_bonding(device, device->bdaddr_type);
7361
7362         device->bredr_state.paired = false;
7363         device->le_state.paired = false;
7364
7365         if (device->blocked)
7366                 device_unblock(device, TRUE, FALSE);
7367
7368         ba2str(&device->bdaddr, device_addr);
7369
7370 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7371         if (device->rpa)
7372                 ba2str(device->rpa, device_addr);
7373 #endif
7374
7375         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s",
7376                                 btd_adapter_get_storage_dir(device->adapter),
7377                                 device_addr);
7378         delete_folder_tree(filename);
7379
7380         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
7381                                 btd_adapter_get_storage_dir(device->adapter),
7382                                 device_addr);
7383
7384         key_file = g_key_file_new();
7385         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
7386                 g_error_free(gerr);
7387                 g_key_file_free(key_file);
7388                 return;
7389         }
7390         g_key_file_remove_group(key_file, "ServiceRecords", NULL);
7391         g_key_file_remove_group(key_file, "Attributes", NULL);
7392
7393         data = g_key_file_to_data(key_file, &length, NULL);
7394         if (length > 0) {
7395                 create_file(filename, 0600);
7396                 if (!g_file_set_contents(filename, data, length, &gerr)) {
7397                         error("Unable set contents for %s: (%s)", filename,
7398                                                                 gerr->message);
7399                         g_error_free(gerr);
7400                 }
7401         }
7402
7403         g_free(data);
7404         g_key_file_free(key_file);
7405 }
7406
7407 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7408 void device_unpair(struct btd_device *device, gboolean remove_stored)
7409 {
7410         DBG("+");
7411         DBG("Unpairing device %s", device->path);
7412
7413         if (device->bonding) {
7414                 uint8_t status;
7415
7416                 if (device->bredr_state.connected)
7417                         status = MGMT_STATUS_DISCONNECTED;
7418                 else
7419                         status = MGMT_STATUS_CONNECT_FAILED;
7420
7421                 device_cancel_bonding(device, status);
7422         }
7423
7424         if (device->browse)
7425                 browse_request_cancel(device->browse);
7426
7427
7428         //      while (device->services != NULL) {
7429         //              struct btd_service *service = device->services->data;
7430         //
7431         //              device->services = g_slist_remove(device->services, service);
7432         //              service_remove(service);
7433         //      }
7434
7435         g_slist_free(device->pending);
7436         device->pending = NULL;
7437
7438         if (btd_device_is_connected(device))
7439                 disconnect_all(device);
7440
7441         if (device->store_id > 0) {
7442                 g_source_remove(device->store_id);
7443                 device->store_id = 0;
7444
7445                 if (!remove_stored)
7446                         store_device_info_cb(device);
7447         }
7448
7449         if (remove_stored)
7450                 device_remove_stored(device);
7451
7452         gatt_db_clear(device->db);
7453
7454         if (device->rpa) {
7455                 bacpy(&device->bdaddr, device->rpa);
7456                 device->bdaddr_type = BDADDR_LE_RANDOM;
7457
7458                 g_free(device->rpa);
7459                 device->rpa = NULL;
7460         }
7461
7462         device->bredr_state.paired = 0;
7463         device->le_state.paired = 0;
7464         device->bredr_state.svc_resolved = false;
7465         device->trusted = false;
7466         device->trusted_profiles.pbap = SHOW_AUTHORIZATION;
7467         device->trusted_profiles.map = SHOW_AUTHORIZATION;
7468         device->trusted_profiles.sap = SHOW_AUTHORIZATION;
7469         if (TIZEN_MODEL_DA) {
7470                 device->trusted_profiles.hfp_hs = SHOW_AUTHORIZATION;
7471                 device->trusted_profiles.a2dp = SHOW_AUTHORIZATION;
7472         } else {
7473                 device->trusted_profiles.hfp_hs = SUPPORTED_TRUSTED;
7474                 device->trusted_profiles.a2dp = SUPPORTED_TRUSTED;
7475         }
7476         if (device->alias != NULL) {
7477                 /* Remove alias name because
7478                  * In UG if we rename and then unpair device and
7479                  * initiates connection without scanning then paired
7480                  * list will have alias name as first preference is
7481                  * given to alias name.
7482                  */
7483                 DBG("Freeing device alias name");
7484                 g_free(device->alias);
7485                 device->alias = NULL;
7486         }
7487         g_dbus_emit_property_changed(dbus_conn, device->path,
7488                         DEVICE_INTERFACE, "Paired");
7489         //      btd_device_unref(device);
7490         DBG("-");
7491 }
7492
7493 void device_remove_stored_folder(struct btd_device *device)
7494 {
7495         const bdaddr_t *src = btd_adapter_get_address(device->adapter);
7496         char adapter_addr[18];
7497         char device_addr[18];
7498         char filename[PATH_MAX];
7499
7500         ba2str(src, adapter_addr);
7501         ba2str(&device->bdaddr, device_addr);
7502
7503         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
7504                         device_addr);
7505
7506         delete_folder_tree(filename);
7507 }
7508 #endif
7509
7510 void device_remove(struct btd_device *device, gboolean remove_stored)
7511 {
7512         DBG("Removing device %s", device->path);
7513
7514         if (device->auto_connect) {
7515                 device->disable_auto_connect = TRUE;
7516                 device_set_auto_connect(device, FALSE);
7517         }
7518
7519         if (device->bonding) {
7520                 uint8_t status;
7521
7522                 if (device->bredr_state.connected)
7523                         status = MGMT_STATUS_DISCONNECTED;
7524                 else
7525                         status = MGMT_STATUS_CONNECT_FAILED;
7526
7527                 device_cancel_bonding(device, status);
7528         }
7529
7530         if (device->browse)
7531                 browse_request_cancel(device->browse);
7532
7533         while (device->services != NULL) {
7534                 struct btd_service *service = device->services->data;
7535
7536                 device->services = g_slist_remove(device->services, service);
7537                 service_remove(service);
7538         }
7539
7540         g_slist_free(device->pending);
7541         device->pending = NULL;
7542
7543         if (btd_device_is_connected(device)) {
7544                 if (device->disconn_timer > 0)
7545                         timeout_remove(device->disconn_timer);
7546                 disconnect_all(device);
7547         }
7548
7549         clear_temporary_timer(device);
7550
7551         if (device->store_id > 0) {
7552                 g_source_remove(device->store_id);
7553                 device->store_id = 0;
7554
7555                 if (!remove_stored)
7556                         store_device_info_cb(device);
7557         }
7558
7559         if (remove_stored)
7560                 device_remove_stored(device);
7561
7562         btd_device_unref(device);
7563 }
7564
7565 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7566 int device_rpa_cmp(gconstpointer a, gconstpointer b)
7567 {
7568         const struct btd_device *device = a;
7569         const char *address = b;
7570         char addr[18];
7571
7572         if (!device->rpa)
7573                 return -1;
7574
7575         ba2str(device->rpa, addr);
7576
7577         return strcasecmp(addr, address);
7578 }
7579
7580 int device_addr_cmp(gconstpointer a, gconstpointer b)
7581 {
7582         const struct btd_device *device = a;
7583         const bdaddr_t *bdaddr = b;
7584
7585         return bacmp(&device->bdaddr, bdaddr);
7586 }
7587
7588 int device_rpa_ida_cmp(gconstpointer a, gconstpointer b)
7589 {
7590         const struct btd_device *device = a;
7591         const char *address = b;
7592         char addr[18];
7593
7594         if (!device->rpa || device->le == false)
7595                 return -1;
7596
7597         ba2str(&device->bdaddr, addr);
7598         return strcasecmp(addr, address);
7599 }
7600 #endif
7601
7602 int device_address_cmp(gconstpointer a, gconstpointer b)
7603 {
7604         const struct btd_device *device = a;
7605         const char *address = b;
7606         char addr[18];
7607
7608         ba2str(&device->bdaddr, addr);
7609         return strcasecmp(addr, address);
7610 }
7611
7612 int device_bdaddr_cmp(gconstpointer a, gconstpointer b)
7613 {
7614         const struct btd_device *device = a;
7615         const bdaddr_t *bdaddr = b;
7616
7617         return bacmp(&device->bdaddr, bdaddr);
7618 }
7619
7620 static bool addr_is_public(uint8_t addr_type)
7621 {
7622         if (addr_type == BDADDR_BREDR || addr_type == BDADDR_LE_PUBLIC)
7623                 return true;
7624
7625         return false;
7626 }
7627
7628 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7629 int device_addr_type_strict_cmp(gconstpointer a, gconstpointer b)
7630 {
7631         const struct btd_device *dev = a;
7632         const struct device_addr_type *addr = b;
7633         int cmp;
7634
7635         cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7636
7637         if (addr->bdaddr_type == BDADDR_BREDR) {
7638                 if (!dev->bredr)
7639                         return -1;
7640
7641                 return cmp;
7642         }
7643
7644         if (!dev->le)
7645                 return -1;
7646
7647         if (cmp && dev->rpa && addr->bdaddr_type == BDADDR_LE_RANDOM &&
7648                         (addr->bdaddr.b[5] >> 6) == 0x01)
7649                 return bacmp(dev->rpa, &addr->bdaddr);
7650
7651         if (addr->bdaddr_type != dev->bdaddr_type)
7652                 return -1;
7653
7654         return cmp;
7655 }
7656 #endif
7657
7658 int device_addr_type_cmp(gconstpointer a, gconstpointer b)
7659 {
7660         const struct btd_device *dev = a;
7661         const struct device_addr_type *addr = b;
7662         int cmp;
7663
7664         cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7665
7666         /*
7667          * Address matches and both old and new are public addresses
7668          * (doesn't matter whether LE or BR/EDR, then consider this a
7669          * match.
7670          */
7671         if (!cmp && addr_is_public(addr->bdaddr_type) &&
7672                                         addr_is_public(dev->bdaddr_type))
7673 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7674         {
7675                 if (dev->rpa && addr->bdaddr_type == BDADDR_BREDR) {
7676                         char addr_str[18];
7677
7678                         ba2str(&dev->bdaddr, addr_str);
7679                         DBG("Don't match. LE Only device [%s]", addr_str);
7680                         return -1;
7681                 }
7682                 return 0;
7683         }
7684 #else
7685                 return 0;
7686 #endif
7687
7688         if (addr->bdaddr_type == BDADDR_BREDR) {
7689                 if (!dev->bredr)
7690                         return -1;
7691
7692                 return cmp;
7693         }
7694
7695         if (!dev->le)
7696                 return -1;
7697
7698         if (addr->bdaddr_type != dev->bdaddr_type) {
7699                 if (addr->bdaddr_type == dev->conn_bdaddr_type)
7700                         return bacmp(&dev->conn_bdaddr, &addr->bdaddr);
7701                 return -1;
7702         }
7703
7704         return cmp;
7705 }
7706
7707 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7708 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
7709 void device_change_pkt_type(gpointer data, gpointer user_data)
7710 {
7711         int pkt_type = (int)user_data;
7712         struct btd_device *device = data;
7713         struct hci_conn_info_req *cr;
7714         set_conn_ptype_cp cp;
7715         char addr[18];
7716         int hdev = 0;
7717         int err = 0;
7718
7719         /* Change a packet type only for Phone device */
7720         if ((device->class & 0x00001F00) >> 8 != 0x02)
7721                 return;
7722
7723         if (!device->bredr_state.connected)
7724                 return;
7725
7726         hdev = hci_open_dev(0);
7727         if (hdev < 0) {
7728                 error("Cannot open hdev");
7729                 return;
7730         }
7731
7732         cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
7733         if (cr == NULL) {
7734                 error("Out of memory");
7735                 return;
7736         }
7737         cr->type = ACL_LINK;
7738         bacpy(&cr->bdaddr, &device->bdaddr);
7739
7740         err = ioctl(hdev, HCIGETCONNINFO, cr);
7741         if (err < 0) {
7742                 error("Fail to get HCIGETCOINFO");
7743                 g_free(cr);
7744                 hci_close_dev(hdev);
7745                 return;
7746         }
7747
7748         cp.handle = cr->conn_info->handle;
7749         g_free(cr);
7750         cp.pkt_type = cpu_to_le16((uint16_t)pkt_type);
7751
7752         ba2str(&device->bdaddr, addr);
7753         DBG("Handle %d, Addr %s", cp.handle, addr);
7754         DBG("Send Change pkt type request : 0x%X", pkt_type);
7755
7756         if (hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SET_CONN_PTYPE,
7757                                 SET_CONN_PTYPE_CP_SIZE, &cp) < 0) {
7758                 error("hci_send_cmd is failed");
7759                 hci_close_dev(hdev);
7760                 return;
7761         }
7762
7763         hci_close_dev(hdev);
7764         return;
7765 }
7766 #endif  /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
7767 #endif
7768
7769 static gboolean record_has_uuid(const sdp_record_t *rec,
7770                                 const char *profile_uuid)
7771 {
7772         sdp_list_t *pat;
7773
7774         for (pat = rec->pattern; pat != NULL; pat = pat->next) {
7775                 char *uuid;
7776                 int ret;
7777
7778                 uuid = bt_uuid2string(pat->data);
7779                 if (!uuid)
7780                         continue;
7781
7782                 ret = strcasecmp(uuid, profile_uuid);
7783
7784                 free(uuid);
7785
7786                 if (ret == 0)
7787                         return TRUE;
7788         }
7789
7790         return FALSE;
7791 }
7792
7793 GSList *btd_device_get_uuids(struct btd_device *device)
7794 {
7795         return device->uuids;
7796 }
7797
7798 struct probe_data {
7799         struct btd_device *dev;
7800         GSList *uuids;
7801 };
7802
7803 static struct btd_service *probe_service(struct btd_device *device,
7804                                                 struct btd_profile *profile,
7805                                                 GSList *uuids)
7806 {
7807         GSList *l;
7808         struct btd_service *service;
7809
7810         if (profile->device_probe == NULL)
7811                 return NULL;
7812
7813         if (!device_match_profile(device, profile, uuids))
7814                 return NULL;
7815
7816         l = find_service_with_profile(device->services, profile);
7817         /* If the service already exists, return NULL so that it won't be added
7818          * to the device->services.
7819          */
7820         if (l)
7821                 return NULL;
7822
7823         service = service_create(device, profile);
7824
7825         if (service_probe(service)) {
7826                 btd_service_unref(service);
7827                 return NULL;
7828         }
7829
7830         /* Only set auto connect if profile has set the flag and can really
7831          * accept connections.
7832          */
7833 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
7834         if (profile->auto_connect && profile->accept)
7835                 device_set_auto_connect(device, TRUE);
7836 #endif
7837
7838         return service;
7839 }
7840
7841 static void dev_probe(struct btd_profile *p, void *user_data)
7842 {
7843         struct probe_data *d = user_data;
7844         struct btd_service *service;
7845
7846 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7847         if (find_service_with_profile(d->dev->services, p)) {
7848                 DBG("%s is already probed.(UUID:%s)", p->name, p->remote_uuid);
7849                 return;
7850         }
7851 #endif
7852
7853         service = probe_service(d->dev, p, d->uuids);
7854         if (!service)
7855                 return;
7856
7857         d->dev->services = g_slist_append(d->dev->services, service);
7858 }
7859
7860 void device_probe_profile(gpointer a, gpointer b)
7861 {
7862         struct btd_device *device = a;
7863         struct btd_profile *profile = b;
7864         struct btd_service *service;
7865
7866         service = probe_service(device, profile, device->uuids);
7867         if (!service)
7868                 return;
7869
7870         device->services = g_slist_append(device->services, service);
7871
7872         if (!profile->auto_connect || !device->general_connect)
7873                 return;
7874
7875         device->pending = g_slist_append(device->pending, service);
7876
7877         if (g_slist_length(device->pending) == 1)
7878                 connect_next(device);
7879 }
7880
7881 void device_remove_profile(gpointer a, gpointer b)
7882 {
7883         struct btd_device *device = a;
7884         struct btd_profile *profile = b;
7885         struct btd_service *service;
7886         GSList *l;
7887
7888         l = find_service_with_profile(device->services, profile);
7889 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
7890         if (l == NULL) {
7891                 if (g_strcmp0(profile->local_uuid , HID_DEVICE_UUID) == 0) {
7892                         l = find_service_with_uuid(device->services,
7893                                         HID_DEVICE_UUID);
7894                         if (l == NULL)
7895                                 return;
7896
7897                         service = l->data;
7898
7899                         if (btd_service_get_state(service) ==
7900                                 BTD_SERVICE_STATE_CONNECTED) {
7901                                 int err;
7902                                 err = btd_service_disconnect(service);
7903                                 if (err)
7904                                         error("error: %s", strerror(-err));
7905                         }
7906                 }
7907                 return;
7908         }
7909 #else
7910         if (l == NULL)
7911                 return;
7912 #endif
7913
7914         service = l->data;
7915         device->services = g_slist_delete_link(device->services, l);
7916         device->pending = g_slist_remove(device->pending, service);
7917         service_remove(service);
7918 }
7919
7920 void device_probe_profiles(struct btd_device *device, GSList *uuids)
7921 {
7922         struct probe_data d = { device, uuids };
7923         char addr[18];
7924
7925         ba2str(&device->bdaddr, addr);
7926
7927         if (device->blocked) {
7928                 DBG("Skipping profiles for blocked device %s", addr);
7929                 goto add_uuids;
7930         }
7931
7932         DBG("Probing profiles for device %s", addr);
7933
7934         btd_profile_foreach(dev_probe, &d);
7935
7936 add_uuids:
7937         device_add_uuids(device, uuids);
7938 }
7939
7940 static void store_sdp_record(GKeyFile *key_file, sdp_record_t *rec)
7941 {
7942         char handle_str[11];
7943         sdp_buf_t buf;
7944         int size, i;
7945         char *str;
7946
7947         sprintf(handle_str, "0x%8.8X", rec->handle);
7948
7949         if (sdp_gen_record_pdu(rec, &buf) < 0)
7950                 return;
7951
7952         size = buf.data_size;
7953
7954         str = g_malloc0(size*2+1);
7955
7956         for (i = 0; i < size; i++)
7957                 sprintf(str + (i * 2), "%02X", buf.data[i]);
7958
7959         g_key_file_set_string(key_file, "ServiceRecords", handle_str, str);
7960
7961         free(buf.data);
7962         g_free(str);
7963 }
7964
7965 static void store_primaries_from_sdp_record(GKeyFile *key_file,
7966                                                 sdp_record_t *rec)
7967 {
7968         uuid_t uuid;
7969         char *att_uuid, *prim_uuid;
7970         uint16_t start = 0, end = 0, psm = 0;
7971         char handle[6], uuid_str[33];
7972         int i;
7973
7974         sdp_uuid16_create(&uuid, ATT_UUID);
7975         att_uuid = bt_uuid2string(&uuid);
7976
7977         sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
7978         prim_uuid = bt_uuid2string(&uuid);
7979
7980         if (!record_has_uuid(rec, att_uuid))
7981                 goto done;
7982
7983         if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
7984                 goto done;
7985
7986         sprintf(handle, "%hu", start);
7987         switch (uuid.type) {
7988         case SDP_UUID16:
7989                 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
7990                 break;
7991         case SDP_UUID32:
7992                 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
7993                 break;
7994         case SDP_UUID128:
7995                 for (i = 0; i < 16; i++)
7996                         sprintf(uuid_str + (i * 2), "%2.2X",
7997                                         uuid.value.uuid128.data[i]);
7998                 break;
7999         default:
8000                 uuid_str[0] = '\0';
8001         }
8002
8003         g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
8004         g_key_file_set_string(key_file, handle, "Value", uuid_str);
8005         g_key_file_set_integer(key_file, handle, "EndGroupHandle", end);
8006
8007 done:
8008         free(prim_uuid);
8009         free(att_uuid);
8010 }
8011
8012 static int rec_cmp(const void *a, const void *b)
8013 {
8014         const sdp_record_t *r1 = a;
8015         const sdp_record_t *r2 = b;
8016
8017         return r1->handle - r2->handle;
8018 }
8019
8020 static int update_record(struct browse_req *req, const char *uuid,
8021                                                         sdp_record_t *rec)
8022 {
8023         GSList *l;
8024
8025         /* Check for duplicates */
8026         if (sdp_list_find(req->records, rec, rec_cmp))
8027                 return -EALREADY;
8028
8029         /* Copy record */
8030         req->records = sdp_list_append(req->records, sdp_copy_record(rec));
8031
8032         /* Check if UUID is duplicated */
8033         l = g_slist_find_custom(req->device->uuids, uuid, bt_uuid_strcmp);
8034         if (l == NULL) {
8035                 l = g_slist_find_custom(req->profiles_added, uuid,
8036                                                         bt_uuid_strcmp);
8037                 if (l != NULL)
8038                         return 0;
8039                 req->profiles_added = g_slist_append(req->profiles_added,
8040                                                         g_strdup(uuid));
8041         }
8042
8043         return 0;
8044 }
8045
8046 static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
8047 {
8048         struct btd_device *device = req->device;
8049         sdp_list_t *seq;
8050         char srcaddr[18], dstaddr[18];
8051         char sdp_file[PATH_MAX];
8052         char att_file[PATH_MAX];
8053         GKeyFile *sdp_key_file;
8054         GKeyFile *att_key_file;
8055         GError *gerr = NULL;
8056
8057         char *data;
8058         gsize length = 0;
8059
8060         ba2str(btd_adapter_get_address(device->adapter), srcaddr);
8061         ba2str(&device->bdaddr, dstaddr);
8062
8063         snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
8064                                                                 dstaddr);
8065         create_file(sdp_file, 0600);
8066
8067         sdp_key_file = g_key_file_new();
8068         if (!g_key_file_load_from_file(sdp_key_file, sdp_file, 0, &gerr)) {
8069                 error("Unable to load key file from %s: (%s)", sdp_file,
8070                                                                 gerr->message);
8071                 g_clear_error(&gerr);
8072                 g_key_file_free(sdp_key_file);
8073                 sdp_key_file = NULL;
8074         }
8075
8076         snprintf(att_file, PATH_MAX, STORAGEDIR "/%s/%s/attributes", srcaddr,
8077                                                                 dstaddr);
8078         create_file(att_file, 0600);
8079
8080         att_key_file = g_key_file_new();
8081         if (!g_key_file_load_from_file(att_key_file, att_file, 0, &gerr)) {
8082                 error("Unable to load key file from %s: (%s)", att_file,
8083                                                                 gerr->message);
8084                 g_clear_error(&gerr);
8085                 g_key_file_free(att_key_file);
8086                 att_key_file = NULL;
8087         }
8088
8089         for (seq = recs; seq; seq = seq->next) {
8090                 sdp_record_t *rec = (sdp_record_t *) seq->data;
8091                 char *profile_uuid;
8092
8093                 if (!rec)
8094                         break;
8095
8096                 /* If service class attribute is missing, svclass will be all
8097                  * zero and the resulting uuid string will be NULL.
8098                  */
8099                 profile_uuid = bt_uuid2string(&rec->svclass);
8100
8101                 if (!profile_uuid)
8102                         continue;
8103
8104                 if (bt_uuid_strcmp(profile_uuid, PNP_UUID) == 0) {
8105                         uint16_t source, vendor, product, version;
8106                         sdp_data_t *pdlist;
8107
8108                         pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
8109                         source = pdlist ? pdlist->val.uint16 : 0x0000;
8110
8111                         pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
8112                         vendor = pdlist ? pdlist->val.uint16 : 0x0000;
8113
8114                         pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
8115                         product = pdlist ? pdlist->val.uint16 : 0x0000;
8116
8117                         pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
8118                         version = pdlist ? pdlist->val.uint16 : 0x0000;
8119
8120                         if (source || vendor || product || version)
8121                                 btd_device_set_pnpid(device, source, vendor,
8122                                                         product, version);
8123                 }
8124
8125                 if (update_record(req, profile_uuid, rec) < 0)
8126                         goto next;
8127
8128                 if (sdp_key_file)
8129                         store_sdp_record(sdp_key_file, rec);
8130
8131                 if (att_key_file)
8132                         store_primaries_from_sdp_record(att_key_file, rec);
8133
8134 next:
8135                 free(profile_uuid);
8136         }
8137
8138         if (sdp_key_file) {
8139                 data = g_key_file_to_data(sdp_key_file, &length, NULL);
8140                 if (length > 0) {
8141                         if (!g_file_set_contents(sdp_file, data, length,
8142                                                                 &gerr)) {
8143                                 error("Unable set contents for %s: (%s)",
8144                                                 sdp_file, gerr->message);
8145                                 g_clear_error(&gerr);
8146                         }
8147                 }
8148
8149                 g_free(data);
8150                 g_key_file_free(sdp_key_file);
8151         }
8152
8153         if (att_key_file) {
8154                 data = g_key_file_to_data(att_key_file, &length, NULL);
8155                 if (length > 0) {
8156                         if (!g_file_set_contents(att_file, data, length,
8157                                                                 &gerr)) {
8158                                 error("Unable set contents for %s: (%s)",
8159                                                 att_file, gerr->message);
8160                                 g_clear_error(&gerr);
8161                         }
8162                 }
8163
8164                 g_free(data);
8165                 g_key_file_free(att_key_file);
8166         }
8167 }
8168
8169 static int primary_cmp(gconstpointer a, gconstpointer b)
8170 {
8171         return memcmp(a, b, sizeof(struct gatt_primary));
8172 }
8173
8174 static void update_gatt_uuids(struct browse_req *req, GSList *current,
8175                                                                 GSList *found)
8176 {
8177         GSList *l, *lmatch;
8178
8179         /* Added Profiles */
8180         for (l = found; l; l = g_slist_next(l)) {
8181                 struct gatt_primary *prim = l->data;
8182
8183                 /* Entry found ? */
8184                 lmatch = g_slist_find_custom(current, prim, primary_cmp);
8185                 if (lmatch)
8186                         continue;
8187
8188                 /* New entry */
8189                 req->profiles_added = g_slist_append(req->profiles_added,
8190                                                         g_strdup(prim->uuid));
8191
8192                 DBG("UUID Added: %s", prim->uuid);
8193         }
8194 }
8195
8196 static GSList *device_services_from_record(struct btd_device *device,
8197                                                         GSList *profiles)
8198 {
8199         GSList *l, *prim_list = NULL;
8200         char *att_uuid;
8201         uuid_t proto_uuid;
8202
8203         sdp_uuid16_create(&proto_uuid, ATT_UUID);
8204         att_uuid = bt_uuid2string(&proto_uuid);
8205
8206         for (l = profiles; l; l = l->next) {
8207                 const char *profile_uuid = l->data;
8208                 const sdp_record_t *rec;
8209                 struct gatt_primary *prim;
8210                 uint16_t start = 0, end = 0, psm = 0;
8211                 uuid_t prim_uuid;
8212
8213                 rec = btd_device_get_record(device, profile_uuid);
8214                 if (!rec)
8215                         continue;
8216
8217                 if (!record_has_uuid(rec, att_uuid))
8218                         continue;
8219
8220                 if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
8221                         continue;
8222
8223                 prim = g_new0(struct gatt_primary, 1);
8224                 prim->range.start = start;
8225                 prim->range.end = end;
8226                 sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
8227
8228                 prim_list = g_slist_append(prim_list, prim);
8229         }
8230
8231         free(att_uuid);
8232
8233         return prim_list;
8234 }
8235
8236 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
8237 {
8238         struct browse_req *req = user_data;
8239         struct btd_device *device = req->device;
8240         DBusMessage *reply;
8241         GSList *primaries;
8242         char addr[18];
8243
8244         ba2str(&device->bdaddr, addr);
8245
8246         if (err < 0) {
8247                 error("%s: error updating services: %s (%d)",
8248                                 addr, strerror(-err), -err);
8249                 goto send_reply;
8250         }
8251
8252         update_bredr_services(req, recs);
8253
8254         if (device->tmp_records)
8255                 sdp_list_free(device->tmp_records,
8256                                         (sdp_free_func_t) sdp_record_free);
8257
8258         device->tmp_records = req->records;
8259         req->records = NULL;
8260
8261         if (!req->profiles_added) {
8262                 DBG("%s: No service update", addr);
8263                 goto send_reply;
8264         }
8265
8266         primaries = device_services_from_record(device, req->profiles_added);
8267         if (primaries)
8268                 device_register_primaries(device, primaries, ATT_PSM);
8269
8270         /*
8271          * TODO: The btd_service instances for GATT services need to be
8272          * initialized with the service handles. Eventually this code should
8273          * perform ATT protocol service discovery over the ATT PSM to obtain
8274          * the full list of services and populate a client-role gatt_db over
8275          * BR/EDR.
8276          */
8277         device_probe_profiles(device, req->profiles_added);
8278
8279         /* Propagate services changes */
8280         g_dbus_emit_property_changed(dbus_conn, req->device->path,
8281                                                 DEVICE_INTERFACE, "UUIDs");
8282
8283 send_reply:
8284 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8285         if (!req->msg)
8286                 goto done;
8287
8288         /* since no new services are found, UUID signal is not emitted,
8289         ** so send a reply to the framework with the existing services */
8290         if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
8291                                 "DiscoverServices"))
8292                 discover_services_reply(req, err, device->tmp_records);
8293
8294 done:
8295 #endif
8296         /* If SDP search failed during an ongoing connection request, we should
8297          * reply to D-Bus method call.
8298          */
8299         if (err < 0 && device->connect) {
8300                 DBG("SDP failed during connection");
8301                 reply = btd_error_failed(device->connect, strerror(-err));
8302                 g_dbus_send_message(dbus_conn, reply);
8303                 dbus_message_unref(device->connect);
8304                 device->connect = NULL;
8305         }
8306
8307         device_svc_resolved(device, BROWSE_SDP, BDADDR_BREDR, err);
8308 }
8309
8310 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
8311 {
8312         struct browse_req *req = user_data;
8313         struct btd_device *device = req->device;
8314         struct btd_adapter *adapter = device->adapter;
8315         uuid_t uuid;
8316
8317         /* If we have a valid response and req->search_uuid == 2, then L2CAP
8318          * UUID & PNP searching was successful -- we are done */
8319         if (err < 0 || (req->search_uuid == 2 && req->records)) {
8320                 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
8321                         req->search_uuid--;
8322                         req->reconnect_attempt++;
8323                 } else
8324                         goto done;
8325         }
8326
8327         update_bredr_services(req, recs);
8328
8329         /* Search for mandatory uuids */
8330         if (uuid_list[req->search_uuid]) {
8331                 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
8332                 bt_search_service(btd_adapter_get_address(adapter),
8333                                                 &device->bdaddr, &uuid,
8334                                                 browse_cb, user_data, NULL,
8335                                                 req->sdp_flags);
8336                 return;
8337         }
8338
8339 done:
8340         search_cb(recs, err, user_data);
8341 }
8342
8343 static bool device_get_auto_connect(struct btd_device *device)
8344 {
8345         if (device->disable_auto_connect)
8346                 return false;
8347
8348         return device->auto_connect;
8349 }
8350
8351 static void disconnect_gatt_service(gpointer data, gpointer user_data)
8352 {
8353         struct btd_service *service = data;
8354         struct btd_profile *profile = btd_service_get_profile(service);
8355
8356         /* Ignore if profile cannot accept connections */
8357         if (!profile->accept)
8358                 return;
8359
8360         btd_service_disconnect(service);
8361 }
8362
8363 static void att_disconnected_cb(int err, void *user_data)
8364 {
8365         struct btd_device *device = user_data;
8366
8367         DBG("");
8368
8369         if (device->browse)
8370                 goto done;
8371
8372         DBG("%s (%d)", strerror(err), err);
8373
8374         g_slist_foreach(device->services, disconnect_gatt_service, NULL);
8375
8376         btd_gatt_client_disconnected(device->client_dbus);
8377
8378         if (!device_get_auto_connect(device)) {
8379                 DBG("Automatic connection disabled");
8380                 goto done;
8381         }
8382
8383         /*
8384          * Keep scanning/re-connection active if disconnection reason
8385          * is connection timeout, remote user terminated connection or local
8386          * initiated disconnection.
8387          */
8388         if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
8389                 adapter_connect_list_add(device->adapter, device);
8390
8391 done:
8392 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8393         device_set_gatt_connected(device, FALSE);
8394 #endif
8395         attio_cleanup(device);
8396 }
8397
8398 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8399 static void att_mtu_changed(uint16_t mtu, void *user_data)
8400 {
8401         struct btd_device *device = user_data;
8402
8403         DBG("att mtu changed %d", mtu);
8404
8405         g_dbus_emit_signal(dbus_conn, device->path,
8406                 DEVICE_INTERFACE, "AttMtuChanged",
8407                 DBUS_TYPE_UINT16, &mtu,
8408                 DBUS_TYPE_INVALID);
8409 }
8410 #endif
8411
8412 static void register_gatt_services(struct btd_device *device)
8413 {
8414         struct browse_req *req = device->browse;
8415         GSList *services = NULL;
8416
8417         if (!bt_gatt_client_is_ready(device->client))
8418                 return;
8419
8420         /*
8421          * TODO: Remove the primaries list entirely once all profiles use
8422          * shared/gatt.
8423          */
8424         gatt_db_foreach_service(device->db, NULL, add_primary, &services);
8425
8426         btd_device_set_temporary(device, false);
8427
8428 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8429         if (req) {
8430                 if (req->search_uuid)
8431                         DBG("browse req. is for SDP. Ignore it.");
8432                 else
8433                         update_gatt_uuids(req, device->primaries, services);
8434         }
8435 #else
8436         if (req)
8437                 update_gatt_uuids(req, device->primaries, services);
8438 #endif
8439
8440 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8441         /* do not delete existing primary list,
8442          * just append the new primary uuids,
8443          * the list will be modifed when service changed
8444          * indication is received during connection */
8445         g_slist_free_full(device->primaries, g_free);
8446         device->primaries = NULL;
8447 #endif
8448
8449         device_register_primaries(device, services, -1);
8450
8451         device_add_gatt_services(device);
8452 }
8453
8454 static void gatt_client_init(struct btd_device *device);
8455
8456 static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
8457                                                                 void *user_data)
8458 {
8459         struct btd_device *device = user_data;
8460
8461         DBG("status: %s, error: %u", success ? "success" : "failed", att_ecode);
8462
8463         if (!success) {
8464                 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8465                                                                         -EIO);
8466                 return;
8467         }
8468
8469 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8470         /* Register the services after setting the client is ready
8471          * and exporting all the services and characteristics paths.
8472          */
8473         register_gatt_services(device);
8474 #endif
8475
8476         btd_gatt_client_ready(device->client_dbus);
8477 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8478         register_gatt_services(device);
8479 #endif
8480
8481         device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type, 0);
8482
8483         store_gatt_db(device);
8484
8485 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8486         if (device->name[0] == '\0') {
8487                 char *name = NULL;
8488                 name = bt_gatt_client_get_gap_device_name(device->client);
8489                 if (name)
8490                         strncpy(device->name, name, MAX_NAME_LENGTH);
8491         }
8492 #endif
8493 }
8494
8495 static void gatt_client_service_changed(uint16_t start_handle,
8496                                                         uint16_t end_handle,
8497                                                         void *user_data)
8498 {
8499         DBG("start 0x%04x, end: 0x%04x", start_handle, end_handle);
8500 }
8501
8502 static void gatt_debug(const char *str, void *user_data)
8503 {
8504         DBG("%s", str);
8505 }
8506
8507 static void gatt_client_init(struct btd_device *device)
8508 {
8509         gatt_client_cleanup(device);
8510
8511         if (!device->connect && !btd_opts.reverse_discovery) {
8512                 DBG("Reverse service discovery disabled: skipping GATT client");
8513                 return;
8514         }
8515
8516         device->client = bt_gatt_client_new(device->db, device->att,
8517                                                         device->att_mtu, 0);
8518         if (!device->client) {
8519                 DBG("Failed to initialize");
8520                 return;
8521         }
8522
8523         bt_gatt_client_set_debug(device->client, gatt_debug, NULL, NULL);
8524
8525         /*
8526          * Notify notify existing service about the new connection so they can
8527          * react to notifications while discovering services
8528          */
8529         device_accept_gatt_profiles(device);
8530
8531         device->gatt_ready_id = bt_gatt_client_ready_register(device->client,
8532                                                         gatt_client_ready_cb,
8533                                                         device, NULL);
8534         if (!device->gatt_ready_id) {
8535                 DBG("Failed to register GATT ready callback");
8536                 gatt_client_cleanup(device);
8537                 return;
8538         }
8539
8540         if (!bt_gatt_client_set_service_changed(device->client,
8541                                                 gatt_client_service_changed,
8542                                                 device, NULL)) {
8543                 DBG("Failed to set service changed handler");
8544                 gatt_client_cleanup(device);
8545                 return;
8546         }
8547
8548         btd_gatt_client_connected(device->client_dbus);
8549
8550         /* Only initiate EATT connection when acting as initiator, as acceptor
8551          * it shall be triggered only when ready to avoid possible clashes where
8552          * both sides attempt to connection at same time.
8553          */
8554         if (device->connect)
8555                 btd_gatt_client_eatt_connect(device->client_dbus);
8556 }
8557
8558 static void gatt_server_init(struct btd_device *device,
8559                                 struct btd_gatt_database *database)
8560 {
8561         struct gatt_db *db = btd_gatt_database_get_db(database);
8562
8563         if (!db) {
8564                 error("No local GATT database exists for this adapter");
8565                 return;
8566         }
8567
8568         gatt_server_cleanup(device);
8569
8570         device->server = bt_gatt_server_new(db, device->att, device->att_mtu,
8571                                                 btd_opts.key_size);
8572         if (!device->server) {
8573                 error("Failed to initialize bt_gatt_server");
8574                 return;
8575         }
8576  
8577         bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
8578
8579         bt_gatt_server_set_debug(device->server, gatt_debug, NULL, NULL);
8580
8581 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8582         if (!bt_gatt_server_set_mtu_changed(device->server,
8583                                                 att_mtu_changed,
8584                                                 device, NULL)) {
8585                 DBG("Failed to set mtu changed handler");
8586                 return;
8587         }
8588 #endif
8589 }
8590
8591 static bool local_counter(uint32_t *sign_cnt, void *user_data)
8592 {
8593         struct btd_device *dev = user_data;
8594
8595         if (!dev->local_csrk)
8596                 return false;
8597
8598         *sign_cnt = dev->local_csrk->counter++;
8599
8600         store_device_info(dev);
8601
8602         return true;
8603 }
8604
8605 static bool remote_counter(uint32_t *sign_cnt, void *user_data)
8606 {
8607         struct btd_device *dev = user_data;
8608
8609         if (!dev->remote_csrk || *sign_cnt < dev->remote_csrk->counter)
8610                 return false;
8611
8612         dev->remote_csrk->counter = *sign_cnt;
8613
8614         store_device_info(dev);
8615
8616         return true;
8617 }
8618
8619 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8620 static bool load_svc_change_indication_status(struct btd_device *device, const char *local,
8621                                 const char *peer)
8622 {
8623         char filename[PATH_MAX];
8624         GKeyFile *key_file;
8625         gboolean svc_change_regd = false;
8626         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
8627
8628         key_file = g_key_file_new();
8629         if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
8630                 goto failed;
8631
8632         /* Load Service changed Registered flag */
8633         svc_change_regd = g_key_file_get_boolean(key_file, "Att",
8634                                                 "SvcChangeRegd", NULL);
8635         bt_att_set_svc_changed_indication_registered(device->att,
8636                                                 svc_change_regd);
8637
8638
8639 failed:
8640         g_key_file_free(key_file);
8641
8642         return svc_change_regd;
8643 }
8644 #endif
8645
8646 bool device_attach_att(struct btd_device *dev, GIOChannel *io)
8647 {
8648         GError *gerr = NULL;
8649         GAttrib *attrib;
8650         BtIOSecLevel sec_level;
8651         uint16_t mtu;
8652         uint16_t cid;
8653         struct btd_gatt_database *database;
8654         const bdaddr_t *dst;
8655         char dstaddr[18];
8656 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8657         uint8_t dst_type = BDADDR_BREDR;
8658         char srcaddr[18];
8659         const bdaddr_t *src;
8660 #endif
8661
8662         bt_io_get(io, &gerr, BT_IO_OPT_SEC_LEVEL, &sec_level,
8663                                                 BT_IO_OPT_IMTU, &mtu,
8664                                                 BT_IO_OPT_CID, &cid,
8665 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8666                                                 BT_IO_OPT_DEST_TYPE, &dst_type,
8667 #endif
8668                                                 BT_IO_OPT_INVALID);
8669
8670         if (gerr) {
8671                 error("bt_io_get: %s", gerr->message);
8672                 g_error_free(gerr);
8673                 return false;
8674         }
8675
8676         if (dev->att) {
8677                 if (btd_opts.gatt_channels == bt_att_get_channels(dev->att)) {
8678                         DBG("EATT channel limit reached");
8679                         return false;
8680                 }
8681
8682                 if (!bt_att_attach_fd(dev->att, g_io_channel_unix_get_fd(io))) {
8683                         DBG("EATT channel connected");
8684                         g_io_channel_set_close_on_unref(io, FALSE);
8685                         return true;
8686                 }
8687
8688                 error("Failed to attach EATT channel");
8689                 return false;
8690         }
8691
8692 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8693         if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
8694                 DBG("Elevating security level since LTK is available");
8695
8696                 sec_level = BT_IO_SEC_MEDIUM;
8697                 bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
8698                                                         BT_IO_OPT_INVALID);
8699                 if (gerr) {
8700                         error("bt_io_set: %s", gerr->message);
8701                         g_error_free(gerr);
8702                         return false;
8703                 }
8704         }
8705 #endif
8706
8707         dev->att_mtu = MIN(mtu, btd_opts.gatt_mtu);
8708         attrib = g_attrib_new(io,
8709                         cid == ATT_CID ? BT_ATT_DEFAULT_LE_MTU : dev->att_mtu,
8710                         false);
8711         if (!attrib) {
8712                 error("Unable to create new GAttrib instance");
8713                 return false;
8714         }
8715
8716         dev->attrib = attrib;
8717         dev->att = g_attrib_get_att(attrib);
8718
8719         bt_att_ref(dev->att);
8720
8721         bt_att_set_debug(dev->att, BT_ATT_DEBUG, gatt_debug, NULL, NULL);
8722
8723         dev->att_disconn_id = bt_att_register_disconnect(dev->att,
8724                                                 att_disconnected_cb, dev, NULL);
8725         bt_att_set_close_on_unref(dev->att, true);
8726
8727         if (dev->local_csrk)
8728                 bt_att_set_local_key(dev->att, dev->local_csrk->key,
8729                                                         local_counter, dev);
8730
8731         if (dev->remote_csrk)
8732                 bt_att_set_remote_key(dev->att, dev->remote_csrk->key,
8733                                                         remote_counter, dev);
8734
8735 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8736         if (dst_type != BDADDR_BREDR && device_get_rpa_exist(dev) == true) {
8737                 bt_att_set_remote_addr(dev->att,
8738                                         device_get_rpa(dev), BDADDR_LE_RANDOM);
8739         } else {
8740                 bt_att_set_remote_addr(dev->att,
8741                                         &dev->bdaddr, dev->bdaddr_type);
8742         }
8743 #endif
8744
8745         database = btd_adapter_get_database(dev->adapter);
8746
8747         dst = device_get_address(dev);
8748         ba2str(dst, dstaddr);
8749
8750         if (gatt_db_isempty(dev->db))
8751                 load_gatt_db(dev, btd_adapter_get_storage_dir(dev->adapter),
8752                                                                 dstaddr);
8753
8754         gatt_client_init(dev);
8755         gatt_server_init(dev, database);
8756
8757         /*
8758          * Remove the device from the connect_list and give the passive
8759          * scanning another chance to be restarted in case there are
8760          * other devices in the connect_list.
8761          */
8762         adapter_connect_list_remove(dev->adapter, dev);
8763
8764 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8765         src = btd_adapter_get_address(dev->adapter);
8766         ba2str(src, srcaddr);
8767
8768         /* load the service changed indication status on connection */
8769         load_svc_change_indication_status(dev, srcaddr, dstaddr);
8770 #endif
8771
8772         return true;
8773 }
8774
8775 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
8776 {
8777         struct btd_device *device = user_data;
8778         DBusMessage *reply;
8779         uint8_t io_cap;
8780         int err = 0;
8781
8782         g_io_channel_unref(device->att_io);
8783         device->att_io = NULL;
8784
8785         if (gerr) {
8786                 DBG("%s", gerr->message);
8787
8788                 if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
8789                         goto done;
8790
8791                 if (device_get_auto_connect(device)) {
8792                         DBG("Enabling automatic connections");
8793                         adapter_connect_list_add(device->adapter, device);
8794                 }
8795
8796                 if (device->browse)
8797                         browse_request_complete(device->browse,
8798                                                 BROWSE_GATT,
8799                                                 device->bdaddr_type,
8800                                                 -ECONNABORTED);
8801
8802                 err = -ECONNABORTED;
8803                 goto done;
8804         }
8805
8806         if (!device_attach_att(device, io))
8807                 goto done;
8808
8809         if (!device->bonding)
8810                 goto done;
8811
8812         if (device->bonding->agent)
8813                 io_cap = agent_get_io_capability(device->bonding->agent);
8814         else
8815                 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
8816
8817         err = adapter_create_bonding(device->adapter, &device->bdaddr,
8818                                         device->bdaddr_type, io_cap);
8819 done:
8820         if (device->bonding && err < 0) {
8821                 reply = btd_error_failed(device->bonding->msg, strerror(-err));
8822                 g_dbus_send_message(dbus_conn, reply);
8823                 bonding_request_cancel(device->bonding);
8824                 bonding_request_free(device->bonding);
8825         }
8826
8827         if (!err)
8828                 device_browse_gatt(device, NULL);
8829
8830         if (device->connect) {
8831                 if (err < 0)
8832                         reply = btd_error_failed(device->connect,
8833                                         btd_error_le_conn_from_errno(err));
8834                 else
8835                         reply = dbus_message_new_method_return(device->connect);
8836
8837                 g_dbus_send_message(dbus_conn, reply);
8838                 dbus_message_unref(device->connect);
8839                 device->connect = NULL;
8840         }
8841 }
8842
8843 int device_connect_le(struct btd_device *dev)
8844 {
8845         struct btd_adapter *adapter = dev->adapter;
8846         BtIOSecLevel sec_level;
8847         GIOChannel *io;
8848         GError *gerr = NULL;
8849         char addr[18];
8850
8851         /* There is one connection attempt going on */
8852         if (dev->att_io)
8853                 return -EALREADY;
8854
8855         ba2str(&dev->bdaddr, addr);
8856
8857         DBG("Connection attempt to: %s", addr);
8858
8859         if (dev->le_state.paired)
8860                 sec_level = BT_IO_SEC_MEDIUM;
8861         else
8862                 sec_level = BT_IO_SEC_LOW;
8863
8864         /*
8865          * This connection will help us catch any PDUs that comes before
8866          * pairing finishes
8867          */
8868         io = bt_io_connect(att_connect_cb, dev, NULL, &gerr,
8869                         BT_IO_OPT_SOURCE_BDADDR,
8870                         btd_adapter_get_address(adapter),
8871                         BT_IO_OPT_SOURCE_TYPE,
8872                         btd_adapter_get_address_type(adapter),
8873                         BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
8874                         BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
8875                         BT_IO_OPT_CID, ATT_CID,
8876                         BT_IO_OPT_SEC_LEVEL, sec_level,
8877                         BT_IO_OPT_INVALID);
8878
8879         if (io == NULL) {
8880                 if (dev->bonding) {
8881                         DBusMessage *reply = btd_error_failed(
8882                                         dev->bonding->msg, gerr->message);
8883
8884                         g_dbus_send_message(dbus_conn, reply);
8885                         bonding_request_cancel(dev->bonding);
8886                         bonding_request_free(dev->bonding);
8887                 }
8888
8889                 error("ATT bt_io_connect(%s): %s", addr, gerr->message);
8890                 g_error_free(gerr);
8891                 return -EIO;
8892         }
8893
8894         /* Keep this, so we can cancel the connection */
8895         dev->att_io = io;
8896
8897         return 0;
8898 }
8899
8900 static struct browse_req *browse_request_new(struct btd_device *device,
8901                                                         uint8_t type,
8902                                                         DBusMessage *msg)
8903 {
8904         struct browse_req *req;
8905
8906         if (device->browse)
8907                 return NULL;
8908
8909         req = g_new0(struct browse_req, 1);
8910         req->device = device;
8911         req->type = type;
8912
8913         device->browse = req;
8914
8915         if (!msg)
8916                 return req;
8917
8918         req->msg = dbus_message_ref(msg);
8919
8920         /*
8921          * Track the request owner to cancel it automatically if the owner
8922          * exits
8923          */
8924         req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
8925                                                 dbus_message_get_sender(msg),
8926                                                 browse_request_exit,
8927                                                 req, NULL);
8928
8929         return req;
8930 }
8931
8932 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg)
8933 {
8934         struct btd_adapter *adapter = device->adapter;
8935         struct browse_req *req;
8936
8937 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8938         DBG("");
8939 #endif
8940         req = browse_request_new(device, BROWSE_GATT, msg);
8941         if (!req)
8942                 return -EBUSY;
8943
8944         if (device->client) {
8945                 /*
8946                  * If discovery has not yet completed, then wait for gatt-client
8947                  * to become ready.
8948                  */
8949                 if (!bt_gatt_client_is_ready(device->client))
8950                         return 0;
8951
8952                 /*
8953                  * Services have already been discovered, so signal this browse
8954                  * request as resolved.
8955                  */
8956                 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8957                                                                         0);
8958                 return 0;
8959         }
8960
8961         device->att_io = bt_io_connect(att_connect_cb,
8962                                 device, NULL, NULL,
8963                                 BT_IO_OPT_SOURCE_BDADDR,
8964                                 btd_adapter_get_address(adapter),
8965                                 BT_IO_OPT_SOURCE_TYPE,
8966                                 btd_adapter_get_address_type(adapter),
8967                                 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
8968                                 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
8969                                 BT_IO_OPT_CID, ATT_CID,
8970                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
8971                                 BT_IO_OPT_INVALID);
8972
8973         if (device->att_io == NULL) {
8974                 browse_request_free(req);
8975                 return -EIO;
8976         }
8977
8978         return 0;
8979 }
8980
8981 static uint16_t get_sdp_flags(struct btd_device *device)
8982 {
8983         uint16_t vid, pid;
8984
8985         vid = btd_device_get_vendor(device);
8986         pid = btd_device_get_product(device);
8987
8988         /* Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
8989          * results in SDP response being dropped by kernel. Workaround this by
8990          * forcing SDP code to use bigger MTU while connecting.
8991          */
8992         if (vid == 0x054c && pid == 0x05c4)
8993                 return SDP_LARGE_MTU;
8994
8995         if (btd_adapter_ssp_enabled(device->adapter))
8996                 return 0;
8997
8998         /* if no EIR try matching Sony DualShock 4 with name and class */
8999         if (!strncmp(device->name, "Wireless Controller", MAX_NAME_LENGTH) &&
9000                         device->class == 0x2508)
9001                 return SDP_LARGE_MTU;
9002
9003         return 0;
9004 }
9005
9006 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
9007 {
9008         struct btd_adapter *adapter = device->adapter;
9009         struct browse_req *req;
9010         uuid_t uuid;
9011         int err;
9012
9013 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9014         DBG("");
9015 #endif
9016         req = browse_request_new(device, BROWSE_SDP, msg);
9017         if (!req)
9018                 return -EBUSY;
9019
9020         sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
9021
9022         req->sdp_flags = get_sdp_flags(device);
9023
9024         err = bt_search(btd_adapter_get_address(adapter),
9025                         &device->bdaddr, &uuid, browse_cb, req, NULL,
9026                         req->sdp_flags);
9027         if (err < 0) {
9028 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9029                 device->browse = NULL;
9030 #endif
9031                 browse_request_free(req);
9032                 return err;
9033         }
9034
9035         return err;
9036 }
9037
9038 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9039 void device_set_last_addr_type(struct btd_device *device, uint8_t type)
9040 {
9041         if (!device)
9042                 return;
9043
9044         //DBG("Last addr type %d", type);
9045
9046         device->last_bdaddr_type = type;
9047 }
9048
9049 gboolean device_is_ipsp_connected(struct btd_device * device)
9050 {
9051         return device->ipsp_connected;
9052 }
9053
9054 void device_set_ipsp_connected(struct btd_device *device, gboolean connected,
9055                                         const unsigned char *ifname)
9056 {
9057         char *iface_name = NULL;
9058
9059         if (device == NULL) {
9060                 error("device is NULL");
9061                 return;
9062         }
9063
9064         if (device->ipsp_connected == connected)
9065                 return;
9066
9067         device->ipsp_connected = connected;
9068
9069         memset(device->if_name, 0, sizeof(device->if_name));
9070         memcpy(device->if_name, ifname, 16);
9071         iface_name = device->if_name;
9072
9073         DBG("ipsp_connected %d", connected);
9074         DBG("ipsp_iface: %s is Up !", iface_name);
9075
9076         g_dbus_emit_signal(dbus_conn, device->path,
9077                         DEVICE_INTERFACE, "IpspStateChanged",
9078                         DBUS_TYPE_BOOLEAN, &connected,
9079                         DBUS_TYPE_STRING, &iface_name,
9080                         DBUS_TYPE_INVALID);
9081 }
9082 void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets,
9083                 uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time)
9084 {
9085         if (device == NULL) {
9086                 error("device is NULL");
9087                 return;
9088         }
9089
9090         device->max_tx_octets = max_tx_octets;
9091         device->max_tx_time = max_tx_time;
9092         device->max_rx_octets = max_rx_octets;
9093         device->max_rx_time = max_rx_time;
9094
9095         DBG("data length changed values :max_tx_octets: %d  max_tx_time: %d  max_rx_octets: %d  max_rx_time: %d",
9096                 max_tx_octets, max_tx_time, max_rx_octets, max_rx_time);
9097
9098         g_dbus_emit_signal(dbus_conn, device->path,
9099                 DEVICE_INTERFACE, "LEDataLengthChanged",
9100                 DBUS_TYPE_UINT16, &max_tx_octets,
9101                 DBUS_TYPE_UINT16, &max_tx_time,
9102                 DBUS_TYPE_UINT16, &max_rx_octets,
9103                 DBUS_TYPE_UINT16, &max_rx_time,
9104                 DBUS_TYPE_INVALID);
9105 }
9106
9107 const bdaddr_t *device_get_rpa(struct btd_device *device)
9108 {
9109         return device->rpa;
9110 }
9111
9112 const uint8_t *device_get_irk_value(struct btd_device *device)
9113 {
9114         return device->irk_val;
9115 }
9116
9117 bool device_get_rpa_exist(struct btd_device *device)
9118 {
9119         return device->rpa ? true : false;
9120 }
9121
9122 void device_set_auth_addr_type(struct btd_device *device, uint8_t type)
9123 {
9124         if (!device)
9125                 return;
9126
9127         DBG("Auth addr type %d", type);
9128
9129         device->auth_bdaddr_type = type;
9130 }
9131
9132 void device_get_tizen_addr(struct btd_device *device, uint8_t type,
9133                            struct device_addr_type *addr)
9134 {
9135         if (!device || !addr)
9136                 return;
9137
9138         if (type == BDADDR_BREDR) {
9139                 bacpy(&addr->bdaddr, &device->bdaddr);
9140                 addr->bdaddr_type = BDADDR_BREDR;
9141                 return;
9142         }
9143
9144         if (device->rpa) {
9145                 bacpy(&addr->bdaddr, device->rpa);
9146                 addr->bdaddr_type = BDADDR_LE_RANDOM;
9147                 return;
9148         }
9149
9150         bacpy(&addr->bdaddr, &device->bdaddr);
9151         addr->bdaddr_type = device->bdaddr_type;
9152 }
9153 #endif
9154
9155 int device_discover_services(struct btd_device *device)
9156 {
9157         int err;
9158
9159         if (device->bredr)
9160                 err = device_browse_sdp(device, NULL);
9161         else
9162                 err = device_browse_gatt(device, NULL);
9163
9164         if (err == 0 && device->discov_timer) {
9165                 timeout_remove(device->discov_timer);
9166                 device->discov_timer = 0;
9167         }
9168
9169         return err;
9170 }
9171
9172 struct btd_adapter *device_get_adapter(struct btd_device *device)
9173 {
9174         if (!device)
9175                 return NULL;
9176
9177         return device->adapter;
9178 }
9179
9180 const bdaddr_t *device_get_address(struct btd_device *device)
9181 {
9182         return &device->bdaddr;
9183 }
9184 uint8_t device_get_le_address_type(struct btd_device *device)
9185 {
9186         return device->bdaddr_type;
9187 }
9188
9189 const char *device_get_path(const struct btd_device *device)
9190 {
9191         if (!device)
9192                 return NULL;
9193
9194         return device->path;
9195 }
9196
9197 gboolean device_is_temporary(struct btd_device *device)
9198 {
9199         return device->temporary;
9200 }
9201
9202 void btd_device_set_temporary(struct btd_device *device, bool temporary)
9203 {
9204         if (!device)
9205                 return;
9206
9207         if (device->temporary == temporary)
9208                 return;
9209
9210         if (device_address_is_private(device))
9211                 return;
9212
9213         DBG("temporary %d", temporary);
9214
9215         device->temporary = temporary;
9216
9217         if (temporary) {
9218                 if (device->bredr)
9219                         adapter_accept_list_remove(device->adapter, device);
9220                 adapter_connect_list_remove(device->adapter, device);
9221                 if (device->auto_connect) {
9222                         device->disable_auto_connect = TRUE;
9223                         device_set_auto_connect(device, FALSE);
9224                 }
9225                 set_temporary_timer(device, btd_opts.tmpto);
9226                 return;
9227         } else
9228                 clear_temporary_timer(device);
9229
9230         if (device->bredr)
9231                 adapter_accept_list_add(device->adapter, device);
9232
9233         store_device_info(device);
9234
9235         /* attributes were not stored when resolved if device was temporary */
9236         if (device->bdaddr_type != BDADDR_BREDR &&
9237                         device->le_state.svc_resolved &&
9238                         g_slist_length(device->primaries) != 0)
9239                 store_services(device);
9240 }
9241
9242 void btd_device_set_trusted(struct btd_device *device, gboolean trusted)
9243 {
9244         if (!device)
9245                 return;
9246
9247         if (device->trusted == trusted)
9248                 return;
9249
9250         DBG("trusted %d", trusted);
9251
9252         device->trusted = trusted;
9253
9254         store_device_info(device);
9255
9256         g_dbus_emit_property_changed(dbus_conn, device->path,
9257                                         DEVICE_INTERFACE, "Trusted");
9258 }
9259
9260 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9261 void device_disconnect_blocked(struct btd_device *device, char *uuid)
9262 {
9263         struct btd_service *service;
9264         GSList *l;
9265
9266         if (!device || !uuid)
9267                 return;
9268
9269         l = find_service_with_uuid(device->services, uuid);
9270         if (l == NULL)
9271                 return;
9272
9273         service = l->data;
9274         if (btd_service_get_state(service) ==
9275                         BTD_SERVICE_STATE_CONNECTED) {
9276                 int err;
9277                 err = btd_service_disconnect(service);
9278                 if (err)
9279                         error("error: %s", strerror(-err));
9280         }
9281 }
9282
9283 void btd_device_set_trusted_profiles(struct btd_device *device,
9284                 uint32_t pbap, uint32_t map, uint32_t sap,
9285                 uint32_t hfp_hs, uint32_t a2dp)
9286 {
9287         if (!device)
9288                 return;
9289
9290         DBG("TrustedProfiles Parameters: [PBAP %d] [MAP %d] [SAP %d] [HFP %d] [A2DP %d]",
9291                         pbap, map, sap, hfp_hs, a2dp);
9292
9293         if (device->trusted_profiles.pbap == pbap &&
9294                         device->trusted_profiles.map == map &&
9295                         device->trusted_profiles.sap == sap &&
9296                         device->trusted_profiles.hfp_hs == hfp_hs &&
9297                         device->trusted_profiles.a2dp == a2dp)
9298                 return;
9299
9300         /* Disconnect OBEX based profiles if connected */
9301         if (device->trusted_profiles.pbap != pbap) {
9302                 device->trusted_profiles.pbap = pbap;
9303                 if (pbap == SUPPORTED_BLOCKED)
9304                         device_disconnect_blocked(device, OBEX_PSE_UUID);
9305         } else if (device->trusted_profiles.map != map) {
9306                 device->trusted_profiles.map = map;
9307                 if (map == SUPPORTED_BLOCKED)
9308                         device_disconnect_blocked(device, OBEX_MAP_UUID);
9309         } else if (device->trusted_profiles.sap != sap) {
9310                 device->trusted_profiles.sap = sap;
9311                 if (sap == SUPPORTED_BLOCKED)
9312                         device_disconnect_blocked(device, SAP_UUID);
9313         } else if (device->trusted_profiles.hfp_hs != hfp_hs) {
9314                 device->trusted_profiles.hfp_hs = hfp_hs;
9315         } else if (device->trusted_profiles.a2dp != a2dp) {
9316                 device->trusted_profiles.a2dp = a2dp;
9317         }
9318
9319         store_device_info(device);
9320         g_dbus_emit_property_changed(dbus_conn, device->path,
9321                                         DEVICE_INTERFACE, "TrustedProfiles");
9322 }
9323 #endif
9324
9325 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type)
9326 {
9327         if (!device)
9328                 return;
9329
9330         DBG("");
9331
9332         if (bdaddr_type == BDADDR_BREDR)
9333                 device->bredr_state.bonded = true;
9334         else
9335                 device->le_state.bonded = true;
9336
9337         btd_device_set_temporary(device, false);
9338 }
9339
9340 void device_set_legacy(struct btd_device *device, bool legacy)
9341 {
9342         if (!device)
9343                 return;
9344
9345         DBG("legacy %d", legacy);
9346
9347         if (device->legacy == legacy)
9348                 return;
9349
9350         device->legacy = legacy;
9351
9352         g_dbus_emit_property_changed(dbus_conn, device->path,
9353                                         DEVICE_INTERFACE, "LegacyPairing");
9354 }
9355
9356 void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type,
9357                                                                 uint16_t value)
9358 {
9359         char filename[PATH_MAX];
9360         char device_addr[18];
9361         GKeyFile *key_file;
9362         GError *gerr = NULL;
9363         uint16_t old_value;
9364         gsize length = 0;
9365         char *str;
9366
9367         ba2str(&device->bdaddr, device_addr);
9368         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9369                                 btd_adapter_get_storage_dir(device->adapter),
9370                                 device_addr);
9371
9372         key_file = g_key_file_new();
9373         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9374                 error("Unable to load key file from %s: (%s)", filename,
9375                                                                 gerr->message);
9376                 g_error_free(gerr);
9377         }
9378
9379         /* for bonded devices this is done on every connection so limit writes
9380          * to storage if no change needed
9381          */
9382         if (bdaddr_type == BDADDR_BREDR) {
9383                 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9384                                                         "CCC_BR/EDR", NULL);
9385                 if (old_value == value)
9386                         goto done;
9387
9388                 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_BR/EDR",
9389                                                                         value);
9390         } else {
9391                 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9392                                                         "CCC_LE", NULL);
9393                 if (old_value == value)
9394                         goto done;
9395
9396                 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_LE",
9397                                                                         value);
9398         }
9399
9400         create_file(filename, 0600);
9401
9402         str = g_key_file_to_data(key_file, &length, NULL);
9403         if (!g_file_set_contents(filename, str, length, &gerr)) {
9404                 error("Unable set contents for %s: (%s)", filename,
9405                                                                 gerr->message);
9406                 g_error_free(gerr);
9407         }
9408         g_free(str);
9409
9410 done:
9411         g_key_file_free(key_file);
9412 }
9413 void device_load_svc_chng_ccc(struct btd_device *device, uint16_t *ccc_le,
9414                                                         uint16_t *ccc_bredr)
9415 {
9416         char filename[PATH_MAX];
9417         char device_addr[18];
9418         GKeyFile *key_file;
9419         GError *gerr = NULL;
9420
9421         ba2str(&device->bdaddr, device_addr);
9422         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9423                                 btd_adapter_get_storage_dir(device->adapter),
9424                                 device_addr);
9425
9426         key_file = g_key_file_new();
9427         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9428                 error("Unable to load key file from %s: (%s)", filename,
9429                                                                 gerr->message);
9430                 g_error_free(gerr);
9431         }
9432
9433         if (!g_key_file_has_group(key_file, "ServiceChanged")) {
9434                 if (ccc_le)
9435                         *ccc_le = 0x0000;
9436                 if (ccc_bredr)
9437                         *ccc_bredr = 0x0000;
9438                 g_key_file_free(key_file);
9439                 return;
9440         }
9441
9442         if (ccc_le)
9443                 *ccc_le = g_key_file_get_integer(key_file, "ServiceChanged",
9444                                                         "CCC_LE", NULL);
9445
9446         if (ccc_bredr)
9447                 *ccc_bredr = g_key_file_get_integer(key_file, "ServiceChanged",
9448                                                         "CCC_BR/EDR", NULL);
9449
9450         g_key_file_free(key_file);
9451 }
9452
9453 void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
9454                                                         int8_t delta_threshold)
9455 {
9456         if (!device)
9457                 return;
9458
9459 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9460         if (rssi == 0 || device->rssi == 0) {
9461                 if (device->rssi == rssi)
9462                         return;
9463         }
9464
9465         device->rssi = rssi;
9466         DBG("rssi %d", rssi);
9467 #else
9468         if (rssi == 0 || device->rssi == 0) {
9469                 if (device->rssi == rssi)
9470                         return;
9471
9472                 DBG("rssi %d", rssi);
9473
9474                 device->rssi = rssi;
9475         } else {
9476                 int delta;
9477
9478                 if (device->rssi > rssi)
9479                         delta = device->rssi - rssi;
9480                 else
9481                         delta = rssi - device->rssi;
9482
9483                 /* only report changes of delta_threshold dBm or more */
9484                 if (delta < delta_threshold)
9485                         return;
9486
9487                 DBG("rssi %d delta %d", rssi, delta);
9488
9489                 device->rssi = rssi;
9490         }
9491 #endif
9492
9493         g_dbus_emit_property_changed(dbus_conn, device->path,
9494                                                 DEVICE_INTERFACE, "RSSI");
9495 }
9496
9497 void device_set_rssi(struct btd_device *device, int8_t rssi)
9498 {
9499         device_set_rssi_with_delta(device, rssi, RSSI_THRESHOLD);
9500 }
9501
9502 void device_set_tx_power(struct btd_device *device, int8_t tx_power)
9503 {
9504         if (!device)
9505                 return;
9506
9507         if (device->tx_power == tx_power)
9508                 return;
9509
9510         DBG("tx_power %d", tx_power);
9511
9512         device->tx_power = tx_power;
9513
9514         g_dbus_emit_property_changed(dbus_conn, device->path,
9515                                                 DEVICE_INTERFACE, "TxPower");
9516 }
9517
9518 void device_set_flags(struct btd_device *device, uint8_t flags)
9519 {
9520         if (!device)
9521                 return;
9522
9523 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
9524         DBG("flags %d", flags);
9525 #endif
9526
9527         if (device->ad_flags[0] == flags)
9528                 return;
9529
9530         device->ad_flags[0] = flags;
9531
9532         g_dbus_emit_property_changed(dbus_conn, device->path,
9533                                         DEVICE_INTERFACE, "AdvertisingFlags");
9534 }
9535
9536 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9537 void device_set_le_connectable(struct btd_device *device, uint8_t adv_type)
9538 {
9539         if (!device)
9540                 return;
9541
9542         if (device->le_connectable)
9543                 return;
9544
9545         if (adv_type == ADV_TYPE_IND || adv_type == ADV_TYPE_DIRECT_IND)
9546                 device->le_connectable = true;
9547 }
9548 #endif
9549
9550 bool device_is_connectable(struct btd_device *device)
9551 {
9552         if (!device)
9553                 return false;
9554
9555         if (device->bredr)
9556                 return true;
9557
9558 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9559         /* Check the ADV type. Some beacon device can be connectable regardless adv flags  */
9560         return device->le_connectable;
9561 #else
9562         /* Check if either Limited or General discoverable are set */
9563         return (device->ad_flags[0] & 0x03);
9564 #endif
9565 }
9566
9567 static bool start_discovery(gpointer user_data)
9568 {
9569         struct btd_device *device = user_data;
9570
9571         if (device->bredr)
9572                 device_browse_sdp(device, NULL);
9573         else
9574                 device_browse_gatt(device, NULL);
9575
9576         device->discov_timer = 0;
9577
9578         return FALSE;
9579 }
9580
9581 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
9582 {
9583         struct bearer_state *state = get_state(dev, bdaddr_type);
9584
9585         if (state->paired)
9586                 return;
9587
9588         state->paired = true;
9589
9590         /* If the other bearer state was already true we don't need to
9591          * send any property signals.
9592          */
9593         if (dev->bredr_state.paired == dev->le_state.paired)
9594                 return;
9595
9596         if (!state->svc_resolved) {
9597                 dev->pending_paired = true;
9598                 return;
9599         }
9600
9601 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9602         if (dev->bonding == NULL)
9603 #endif
9604                 g_dbus_emit_property_changed(dbus_conn, dev->path,
9605                                                 DEVICE_INTERFACE, "Paired");
9606 }
9607
9608 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type)
9609 {
9610         struct bearer_state *state = get_state(dev, bdaddr_type);
9611
9612         if (!state->paired)
9613                 return;
9614
9615         state->paired = false;
9616
9617         /*
9618          * If the other bearer state is still true we don't need to
9619          * send any property signals or remove device.
9620          */
9621         if (dev->bredr_state.paired != dev->le_state.paired) {
9622                 /* TODO disconnect only unpaired bearer */
9623                 if (state->connected)
9624                         device_request_disconnect(dev, NULL);
9625
9626                 return;
9627         }
9628
9629         g_dbus_emit_property_changed(dbus_conn, dev->path,
9630                                                 DEVICE_INTERFACE, "Paired");
9631
9632         btd_device_set_temporary(dev, true);
9633
9634         if (btd_device_is_connected(dev))
9635                 device_request_disconnect(dev, NULL);
9636         else
9637                 btd_adapter_remove_device(dev->adapter, dev);
9638 }
9639
9640 static void device_auth_req_free(struct btd_device *device)
9641 {
9642         struct authentication_req *authr = device->authr;
9643
9644         if (!authr)
9645                 return;
9646
9647         if (authr->agent)
9648                 agent_unref(authr->agent);
9649
9650         g_free(authr->pincode);
9651         g_free(authr);
9652
9653         device->authr = NULL;
9654 }
9655
9656 bool device_is_retrying(struct btd_device *device)
9657 {
9658         struct bonding_req *bonding = device->bonding;
9659
9660         return bonding && bonding->retry_timer > 0;
9661 }
9662
9663 void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
9664                                                                 uint8_t status)
9665 {
9666         struct bonding_req *bonding = device->bonding;
9667         struct authentication_req *auth = device->authr;
9668         struct bearer_state *state = get_state(device, bdaddr_type);
9669
9670         DBG("bonding %p status 0x%02x", bonding, status);
9671
9672         if (auth && auth->agent)
9673                 agent_cancel(auth->agent);
9674
9675         if (status) {
9676                 device_cancel_authentication(device, TRUE);
9677
9678                 /* Put the device back to the temporary state so that it will be
9679                  * treated as a newly discovered device.
9680                  */
9681                 if (!device_is_paired(device, bdaddr_type) &&
9682                                 !device_is_trusted(device))
9683                         btd_device_set_temporary(device, true);
9684
9685                 device_bonding_failed(device, status);
9686 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9687                 device->legacy_pairing = false;
9688 #endif
9689                 return;
9690         }
9691 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9692                 device->legacy_pairing = false;
9693 #endif
9694         device_auth_req_free(device);
9695
9696         /* If we're already paired nothing more is needed */
9697         if (state->paired) {
9698 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9699                 if (bdaddr_type == BDADDR_BREDR && state->svc_resolved) {
9700                         DBG("Link key has been changed. Report it");
9701                         if (!device->rpa)
9702                                 g_dbus_emit_property_changed(dbus_conn,
9703                                                 device->path, DEVICE_INTERFACE,
9704                                                 "Paired");
9705                         else
9706                                 DBG("Just overwrite Link key");
9707                 } else if (bdaddr_type == BDADDR_LE_RANDOM ||
9708                            bdaddr_type == BDADDR_LE_PUBLIC) {
9709                         DBG("Long Term Key has been changed. Report it");
9710                         g_dbus_emit_property_changed(dbus_conn, device->path,
9711                                         DEVICE_INTERFACE, "Paired");
9712                 }
9713 #endif  /* TIZEN_FEATURE_BLUEZ_MODIFY */
9714                 return;
9715         }
9716
9717         device_set_paired(device, bdaddr_type);
9718
9719         /* If services are already resolved just reply to the pairing
9720          * request
9721          */
9722         if (state->svc_resolved && bonding) {
9723                 /* Attept to store services for this device failed because it
9724                  * was not paired. Now that we're paired retry. */
9725                 store_gatt_db(device);
9726
9727                 g_dbus_send_reply(dbus_conn, bonding->msg, DBUS_TYPE_INVALID);
9728                 bonding_request_free(bonding);
9729                 return;
9730         }
9731
9732         /* If we were initiators start service discovery immediately.
9733          * However if the other end was the initator wait a few seconds
9734          * before SDP. This is due to potential IOP issues if the other
9735          * end starts doing SDP at the same time as us */
9736         if (bonding) {
9737                 DBG("Proceeding with service discovery");
9738                 /* If we are initiators remove any discovery timer and just
9739                  * start discovering services directly */
9740                 if (device->discov_timer) {
9741                         timeout_remove(device->discov_timer);
9742                         device->discov_timer = 0;
9743                 }
9744
9745                 if (bdaddr_type == BDADDR_BREDR)
9746                         device_browse_sdp(device, bonding->msg);
9747                 else
9748                         device_browse_gatt(device, bonding->msg);
9749
9750                 bonding_request_free(bonding);
9751         } else if (!state->svc_resolved) {
9752                 if (!device->browse && !device->discov_timer &&
9753                                 btd_opts.reverse_discovery) {
9754                         /* If we are not initiators and there is no currently
9755                          * active discovery or discovery timer, set discovery
9756                          * timer */
9757                         DBG("setting timer for reverse service discovery");
9758                         device->discov_timer = timeout_add_seconds(
9759                                                         DISCOVERY_TIMER,
9760                                                         start_discovery,
9761                                                         device, NULL);
9762                 }
9763         }
9764 }
9765
9766 static gboolean svc_idle_cb(gpointer user_data)
9767 {
9768         struct svc_callback *cb = user_data;
9769         struct btd_device *dev = cb->dev;
9770
9771         dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9772
9773         cb->func(cb->dev, 0, cb->user_data);
9774
9775         g_free(cb);
9776
9777         return FALSE;
9778 }
9779
9780 unsigned int device_wait_for_svc_complete(struct btd_device *dev,
9781                                                         device_svc_cb_t func,
9782                                                         void *user_data)
9783 {
9784         /* This API is only used for BR/EDR (for now) */
9785         struct bearer_state *state = &dev->bredr_state;
9786         static unsigned int id = 0;
9787         struct svc_callback *cb;
9788
9789         cb = g_new0(struct svc_callback, 1);
9790         cb->func = func;
9791         cb->user_data = user_data;
9792         cb->dev = dev;
9793         cb->id = ++id;
9794
9795         dev->svc_callbacks = g_slist_prepend(dev->svc_callbacks, cb);
9796
9797         if (state->svc_resolved || !btd_opts.reverse_discovery)
9798                 cb->idle_id = g_idle_add(svc_idle_cb, cb);
9799         else if (dev->discov_timer >0) {
9800                 timeout_remove(dev->discov_timer);
9801                 dev->discov_timer = timeout_add_seconds(
9802                                                 0,
9803                                                 start_discovery,
9804                                                 dev, NULL);
9805         }
9806 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9807         else if (!dev->browse) {
9808                 DBG("Service is not going on. Start discovery");
9809                 dev->discov_timer = timeout_add_seconds(
9810                                                 0,
9811                                                 start_discovery,
9812                                                 dev, NULL);
9813         } else
9814                 DBG("Wait for service discovery");
9815 #endif
9816
9817         return cb->id;
9818 }
9819
9820 bool device_remove_svc_complete_callback(struct btd_device *dev,
9821                                                         unsigned int id)
9822 {
9823         GSList *l;
9824
9825         for (l = dev->svc_callbacks; l != NULL; l = g_slist_next(l)) {
9826                 struct svc_callback *cb = l->data;
9827
9828                 if (cb->id != id)
9829                         continue;
9830
9831                 if (cb->idle_id > 0)
9832                         g_source_remove(cb->idle_id);
9833
9834                 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9835                 g_free(cb);
9836
9837                 return true;
9838         }
9839
9840         return false;
9841 }
9842
9843 gboolean device_is_bonding(struct btd_device *device, const char *sender)
9844 {
9845         struct bonding_req *bonding = device->bonding;
9846
9847         if (!device->bonding)
9848                 return FALSE;
9849
9850         if (!sender)
9851                 return TRUE;
9852
9853         return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
9854 }
9855
9856 static gboolean device_bonding_retry(gpointer data)
9857 {
9858         struct btd_device *device = data;
9859         struct btd_adapter *adapter = device_get_adapter(device);
9860         struct bonding_req *bonding = device->bonding;
9861         uint8_t io_cap;
9862         int err;
9863
9864         if (!bonding)
9865                 return FALSE;
9866
9867         DBG("retrying bonding");
9868         bonding->retry_timer = 0;
9869
9870         /* Restart the bonding timer to the begining of the pairing. If not
9871          * pincode request/reply occurs during this retry,
9872          * device_bonding_last_duration() will return a consistent value from
9873          * this point. */
9874         device_bonding_restart_timer(device);
9875
9876         if (bonding->agent)
9877                 io_cap = agent_get_io_capability(bonding->agent);
9878         else
9879                 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
9880
9881         err = adapter_bonding_attempt(adapter, &device->bdaddr,
9882                                 device->bdaddr_type, io_cap);
9883         if (err < 0)
9884                 device_bonding_complete(device, bonding->bdaddr_type,
9885                                                         bonding->status);
9886
9887         return FALSE;
9888 }
9889
9890 int device_bonding_attempt_retry(struct btd_device *device)
9891 {
9892         struct bonding_req *bonding = device->bonding;
9893
9894         /* Ignore other failure events while retrying */
9895         if (device_is_retrying(device))
9896                 return 0;
9897
9898         if (!bonding)
9899                 return -EINVAL;
9900
9901         /* Mark the end of a bonding attempt to compute the delta for the
9902          * retry. */
9903         bonding_request_stop_timer(bonding);
9904
9905         if (btd_adapter_pin_cb_iter_end(bonding->cb_iter))
9906                 return -EINVAL;
9907
9908         DBG("scheduling retry");
9909         bonding->retry_timer = g_timeout_add(3000,
9910                                                 device_bonding_retry, device);
9911         return 0;
9912 }
9913
9914 void device_bonding_failed(struct btd_device *device, uint8_t status)
9915 {
9916         struct bonding_req *bonding = device->bonding;
9917         DBusMessage *reply;
9918
9919         DBG("status %u", status);
9920
9921         if (!bonding) {
9922 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9923                 if (device->legacy_pairing) {
9924                         DBG("Emit LegacyPaired");
9925                         g_dbus_emit_property_changed(dbus_conn, device->path,
9926                                         DEVICE_INTERFACE, "LegacyPaired");
9927                 }
9928 #endif
9929                 return;
9930         }
9931 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9932         btd_device_set_temporary(device, TRUE);
9933 #endif
9934
9935         if (device->authr)
9936                 device_cancel_authentication(device, FALSE);
9937
9938         reply = new_authentication_return(bonding->msg, status);
9939         g_dbus_send_message(dbus_conn, reply);
9940
9941         bonding_request_free(bonding);
9942 }
9943
9944 struct btd_adapter_pin_cb_iter *device_bonding_iter(struct btd_device *device)
9945 {
9946         if (device->bonding == NULL)
9947                 return NULL;
9948
9949         return device->bonding->cb_iter;
9950 }
9951
9952 static void pincode_cb(struct agent *agent, DBusError *err, const char *pin,
9953                                                                 void *data)
9954 {
9955         struct authentication_req *auth = data;
9956         struct btd_device *device = auth->device;
9957
9958         /* No need to reply anything if the authentication already failed */
9959         if (auth->agent == NULL)
9960                 return;
9961
9962         btd_adapter_pincode_reply(device->adapter, &device->bdaddr,
9963                                                 pin, pin ? strlen(pin) : 0);
9964
9965         agent_unref(device->authr->agent);
9966         device->authr->agent = NULL;
9967 }
9968
9969 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
9970 {
9971         struct authentication_req *auth = data;
9972         struct btd_device *device = auth->device;
9973
9974         /* No need to reply anything if the authentication already failed */
9975         if (auth->agent == NULL)
9976                 return;
9977
9978 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9979         btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9980                                                 auth->addr_type,
9981                                                 err ? FALSE : TRUE);
9982         device_set_auth_addr_type(device, BDADDR_BREDR);
9983 #else
9984         btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9985                                                         auth->addr_type,
9986                                                         err ? FALSE : TRUE);
9987 #endif
9988
9989         agent_unref(device->authr->agent);
9990         device->authr->agent = NULL;
9991 }
9992
9993 static void passkey_cb(struct agent *agent, DBusError *err,
9994                                                 uint32_t passkey, void *data)
9995 {
9996         struct authentication_req *auth = data;
9997         struct btd_device *device = auth->device;
9998
9999         /* No need to reply anything if the authentication already failed */
10000         if (auth->agent == NULL)
10001                 return;
10002
10003         if (err)
10004                 passkey = INVALID_PASSKEY;
10005
10006 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10007         btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
10008                                         auth->addr_type, passkey);
10009         device_set_auth_addr_type(device, BDADDR_BREDR);
10010 #else
10011         btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
10012                                                 auth->addr_type, passkey);
10013 #endif
10014
10015         agent_unref(device->authr->agent);
10016         device->authr->agent = NULL;
10017 }
10018
10019 static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
10020 {
10021         struct authentication_req *auth = data;
10022         struct btd_device *device = auth->device;
10023
10024         pincode_cb(agent, err, auth->pincode, auth);
10025
10026         g_free(device->authr->pincode);
10027         device->authr->pincode = NULL;
10028 }
10029
10030 static struct authentication_req *new_auth(struct btd_device *device,
10031                                                 uint8_t addr_type,
10032                                                 auth_type_t type,
10033                                                 gboolean secure)
10034 {
10035         struct authentication_req *auth;
10036         struct agent *agent;
10037         char addr[18];
10038
10039         ba2str(&device->bdaddr, addr);
10040         DBG("Requesting agent authentication for %s", addr);
10041
10042         if (device->authr) {
10043                 error("Authentication already requested for %s", addr);
10044                 return NULL;
10045         }
10046
10047         if (device->bonding && device->bonding->agent)
10048                 agent = agent_ref(device->bonding->agent);
10049         else
10050                 agent = agent_get(NULL);
10051
10052         if (!agent) {
10053                 error("No agent available for request type %d", type);
10054                 return NULL;
10055         }
10056
10057         auth = g_new0(struct authentication_req, 1);
10058         auth->agent = agent;
10059         auth->device = device;
10060         auth->type = type;
10061         auth->addr_type = addr_type;
10062         auth->secure = secure;
10063         device->authr = auth;
10064
10065         return auth;
10066 }
10067
10068 int device_request_pincode(struct btd_device *device, gboolean secure)
10069 {
10070         struct authentication_req *auth;
10071         int err;
10072
10073         auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure);
10074         if (!auth)
10075                 return -EPERM;
10076
10077         err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
10078                                                                 auth, NULL);
10079         if (err < 0) {
10080                 error("Failed requesting authentication");
10081                 device_auth_req_free(device);
10082         }
10083
10084         return err;
10085 }
10086
10087 int device_request_passkey(struct btd_device *device, uint8_t type)
10088 {
10089         struct authentication_req *auth;
10090         int err;
10091
10092         auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE);
10093         if (!auth)
10094                 return -EPERM;
10095
10096         err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
10097                                                                         NULL);
10098         if (err < 0) {
10099                 error("Failed requesting authentication");
10100                 device_auth_req_free(device);
10101         }
10102
10103         return err;
10104 }
10105
10106 int device_confirm_passkey(struct btd_device *device, uint8_t type,
10107                                         int32_t passkey, uint8_t confirm_hint)
10108 {
10109         struct authentication_req *auth;
10110         int err;
10111
10112         /* Just-Works repairing policy */
10113         if (confirm_hint && device_is_paired(device, type)) {
10114                 if (btd_opts.jw_repairing == JW_REPAIRING_NEVER) {
10115                         btd_adapter_confirm_reply(device->adapter,
10116                                                   &device->bdaddr,
10117                                                   type, FALSE);
10118                         return 0;
10119                 } else if (btd_opts.jw_repairing == JW_REPAIRING_ALWAYS) {
10120                         btd_adapter_confirm_reply(device->adapter,
10121                                                   &device->bdaddr,
10122                                                   type, TRUE);
10123                         return 0;
10124                 }
10125         }
10126
10127         auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE);
10128         if (!auth)
10129                 return -EPERM;
10130
10131         auth->passkey = passkey;
10132
10133 #ifndef TIZEN_FEATURE_BLUEZ_CONFIRM_ONLY
10134         if (confirm_hint) {
10135                 if (device->bonding != NULL) {
10136                         /* We know the client has indicated the intent to pair
10137                          * with the peer device, so we can auto-accept.
10138                          */
10139                         btd_adapter_confirm_reply(device->adapter,
10140                                                   &device->bdaddr,
10141                                                   type, TRUE);
10142                         return 0;
10143                 }
10144
10145                 err = agent_request_authorization(auth->agent, device,
10146                                                 confirm_cb, auth, NULL);
10147         } else
10148 #endif
10149                 err = agent_request_confirmation(auth->agent, device, passkey,
10150                                                 confirm_cb, auth, NULL);
10151
10152         if (err < 0) {
10153                 if (err == -EINPROGRESS) {
10154                         /* Already in progress */
10155                         confirm_cb(auth->agent, NULL, auth);
10156                         return 0;
10157                 }
10158
10159                 error("Failed requesting authentication");
10160                 device_auth_req_free(device);
10161         }
10162
10163         return err;
10164 }
10165
10166 int device_notify_passkey(struct btd_device *device, uint8_t type,
10167                                         uint32_t passkey, uint8_t entered)
10168 {
10169         struct authentication_req *auth;
10170         int err;
10171
10172         if (device->authr) {
10173                 auth = device->authr;
10174                 if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
10175                         return -EPERM;
10176         } else {
10177                 auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
10178                 if (!auth)
10179                         return -EPERM;
10180         }
10181
10182         err = agent_display_passkey(auth->agent, device, passkey, entered);
10183         if (err < 0) {
10184                 error("Failed requesting authentication");
10185                 device_auth_req_free(device);
10186         }
10187
10188         return err;
10189 }
10190
10191 int device_notify_pincode(struct btd_device *device, gboolean secure,
10192                                                         const char *pincode)
10193 {
10194         struct authentication_req *auth;
10195         int err;
10196
10197         auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure);
10198         if (!auth)
10199                 return -EPERM;
10200
10201         auth->pincode = g_strdup(pincode);
10202
10203         err = agent_display_pincode(auth->agent, device, pincode,
10204                                         display_pincode_cb, auth, NULL);
10205         if (err < 0) {
10206                 if (err == -EINPROGRESS) {
10207                         /* Already in progress */
10208                         display_pincode_cb(auth->agent, NULL, auth);
10209                         return 0;
10210                 }
10211
10212                 error("Failed requesting authentication");
10213                 device_auth_req_free(device);
10214         }
10215
10216         return err;
10217 }
10218
10219 static void cancel_authentication(struct authentication_req *auth)
10220 {
10221         struct agent *agent;
10222         DBusError err;
10223
10224         if (!auth || !auth->agent)
10225                 return;
10226
10227         agent = auth->agent;
10228         auth->agent = NULL;
10229
10230         dbus_error_init(&err);
10231         dbus_set_error_const(&err, ERROR_INTERFACE ".Canceled", NULL);
10232
10233         switch (auth->type) {
10234         case AUTH_TYPE_PINCODE:
10235                 pincode_cb(agent, &err, NULL, auth);
10236                 break;
10237         case AUTH_TYPE_CONFIRM:
10238                 confirm_cb(agent, &err, auth);
10239                 break;
10240         case AUTH_TYPE_PASSKEY:
10241                 passkey_cb(agent, &err, 0, auth);
10242                 break;
10243         case AUTH_TYPE_NOTIFY_PASSKEY:
10244                 /* User Notify doesn't require any reply */
10245                 break;
10246         case AUTH_TYPE_NOTIFY_PINCODE:
10247                 pincode_cb(agent, &err, NULL, auth);
10248                 break;
10249         }
10250
10251         dbus_error_free(&err);
10252 }
10253
10254 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
10255 {
10256         struct authentication_req *auth = device->authr;
10257         char addr[18];
10258
10259         if (!auth)
10260                 return;
10261
10262         ba2str(&device->bdaddr, addr);
10263         DBG("Canceling authentication request for %s", addr);
10264
10265         if (auth->agent)
10266                 agent_cancel(auth->agent);
10267
10268         if (!aborted)
10269                 cancel_authentication(auth);
10270
10271         device_auth_req_free(device);
10272
10273 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10274         device_set_auth_addr_type(device, BDADDR_BREDR);
10275 #endif
10276 }
10277
10278 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10279 gboolean device_is_authenticating(struct btd_device *dev, uint8_t bdaddr_type)
10280 {
10281         return (dev->auth_bdaddr_type == bdaddr_type && dev->authr != NULL);
10282 }
10283 #else
10284 gboolean device_is_authenticating(struct btd_device *device)
10285 {
10286         return (device->authr != NULL);
10287 }
10288 #endif
10289
10290 struct gatt_primary *btd_device_get_primary(struct btd_device *device,
10291                                                         const char *uuid)
10292 {
10293         GSList *match;
10294
10295         match = g_slist_find_custom(device->primaries, uuid, bt_uuid_strcmp);
10296         if (match)
10297                 return match->data;
10298
10299         return NULL;
10300 }
10301
10302 GSList *btd_device_get_primaries(struct btd_device *device)
10303 {
10304         return device->primaries;
10305 }
10306
10307 struct gatt_db *btd_device_get_gatt_db(struct btd_device *device)
10308 {
10309         if (!device)
10310                 return NULL;
10311
10312         return device->db;
10313 }
10314
10315 struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
10316 {
10317         if (!device)
10318                 return NULL;
10319
10320         return device->client;
10321 }
10322
10323 void *btd_device_get_attrib(struct btd_device *device)
10324 {
10325         if (!device)
10326                 return NULL;
10327
10328         return device->attrib;
10329 }
10330
10331 struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device)
10332 {
10333         if (!device)
10334                 return NULL;
10335
10336         return device->server;
10337 }
10338
10339 void btd_device_gatt_set_service_changed(struct btd_device *device,
10340                                                 uint16_t start, uint16_t end)
10341 {
10342         /*
10343          * TODO: Remove this function and handle service changed via
10344          * gatt-client.
10345          */
10346 }
10347
10348 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
10349 {
10350         GSList *uuid_list;
10351         char *new_uuid;
10352
10353         if (g_slist_find_custom(device->uuids, uuid, bt_uuid_strcmp))
10354                 return;
10355
10356         new_uuid = g_strdup(uuid);
10357         uuid_list = g_slist_append(NULL, new_uuid);
10358
10359         device_probe_profiles(device, uuid_list);
10360
10361         g_free(new_uuid);
10362         g_slist_free(uuid_list);
10363
10364         store_device_info(device);
10365
10366         g_dbus_emit_property_changed(dbus_conn, device->path,
10367                                                 DEVICE_INTERFACE, "UUIDs");
10368 }
10369
10370 static sdp_list_t *read_device_records(struct btd_device *device)
10371 {
10372         char local[18], peer[18];
10373         char filename[PATH_MAX];
10374         GKeyFile *key_file;
10375         GError *gerr = NULL;
10376         char **keys, **handle;
10377         char *str;
10378         sdp_list_t *recs = NULL;
10379         sdp_record_t *rec;
10380
10381         ba2str(btd_adapter_get_address(device->adapter), local);
10382         ba2str(&device->bdaddr, peer);
10383
10384 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10385         if (device->rpa)
10386                 ba2str(device->rpa, peer);
10387 #endif
10388
10389         snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
10390
10391         key_file = g_key_file_new();
10392         if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
10393                 error("Unable to load key file from %s: (%s)", filename,
10394                                                                 gerr->message);
10395                 g_error_free(gerr);
10396         }
10397         keys = g_key_file_get_keys(key_file, "ServiceRecords", NULL, NULL);
10398
10399         for (handle = keys; handle && *handle; handle++) {
10400                 str = g_key_file_get_string(key_file, "ServiceRecords",
10401                                                 *handle, NULL);
10402                 if (!str)
10403                         continue;
10404
10405                 rec = record_from_string(str);
10406                 recs = sdp_list_append(recs, rec);
10407                 g_free(str);
10408         }
10409
10410         g_strfreev(keys);
10411         g_key_file_free(key_file);
10412
10413         return recs;
10414 }
10415
10416 void btd_device_set_record(struct btd_device *device, const char *uuid,
10417                                                         const char *record)
10418 {
10419         /* This API is only used for BR/EDR */
10420         struct bearer_state *state = &device->bredr_state;
10421         struct browse_req *req;
10422         sdp_list_t *recs = NULL;
10423         sdp_record_t *rec;
10424
10425         if (!record)
10426                 return;
10427
10428         req = browse_request_new(device, BROWSE_SDP, NULL);
10429         if (!req)
10430                 return;
10431
10432         rec = record_from_string(record);
10433         recs = sdp_list_append(recs, rec);
10434         update_bredr_services(req, recs);
10435         sdp_list_free(recs, NULL);
10436
10437         device->svc_refreshed = true;
10438         state->svc_resolved = true;
10439
10440         device_probe_profiles(device, req->profiles_added);
10441
10442         /* Propagate services changes */
10443         g_dbus_emit_property_changed(dbus_conn, req->device->path,
10444                                                 DEVICE_INTERFACE, "UUIDs");
10445
10446         device_svc_resolved(device, BROWSE_SDP, device->bdaddr_type, 0);
10447 }
10448
10449 const sdp_record_t *btd_device_get_record(struct btd_device *device,
10450                                                         const char *uuid)
10451 {
10452         /* Load records from storage if there is nothing in cache */
10453         if (!device->tmp_records) {
10454                 device->tmp_records = read_device_records(device);
10455                 if (!device->tmp_records)
10456                         return NULL;
10457         }
10458
10459         return find_record_in_list(device->tmp_records, uuid);
10460 }
10461
10462 struct btd_device *btd_device_ref(struct btd_device *device)
10463 {
10464         __sync_fetch_and_add(&device->ref_count, 1);
10465
10466         return device;
10467 }
10468
10469 void btd_device_unref(struct btd_device *device)
10470 {
10471         if (__sync_sub_and_fetch(&device->ref_count, 1))
10472                 return;
10473
10474         if (!device->path) {
10475                 error("freeing device without an object path");
10476                 return;
10477         }
10478
10479         DBG("Freeing device %s", device->path);
10480
10481         g_dbus_unregister_interface(dbus_conn, device->path, DEVICE_INTERFACE);
10482 }
10483
10484 int device_get_appearance(struct btd_device *device, uint16_t *value)
10485 {
10486         if (device->appearance == 0)
10487                 return -1;
10488
10489         if (value)
10490                 *value = device->appearance;
10491
10492         return 0;
10493 }
10494
10495 void device_set_appearance(struct btd_device *device, uint16_t value)
10496 {
10497         const char *icon = gap_appearance_to_icon(value);
10498
10499         if (device->appearance == value)
10500                 return;
10501
10502         g_dbus_emit_property_changed(dbus_conn, device->path,
10503                                         DEVICE_INTERFACE, "Appearance");
10504
10505         if (icon)
10506                 g_dbus_emit_property_changed(dbus_conn, device->path,
10507                                                 DEVICE_INTERFACE, "Icon");
10508
10509         device->appearance = value;
10510         store_device_info(device);
10511 }
10512
10513 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10514 int device_get_rpa_res_char_value(struct btd_device *device)
10515 {
10516         return device->rpa_res_support;
10517 }
10518
10519 /* Store the RPA Resolution Characteristic Value of remote device.
10520  * This value would be checked before start directed advertising using RPA.
10521  */
10522 void device_set_rpa_res_char_value(struct btd_device *device, uint8_t value)
10523 {
10524         if (device->rpa_res_support == value)
10525                 return;
10526
10527         device->rpa_res_support = value;
10528         store_device_info(device);
10529 }
10530
10531 void device_set_manufacturer_info(struct btd_device *device, struct eir_data *eir)
10532 {
10533         if (!device)
10534                 return;
10535
10536         if (eir->manufacturer_data_len == 0)
10537                 return;
10538
10539         device->manufacturer_data = g_memdup(eir->manufacturer_data,
10540                                                                 eir->manufacturer_data_len);
10541         device->manufacturer_data_len = eir->manufacturer_data_len;
10542
10543         store_device_info(device);
10544
10545         g_dbus_emit_property_changed(dbus_conn, device->path,
10546                                         DEVICE_INTERFACE, "LegacyManufacturerDataLen");
10547
10548         g_dbus_emit_property_changed(dbus_conn, device->path,
10549                                         DEVICE_INTERFACE, "LegacyManufacturerData");
10550 }
10551
10552
10553 void device_set_adv_report_info(struct btd_device *device, void *data, uint8_t data_len,
10554                                 uint8_t adv_type, int8_t rssi)
10555 {
10556         if (!device)
10557                 return;
10558
10559         char peer_addr[18];
10560         const char *paddr = peer_addr;
10561         dbus_int32_t rssi_val = rssi;
10562         int adv_len = data_len;
10563         uint8_t addr_type;
10564
10565         ba2str(&device->bdaddr, peer_addr);
10566
10567         /* Replace address type for paired RPA device since IDA passed from controller */
10568         if (device->rpa) {
10569                 ba2str(device->rpa, peer_addr);
10570                 addr_type = BDADDR_LE_RANDOM;
10571         } else
10572                 addr_type = device->bdaddr_type;
10573
10574         g_dbus_emit_signal(dbus_conn, device->path,
10575                 DEVICE_INTERFACE, "AdvReport",
10576                 DBUS_TYPE_STRING, &paddr,
10577                 DBUS_TYPE_BYTE, &addr_type,
10578                 DBUS_TYPE_BYTE, &adv_type,
10579                 DBUS_TYPE_INT32, &rssi_val,
10580                 DBUS_TYPE_INT32, &adv_len,
10581                 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len,
10582                 DBUS_TYPE_INVALID);
10583 }
10584
10585 void device_set_payload_timeout(struct btd_device *device,
10586                         uint16_t payload_timeout)
10587 {
10588         if (!device)
10589                 return;
10590         if (device->auth_payload_timeout == payload_timeout)
10591                 return;
10592
10593         DBG("Payload timeout %d", payload_timeout);
10594
10595         device->auth_payload_timeout = payload_timeout;
10596         g_dbus_emit_property_changed(dbus_conn, device->path,
10597                                 DEVICE_INTERFACE, "PayloadTimeout");
10598 }
10599
10600 void device_set_disconnect_reason(struct btd_device *device, uint8_t reason)
10601 {
10602         device->disc_reason = reason;
10603 }
10604
10605 void btd_device_disconnect(struct btd_device *device)
10606 {
10607         char dst[18];
10608         struct btd_service *service;
10609         btd_service_state_t state;
10610
10611         ba2str(&device->bdaddr, dst);
10612
10613         DBG("");
10614         if (device->bredr_state.connected == false)
10615                 return;
10616
10617         service = btd_device_get_service(device, HFP_HS_UUID);
10618         if (!service)
10619                 return;
10620
10621         state = btd_service_get_state(service);
10622         DBG("Connected State : %d", state);
10623
10624         if (state == BTD_SERVICE_STATE_DISCONNECTED) {
10625                 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
10626                                                                 BDADDR_BREDR);
10627         }
10628
10629         return;
10630 }
10631
10632 #endif
10633
10634 void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
10635                         uint16_t vendor, uint16_t product, uint16_t version)
10636 {
10637         if (device->vendor_src == source && device->version == version &&
10638                         device->vendor == vendor && device->product == product)
10639                 return;
10640
10641         device->vendor_src = source;
10642         device->vendor = vendor;
10643         device->product = product;
10644         device->version = version;
10645
10646         free(device->modalias);
10647         device->modalias = bt_modalias(source, vendor, product, version);
10648
10649         g_dbus_emit_property_changed(dbus_conn, device->path,
10650                                                 DEVICE_INTERFACE, "Modalias");
10651
10652         store_device_info(device);
10653 }
10654
10655 uint32_t btd_device_get_current_flags(struct btd_device *dev)
10656 {
10657         return dev->current_flags;
10658 }
10659
10660 /* This event is sent immediately after add device on all mgmt sockets.
10661  * Afterwards, it is only sent to mgmt sockets other than the one which called
10662  * set_device_flags.
10663  */
10664 void btd_device_flags_changed(struct btd_device *dev, uint32_t supported_flags,
10665                               uint32_t current_flags)
10666 {
10667         const uint32_t changed_flags = dev->current_flags ^ current_flags;
10668         bool flag_value;
10669
10670         dev->supported_flags = supported_flags;
10671         dev->current_flags = current_flags;
10672
10673         if (!changed_flags)
10674                 return;
10675
10676         if (changed_flags & DEVICE_FLAG_REMOTE_WAKEUP) {
10677                 flag_value = !!(current_flags & DEVICE_FLAG_REMOTE_WAKEUP);
10678                 dev->pending_wake_allowed = flag_value;
10679
10680                 /* If an override exists and doesn't match the current state,
10681                  * apply it. This logic will run after Add Device only and will
10682                  * enable wake for previously paired devices.
10683                  */
10684                 if (dev->wake_override != WAKE_FLAG_DEFAULT) {
10685                         bool wake_allowed =
10686                                 dev->wake_override == WAKE_FLAG_ENABLED;
10687                         if (flag_value != wake_allowed)
10688                                 device_set_wake_allowed(dev, wake_allowed, -1U);
10689                         else
10690                                 device_set_wake_allowed_complete(dev);
10691                 } else {
10692                         device_set_wake_allowed_complete(dev);
10693                 }
10694         }
10695 }
10696
10697 static void service_state_changed(struct btd_service *service,
10698                                                 btd_service_state_t old_state,
10699                                                 btd_service_state_t new_state,
10700                                                 void *user_data)
10701 {
10702         struct btd_profile *profile = btd_service_get_profile(service);
10703         struct btd_device *device = btd_service_get_device(service);
10704         int err = btd_service_get_error(service);
10705
10706 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10707         if (!err) {
10708                 if (old_state == BTD_SERVICE_STATE_UNAVAILABLE ||
10709                                         new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10710                         DBG("Skip status updating ([%d] -> [%d])", old_state, new_state);
10711                 else
10712                         g_dbus_emit_signal(dbus_conn, device->path,
10713                                 DEVICE_INTERFACE, "ProfileStateChanged",
10714                                 DBUS_TYPE_STRING, &profile->remote_uuid,
10715                                 DBUS_TYPE_INT32, &new_state,
10716                                 DBUS_TYPE_INVALID);
10717         }
10718
10719         if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10720                         new_state == BTD_SERVICE_STATE_DISCONNECTING ||
10721                         new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10722 #else
10723         if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10724                                 new_state == BTD_SERVICE_STATE_DISCONNECTING)
10725 #endif
10726                 return;
10727
10728         if (old_state == BTD_SERVICE_STATE_CONNECTING)
10729                 device_profile_connected(device, profile, err);
10730         else if (old_state == BTD_SERVICE_STATE_DISCONNECTING)
10731                 device_profile_disconnected(device, profile, err);
10732 }
10733
10734 struct btd_service *btd_device_get_service(struct btd_device *dev,
10735                                                 const char *remote_uuid)
10736 {
10737         GSList *l;
10738
10739         for (l = dev->services; l != NULL; l = g_slist_next(l)) {
10740                 struct btd_service *service = l->data;
10741                 struct btd_profile *p = btd_service_get_profile(service);
10742
10743                 if (g_str_equal(p->remote_uuid, remote_uuid))
10744                         return service;
10745
10746 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
10747                 if (g_str_equal(HID_UUID, remote_uuid)) {
10748                         if (strcmp(p->name, "hid-device") == 0)
10749                                 return service;
10750                 }
10751 #endif
10752         }
10753
10754         return NULL;
10755 }
10756
10757 void btd_device_init(void)
10758 {
10759         dbus_conn = btd_get_dbus_connection();
10760         service_state_cb_id = btd_service_add_state_cb(
10761                                                 service_state_changed, NULL);
10762 }
10763
10764 void btd_device_cleanup(void)
10765 {
10766         btd_service_remove_state_cb(service_state_cb_id);
10767 }
10768
10769 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10770 void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing)
10771 {
10772         dev->legacy_pairing = legacy_pairing;
10773 }
10774
10775 void btd_device_set_svc_changed_indication(struct btd_device *dev, bool value)
10776 {
10777         bt_att_set_svc_changed_indication_registered(dev->att, value);
10778         store_device_info(dev);
10779 }
10780
10781 bool btd_device_get_svc_changed_indication(struct btd_device *dev)
10782 {
10783         return bt_att_get_svc_changed_indication_registered(dev->att);
10784 }
10785 #endif