Set trusted profile/device in ACCEPT_ALWAYS authorization case
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-device-dbus-handler.c
1 /*
2  * BLUETOOTH HAL
3  *
4  * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
5  *
6  * Contact: Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <string.h>
26
27 #include <glib.h>
28 #include <gio/gio.h>
29 #include <dlog.h>
30 #include <vconf.h>
31
32 #include <bundle_internal.h>
33
34 /* BT HAL Headers */
35 #include "bt-hal.h"
36 #include "bt-hal-log.h"
37 #include "bt-hal-msg.h"
38 #include "bt-hal-utils.h"
39 #include "bt-hal-internal.h"
40 #include "bt-hal-event-receiver.h"
41 #include "bt-hal-dbus-common-utils.h"
42
43 #include "bt-hal-adapter-dbus-handler.h"
44 #include "bt-hal-device-dbus-handler.h"
45 #include "bt-hal-event-receiver.h"
46 #include "bt-hal-agent.h"
47 #include "bt-hal-gap-agent.h"
48
49 #define PROFILE_SUPPORTED 0x03
50 #define PROFILE_TRUSTED 0x02
51 #define PROFILE_BLOCKED 0x01
52
53 static handle_stack_msg event_cb = NULL;
54
55 /* Forward Delcaration */
56 static void __bt_hal_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data);
57
58 static void __bt_hal_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
59                 gpointer user_data);
60 static void __bt_hal_device_service_search_cb(GDBusProxy *proxy, GAsyncResult *res,
61                 gpointer user_data);
62 int __bt_hal_dbus_enquire_remote_device_services(char *address);
63
64 static void __bt_device_parse_services(GVariant *result);
65
66 int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr, unsigned short transport)
67 {
68         GDBusProxy *proxy;
69         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
70
71         GDBusConnection *conn;
72         char *device_path = NULL;
73         GDBusProxy *adapter_proxy;
74         GError *error = NULL;
75         struct hal_ev_bond_state_changed ev;
76         memset(&ev, 0, sizeof(ev));
77
78         DBG("Transport [0x%x] Add [%02x:%02x:%02x:%02x:%02x:%02x]",
79                         transport, bd_addr->address[0], bd_addr->address[1],
80                         bd_addr->address[2], bd_addr->address[3],
81                         bd_addr->address[4], bd_addr->address[5]);
82         conn = _bt_hal_get_system_gconn();
83         if (!conn) {
84                 ERR("Could not get DBUS connection!");
85                 return BT_STATUS_FAIL;
86         }
87
88         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
89         device_path = _bt_hal_get_device_object_path(address);
90
91         if (device_path == NULL) {
92                 ERR("No searched device, attempt to create device");
93                 GVariant *ret = NULL;
94                 adapter_proxy = _bt_hal_get_adapter_proxy();
95                 if (!adapter_proxy) {
96                         ERR("Could not get Adapter Proxy");
97                         return BT_STATUS_FAIL;
98                 }
99
100                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
101                                 g_variant_new("(s)", address),
102                                 G_DBUS_CALL_FLAGS_NONE,
103                                 -1,
104                                 NULL,
105                                 &error);
106
107                 if (error != NULL) {
108                         ERR("CreateDevice Fail: %s", error->message);
109                         g_clear_error(&error);
110                 }
111                 if (ret)
112                         g_variant_unref(ret);
113                 device_path = _bt_hal_get_device_object_path(address);
114
115                 if (device_path == NULL) {
116                         ERR("Device path is still not created!!");
117                         return BT_STATUS_FAIL;
118                 } else {
119                         DBG("Device_path is created[%s]", device_path);
120                 }
121         }
122         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
123                         NULL, BT_HAL_BLUEZ_NAME,
124                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
125
126         g_free(device_path);
127         if (!proxy) {
128                 ERR("Could not get Device Proxy");
129                 return BT_STATUS_FAIL;
130         }
131
132         g_dbus_proxy_call(proxy, "Pair",
133                         g_variant_new("(y)", transport),
134                         G_DBUS_CALL_FLAGS_NONE,
135                         BT_HAL_MAX_DBUS_TIMEOUT,
136                         NULL,
137                         (GAsyncReadyCallback)__bt_hal_bond_device_cb,
138                         NULL);
139
140         /* Prepare to send Bonding event event to HAL bluetooth */
141         ev.status = BT_STATUS_SUCCESS;
142         ev.state = BT_BOND_STATE_BONDING;
143
144         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
145
146         if (!event_cb)
147                 event_cb = _bt_hal_get_stack_message_handler();
148         if (event_cb) {
149                 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
150                 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
151         }
152
153         return BT_STATUS_SUCCESS;
154 }
155
156 int _bt_hal_device_remove_bond(const bt_bdaddr_t *bd_addr)
157 {
158         char *device_path = NULL;
159         GDBusProxy *adapter_proxy = NULL;
160         GDBusProxy *device_proxy = NULL;
161         GDBusConnection *conn;
162         GError *error = NULL;
163         GVariant *ret = NULL;
164         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
165         GVariant *value = NULL;
166         gboolean is_paired = FALSE;
167
168         DBG("Add [%02x:%02x:%02x:%02x:%02x:%02x]",
169                         bd_addr->address[0], bd_addr->address[1],
170                         bd_addr->address[2], bd_addr->address[3],
171                         bd_addr->address[4], bd_addr->address[5]);
172
173         adapter_proxy = _bt_hal_get_adapter_proxy();
174         if (!adapter_proxy) {
175                 ERR("Could not get Adapter Proxy");
176                 return BT_STATUS_FAIL;
177         }
178
179         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
180
181         device_path = _bt_hal_get_device_object_path(address);
182
183         /* This is a special case, bluedroid always sends success to HAL even if device is already removed
184            whereas bluez sends BLUETOOTH_ERROR_NOT_PAIRED. However we will return Failure
185            in case of bluez*/
186         if (device_path == NULL) {
187                 ERR("No paired device");
188                 return BT_STATUS_NOT_PAIRED;
189         }
190
191         conn = _bt_hal_get_system_gconn();
192         if (conn == NULL) {
193                 g_free(device_path);
194                 ERR("conn is NULL");
195                 return BT_STATUS_FAIL;
196         }
197
198         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
199                         NULL, BT_HAL_BLUEZ_NAME,
200                         device_path, BT_HAL_PROPERTIES_INTERFACE,  NULL, NULL);
201         if (device_proxy != NULL) {
202                 ret = g_dbus_proxy_call_sync(device_proxy, "Get",
203                                 g_variant_new("(ss)", BT_HAL_DEVICE_INTERFACE, "Paired"),
204                                 G_DBUS_CALL_FLAGS_NONE,
205                                 -1,
206                                 NULL,
207                                 &error);
208                 g_object_unref(device_proxy);
209                 if (error) {
210                         ERR("Getting property failed: [%s]\n", error->message);
211                         g_error_free(error);
212                         return BT_STATUS_FAIL;
213                 } else {
214                         if (!ret) {
215                                 ERR("No paired device");
216                                 return BT_STATUS_NOT_PAIRED;
217                         }
218
219                         g_variant_get(ret, "(v)", &value);
220                         is_paired = g_variant_get_boolean(value);
221                         DBG("is_paired = %d", is_paired);
222                         g_variant_unref(value);
223                         g_variant_unref(ret);
224                 }
225         }
226
227         if (is_paired == FALSE) {
228                 ERR("No paired device");
229                 return BT_STATUS_NOT_PAIRED;
230         }
231
232         g_dbus_proxy_call(adapter_proxy, "UnpairDevice",
233                         g_variant_new("(o)", device_path),
234                         G_DBUS_CALL_FLAGS_NONE,
235                         BT_HAL_MAX_DBUS_TIMEOUT,
236                         NULL,
237                         (GAsyncReadyCallback)__bt_hal_unbond_device_cb,
238                         (gpointer)device_path);
239
240         return BT_STATUS_SUCCESS;
241 }
242
243 int _bt_hal_device_cancel_bond(const bt_bdaddr_t *bd_addr)
244 {
245         int result = BT_STATUS_SUCCESS;
246         DBG("+");
247
248         result = _bt_hal_agent_reply_cancellation();
249         if (result != BT_HAL_ERROR_NONE) {
250                 ERR("Fail to call reply cancellation");
251                 return BT_STATUS_FAIL;
252         }
253
254         _bt_hal_agent_set_canceled(TRUE);
255         return result;
256 }
257
258 int _bt_hal_device_legacy_pin_reply(const bt_bdaddr_t *bd_addr,
259                 gboolean accept, uint8_t pin_len, char *pincode)
260 {
261         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
262         DBG("+");
263
264         if (!agent)
265                 return BT_STATUS_FAIL;
266
267         DBG("pin_len [0x%x]", pin_len);
268         DBG("pincode [%s]", pincode);
269
270         if (accept)
271                 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, pincode, NULL);
272         else
273                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, NULL, NULL);
274
275         DBG("-");
276         return BT_STATUS_SUCCESS;
277 }
278
279 int _bt_hal_device_ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
280                 uint8_t accept, uint32_t passkey)
281 {
282         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
283         DBG("+");
284
285         if (!agent)
286                 return BT_STATUS_FAIL;
287
288         switch (variant) {
289         case BT_SSP_VARIANT_PASSKEY_CONFIRMATION:
290                 DBG("SSP: PASSKEY_CONFIRMATION");
291                 if (accept)
292                         gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
293                 else
294                         gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
295                 break;
296         case BT_SSP_VARIANT_PASSKEY_NOTIFICATION:
297                 DBG("SSP: PASSKEY_NOTIFICATION");
298                 break;
299         case BT_SSP_VARIANT_PASSKEY_ENTRY:
300                 DBG("SSP: PASSKEY_ENTRY");
301                 if (accept) {
302                         char str_passkey[7];
303                         snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
304                         DBG("Passkey [%s]", str_passkey);
305                         gap_agent_reply_passkey(agent, GAP_AGENT_ACCEPT, str_passkey, NULL);
306                 } else
307                         gap_agent_reply_passkey(agent, GAP_AGENT_REJECT, NULL, NULL);
308                 break;
309         case BT_SSP_VARIANT_CONSENT:
310                 DBG("SSP: VARIANT_CONSENT: Unhandled!");
311                 break;
312         default:
313                 break;
314         }
315
316         DBG("-");
317         return BT_STATUS_SUCCESS;
318 }
319
320 int _bt_hal_dbus_get_remote_device_services(const bt_bdaddr_t *remote_addr)
321 {
322         char *device_path = NULL;
323         GDBusProxy *device_proxy = NULL;
324         GDBusConnection *conn;
325         GDBusProxy *adapter_proxy;
326         //char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
327         char *address = NULL;
328         int result = BT_STATUS_SUCCESS;
329         DBG("+");
330
331         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
332
333         _bt_hal_convert_addr_type_to_string(address, remote_addr->address);
334
335         if (remote_addr == NULL) {
336                 result = BT_STATUS_PARM_INVALID;
337                 goto fail;
338         }
339
340         adapter_proxy = _bt_hal_get_adapter_proxy();
341         if (adapter_proxy == NULL) {
342                 result = BT_STATUS_FAIL;
343                 goto fail;
344         }
345
346         conn = _bt_hal_get_system_gconn();
347         if (conn == NULL) {
348                 ERR("Could not get System DBUS Connection");
349                 result = BT_STATUS_FAIL;
350                 goto fail;
351         }
352
353         device_path = _bt_hal_get_device_object_path(address);
354
355         if (device_path == NULL) {
356                 ERR("Remote device is not paired..can not perform SDP!!!");
357                 result = BT_STATUS_FAIL;
358                 goto fail;
359         }
360
361         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
362                         NULL, BT_HAL_BLUEZ_NAME,
363                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
364         g_free(device_path);
365
366         if (device_proxy == NULL) {
367                 ERR("Could not create Device Proxy");
368                 result = BT_STATUS_FAIL;
369                 goto fail;
370         }
371
372         g_dbus_proxy_call(device_proxy, "DiscoverServices",
373                         g_variant_new("(s)", ""),
374                         G_DBUS_CALL_FLAGS_NONE,
375                         BT_HAL_MAX_DBUS_TIMEOUT,
376                         NULL,
377                         (GAsyncReadyCallback)__bt_hal_device_service_search_cb,
378                         address);
379
380         return BT_STATUS_SUCCESS;
381
382 fail:
383         g_free(address);
384         return result;
385 }
386
387 int _bt_hal_device_authorize_response(const bt_bdaddr_t *bd_addr, bt_service_id_t service_id,
388                 uint8_t authorize, uint8_t save_settings)
389 {
390         int reply = GAP_AGENT_ACCEPT;
391         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
392         DBG("+");
393
394         if (!agent)
395                 return BT_STATUS_FAIL;
396
397         if (!authorize)
398                 reply = GAP_AGENT_REJECT;
399         else if (authorize && save_settings)
400                 reply = GAP_AGENT_ACCEPT_ALWAYS;
401
402         gap_agent_reply_authorize(agent, reply, NULL);
403
404         DBG("-");
405         return BT_STATUS_SUCCESS;
406 }
407
408 int _bt_hal_device_set_trust(const bt_bdaddr_t *bd_addr, uint8_t trust)
409 {
410         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
411         gchar *device_path = NULL;
412         GDBusProxy *device_proxy;
413         gboolean previous_value;
414         gboolean authorize;
415         GDBusConnection *conn;
416         GError *error = NULL;
417         GVariant *result = NULL;
418         GVariant *temp = NULL;
419         int ret = BT_STATUS_SUCCESS;
420         DBG("+");
421
422         if (!bd_addr)
423                 return BT_STATUS_PARM_INVALID;
424
425         if (trust == 1)
426                 authorize = TRUE;
427         else
428                 authorize = FALSE;
429
430         conn = _bt_hal_get_system_gconn();
431
432         if (conn == NULL) {
433                 ERR("Failed to get DBUS connection");
434                 return BT_STATUS_FAIL;
435         }
436
437         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
438
439         device_path = _bt_hal_get_device_object_path(address);
440
441         if (device_path == NULL) {
442                 ERR("No paired device");
443                 return BT_STATUS_FAIL;
444         }
445
446         DBG("Device path [%s]", device_path);
447         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
448                         NULL, BT_HAL_BLUEZ_NAME,
449                         device_path, BT_HAL_PROPERTIES_INTERFACE,  NULL, &error);
450
451         g_free(device_path);
452
453         if (device_proxy == NULL) {
454                 if (error) {
455                         g_dbus_error_strip_remote_error(error);
456                         ERR("Device proxy get failed %s", error->message);
457                         g_error_free(error);
458                 }
459                 ERR("Failed to get Device Proxy");
460                 return BT_STATUS_FAIL;
461         }
462
463         result = g_dbus_proxy_call_sync(device_proxy, "Get",
464                         g_variant_new("(ss)", BT_HAL_DEVICE_INTERFACE, "Trusted"),
465                         G_DBUS_CALL_FLAGS_NONE,
466                         -1,
467                         NULL,
468                         &error);
469
470         if (error != NULL) {
471                 ERR("Getting property failed: [%s]\n", error->message);
472                 g_error_free(error);
473                 g_object_unref(device_proxy);
474                 return BT_STATUS_FAIL;
475         }
476
477         /* Fetch GVaraint*/
478         g_variant_get(result, "(v)", &temp);
479         previous_value = g_variant_get_boolean(temp);
480         DBG("Previous value [%d]", previous_value);
481
482         /* If the input is same with previous value, return error. */
483         if (previous_value == authorize) {
484                 ERR("Same value: %d", previous_value);
485                 g_object_unref(device_proxy);
486                 g_object_unref(result);
487                 g_object_unref(temp);
488                 return BT_STATUS_PARM_INVALID;
489         }
490
491         DBG("Set authorize [%d]", authorize);
492         result = g_dbus_proxy_call_sync(device_proxy, "Set",
493                         g_variant_new("(ssv)", BT_HAL_DEVICE_INTERFACE, "Trusted", g_variant_new("b", authorize)),
494                         G_DBUS_CALL_FLAGS_NONE,
495                         -1,
496                         NULL,
497                         &error);
498
499         if (error) {
500                 ERR("SetProperty error: [%s]", error->message);
501                 g_error_free(error);
502                 ret = BT_STATUS_FAIL;
503         }
504
505         g_object_unref(device_proxy);
506
507         if (result)
508                 g_object_unref(result);
509         if (temp)
510                 g_object_unref(temp);
511
512         DBG("-");
513         return ret;
514 }
515
516 static void __bt_hal_device_service_search_cb(GDBusProxy *proxy, GAsyncResult *res,
517                 gpointer user_data)
518 {
519         /* Buffer and propety count management */
520         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
521         struct hal_ev_remote_device_props *ev = (void*) buf;;
522         size_t size = 0;
523
524         GError *err = NULL;
525         int result = BT_HAL_ERROR_NONE;
526         char *address = (char*) user_data;
527         DBG("+");
528
529         g_dbus_proxy_call_finish(proxy, res, &err);
530         g_object_unref(proxy);
531
532         /* Check event pointer */
533         if (!event_cb)
534                 event_cb = _bt_hal_get_stack_message_handler();
535         if (!event_cb) {
536                 ERR("event_cb is NULL, can not send Service search results to HAL User");
537                 goto cleanup;
538         }
539
540         if (err != NULL) {
541                 g_dbus_error_strip_remote_error(err);
542                 ERR("Error occured in Proxy call [%s]\n", err->message);
543
544                 if (g_strrstr("Operation canceled", err->message))
545                         result = BT_HAL_ERROR_CANCEL_BY_USER;
546                 else if (g_strrstr("In Progress", err->message))
547                         result = BT_HAL_ERROR_IN_PROGRESS;
548                 else if (g_strrstr("Host is down", err->message))
549                         result = BT_HAL_ERROR_HOST_DOWN;
550                 else
551                         result = BT_HAL_ERROR_CONNECTION_ERROR;
552
553
554                 if (result == BT_HAL_ERROR_HOST_DOWN ||
555                                 result == BT_HAL_ERROR_CONNECTION_ERROR) {
556                         ERR("Service search has failed due to Host Down or connection error, attempt to find properties");
557                         if (__bt_hal_dbus_enquire_remote_device_services(address) == BT_STATUS_SUCCESS)
558                                 goto cleanup;
559
560                 }
561                 goto done;
562         }
563
564         DBG("SDP is successful..lets fetch the device properties..");
565         if (__bt_hal_dbus_enquire_remote_device_services(address) == BT_STATUS_SUCCESS)
566                 goto cleanup;
567 done:
568         ev->status = BT_STATUS_FAIL;
569         ev->num_props = 0;
570         size = sizeof(*ev);
571         ERR("Error: Failed to get Remote device properties after SDP,"
572                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
573         event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
574
575 cleanup:
576         if (err)
577                 g_error_free(err);
578         g_free(address);
579 }
580
581 static void __bt_device_parse_services(GVariant *result)
582 {
583         /* Buffer and propety count management */
584         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
585         struct hal_ev_remote_device_props *ev = (void*) buf;;
586         size_t size = 0;
587
588         GVariantIter *property_iter;
589
590         const gchar *key;
591         GVariant *value;
592         const gchar *address = NULL;
593
594         memset(buf, 0, sizeof(buf));
595         size = sizeof(*ev);
596         ev->num_props = 0;
597         ev->status = BT_STATUS_SUCCESS;
598
599         g_variant_get(result, "(a{sv})", &property_iter);
600         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
601                 if (!g_strcmp0(key, "Address")) {
602                         address = g_variant_get_string(value, NULL);
603                         DBG("Address [%s]", address);
604                         _bt_hal_convert_addr_string_to_type(ev->bdaddr, address);
605                 } else if (!g_strcmp0(key, "UUIDs")) {
606                         char **uuid_value;
607                         int uuid_count = 0;
608                         gsize size1 = 0;
609                         int i = 0;
610                         size1 = g_variant_get_size(value);
611                         int num_props_tmp = ev->num_props;
612                         if (size1 > 0) {
613                                 uuid_value = (char **)g_variant_get_strv(value, &size1);
614                                 for (i = 0; uuid_value[i] != NULL; i++)
615                                         uuid_count++;
616                                 /* UUID collection */
617                                 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
618                                 for (i = 0; uuid_value[i] != NULL; i++) {
619                                         char *uuid_str = NULL;
620                                         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
621                                         memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
622                                         uuid_str = g_strdup(uuid_value[i]);
623                                         DBG("UUID string [%s]\n", uuid_str);
624                                         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
625                                         memcpy(uuids + i * BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
626                                         g_free(uuid_str);
627                                 }
628                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
629                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count), uuids);
630                                 ev->num_props = num_props_tmp + 1;
631                                 g_free(uuid_value);
632                         }
633                 } else {
634                         ERR("Unhandled Property:[%s]", key);
635                 }
636         }
637
638         DBG("Send Remote Device services to HAL,"
639                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
640         event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
641
642         g_variant_unref(result);
643         g_variant_iter_free(property_iter);
644 }
645
646 int __bt_hal_dbus_enquire_remote_device_services(char *address)
647 {
648         char *device_path = NULL;
649         GError *error = NULL;
650         GDBusProxy *device_proxy;
651         GDBusConnection *conn;
652         GVariant *result;
653
654         device_path = _bt_hal_get_device_object_path(address);
655         if (!device_path) {
656                 ERR("Device not paired");
657                 return BT_STATUS_FAIL;
658         }
659
660         conn = _bt_hal_get_system_gconn();
661         if (!conn) {
662                 g_free(device_path);
663                 ERR("_bt_hal_get_system_gconn failed");
664                 return BT_STATUS_FAIL;
665         }
666
667         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
668                         NULL,
669                         BT_HAL_BLUEZ_NAME,
670                         device_path,
671                         BT_HAL_PROPERTIES_INTERFACE,
672                         NULL, NULL);
673
674         if (!device_proxy) {
675                 ERR("Error creating device_proxy");
676                 g_free(device_path);
677                 return BT_STATUS_FAIL;
678         }
679
680         result = g_dbus_proxy_call_sync(device_proxy,
681                         "GetAll",
682                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
683                         G_DBUS_CALL_FLAGS_NONE,
684                         -1,
685                         NULL,
686                         &error);
687
688         if (!result) {
689                 ERR("Error occured in Proxy call");
690                 if (error != NULL) {
691                         ERR("Error occured in Proxy call (Error: %s)", error->message);
692                         g_clear_error(&error);
693                 }
694                 g_object_unref(device_proxy);
695                 g_free(device_path);
696                 return BT_STATUS_FAIL;
697         }
698
699         g_object_unref(device_proxy);
700         g_free(device_path);
701
702         /* Fetch Device Services and send to HAL User */
703         __bt_device_parse_services(result);
704
705         DBG("-");
706         return BT_STATUS_SUCCESS;
707 }
708
709 static void __bt_hal_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
710                 gpointer user_data)
711 {
712         GError *err = NULL;
713         const char *device_path;
714         int result = BT_STATUS_SUCCESS;
715         struct hal_ev_bond_state_changed ev;
716         memset(&ev, 0, sizeof(ev));
717         char dev_address[18];
718
719 /* #if TODO_40 */
720         /* Terminate ALL system popup */
721 /*
722         if (headed_plugin_info->plugin_headed_enabled)
723                 headed_plugin_info->headed_plugin->bt_destroy_popup_all();
724 #endif
725 */
726
727         g_dbus_proxy_call_finish(proxy, res, &err);
728         device_path = g_dbus_proxy_get_object_path(proxy);
729         _bt_hal_convert_device_path_to_address(device_path, dev_address);
730         g_object_unref(proxy);
731
732         if (err != NULL) {
733                 g_dbus_error_strip_remote_error(err);
734                 ERR("@@@Error occured in CreateBonding [%s]", err->message);
735                 if (g_strrstr(err->message, "Already Exists")) {
736                         ERR("Bond Already exists");
737                         result = BT_STATUS_ALREADY_CONNECT;
738                 } else if (g_strrstr(err->message, "Authentication Rejected")) {
739                         INFO("REJECTED");
740                         result = BT_STATUS_AUTH_REJECTED;
741                 } else if (_bt_hal_agent_is_canceled() ||
742                                 g_strrstr(err->message, "Authentication Canceled")) {
743                         INFO("Cancelled by USER");
744                         result = BT_STATUS_AUTH_FAILURE;
745                 } else if (g_strrstr(err->message, "In Progress")) {
746                         INFO("Bond in progress, cancel and retry");
747                 } else if (g_strrstr(err->message, "Authentication Failed")) {
748                         INFO("Authentication Failed");
749                         result = BT_STATUS_AUTH_FAILURE;
750                 } else if (g_strrstr(err->message, "Page Timeout")) {
751                         INFO("Page Timeout");
752                         /* This is the special case
753                            As soon as call bluetooth_bond_device, try to cancel bonding.
754                            In this case, before completing to call 'CreatePairedDevice' method
755                            the procedure is stopped. So 'Cancle' error is not return.
756                          */
757                         result = BT_STATUS_RMT_DEV_DOWN;
758                 } else if (g_strrstr(err->message, BT_HAL_TIMEOUT_MESSAGE)) {
759                         INFO("Timeout");
760                         result = BT_STATUS_FAIL;
761                 } else if (g_strrstr(err->message, "Connection Timeout")) {
762                         /* Pairing request timeout */
763                         result = BT_STATUS_RMT_DEV_DOWN;
764                 } else if (g_strrstr(err->message, "Authentication Timeout")) {
765                         /* Pairing request timeout */
766                         result = BT_STATUS_AUTH_FAILURE;
767                 } else {
768                         DBG("Default case: Pairing failed");
769                         result = BT_STATUS_AUTH_FAILURE;
770                 }
771         }
772
773         if (result != BT_STATUS_SUCCESS) {
774                 DBG("Bonding Failed!!");
775
776                 /* Prepare to send event to HAL bluetooth */
777                 ev.status = result;
778                 ev.state = BT_BOND_STATE_NONE;
779
780                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, dev_address);
781
782                 if (!event_cb)
783                         event_cb = _bt_hal_get_stack_message_handler();
784                 if (event_cb) {
785                         DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
786                         event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
787                 }
788         } else {
789                 DBG("Bonding Success!! [%s]", dev_address);
790         }
791
792 }
793
794 static void __bt_hal_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
795                 gpointer user_data)
796 {
797         GError *err = NULL;
798         char *device_path = NULL;
799         char dev_address[18];
800         int result = BT_STATUS_SUCCESS;
801         struct hal_ev_bond_state_changed ev;
802         memset(&ev, 0, sizeof(ev));
803
804         g_dbus_proxy_call_finish(proxy, res, &err);
805         if (err != NULL) {
806                 ERR("Error occured in RemoveBonding [%s]\n", err->message);
807                 result = BT_STATUS_FAIL;
808                 g_error_free(err);
809         }
810
811         device_path = (char *)user_data;
812         if (result != BT_STATUS_SUCCESS) {
813                 /* Prepare to send event to HAL bluetooth */
814                 ev.status = result;
815                 ev.state = BT_BOND_STATE_NONE;
816
817                 _bt_hal_convert_device_path_to_address(device_path, dev_address);
818                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, dev_address);
819
820                 if (!event_cb)
821                         event_cb = _bt_hal_get_stack_message_handler();
822                 if (event_cb) {
823                         DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
824                         event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
825                 }
826         }
827         g_free(device_path);
828 }
829
830 static gboolean __bt_device_bonded_device_info_cb(gpointer user_data)
831 {
832         /* Buffer and propety count management */
833         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
834         struct hal_ev_remote_device_props *ev = (void*) buf;;
835         size_t size = 0;
836
837         GVariant *result = user_data;
838         GVariantIter *property_iter;
839         GVariantIter *char_value_iter;
840
841         const gchar *address = NULL;
842         const gchar *name = NULL;
843         unsigned int cod = 0;
844         gint rssi = 0;
845         uint8_t trust = 0;
846         uint8_t paired = 0;
847         int connected = 0;
848         GByteArray *manufacturer_data = NULL;
849         const gchar *key;
850         GVariant *value;
851         guint8 char_value;
852         unsigned int data_len = 0;
853         uint8_t is_alias_set;
854
855         memset(buf, 0, sizeof(buf));
856         size = sizeof(*ev);
857         ev->num_props = 0;
858         ev->status = BT_STATUS_SUCCESS;
859
860         g_variant_get(result, "(a{sv})", &property_iter);
861         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
862                 if (!g_strcmp0(key, "Address")) {
863                         address = g_variant_get_string(value, NULL);
864                         DBG("Address [%s]", address);
865                         _bt_hal_convert_addr_string_to_type(ev->bdaddr, address);
866                 } else if (!g_strcmp0(key, "Alias")) {
867                         name = g_variant_get_string(value, NULL);
868                         DBG("Alias [%s]", name);
869                         size += __bt_insert_hal_properties(buf + size,
870                                         HAL_PROP_DEVICE_FRIENDLY_NAME, strlen(name) + 1, name);
871                         ev->num_props++;
872                 } else if (!g_strcmp0(key, "Class")) {
873                         cod = g_variant_get_uint32(value);
874                         DBG("Class [%d]", cod);
875                         size += __bt_insert_hal_properties(buf + size,
876                                         HAL_PROP_DEVICE_CLASS, sizeof(unsigned int), &cod);
877                         ev->num_props++;
878                 } else if (!g_strcmp0(key, "Connected")) {
879                         connected = g_variant_get_byte(value);
880                         DBG("Connected [%d]", connected);
881                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
882                                         sizeof(unsigned int), &connected);
883                         ev->num_props++;
884                 } else if (!g_strcmp0(key, "Paired")) {
885                         paired = (g_variant_get_boolean(value) ? 1 : 0);
886                         DBG("Paired [%d]", paired);
887                         size += __bt_insert_hal_properties(buf + size,
888                                         HAL_PROP_DEVICE_PAIRED, sizeof(uint8_t), &paired);
889                         ev->num_props++;
890                 } else if (!g_strcmp0(key, "Trusted")) {
891                         trust = (g_variant_get_boolean(value) ? 1 : 0);
892                         DBG("Trusted [%d]", trust);
893                         size += __bt_insert_hal_properties(buf + size,
894                                         HAL_PROP_DEVICE_TRUSTED, sizeof(uint8_t), &trust);
895                         ev->num_props++;
896                 } else if (!g_strcmp0(key, "Name")) {
897                         name = g_variant_get_string(value, NULL);
898                         DBG("Name [%s]", name);
899                         size += __bt_insert_hal_properties(buf + size,
900                                         HAL_PROP_DEVICE_NAME, strlen(name) + 1, name);
901                         ev->num_props++;
902                 } else if (!g_strcmp0(key, "RSSI")) {
903                         rssi = g_variant_get_int16(value);
904                         DBG("RSSI [%d]", rssi);
905                         size += __bt_insert_hal_properties(buf + size,
906                                         HAL_PROP_DEVICE_RSSI, sizeof(unsigned int), &rssi);
907                         ev->num_props++;
908                 } else if (!g_strcmp0(key, "UUIDs")) {
909                         char **uuid_value;
910                         int uuid_count = 0;
911                         gsize size1 = 0;
912                         int i = 0;
913                         size1 = g_variant_get_size(value);
914                         int num_props_tmp = ev->num_props;
915                         if (size1 > 0) {
916                                 uuid_value = (char **)g_variant_get_strv(value, &size1);
917                                 for (i = 0; uuid_value[i] != NULL; i++)
918                                         uuid_count++;
919                                 /* UUID collection */
920                                 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
921                                 for (i = 0; uuid_value[i] != NULL; i++) {
922                                         char *uuid_str = NULL;
923                                         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
924                                         memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
925                                         uuid_str = g_strdup(uuid_value[i]);
926                                         DBG("[%d] [%s]", i, uuid_str);
927                                         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
928                                         memcpy(uuids + i * BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
929                                         g_free(uuid_str);
930                                 }
931                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
932                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count), uuids);
933                                 ev->num_props = num_props_tmp + 1;
934                                 g_free(uuid_value);
935                         }
936                 } else if (!g_strcmp0(key, "LegacyManufacturerDataLen")) {
937                         data_len = g_variant_get_uint16(value);
938                         DBG("LegacyManufacturerDataLen [%d]", data_len);
939                 } else if (!g_strcmp0(key, "LegacyManufacturerData")) {
940                         manufacturer_data = g_byte_array_new();
941                         g_variant_get(value, "ay", &char_value_iter);
942                         while (g_variant_iter_loop(char_value_iter, "y", &char_value))
943                                 g_byte_array_append(manufacturer_data, &char_value, 1);
944
945                         g_variant_iter_free(char_value_iter);
946
947                         if (manufacturer_data) {
948                                 if (manufacturer_data->len > 0) {
949                                         size += __bt_insert_hal_properties(
950                                                         buf + size, HAL_PROP_DEVICE_BLE_ADV_DATA,
951                                                         manufacturer_data->len, manufacturer_data->data);
952                                         ev->num_props++;
953                                 }
954                         }
955                         g_byte_array_free(manufacturer_data, FALSE);
956                 } else if (!g_strcmp0(key, "IsAliasSet")) {
957                         is_alias_set = (g_variant_get_boolean(value) ? 1 : 0);
958                         DBG("IsAliasSet: %s", ((is_alias_set == 1) ? "TRUE" : "FALSE"));
959                         size += __bt_insert_hal_properties(buf + size,
960                                         HAL_PROP_DEVICE_IS_ALIAS_SET, sizeof(uint8_t), &is_alias_set);
961                         ev->num_props++;
962                 } else {
963                         DBG("Unhandled Property:[%s]", key);
964                 }
965         }
966
967         if (!event_cb)
968                 event_cb = _bt_hal_get_stack_message_handler();
969         if (!event_cb) {
970                 ERR("event_cb is NULL");
971                 goto done;
972         }
973
974         if ((paired == 0) && (trust == 0)) {
975                 ev->status = BT_STATUS_FAIL;
976                 ev->num_props = 0;
977                 size = sizeof(*ev);
978                 DBG("Send Remote Device properties event to HAL,"
979                                 " Num Prop [%d] total size [%zd]", ev->num_props, size);
980                 event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
981         } else {
982                 if (size > 2) {
983                         DBG("Send Remote Device properties event to HAL,"
984                                 " Num Prop [%d] total size [%zd]", ev->num_props, size);
985                         event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
986                 }
987         }
988
989 done:
990         g_variant_unref(result);
991         g_variant_iter_free(property_iter);
992         return FALSE;
993 }
994
995 int _bt_hal_dbus_get_remote_device_properties(bt_bdaddr_t *remote_addr)
996 {
997         char *device_path = NULL;
998         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
999         GError *error = NULL;
1000         GDBusProxy *device_proxy;
1001         GDBusConnection *conn;
1002         GVariant *result;
1003
1004         if (!remote_addr) {
1005                 ERR("Invalid device address ptr received");
1006                 return BT_STATUS_PARM_INVALID;
1007         }
1008
1009         _bt_hal_convert_addr_type_to_string(address, remote_addr->address);
1010         device_path = _bt_hal_get_device_object_path(address);
1011         if (!device_path) {
1012                 ERR("Device not paired");
1013                 return BT_STATUS_FAIL;
1014         }
1015
1016         conn = _bt_hal_get_system_gconn();
1017         if (!conn) {
1018                 g_free(device_path);
1019                 ERR("_bt_hal_get_system_gconn failed");
1020                 return BT_STATUS_FAIL;
1021         }
1022
1023         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1024                         NULL,
1025                         BT_HAL_BLUEZ_NAME,
1026                         device_path,
1027                         BT_HAL_PROPERTIES_INTERFACE,
1028                         NULL, NULL);
1029
1030         if (!device_proxy) {
1031                 ERR("Error creating device_proxy");
1032                 g_free(device_path);
1033                 return BT_STATUS_FAIL;
1034         }
1035
1036         result = g_dbus_proxy_call_sync(device_proxy,
1037                         "GetAll",
1038                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1039                         G_DBUS_CALL_FLAGS_NONE,
1040                         -1,
1041                         NULL,
1042                         &error);
1043
1044         if (!result) {
1045                 ERR("Error occured in Proxy call");
1046                 if (error != NULL) {
1047                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1048                         g_clear_error(&error);
1049                 }
1050                 g_object_unref(device_proxy);
1051                 g_free(device_path);
1052                 return BT_STATUS_FAIL;
1053         }
1054
1055         g_object_unref(device_proxy);
1056         g_free(device_path);
1057         /*
1058          * As we need to provide async callback to user from HAL, simply schedule a
1059          * callback method which will carry actual result
1060          */
1061         g_idle_add(__bt_device_bonded_device_info_cb, (gpointer)result);
1062
1063         return BT_STATUS_SUCCESS;
1064 }
1065
1066 static int __bt_hal_dbus_set_remote_device_alias(bt_bdaddr_t *remote_addr, char *alias)
1067 {
1068         char address[BT_HAL_ADDRESS_STRING_SIZE];
1069         gchar *device_path = NULL;
1070         GDBusProxy *adapter_proxy;
1071         GDBusProxy *device_proxy;
1072         GError *error = NULL;
1073         GDBusConnection *conn;
1074         GVariant *result;
1075
1076         adapter_proxy = _bt_hal_get_adapter_proxy();
1077                 if (!adapter_proxy) {
1078                         ERR("Could not get Adapter Proxy");
1079                         return BT_STATUS_FAIL;
1080                 }
1081
1082         conn = _bt_hal_get_system_gconn();
1083         if (!conn) {
1084                 ERR("_bt_hal_get_system_gconn failed");
1085                 return BT_STATUS_FAIL;
1086         }
1087
1088         _bt_hal_convert_addr_type_to_string(address, remote_addr->address);
1089         INFO("Address: %s, Alias: %s", address, alias);
1090
1091         device_path = _bt_hal_get_device_object_path(address);
1092         if (device_path == NULL) {
1093                 ERR("No paired device");
1094                 return BT_STATUS_FAIL;
1095         }
1096
1097         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1098                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1099                         BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
1100         g_free(device_path);
1101         if (!device_proxy) {
1102                 ERR("Error creating device_proxy");
1103                 return BT_STATUS_FAIL;
1104         }
1105
1106         result = g_dbus_proxy_call_sync(device_proxy, "Set",
1107                         g_variant_new("(ssv)",
1108                                 BT_HAL_DEVICE_INTERFACE,
1109                                 "Alias", g_variant_new("s", alias)),
1110                         G_DBUS_CALL_FLAGS_NONE,
1111                         -1,
1112                         NULL,
1113                         &error);
1114         g_object_unref(device_proxy);
1115         if (!result) {
1116                 ERR("Error occured in Proxy call");
1117                 if (error != NULL) {
1118                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1119                         g_clear_error(&error);
1120                 }
1121                 return BT_STATUS_FAIL;
1122         }
1123         g_variant_unref(result);
1124
1125         return BT_STATUS_SUCCESS;
1126 }
1127
1128 /* Set Remote Device Properties */
1129 int _bt_hal_dbus_set_remote_device_property(
1130                 bt_bdaddr_t *remote_addr, const bt_property_t *property)
1131 {
1132         int result;
1133
1134         if (remote_addr == NULL) {
1135                 ERR("Invalid parameters received");
1136                 return BT_STATUS_PARM_INVALID;
1137         }
1138
1139         if (property == NULL || property->val == NULL) {
1140                 ERR("Invalid parameters received");
1141                 return BT_STATUS_PARM_INVALID;
1142         }
1143
1144         switch (property->type) {
1145         case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
1146                 result =  __bt_hal_dbus_set_remote_device_alias(
1147                                 remote_addr, (char *) property->val);
1148                 break;
1149         default:
1150                 result = BT_STATUS_UNSUPPORTED;
1151         }
1152
1153         DBG("Result [%d]", result);
1154         return result;
1155 }
1156
1157 int _bt_hal_device_get_connection_state(const bt_bdaddr_t *bd_addr)
1158 {
1159         char address[BT_HAL_ADDRESS_STRING_SIZE];
1160         gchar *device_path = NULL;
1161         GDBusProxy *adapter_proxy;
1162         GDBusProxy *device_proxy;
1163         GError *error = NULL;
1164         GDBusConnection *conn;
1165         GVariant *result;
1166         GVariant *tmp_value = NULL;
1167         GVariant *value = NULL;
1168         gboolean is_connected = FALSE;
1169
1170         if (!bd_addr) {
1171                 ERR("bd_addr is NULL");
1172                 return 0;
1173         }
1174
1175         adapter_proxy = _bt_hal_get_adapter_proxy();
1176         if (!adapter_proxy) {
1177                 ERR("Could not get Adapter Proxy");
1178                 return 0;
1179         }
1180
1181         conn = _bt_hal_get_system_gconn();
1182         if (!conn) {
1183                 ERR("_bt_hal_get_system_gconn failed");
1184                 return 0;
1185         }
1186
1187         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1188         DBG("Address: %s", address);
1189
1190         device_path = _bt_hal_get_device_object_path(address);
1191         if (device_path == NULL) {
1192                 ERR("No paired device");
1193                 return 0;
1194         }
1195
1196         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1197                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1198                         BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
1199         g_free(device_path);
1200         if (!device_proxy) {
1201                 ERR("Error creating device_proxy");
1202                 return 0;
1203         }
1204
1205         result = g_dbus_proxy_call_sync(device_proxy, "GetProperties",
1206                         g_variant_new("(s)", address),
1207                         G_DBUS_CALL_FLAGS_NONE,
1208                         -1,
1209                         NULL,
1210                         &error);
1211         g_object_unref(device_proxy);
1212         if (!result) {
1213                 ERR("Error occured in Proxy call");
1214                 if (error != NULL) {
1215                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1216                         g_clear_error(&error);
1217                 }
1218                 return 0;
1219         }
1220
1221         g_variant_get(result , "(@a{sv})", &value);
1222         g_variant_unref(result);
1223
1224         if (value) {
1225                 tmp_value = g_variant_lookup_value(value,
1226                                 "Connected",
1227                                 G_VARIANT_TYPE_BOOLEAN);
1228                 if (tmp_value) {
1229                         is_connected = g_variant_get_boolean(tmp_value);
1230                         g_variant_unref(tmp_value);
1231                 }
1232                 g_variant_unref(value);
1233         }
1234
1235         if (!is_connected)
1236                 return 0;
1237
1238         return 1;
1239 }
1240
1241 #ifdef TIZEN_BT_HAL
1242 int _bt_hal_device_get_service_connection_state(
1243                 const bt_bdaddr_t *bd_addr, bt_service_id_t rem_svc_id)
1244 {
1245         char address[BT_HAL_ADDRESS_STRING_SIZE];
1246         gchar *device_path = NULL;
1247         GDBusProxy *adapter_proxy;
1248         GDBusProxy *device_proxy;
1249         GError *error = NULL;
1250         GDBusConnection *conn;
1251         GVariant *result;
1252         gboolean is_connected;
1253         char *uuid = NULL;
1254
1255         if (!bd_addr) {
1256                 ERR("bd_addr is NULL");
1257                 return 0;
1258         }
1259
1260         adapter_proxy = _bt_hal_get_adapter_proxy();
1261         if (!adapter_proxy) {
1262                 ERR("Could not get Adapter Proxy");
1263                 return 0;
1264         }
1265
1266         conn = _bt_hal_get_system_gconn();
1267         if (!conn) {
1268                 ERR("_bt_hal_get_system_gconn failed");
1269                 return 0;
1270         }
1271
1272         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1273         INFO("Address: %s: Remote svc_id: %d", address + 12, rem_svc_id);
1274
1275         device_path = _bt_hal_get_device_object_path(address);
1276         if (device_path == NULL) {
1277                 ERR("No paired device");
1278                 return 0;
1279         }
1280
1281         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1282                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1283                         BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1284         g_free(device_path);
1285         if (!device_proxy) {
1286                 ERR("Error creating device_proxy");
1287                 return 0;
1288         }
1289
1290         uuid = _bt_convert_service_id_to_uuid_string(rem_svc_id);
1291         DBG("uuid: %s", uuid);
1292         if (!uuid) {
1293                 g_object_unref(device_proxy);
1294                 return 0;
1295         }
1296
1297         result = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
1298                         g_variant_new("(s)", uuid),
1299                         G_DBUS_CALL_FLAGS_NONE,
1300                         -1,
1301                         NULL,
1302                         &error);
1303         g_free(uuid);
1304         g_object_unref(device_proxy);
1305         if (!result) {
1306                 ERR("Error occured in Proxy call");
1307                 if (error != NULL) {
1308                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1309                         g_clear_error(&error);
1310                 }
1311                 return 0;
1312         }
1313
1314         g_variant_get(result, "(b)", &is_connected);
1315         g_variant_unref(result);
1316
1317         if (!is_connected)
1318                 return 0;
1319
1320         return 1;
1321 }
1322
1323 int _bt_hal_device_register_osp_server(uint32_t type, char *uuid, char *path, int fd)
1324 {
1325         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
1326         gboolean result = FALSE;
1327
1328         DBG("+");
1329         if (!agent)
1330                 return BT_STATUS_FAIL;
1331
1332         result = _bt_hal_gap_agent_register_osp_server(agent, type, uuid, path, fd);
1333         if (!result)
1334                 return BT_STATUS_FAIL;
1335
1336         DBG("-");
1337         return BT_STATUS_SUCCESS;
1338 }
1339
1340 int _bt_hal_device_unregister_osp_server(uint32_t type, char *uuid)
1341 {
1342         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
1343         gboolean result = FALSE;
1344
1345         DBG("+");
1346         if (!agent)
1347                 return BT_STATUS_FAIL;
1348
1349         result = _bt_hal_gap_agent_unregister_osp_server(agent, type, uuid);
1350         if (!result)
1351                 return BT_STATUS_FAIL;
1352
1353         DBG("-");
1354         return BT_STATUS_SUCCESS;
1355 }
1356
1357 static char* __bt_hal_get_trusted_profile_uuid(bt_trusted_profile_t profile)
1358 {
1359         switch (profile) {
1360         case BT_TRUSTED_PROFILE_PBAP:
1361                 return g_strdup("00001130-0000-1000-8000-00805f9b34fb");
1362         case BT_TRUSTED_PROFILE_MAP:
1363                 return g_strdup("00001134-0000-1000-8000-00805f9b34fb");
1364         case BT_TRUSTED_PROFILE_SAP:
1365                 return g_strdup("0000112D-0000-1000-8000-00805f9b34fb");
1366         case BT_TRUSTED_PROFILE_HFP_HF:
1367                 return g_strdup("0000111e-0000-1000-8000-00805f9b34fb");
1368         case BT_TRUSTED_PROFILE_A2DP:
1369                 return g_strdup("0000110b-0000-1000-8000-00805f9b34fb");
1370         case BT_TRUSTED_PROFILE_ALL:
1371                 return NULL;
1372         }
1373
1374         return NULL;
1375 }
1376
1377 bt_trusted_profile_t _bt_hal_get_trusted_profile_enum(const char *uuid)
1378 {
1379         if (g_strcmp0("0000112f-0000-1000-8000-00805f9b34fb", uuid) == 0)
1380                 return BT_TRUSTED_PROFILE_PBAP;
1381         else if (g_strcmp0("00001132-0000-1000-8000-00805f9b34fb", uuid) == 0)
1382                 return BT_TRUSTED_PROFILE_MAP;
1383         else if (g_strcmp0("0000112D-0000-1000-8000-00805f9b34fb", uuid) == 0)
1384                 return BT_TRUSTED_PROFILE_SAP;
1385
1386         return 0; /* 0 - Unknown Profile */
1387 }
1388
1389 int _bt_hal_device_set_trusted_profile(const bt_bdaddr_t *bd_addr,
1390                 bt_trusted_profile_t profile, uint8_t trust)
1391 {
1392         char address[BT_HAL_ADDRESS_STRING_SIZE];
1393         gchar *device_path = NULL;
1394         GDBusProxy *adapter_proxy;
1395         GDBusProxy *device_proxy;
1396         GError *error = NULL;
1397         GDBusConnection *conn;
1398         GVariant *result;
1399         char *uuid = NULL;
1400         gboolean trusted;
1401
1402         if (!bd_addr) {
1403                 ERR("bd_addr is NULL");
1404                 return BT_STATUS_PARM_INVALID;
1405         }
1406
1407         adapter_proxy = _bt_hal_get_adapter_proxy();
1408         if (!adapter_proxy) {
1409                 ERR("Could not get Adapter Proxy");
1410                 return BT_STATUS_FAIL;
1411         }
1412
1413         conn = _bt_hal_get_system_gconn();
1414         if (!conn) {
1415                 ERR("_bt_hal_get_system_gconn failed");
1416                 return BT_STATUS_FAIL;
1417         }
1418
1419         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1420         INFO("Address: %s: profile: %d, trusted: %d", address + 12, profile, trust);
1421
1422         device_path = _bt_hal_get_device_object_path(address);
1423         if (device_path == NULL) {
1424                 ERR("No paired device");
1425                 return BT_STATUS_FAIL;
1426         }
1427
1428         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1429                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1430                         BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1431         g_free(device_path);
1432         if (!device_proxy) {
1433                 ERR("Error creating device_proxy");
1434                 return BT_STATUS_FAIL;
1435         }
1436
1437         uuid = __bt_hal_get_trusted_profile_uuid(profile);
1438         if (!uuid) {
1439                 ERR("Not supported");
1440                 g_object_unref(device_proxy);
1441                 return BT_STATUS_UNSUPPORTED;
1442         }
1443
1444         trusted = ((trust == 0) ? FALSE : TRUE);
1445         DBG("uuid: %s", uuid);
1446         result = g_dbus_proxy_call_sync(device_proxy, "SetTrustedProfile",
1447                         g_variant_new("(sb)", uuid, trusted),
1448                         G_DBUS_CALL_FLAGS_NONE,
1449                         -1, NULL, &error);
1450         g_free(uuid);
1451         g_object_unref(device_proxy);
1452         if (!result) {
1453                 ERR("Failed to Set Profile Trusted, Error occured in proxy call");
1454                 if (error != NULL) {
1455                         ERR("(Error: %s)", error->message);
1456                         g_clear_error(&error);
1457                 }
1458                 return BT_STATUS_FAIL;
1459         }
1460
1461         g_variant_unref(result);
1462
1463         return BT_STATUS_SUCCESS;
1464 }
1465
1466 static int __hal_get_trusted_value_from_flag(bt_trusted_profile_t profile,
1467                 uint32_t trusted_flag, uint32_t *trusted)
1468 {
1469         *trusted = 0;
1470         switch (profile) {
1471         case BT_TRUSTED_PROFILE_PBAP:
1472                 /* Bit 0 & 1 - for PBAP Supported */
1473                 trusted_flag = (trusted_flag >> 0);
1474
1475                 if (!(trusted_flag & PROFILE_SUPPORTED))
1476                         return BT_STATUS_UNSUPPORTED;
1477
1478                 *trusted = trusted_flag & PROFILE_TRUSTED;
1479                 DBG("Profile %d, trusted: %s", profile,
1480                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1481                 break;
1482         case BT_TRUSTED_PROFILE_MAP:
1483                 /* Bit 2 & 3 - for MAP Supported */
1484                 trusted_flag = (trusted_flag >> 2);
1485
1486                 if (!(trusted_flag & PROFILE_SUPPORTED))
1487                         return BT_STATUS_UNSUPPORTED;
1488
1489                 *trusted = trusted_flag & PROFILE_TRUSTED;
1490                 DBG("Profile %d, trusted: %s", profile,
1491                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1492                 break;
1493         case BT_TRUSTED_PROFILE_SAP:
1494                 /* Bit 4 & 5 - for SAP Supported */
1495                 trusted_flag = (trusted_flag >> 4);
1496
1497                 if (!(trusted_flag & PROFILE_SUPPORTED))
1498                         return BT_STATUS_UNSUPPORTED;
1499
1500                 *trusted = trusted_flag & PROFILE_TRUSTED;
1501                 DBG("Profile %d, trusted: %s", profile,
1502                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1503                 break;
1504         case BT_TRUSTED_PROFILE_HFP_HF:
1505                 /* Bit 6 & 7 - for HFP_HF Supported */
1506                 trusted_flag = (trusted_flag >> 6);
1507
1508                 if (PROFILE_BLOCKED != (trusted_flag & PROFILE_SUPPORTED))
1509                         *trusted = 1;
1510
1511                 DBG("Profile %d, trusted: %s", profile,
1512                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1513                 break;
1514         case BT_TRUSTED_PROFILE_A2DP:
1515                 /* Bit 8 & 9 - for A2DP Supported */
1516                 trusted_flag = (trusted_flag >> 8);
1517
1518                 if (PROFILE_BLOCKED != (trusted_flag & PROFILE_SUPPORTED))
1519                         *trusted = 1;
1520
1521                 DBG("Profile %d, trusted: %s", profile,
1522                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1523                 break;
1524         case BT_TRUSTED_PROFILE_ALL:
1525                 /* Return Flag for All profiles*/
1526                 *trusted = trusted_flag;
1527                 return BT_STATUS_SUCCESS;
1528         default:
1529                 return BT_STATUS_UNSUPPORTED;
1530         }
1531
1532         if (0 != *trusted)
1533                 *trusted = 1;
1534
1535         return BT_STATUS_SUCCESS;
1536 }
1537
1538 int _bt_hal_device_get_trusted_profile(const bt_bdaddr_t *bd_addr,
1539                 bt_trusted_profile_t profile, uint32_t *trusted)
1540 {
1541         char address[BT_HAL_ADDRESS_STRING_SIZE];
1542         gchar *device_path = NULL;
1543         GDBusProxy *adapter_proxy;
1544         GDBusProxy *device_proxy;
1545         GError *error = NULL;
1546         GDBusConnection *conn;
1547         GVariant *result;
1548         GVariant *temp;
1549         uint32_t trusted_flag;
1550
1551         if (!bd_addr) {
1552                 ERR("bd_addr is NULL");
1553                 return BT_STATUS_PARM_INVALID;
1554         }
1555
1556         adapter_proxy = _bt_hal_get_adapter_proxy();
1557         if (!adapter_proxy) {
1558                 ERR("Could not get Adapter Proxy");
1559                 return BT_STATUS_FAIL;
1560         }
1561
1562         conn = _bt_hal_get_system_gconn();
1563         if (!conn) {
1564                 ERR("_bt_hal_get_system_gconn failed");
1565                 return BT_STATUS_FAIL;
1566         }
1567
1568         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1569         INFO("Address: %s: profile: %d", address + 12, profile);
1570
1571         device_path = _bt_hal_get_device_object_path(address);
1572         if (device_path == NULL) {
1573                 ERR("No paired device");
1574                 return BT_STATUS_FAIL;
1575         }
1576
1577         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1578                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1579                         BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
1580         g_free(device_path);
1581         if (!device_proxy) {
1582                 ERR("Error creating device_proxy");
1583                 return BT_STATUS_FAIL;
1584         }
1585
1586         result = g_dbus_proxy_call_sync(device_proxy, "Get",
1587                         g_variant_new("(ss)", BT_HAL_DEVICE_INTERFACE, "TrustedProfiles"),
1588                         G_DBUS_CALL_FLAGS_NONE, -1,
1589                         NULL, &error);
1590         g_object_unref(device_proxy);
1591         if (!result) {
1592                 ERR("Failed to get trusted profile, Error occured in proxy call");
1593                 if (error != NULL) {
1594                         ERR("(Error: %s)", error->message);
1595                         g_clear_error(&error);
1596                 }
1597                 *trusted = 0;
1598                 return BT_STATUS_FAIL;
1599         }
1600
1601         g_variant_get(result, "(v)", &temp);
1602         trusted_flag = g_variant_get_uint32(temp);
1603         DBG("TRUST_FLAG 0x%X", trusted_flag);
1604         g_variant_unref(temp);
1605         g_variant_unref(result);
1606
1607         return __hal_get_trusted_value_from_flag(profile,
1608                         trusted_flag, trusted);
1609 }
1610
1611 int _bt_hal_device_get_ida(bt_bdaddr_t *bd_addr, bt_bdaddr_t *id_addr)
1612 {
1613         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1614         gchar *device_path = NULL;
1615         const gchar *idaddress = NULL;
1616         GDBusProxy *device_proxy;
1617         GError *error = NULL;
1618         GVariant *result = NULL;
1619         GDBusConnection *conn;
1620         int ret = BT_STATUS_SUCCESS;
1621
1622         if (bd_addr == NULL)
1623                 return BT_STATUS_PARM_INVALID;
1624
1625         conn = _bt_hal_get_system_gconn();
1626
1627         if (!conn) {
1628                 ERR("_bt_hal_get_system_gconn failed");
1629                 return BT_STATUS_FAIL;
1630         }
1631
1632         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1633
1634         DBG("The device_address is: [%s]", address);
1635
1636         device_path = _bt_hal_get_device_object_path(address);
1637
1638         if (!device_path) {
1639                 ERR("_bt_hal_get_device_object_path failed");
1640                 return BT_STATUS_FAIL;
1641         }
1642
1643         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1644                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1645                         BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1646         g_free(device_path);
1647         if (!device_proxy) {
1648                 ERR("Unable to get proxy");
1649                 return BT_STATUS_FAIL;
1650         }
1651
1652         result = g_dbus_proxy_call_sync(device_proxy, "GetIDAddress", NULL,
1653                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1654         if (result == NULL) {
1655                 ERR("Failed to get device ID address");
1656
1657                 ret = BT_STATUS_FAIL;
1658                 if (error != NULL) {
1659                         g_dbus_error_strip_remote_error(error);
1660                         ERR("Error occured in Proxy call [%s]", error->message);
1661                         if (g_strcmp0(error->message, "Does Not Exist") == 0)
1662                                 ERR("Device does not exist");
1663                         g_error_free(error);
1664                 }
1665                 g_object_unref(device_proxy);
1666                 return ret;
1667         }
1668
1669         g_variant_get(result , "(&s)", &idaddress);
1670
1671         DBG_SECURE("ID Address : %s", idaddress);
1672         _bt_hal_convert_addr_string_to_type(id_addr->address, idaddress);
1673
1674         g_variant_unref(result);
1675         g_object_unref(device_proxy);
1676
1677         return ret;
1678 }
1679
1680 int _bt_hal_device_enable_rssi_monitoring(bt_bdaddr_t *bd_addr, uint32_t link_type,
1681                     int low_threshold, int in_range_threshold, int high_threshold)
1682 {
1683         char address[BT_HAL_ADDRESS_STRING_SIZE];
1684         GDBusProxy *adapter_proxy;
1685         GError *error = NULL;
1686         GVariant *result;
1687
1688         DBG("+");
1689
1690         if (!bd_addr) {
1691                 ERR("bd_addr is NULL");
1692                 return BT_STATUS_PARM_INVALID;
1693         }
1694
1695         adapter_proxy = _bt_hal_get_adapter_proxy();
1696         if (!adapter_proxy) {
1697                 ERR("Could not get Adapter Proxy");
1698                 return BT_STATUS_FAIL;
1699         }
1700
1701         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1702         INFO("Address: %s: link_type: %d", address, link_type);
1703
1704         result = g_dbus_proxy_call_sync(adapter_proxy, "EnableRssi",
1705                         g_variant_new("(siiii)", address, link_type,
1706                                 low_threshold, in_range_threshold, high_threshold),
1707                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1708         if (!result) {
1709                 ERR("Proxy call to GetRssiStrength failed");
1710                 if (error) {
1711                         ERR("Dbus Call Error:[%s]", error->message);
1712                         g_error_free(error);
1713                 }
1714                 return BT_STATUS_FAIL;
1715         }
1716
1717         g_variant_unref(result);
1718
1719         DBG("-");
1720         return BT_STATUS_SUCCESS;
1721 }
1722
1723 int _bt_hal_device_get_connected_link_rssi_strength(const bt_bdaddr_t *bd_addr, uint32_t link_type)
1724 {
1725         char address[BT_HAL_ADDRESS_STRING_SIZE];
1726         GDBusProxy *adapter_proxy;
1727         GError *error = NULL;
1728         GVariant *result;
1729
1730         DBG("+");
1731
1732         if (!bd_addr) {
1733                 ERR("bd_addr is NULL");
1734                 return BT_STATUS_PARM_INVALID;
1735         }
1736
1737         adapter_proxy = _bt_hal_get_adapter_proxy();
1738         if (!adapter_proxy) {
1739                 ERR("Could not get Adapter Proxy");
1740                 return BT_STATUS_FAIL;
1741         }
1742
1743         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1744         INFO("Address: %s: link_type: %d", address, link_type);
1745
1746         result = g_dbus_proxy_call_sync(adapter_proxy, "GetRssiStrength",
1747                         g_variant_new("(si)", address, link_type),
1748                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1749         if (!result) {
1750                 ERR("Proxy call to GetRssiStrength failed");
1751                 if (error) {
1752                         ERR("Dbus Call Error:[%s]", error->message);
1753                         g_error_free(error);
1754                 }
1755                 return BT_STATUS_FAIL;
1756         }
1757
1758         g_variant_unref(result);
1759
1760         DBG("-");
1761         return BT_STATUS_SUCCESS;
1762 }
1763
1764
1765 int _bt_hal_device_disconnect(const bt_bdaddr_t *bd_addr)
1766 {
1767         GDBusProxy *proxy;
1768         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1769         GError *error = NULL;
1770         GVariant *result = NULL;
1771         GDBusConnection *conn;
1772         char *device_path = NULL;
1773         DBG("+");
1774
1775         conn = _bt_hal_get_system_gconn();
1776         if (!conn) {
1777                 DBG("Could not get DBUS connection!");
1778                 return BT_STATUS_FAIL;
1779         }
1780
1781         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1782         device_path = _bt_hal_get_device_object_path(address);
1783
1784         if (device_path == NULL) {
1785                 ERR("No created device with address:[%s] in statck", address);
1786                 return BT_STATUS_FAIL;
1787         }
1788         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1789                         NULL, BT_HAL_BLUEZ_NAME,
1790                         device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1791
1792         g_free(device_path);
1793         if (proxy == NULL) {
1794                 ERR("Could not get Device Proxy");
1795                 return BT_STATUS_FAIL;
1796         }
1797
1798         result = g_dbus_proxy_call_sync(proxy, "Disconnect",
1799                         NULL,
1800                         G_DBUS_CALL_FLAGS_NONE,
1801                         -1, NULL,
1802                         &error);
1803
1804         if (error != NULL) {
1805                 ERR("Dbus Call Error:[%s]", error->message);
1806                 g_clear_error(&error);
1807                 g_object_unref(proxy);
1808                 return BT_STATUS_FAIL;
1809         }
1810
1811         g_object_unref(proxy);
1812         if (result)
1813                 g_variant_unref(result);
1814
1815         DBG("-");
1816         return BT_STATUS_SUCCESS;
1817 }
1818 #endif