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