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