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