resolved the code rule warnings
[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         DBG("-");
235         return BT_STATUS_SUCCESS;
236 }
237
238 int _bt_hal_device_cancel_bond(const bt_bdaddr_t *bd_addr)
239 {
240         int result = BT_STATUS_SUCCESS;
241         DBG("+");
242
243         result = _bt_hal_agent_reply_cancellation();
244         if (result != BT_HAL_ERROR_NONE) {
245                 ERR("Fail to call reply cancellation");
246                 return BT_STATUS_FAIL;
247         }
248
249         _bt_hal_agent_set_canceled(TRUE);
250         return result;
251 }
252
253 int _bt_hal_device_legacy_pin_reply(const bt_bdaddr_t *bd_addr,
254                 gboolean accept, uint8_t pin_len, char *pincode)
255 {
256         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
257         DBG("+");
258
259         if (!agent)
260                 return BT_STATUS_FAIL;
261
262         DBG("pin_len [0x%x]", pin_len);
263         DBG("pincode [%s]", pincode);
264
265         if (accept)
266                 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, pincode, NULL);
267         else
268                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, NULL, NULL);
269
270         DBG("-");
271         return BT_STATUS_SUCCESS;
272 }
273
274 int _bt_hal_device_ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
275                 uint8_t accept, uint32_t passkey)
276 {
277         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
278         DBG("+");
279
280         if (!agent)
281                 return BT_STATUS_FAIL;
282
283         switch (variant) {
284         case BT_SSP_VARIANT_PASSKEY_CONFIRMATION:
285                 DBG("SSP: PASSKEY_CONFIRMATION");
286                 if (accept)
287                         gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
288                 else
289                         gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
290                 break;
291         case BT_SSP_VARIANT_PASSKEY_NOTIFICATION:
292                 DBG("SSP: PASSKEY_NOTIFICATION");
293                 break;
294         case BT_SSP_VARIANT_PASSKEY_ENTRY:
295                 DBG("SSP: PASSKEY_ENTRY");
296                 if (accept) {
297                         char str_passkey[7];
298                         snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
299                         DBG("Passkey [%s]", str_passkey);
300                         gap_agent_reply_passkey(agent, GAP_AGENT_ACCEPT, str_passkey, NULL);
301                 } else
302                         gap_agent_reply_passkey(agent, GAP_AGENT_REJECT, NULL, NULL);
303                 break;
304         case BT_SSP_VARIANT_CONSENT:
305                 DBG("SSP: VARIANT_CONSENT: Unhandled!");
306                 break;
307         default:
308                 break;
309         }
310
311         DBG("-");
312         return BT_STATUS_SUCCESS;
313 }
314
315 int _bt_hal_dbus_get_remote_device_services(const bt_bdaddr_t *remote_addr)
316 {
317         char *device_path = NULL;
318         GDBusProxy *device_proxy = NULL;
319         GDBusConnection *conn;
320         GDBusProxy *adapter_proxy;
321         //char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
322         char *address = NULL;
323         int result = BT_STATUS_SUCCESS;
324         DBG("+");
325
326         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
327
328         _bt_hal_convert_addr_type_to_string(address, remote_addr->address);
329
330         if (remote_addr == NULL) {
331                 result = BT_STATUS_PARM_INVALID;
332                 goto fail;
333         }
334
335         adapter_proxy = _bt_hal_get_adapter_proxy();
336         if (adapter_proxy == NULL) {
337                 result = BT_STATUS_FAIL;
338                 goto fail;
339         }
340
341         conn = _bt_hal_get_system_gconn();
342         if (conn == NULL) {
343                 ERR("Could not get System DBUS Connection");
344                 result = BT_STATUS_FAIL;
345                 goto fail;
346         }
347
348         device_path = _bt_hal_get_device_object_path(address);
349
350         if (device_path == NULL) {
351                 ERR("Remote device is not paired..can not perform SDP!!!");
352                 result = BT_STATUS_FAIL;
353                 goto fail;
354         }
355
356         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
357                         NULL, BT_HAL_BLUEZ_NAME,
358                         device_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
359         g_free(device_path);
360
361         if (device_proxy == NULL) {
362                 ERR("Could not create Device Proxy");
363                 result = BT_STATUS_FAIL;
364                 goto fail;
365         }
366
367
368         g_dbus_proxy_call(device_proxy, "DiscoverServices",
369                         g_variant_new("(s)", ""),
370                         G_DBUS_CALL_FLAGS_NONE,
371                         BT_HAL_MAX_DBUS_TIMEOUT,
372                         NULL,
373                         (GAsyncReadyCallback)__bt_hal_device_service_search_cb,
374                         address);
375
376         return BT_STATUS_SUCCESS;
377
378 fail:
379         g_free(address);
380         return result;
381 }
382
383 int _bt_hal_device_authorize_response(const bt_bdaddr_t *bd_addr, bt_service_id_t service_id,
384                 uint8_t authorize, uint8_t save_settings)
385 {
386         int reply = GAP_AGENT_ACCEPT;
387         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
388         DBG("+");
389
390         if (!agent)
391                 return BT_STATUS_FAIL;
392
393         if (!authorize)
394                 reply = GAP_AGENT_REJECT;
395         else if (authorize && save_settings)
396                 reply = GAP_AGENT_ACCEPT_ALWAYS;
397
398         gap_agent_reply_authorize(agent, reply, NULL);
399
400         DBG("-");
401         return BT_STATUS_SUCCESS;
402 }
403
404 int _bt_hal_device_set_trust(const bt_bdaddr_t *bd_addr, uint8_t trust)
405 {
406         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
407         gchar *device_path = NULL;
408         GDBusProxy *device_proxy;
409         gboolean previous_value;
410         gboolean authorize;
411         GDBusConnection *conn;
412         GError *error = NULL;
413         GVariant *result = NULL;
414         GVariant *temp = NULL;
415         int ret = BT_STATUS_SUCCESS;
416         DBG("+");
417
418         if (!bd_addr)
419                 return BT_STATUS_PARM_INVALID;
420
421         if (trust == 1)
422                 authorize = TRUE;
423         else
424                 authorize = FALSE;
425
426         conn = _bt_hal_get_system_gconn();
427
428         if (conn == NULL) {
429                 ERR("Failed to get DBUS connection");
430                 return BT_STATUS_FAIL;
431         }
432
433         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
434
435         device_path = _bt_hal_get_device_object_path(address);
436
437         if (device_path == NULL) {
438                 ERR("No paired device");
439                 return BT_STATUS_FAIL;
440         }
441
442         DBG("Device path [%s]", device_path);
443         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
444                         NULL, BT_HAL_BLUEZ_NAME,
445                         device_path, BT_HAL_PROPERTIES_INTERFACE,  NULL, &error);
446
447         g_free(device_path);
448
449         if (device_proxy == NULL) {
450                 if (error) {
451                         g_dbus_error_strip_remote_error(error);
452                         ERR("Device proxy get failed %s", error->message);
453                         g_error_free(error);
454                 }
455                 ERR("Failed to get Device Proxy");
456                 return BT_STATUS_FAIL;
457         }
458
459         result = g_dbus_proxy_call_sync(device_proxy, "Get",
460                         g_variant_new("(ss)", BT_HAL_DEVICE_INTERFACE, "Trusted"),
461                         G_DBUS_CALL_FLAGS_NONE,
462                         -1,
463                         NULL,
464                         &error);
465
466         if (error != NULL) {
467                 ERR("Getting property failed: [%s]\n", error->message);
468                 g_error_free(error);
469                 g_object_unref(device_proxy);
470                 return BT_STATUS_FAIL;
471         }
472
473         /* Fetch GVaraint*/
474         g_variant_get(result, "(v)", &temp);
475         previous_value = g_variant_get_boolean(temp);
476         DBG("Previous value [%d]", previous_value);
477
478         /* If the input is same with previous value, return error. */
479         if (previous_value == authorize) {
480                 ERR("Same value: %d", previous_value);
481                 g_object_unref(device_proxy);
482                 g_object_unref(result);
483                 g_object_unref(temp);
484                 return BT_STATUS_PARM_INVALID;
485         }
486
487         DBG("Set authotrize [%d]", authorize);
488         result = g_dbus_proxy_call_sync(device_proxy, "Set",
489                         g_variant_new("(ssv)", BT_HAL_DEVICE_INTERFACE, "Trusted", g_variant_new("b", authorize)),
490                         G_DBUS_CALL_FLAGS_NONE,
491                         -1,
492                         NULL,
493                         &error);
494
495         if (error) {
496                 ERR("SetProperty error: [%s]", error->message);
497                 g_error_free(error);
498                 ret = BT_STATUS_FAIL;
499         }
500
501         g_object_unref(device_proxy);
502
503         if (result)
504                 g_object_unref(result);
505         if (temp)
506                 g_object_unref(temp);
507
508         DBG("-");
509         return ret;
510 }
511
512 static void __bt_hal_device_service_search_cb(GDBusProxy *proxy, GAsyncResult *res,
513                 gpointer user_data)
514 {
515         /* Buffer and propety count management */
516         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
517         struct hal_ev_remote_device_props *ev = (void*) buf;;
518         size_t size = 0;
519
520         GError *err = NULL;
521         int result = BT_HAL_ERROR_NONE;
522         char *address = (char*) user_data;
523         DBG("+");
524
525         g_dbus_proxy_call_finish(proxy, res, &err);
526
527         g_object_unref(proxy);
528
529         /* Check event pointer */
530         if (!event_cb)
531                 event_cb = _bt_hal_get_stack_message_handler();
532         if (!event_cb) {
533                 ERR("event_cb is NULL, can not send Service search results to HAL User");
534                 goto cleanup;
535         }
536
537         if (err != NULL) {
538                 g_dbus_error_strip_remote_error(err);
539                 ERR("Error occured in Proxy call [%s]\n", err->message);
540
541                 if (g_strrstr("Operation canceled", err->message))
542                         result = BT_HAL_ERROR_CANCEL_BY_USER;
543                 else if (g_strrstr("In Progress", err->message))
544                         result = BT_HAL_ERROR_IN_PROGRESS;
545                 else if (g_strrstr("Host is down", err->message))
546                         result = BT_HAL_ERROR_HOST_DOWN;
547                 else
548                         result = BT_HAL_ERROR_CONNECTION_ERROR;
549
550
551                 if (result == BT_HAL_ERROR_HOST_DOWN ||
552                                 result == BT_HAL_ERROR_CONNECTION_ERROR) {
553                         ERR("Service search has failed due to Host Down or connection error, attempt to find properties");
554                         if (__bt_hal_dbus_enquire_remote_device_services(address) == BT_STATUS_SUCCESS)
555                                 goto cleanup;
556
557                 }
558                 goto done;
559         }
560
561         DBG("SDP is successful..lets fetch the device properties..");
562         if (__bt_hal_dbus_enquire_remote_device_services(address) == BT_STATUS_SUCCESS)
563                 goto cleanup;
564 done:
565         ev->status = BT_STATUS_FAIL;
566         ev->num_props = 0;
567         size = sizeof(*ev);
568         ERR("Error: Failed to get Remote device properties after SDP,"
569                         " Num Prop [%d] total size [%d]", ev->num_props, size);
570         event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
571
572 cleanup:
573         if (err)
574                 g_error_free(err);
575         g_free(address);
576 }
577
578 static void __bt_device_parse_services(GVariant *result)
579 {
580         /* Buffer and propety count management */
581         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
582         struct hal_ev_remote_device_props *ev = (void*) buf;;
583         size_t size = 0;
584
585         GVariantIter *property_iter;
586
587         const gchar *key;
588         GVariant *value;
589         const gchar *address = NULL;
590
591         memset(buf, 0, sizeof(buf));
592         size = sizeof(*ev);
593         ev->num_props = 0;
594         ev->status = BT_STATUS_SUCCESS;
595
596         g_variant_get(result, "(a{sv})", &property_iter);
597         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
598                 if (!g_strcmp0(key, "Address")) {
599                         address = g_variant_get_string(value, NULL);
600                         DBG("Address [%s]", address);
601                         _bt_hal_convert_addr_string_to_type(ev->bdaddr, address);
602                 } else if (!g_strcmp0(key, "UUIDs")) {
603                         char **uuid_value;
604                         int uuid_count = 0;
605                         gsize size1 = 0;
606                         int i = 0;
607                         size1 = g_variant_get_size(value);
608                         int num_props_tmp = ev->num_props;
609                         if (size1 > 0) {
610                                 uuid_value = (char **)g_variant_get_strv(value, &size1);
611                                 for (i = 0; uuid_value[i] != NULL; i++)
612                                         uuid_count++;
613                                 /* UUID collection */
614                                 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
615                                 for (i = 0; uuid_value[i] != NULL; i++) {
616                                         char *uuid_str = NULL;
617                                         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
618                                         memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
619                                         uuid_str = g_strdup(uuid_value[i]);
620                                         DBG("UUID string [%s]\n", uuid_str);
621                                         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
622                                         memcpy(uuids + i * BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
623                                         g_free(uuid_str);
624                                 }
625                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
626                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count), uuids);
627                                 ev->num_props = num_props_tmp + 1;
628                                 g_free(uuid_value);
629                         }
630                 } else {
631                         ERR("Unhandled Property:[%s]", key);
632                 }
633         }
634
635         DBG("Send Remote Device services to HAL,"
636                         " Num Prop [%d] total size [%d]", ev->num_props, size);
637         event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
638
639         g_variant_unref(result);
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         DBG("+");
715
716 #if TODO_40
717         /* Terminate ALL system popup */
718         if (headed_plugin_info->plugin_headed_enabled)
719                 headed_plugin_info->headed_plugin->bt_destroy_popup_all();
720 #endif
721
722         g_dbus_proxy_call_finish(proxy, res, &err);
723         device_path = g_dbus_proxy_get_object_path(proxy);
724         DBG("Device path: %s", device_path);
725         _bt_hal_convert_device_path_to_address(device_path, dev_address);
726         DBG("Remote Device address [%s]", dev_address);
727
728         if (err != NULL) {
729                 g_dbus_error_strip_remote_error(err);
730                 ERR("@@@Error occured in CreateBonding [%s]", err->message);
731                 if (g_strrstr(err->message, "Already Exists")) {
732                         ERR("Still bond existing even after remove");
733                         result = BT_STATUS_AUTH_FAILURE;
734                 } else if (g_strrstr(err->message, "Authentication Rejected")) {
735                         INFO("REJECTED");
736                         result = BT_STATUS_AUTH_REJECTED;
737                 } else if (_bt_hal_agent_is_canceled() ||
738                                 g_strrstr(err->message, "Authentication Canceled")) {
739                         INFO("Cancelled by USER");
740                         result = BT_STATUS_AUTH_FAILURE;
741                 } else if (g_strrstr(err->message, "In Progress")) {
742                         INFO("Bond in progress, cancel and retry");
743                 } else if (g_strrstr(err->message, "Authentication Failed")) {
744                         INFO("Authentication Failed");
745                         result = BT_STATUS_AUTH_FAILURE;
746                 } else if (g_strrstr(err->message, "Page Timeout")) {
747                         INFO("Page Timeout");
748                         /* This is the special case
749                            As soon as call bluetooth_bond_device, try to cancel bonding.
750                            In this case, before completing to call 'CreatePairedDevice' method
751                            the procedure is stopped. So 'Cancle' error is not return.
752                          */
753                         result = BT_STATUS_RMT_DEV_DOWN;
754                 } else if (g_strrstr(err->message, BT_HAL_TIMEOUT_MESSAGE)) {
755                         INFO("Timeout");
756                         result = BT_STATUS_FAIL;
757                 } else if (g_strrstr(err->message, "Connection Timeout")) {
758                         /* Pairing request timeout */
759                         result = BT_STATUS_RMT_DEV_DOWN;
760                 } else if (g_strrstr(err->message, "Authentication Timeout")) {
761                         /* Pairing request timeout */
762                         result = BT_STATUS_AUTH_FAILURE;
763                 } else {
764                         DBG("Default case: Pairing failed");
765                         result = BT_STATUS_AUTH_FAILURE;
766                 }
767         }
768
769         if (result == BT_STATUS_AUTH_FAILURE ||
770                         result == BT_STATUS_RMT_DEV_DOWN ||
771                         result == BT_STATUS_AUTH_REJECTED ||
772                         result == BT_STATUS_FAIL) {
773                 DBG("Bonding Failed!!");
774
775                 /* Prepare to send event to HAL bluetooth */
776                 ev.status = result;
777                 ev.state = BT_BOND_STATE_NONE;
778
779                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, dev_address);
780
781                 if (!event_cb)
782                         event_cb = _bt_hal_get_stack_message_handler();
783                 if (event_cb) {
784                         DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
785                         event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
786                 }
787         } else {
788                 DBG("Bonding Success!!");
789         }
790
791         DBG("-");
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         DBG("+");
804
805         g_dbus_proxy_call_finish(proxy, res, &err);
806         if (err != NULL) {
807                 ERR("Error occured in RemoveBonding [%s]\n", err->message);
808                 result = BT_STATUS_FAIL;
809                 g_error_free(err);
810         }
811
812         device_path = (char *)user_data;
813         if (result != BT_STATUS_SUCCESS) {
814                 /* Prepare to send event to HAL bluetooth */
815                 ev.status = result;
816                 ev.state = BT_BOND_STATE_NONE;
817
818                 _bt_hal_convert_device_path_to_address(device_path, dev_address);
819                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, dev_address);
820
821                 if (!event_cb)
822                         event_cb = _bt_hal_get_stack_message_handler();
823                 if (event_cb) {
824                         DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
825                         event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
826                 }
827         }
828         g_free(device_path);
829
830         DBG("-");
831 }
832
833 static gboolean __bt_device_bonded_device_info_cb(gpointer user_data)
834 {
835         /* Buffer and propety count management */
836         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
837         struct hal_ev_remote_device_props *ev = (void*) buf;;
838         size_t size = 0;
839
840         GVariant *result = user_data;
841         GVariantIter *property_iter;
842         GVariantIter *char_value_iter;
843
844         const gchar *address = NULL;
845         const gchar *name = NULL;
846         unsigned int cod = 0;
847         gint rssi = 0;
848         uint8_t trust = 0;
849         uint8_t paired = 0;
850         int connected = 0;
851         GByteArray *manufacturer_data = NULL;
852         const gchar *key;
853         GVariant *value;
854         guint8 char_value;
855         unsigned int data_len = 0;
856         uint8_t is_alias_set;
857
858         memset(buf, 0, sizeof(buf));
859         size = sizeof(*ev);
860         ev->num_props = 0;
861         ev->status = BT_STATUS_SUCCESS;
862
863         g_variant_get(result, "(a{sv})", &property_iter);
864         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
865                 if (!g_strcmp0(key, "Address")) {
866                         address = g_variant_get_string(value, NULL);
867                         DBG("Address [%s]", address);
868                         _bt_hal_convert_addr_string_to_type(ev->bdaddr, address);
869                 } else if (!g_strcmp0(key, "Alias")) {
870                         name = g_variant_get_string(value, NULL);
871                         DBG("Alias [%s]", name);
872                         size += __bt_insert_hal_properties(buf + size,
873                                         HAL_PROP_DEVICE_FRIENDLY_NAME, strlen(name) + 1, name);
874                         ev->num_props++;
875                 } else if (!g_strcmp0(key, "Class")) {
876                         cod = g_variant_get_uint32(value);
877                         DBG("Class [%d]", cod);
878                         size += __bt_insert_hal_properties(buf + size,
879                                         HAL_PROP_DEVICE_CLASS, sizeof(unsigned int), &cod);
880                         ev->num_props++;
881                 } else if (!g_strcmp0(key, "Connected")) {
882                         connected = g_variant_get_byte(value);
883                         DBG("Connected [%d]", connected);
884                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
885                                         sizeof(unsigned int), &connected);
886                         ev->num_props++;
887                 } else if (!g_strcmp0(key, "Paired")) {
888                         paired = (g_variant_get_boolean(value) ? 1 : 0);
889                         DBG("Paired [%d]", paired);
890                         size += __bt_insert_hal_properties(buf + size,
891                                         HAL_PROP_DEVICE_PAIRED, sizeof(uint8_t), &paired);
892                         ev->num_props++;
893                 } else if (!g_strcmp0(key, "Trusted")) {
894                         trust = (g_variant_get_boolean(value) ? 1 : 0);
895                         DBG("Trusted [%d]", trust);
896                         size += __bt_insert_hal_properties(buf + size,
897                                         HAL_PROP_DEVICE_TRUSTED, sizeof(uint8_t), &trust);
898                         ev->num_props++;
899                 } else if (!g_strcmp0(key, "Name")) {
900                         name = g_variant_get_string(value, NULL);
901                         DBG("Name [%s]", name);
902                         size += __bt_insert_hal_properties(buf + size,
903                                         HAL_PROP_DEVICE_NAME, strlen(name) + 1, name);
904                         ev->num_props++;
905                 } else if (!g_strcmp0(key, "RSSI")) {
906                         rssi = g_variant_get_int16(value);
907                         DBG("RSSI [%d]", rssi);
908                         size += __bt_insert_hal_properties(buf + size,
909                                         HAL_PROP_DEVICE_RSSI, sizeof(unsigned int), &rssi);
910                         ev->num_props++;
911                 } else if (!g_strcmp0(key, "UUIDs")) {
912                         char **uuid_value;
913                         int uuid_count = 0;
914                         gsize size1 = 0;
915                         int i = 0;
916                         size1 = g_variant_get_size(value);
917                         int num_props_tmp = ev->num_props;
918                         if (size1 > 0) {
919                                 uuid_value = (char **)g_variant_get_strv(value, &size1);
920                                 for (i = 0; uuid_value[i] != NULL; i++)
921                                         uuid_count++;
922                                 /* UUID collection */
923                                 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
924                                 for (i = 0; uuid_value[i] != NULL; i++) {
925                                         char *uuid_str = NULL;
926                                         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
927                                         memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
928                                         uuid_str = g_strdup(uuid_value[i]);
929                                         DBG("UUID string [%s]\n", uuid_str);
930                                         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
931                                         memcpy(uuids + i * BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
932                                         g_free(uuid_str);
933                                 }
934                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
935                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count), uuids);
936                                 ev->num_props = num_props_tmp + 1;
937                                 g_free(uuid_value);
938                         }
939                 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
940                         data_len = g_variant_get_uint16(value);
941                         DBG("ManufacturerDataLen [%d]", data_len);
942                 } else if (!g_strcmp0(key, "ManufacturerData")) {
943                         manufacturer_data = g_byte_array_new();
944                         g_variant_get(value, "ay", &char_value_iter);
945                         while (g_variant_iter_loop(char_value_iter, "y", &char_value))
946                                 g_byte_array_append(manufacturer_data, &char_value, 1);
947
948                         if (manufacturer_data) {
949                                 if (manufacturer_data->len > 0) {
950                                         size += __bt_insert_hal_properties(
951                                                         buf + size, HAL_PROP_DEVICE_BLE_ADV_DATA,
952                                                         manufacturer_data->len, manufacturer_data->data);
953                                         ev->num_props++;
954                                 }
955                         }
956                         g_byte_array_free(manufacturer_data, FALSE);
957                 } else if (!g_strcmp0(key, "IsAliasSet")) {
958                         is_alias_set = (g_variant_get_boolean(value) ? 1 : 0);
959                         DBG("IsAliasSet: %s", ((is_alias_set == 1) ? "TRUE" : "FALSE"));
960                         size += __bt_insert_hal_properties(buf + size,
961                                         HAL_PROP_DEVICE_IS_ALIAS_SET, sizeof(uint8_t), &is_alias_set);
962                         ev->num_props++;
963                 } else {
964                         ERR("Unhandled Property:[%s]", key);
965                 }
966         }
967
968         DBG("trust: %d, paired: %d", trust, paired);
969         if (!event_cb)
970                 event_cb = _bt_hal_get_stack_message_handler();
971         if (!event_cb) {
972                 ERR("event_cb is NULL");
973                 goto done;
974         }
975
976         if ((paired == 0) && (trust == 0)) {
977                 ev->status = BT_STATUS_FAIL;
978                 ev->num_props = 0;
979                 size = sizeof(*ev);
980                 DBG("Send Remote Device properties event to HAL,"
981                                 " Num Prop [%d] total size [%d]", ev->num_props, size);
982                 event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
983         } else {
984                 if (size > 2) {
985                         DBG("Send Remote Device properties event to HAL,"
986                                 " Num Prop [%d] total size [%d]", ev->num_props, size);
987                         event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
988                 }
989         }
990
991 done:
992         g_variant_unref(result);
993         return FALSE;
994 }
995
996 int _bt_hal_dbus_get_remote_device_properties(bt_bdaddr_t *remote_addr)
997 {
998         char *device_path = NULL;
999         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1000         GError *error = NULL;
1001         GDBusProxy *device_proxy;
1002         GDBusConnection *conn;
1003         GVariant *result;
1004
1005         if (!remote_addr) {
1006                 ERR("Invalid device address ptr received");
1007                 return BT_STATUS_PARM_INVALID;
1008         }
1009
1010         _bt_hal_convert_addr_type_to_string(address, remote_addr->address);
1011         device_path = _bt_hal_get_device_object_path(address);
1012         if (!device_path) {
1013                 ERR("Device not paired");
1014                 return BT_STATUS_FAIL;
1015         }
1016
1017         conn = _bt_hal_get_system_gconn();
1018         if (!conn) {
1019                 g_free(device_path);
1020                 ERR("_bt_hal_get_system_gconn failed");
1021                 return BT_STATUS_FAIL;
1022         }
1023
1024         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1025                         NULL,
1026                         BT_HAL_BLUEZ_NAME,
1027                         device_path,
1028                         BT_HAL_PROPERTIES_INTERFACE,
1029                         NULL, NULL);
1030
1031         if (!device_proxy) {
1032                 ERR("Error creating device_proxy");
1033                 g_free(device_path);
1034                 return BT_STATUS_FAIL;
1035         }
1036
1037         result = g_dbus_proxy_call_sync(device_proxy,
1038                         "GetAll",
1039                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1040                         G_DBUS_CALL_FLAGS_NONE,
1041                         -1,
1042                         NULL,
1043                         &error);
1044
1045         if (!result) {
1046                 ERR("Error occured in Proxy call");
1047                 if (error != NULL) {
1048                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1049                         g_clear_error(&error);
1050                 }
1051                 g_object_unref(device_proxy);
1052                 g_free(device_path);
1053                 return BT_STATUS_FAIL;
1054         }
1055
1056         g_object_unref(device_proxy);
1057         g_free(device_path);
1058         /*
1059          * As we need to provide async callback to user from HAL, simply schedule a
1060          * callback method which will carry actual result
1061          */
1062         g_idle_add(__bt_device_bonded_device_info_cb, (gpointer)result);
1063
1064         DBG("-");
1065         return BT_STATUS_SUCCESS;
1066 }
1067
1068 static int __bt_hal_dbus_set_remote_device_alias(bt_bdaddr_t *remote_addr, char *alias)
1069 {
1070         char address[BT_HAL_ADDRESS_STRING_SIZE];
1071         gchar *device_path = NULL;
1072         GDBusProxy *adapter_proxy;
1073         GDBusProxy *device_proxy;
1074         GError *error = NULL;
1075         GDBusConnection *conn;
1076         GVariant *result;
1077
1078         adapter_proxy = _bt_hal_get_adapter_proxy();
1079                 if (!adapter_proxy) {
1080                         ERR("Could not get Adapter Proxy");
1081                         return BT_STATUS_FAIL;
1082                 }
1083
1084         conn = _bt_hal_get_system_gconn();
1085         if (!conn) {
1086                 ERR("_bt_hal_get_system_gconn failed");
1087                 return BT_STATUS_FAIL;
1088         }
1089
1090         _bt_hal_convert_addr_type_to_string(address, remote_addr->address);
1091         INFO("Address: %s, Alias: %s", address, alias);
1092
1093         device_path = _bt_hal_get_device_object_path(address);
1094         if (device_path == NULL) {
1095                 ERR("No paired device");
1096                 return BT_STATUS_FAIL;
1097         }
1098
1099         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1100                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1101                         BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
1102         g_free(device_path);
1103         if (!device_proxy) {
1104                 ERR("Error creating device_proxy");
1105                 return BT_STATUS_FAIL;
1106         }
1107
1108         result = g_dbus_proxy_call_sync(device_proxy, "Set",
1109                         g_variant_new("(ssv)",
1110                                 BT_HAL_DEVICE_INTERFACE,
1111                                 "Alias", g_variant_new("s", alias)),
1112                         G_DBUS_CALL_FLAGS_NONE,
1113                         -1,
1114                         NULL,
1115                         &error);
1116         g_object_unref(device_proxy);
1117         if (!result) {
1118                 ERR("Error occured in Proxy call");
1119                 if (error != NULL) {
1120                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1121                         g_clear_error(&error);
1122                 }
1123                 return BT_STATUS_FAIL;
1124         }
1125         g_variant_unref(result);
1126
1127         return BT_STATUS_SUCCESS;
1128 }
1129
1130 /* Set Remote Device Properties */
1131 int _bt_hal_dbus_set_remote_device_property(
1132                 bt_bdaddr_t *remote_addr, const bt_property_t *property)
1133 {
1134         int result;
1135
1136         DBG("+");
1137
1138         if (remote_addr == NULL) {
1139                 ERR("Invalid parameters received");
1140                 return BT_STATUS_PARM_INVALID;
1141         }
1142
1143         if (property == NULL || property->val == NULL) {
1144                 ERR("Invalid parameters received");
1145                 return BT_STATUS_PARM_INVALID;
1146         }
1147
1148         switch (property->type) {
1149         case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
1150                 result =  __bt_hal_dbus_set_remote_device_alias(
1151                                 remote_addr, (char *) property->val);
1152                 break;
1153         default:
1154                 result = BT_STATUS_UNSUPPORTED;
1155         }
1156
1157         DBG("Result= [%d]", result);
1158         DBG("-");
1159         return result;
1160 }
1161
1162 int _bt_hal_device_get_connection_state(const bt_bdaddr_t *bd_addr)
1163 {
1164         char address[BT_HAL_ADDRESS_STRING_SIZE];
1165         gchar *device_path = NULL;
1166         GDBusProxy *adapter_proxy;
1167         GDBusProxy *device_proxy;
1168         GError *error = NULL;
1169         GDBusConnection *conn;
1170         GVariant *result;
1171         GVariant *tmp_value = NULL;
1172         GVariant *value = NULL;
1173         gboolean is_connected = FALSE;
1174
1175         if (!bd_addr) {
1176                 ERR("bd_addr is NULL");
1177                 return 0;
1178         }
1179
1180         adapter_proxy = _bt_hal_get_adapter_proxy();
1181         if (!adapter_proxy) {
1182                 ERR("Could not get Adapter Proxy");
1183                 return 0;
1184         }
1185
1186         conn = _bt_hal_get_system_gconn();
1187         if (!conn) {
1188                 ERR("_bt_hal_get_system_gconn failed");
1189                 return 0;
1190         }
1191
1192         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1193         INFO("Address: %s", address);
1194
1195         device_path = _bt_hal_get_device_object_path(address);
1196         if (device_path == NULL) {
1197                 ERR("No paired device");
1198                 return 0;
1199         }
1200
1201         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1202                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1203                         BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
1204         g_free(device_path);
1205         if (!device_proxy) {
1206                 ERR("Error creating device_proxy");
1207                 return 0;
1208         }
1209
1210         result = g_dbus_proxy_call_sync(device_proxy, "GetProperties",
1211                         g_variant_new("(s)", address),
1212                         G_DBUS_CALL_FLAGS_NONE,
1213                         -1,
1214                         NULL,
1215                         &error);
1216         g_object_unref(device_proxy);
1217         if (!result) {
1218                 ERR("Error occured in Proxy call");
1219                 if (error != NULL) {
1220                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1221                         g_clear_error(&error);
1222                 }
1223                 return 0;
1224         }
1225
1226         g_variant_get(result , "(@a{sv})", &value);
1227         g_variant_unref(result);
1228
1229         if (value) {
1230                 tmp_value = g_variant_lookup_value(value,
1231                                 "Connected",
1232                                 G_VARIANT_TYPE_BOOLEAN);
1233                 if (tmp_value) {
1234                         is_connected = g_variant_get_boolean(tmp_value);
1235                         g_variant_unref(tmp_value);
1236                 }
1237                 g_variant_unref(value);
1238         }
1239
1240         if (!is_connected)
1241                 return 0;
1242
1243         return 1;
1244 }
1245
1246 #ifdef TIZEN_BT_HAL
1247 int _bt_hal_device_get_service_connection_state(
1248                 const bt_bdaddr_t *bd_addr, bt_service_id_t rem_svc_id)
1249 {
1250         char address[BT_HAL_ADDRESS_STRING_SIZE];
1251         gchar *device_path = NULL;
1252         GDBusProxy *adapter_proxy;
1253         GDBusProxy *device_proxy;
1254         GError *error = NULL;
1255         GDBusConnection *conn;
1256         GVariant *result;
1257         gboolean is_connected;
1258         char *uuid = NULL;
1259
1260         if (!bd_addr) {
1261                 ERR("bd_addr is NULL");
1262                 return 0;
1263         }
1264
1265         adapter_proxy = _bt_hal_get_adapter_proxy();
1266         if (!adapter_proxy) {
1267                 ERR("Could not get Adapter Proxy");
1268                 return 0;
1269         }
1270
1271         conn = _bt_hal_get_system_gconn();
1272         if (!conn) {
1273                 ERR("_bt_hal_get_system_gconn failed");
1274                 return 0;
1275         }
1276
1277         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1278         INFO("Address: %s: Remote svc_id: %d", address, rem_svc_id);
1279
1280         device_path = _bt_hal_get_device_object_path(address);
1281         if (device_path == NULL) {
1282                 ERR("No paired device");
1283                 return 0;
1284         }
1285
1286         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1287                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1288                         BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1289         g_free(device_path);
1290         if (!device_proxy) {
1291                 ERR("Error creating device_proxy");
1292                 return 0;
1293         }
1294
1295         uuid = _bt_convert_service_id_to_uuid_string(rem_svc_id);
1296         DBG("uuid: %s", uuid);
1297         if (!uuid)
1298                 return 0;
1299
1300         result = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
1301                         g_variant_new("(s)", uuid),
1302                         G_DBUS_CALL_FLAGS_NONE,
1303                         -1,
1304                         NULL,
1305                         &error);
1306         g_free(uuid);
1307         g_object_unref(device_proxy);
1308         if (!result) {
1309                 ERR("Error occured in Proxy call");
1310                 if (error != NULL) {
1311                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1312                         g_clear_error(&error);
1313                 }
1314                 return 0;
1315         }
1316
1317         g_variant_get(result, "(b)", &is_connected);
1318         g_variant_unref(result);
1319
1320         if (!is_connected)
1321                 return 0;
1322
1323         return 1;
1324 }
1325
1326 int _bt_hal_device_set_osp_server(uint32_t type, gboolean enable)
1327 {
1328         GapAgentPrivate *agent = _bt_hal_get_adapter_agent();
1329         gboolean result = FALSE;
1330
1331         DBG("+");
1332         if (!agent)
1333                 return BT_STATUS_FAIL;
1334
1335         if (enable)
1336                 result = _bt_hal_gap_agent_register_osp_server(agent, type);
1337         else
1338                 result = _bt_hal_gap_agent_unregister_osp_server(agent, type);
1339
1340         if (!result)
1341                 return BT_STATUS_FAIL;
1342
1343         DBG("-");
1344         return BT_STATUS_SUCCESS;
1345 }
1346
1347 static char* __bt_hal_get_trusted_profile_uuid(bt_trusted_profile_t profile)
1348 {
1349         switch (profile) {
1350         case BT_TRUSTED_PROFILE_PBAP:
1351                 return g_strdup("00001130-0000-1000-8000-00805f9b34fb");
1352         case BT_TRUSTED_PROFILE_MAP:
1353                 return g_strdup("00001134-0000-1000-8000-00805f9b34fb");
1354         case BT_TRUSTED_PROFILE_SAP:
1355                 return g_strdup("0000112D-0000-1000-8000-00805f9b34fb");
1356         case BT_TRUSTED_PROFILE_HFP_HF:
1357                 return g_strdup("0000111e-0000-1000-8000-00805f9b34fb");
1358         case BT_TRUSTED_PROFILE_A2DP:
1359                 return g_strdup("0000110b-0000-1000-8000-00805f9b34fb");
1360         case BT_TRUSTED_PROFILE_ALL:
1361                 return NULL;
1362         }
1363
1364         return NULL;
1365 }
1366
1367 int _bt_hal_device_set_trusted_profile(const bt_bdaddr_t *bd_addr,
1368                 bt_trusted_profile_t profile, uint8_t trust)
1369 {
1370         char address[BT_HAL_ADDRESS_STRING_SIZE];
1371         gchar *device_path = NULL;
1372         GDBusProxy *adapter_proxy;
1373         GDBusProxy *device_proxy;
1374         GError *error = NULL;
1375         GDBusConnection *conn;
1376         GVariant *result;
1377         char *uuid = NULL;
1378         gboolean trusted;
1379
1380         DBG("+");
1381
1382         if (!bd_addr) {
1383                 ERR("bd_addr is NULL");
1384                 return BT_STATUS_PARM_INVALID;
1385         }
1386
1387         adapter_proxy = _bt_hal_get_adapter_proxy();
1388         if (!adapter_proxy) {
1389                 ERR("Could not get Adapter Proxy");
1390                 return BT_STATUS_FAIL;
1391         }
1392
1393         conn = _bt_hal_get_system_gconn();
1394         if (!conn) {
1395                 ERR("_bt_hal_get_system_gconn failed");
1396                 return BT_STATUS_FAIL;
1397         }
1398
1399         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1400         INFO("Address: %s: profile: %d, trusted: %d", address, profile, trust);
1401
1402         device_path = _bt_hal_get_device_object_path(address);
1403         if (device_path == NULL) {
1404                 ERR("No paired device");
1405                 return BT_STATUS_FAIL;
1406         }
1407
1408         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1409                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1410                         BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1411         g_free(device_path);
1412         if (!device_proxy) {
1413                 ERR("Error creating device_proxy");
1414                 return BT_STATUS_FAIL;
1415         }
1416
1417         uuid = __bt_hal_get_trusted_profile_uuid(profile);
1418         if (!uuid) {
1419                 ERR("Not supported");
1420                 g_object_unref(device_proxy);
1421                 return BT_STATUS_UNSUPPORTED;
1422         }
1423
1424         trusted = ((trust == 0) ? FALSE : TRUE);
1425         DBG("uuid: %s", uuid);
1426         result = g_dbus_proxy_call_sync(device_proxy, "SetTrustedProfile",
1427                         g_variant_new("(sb)", uuid, trusted),
1428                         G_DBUS_CALL_FLAGS_NONE,
1429                         -1, NULL, &error);
1430         g_free(uuid);
1431         g_object_unref(device_proxy);
1432         if (!result) {
1433                 ERR("Failed to Set Profile Trusted, Error occured in proxy call");
1434                 if (error != NULL) {
1435                         ERR("(Error: %s)", error->message);
1436                         g_clear_error(&error);
1437                 }
1438                 return BT_STATUS_FAIL;
1439         }
1440
1441         g_variant_unref(result);
1442
1443         DBG("-");
1444         return BT_STATUS_SUCCESS;
1445 }
1446
1447 static int __hal_get_trusted_value_from_flag(bt_trusted_profile_t profile,
1448                 uint32_t trusted_flag, uint32_t *trusted)
1449 {
1450         DBG("+");
1451
1452         *trusted = 0;
1453         switch (profile) {
1454         case BT_TRUSTED_PROFILE_PBAP:
1455                 /* Bit 0 & 1 - for PBAP Supported */
1456                 trusted_flag = (trusted_flag >> 0);
1457
1458                 if (!(trusted_flag & PROFILE_SUPPORTED))
1459                         return BT_STATUS_UNSUPPORTED;
1460
1461                 *trusted = trusted_flag & PROFILE_TRUSTED;
1462                 DBG("Profile %d, trusted: %s", profile,
1463                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1464                 break;
1465         case BT_TRUSTED_PROFILE_MAP:
1466                 /* Bit 2 & 3 - for MAP Supported */
1467                 trusted_flag = (trusted_flag >> 2);
1468
1469                 if (!(trusted_flag & PROFILE_SUPPORTED))
1470                         return BT_STATUS_UNSUPPORTED;
1471
1472                 *trusted = trusted_flag & PROFILE_TRUSTED;
1473                 DBG("Profile %d, trusted: %s", profile,
1474                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1475                 break;
1476         case BT_TRUSTED_PROFILE_SAP:
1477                 /* Bit 4 & 5 - for SAP Supported */
1478                 trusted_flag = (trusted_flag >> 4);
1479
1480                 if (!(trusted_flag & PROFILE_SUPPORTED))
1481                         return BT_STATUS_UNSUPPORTED;
1482
1483                 *trusted = trusted_flag & PROFILE_TRUSTED;
1484                 DBG("Profile %d, trusted: %s", profile,
1485                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1486                 break;
1487         case BT_TRUSTED_PROFILE_HFP_HF:
1488                 /* Bit 6 & 7 - for HFP_HF Supported */
1489                 trusted_flag = (trusted_flag >> 6);
1490
1491                 if (PROFILE_BLOCKED != (trusted_flag & PROFILE_SUPPORTED))
1492                         *trusted = 1;
1493
1494                 DBG("Profile %d, trusted: %s", profile,
1495                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1496                 break;
1497         case BT_TRUSTED_PROFILE_A2DP:
1498                 /* Bit 8 & 9 - for A2DP Supported */
1499                 trusted_flag = (trusted_flag >> 8);
1500
1501                 if (PROFILE_BLOCKED != (trusted_flag & PROFILE_SUPPORTED))
1502                         *trusted = 1;
1503
1504                 DBG("Profile %d, trusted: %s", profile,
1505                                 ((*trusted == 0) ? "FALSE" : "TRUE"));
1506                 break;
1507         case BT_TRUSTED_PROFILE_ALL:
1508                 /* Return Flag for All profiles*/
1509                 *trusted = trusted_flag;
1510                 return BT_STATUS_SUCCESS;
1511         default:
1512                 return BT_STATUS_UNSUPPORTED;
1513         }
1514
1515         if (0 != *trusted)
1516                 *trusted = 1;
1517
1518         DBG("-");
1519         return BT_STATUS_SUCCESS;
1520 }
1521
1522 int _bt_hal_device_get_trusted_profile(const bt_bdaddr_t *bd_addr,
1523                 bt_trusted_profile_t profile, uint32_t *trusted)
1524 {
1525         char address[BT_HAL_ADDRESS_STRING_SIZE];
1526         gchar *device_path = NULL;
1527         GDBusProxy *adapter_proxy;
1528         GDBusProxy *device_proxy;
1529         GError *error = NULL;
1530         GDBusConnection *conn;
1531         GVariant *result;
1532         GVariant *temp;
1533         uint32_t trusted_flag;
1534
1535         if (!bd_addr) {
1536                 ERR("bd_addr is NULL");
1537                 return BT_STATUS_PARM_INVALID;
1538         }
1539
1540         adapter_proxy = _bt_hal_get_adapter_proxy();
1541         if (!adapter_proxy) {
1542                 ERR("Could not get Adapter Proxy");
1543                 return BT_STATUS_FAIL;
1544         }
1545
1546         conn = _bt_hal_get_system_gconn();
1547         if (!conn) {
1548                 ERR("_bt_hal_get_system_gconn failed");
1549                 return BT_STATUS_FAIL;
1550         }
1551
1552         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1553         INFO("Address: %s: profile: %d", address, profile);
1554
1555         device_path = _bt_hal_get_device_object_path(address);
1556         if (device_path == NULL) {
1557                 ERR("No paired device");
1558                 return BT_STATUS_FAIL;
1559         }
1560
1561         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1562                         NULL, BT_HAL_BLUEZ_NAME, device_path,
1563                         BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
1564         g_free(device_path);
1565         if (!device_proxy) {
1566                 ERR("Error creating device_proxy");
1567                 return BT_STATUS_FAIL;
1568         }
1569
1570         result = g_dbus_proxy_call_sync(device_proxy, "Get",
1571                         g_variant_new("(ss)", BT_HAL_DEVICE_INTERFACE, "TrustedProfiles"),
1572                         G_DBUS_CALL_FLAGS_NONE, -1,
1573                         NULL, &error);
1574         g_object_unref(device_proxy);
1575         if (!result) {
1576                 ERR("Failed to get trusted profile, Error occured in proxy call");
1577                 if (error != NULL) {
1578                         ERR("(Error: %s)", error->message);
1579                         g_clear_error(&error);
1580                 }
1581                 *trusted = 0;
1582                 return BT_STATUS_FAIL;
1583         }
1584
1585         g_variant_get(result, "(v)", &temp);
1586         trusted_flag = g_variant_get_uint32(temp);
1587         DBG("TRUST_FLAG 0x%X", trusted_flag);
1588         g_variant_unref(temp);
1589         g_variant_unref(result);
1590
1591         return __hal_get_trusted_value_from_flag(profile,
1592                         trusted_flag, trusted);
1593 }
1594
1595 int _bt_hal_device_enable_rssi_monitoring(bt_bdaddr_t *bd_addr, uint32_t link_type,
1596                     int low_threshold, int in_range_threshold, int high_threshold)
1597 {
1598         char address[BT_HAL_ADDRESS_STRING_SIZE];
1599         GDBusProxy *adapter_proxy;
1600         GError *error = NULL;
1601         GVariant *result;
1602
1603         DBG("+");
1604
1605         if (!bd_addr) {
1606                 ERR("bd_addr is NULL");
1607                 return BT_STATUS_PARM_INVALID;
1608         }
1609
1610         adapter_proxy = _bt_hal_get_adapter_proxy();
1611         if (!adapter_proxy) {
1612                 ERR("Could not get Adapter Proxy");
1613                 return BT_STATUS_FAIL;
1614         }
1615
1616         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1617         INFO("Address: %s: link_type: %d", address, link_type);
1618
1619         result = g_dbus_proxy_call_sync(adapter_proxy, "EnableRssi",
1620                         g_variant_new("(siiii)", address, link_type,
1621                                 low_threshold, in_range_threshold, high_threshold),
1622                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1623         if (!result) {
1624                 ERR("Proxy call to GetRssiStrength failed");
1625                 if (error) {
1626                         ERR("Dbus Call Error:[%s]", error->message);
1627                         g_error_free(error);
1628                 }
1629                 return BT_STATUS_FAIL;
1630         }
1631
1632         g_variant_unref(result);
1633
1634         DBG("-");
1635         return BT_STATUS_SUCCESS;
1636 }
1637
1638 int _bt_hal_device_get_connected_link_rssi_strength(const bt_bdaddr_t *bd_addr, uint32_t link_type)
1639 {
1640         char address[BT_HAL_ADDRESS_STRING_SIZE];
1641         GDBusProxy *adapter_proxy;
1642         GError *error = NULL;
1643         GVariant *result;
1644
1645         DBG("+");
1646
1647         if (!bd_addr) {
1648                 ERR("bd_addr is NULL");
1649                 return BT_STATUS_PARM_INVALID;
1650         }
1651
1652         adapter_proxy = _bt_hal_get_adapter_proxy();
1653         if (!adapter_proxy) {
1654                 ERR("Could not get Adapter Proxy");
1655                 return BT_STATUS_FAIL;
1656         }
1657
1658         _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
1659         INFO("Address: %s: link_type: %d", address, link_type);
1660
1661         result = g_dbus_proxy_call_sync(adapter_proxy, "GetRssiStrength",
1662                         g_variant_new("(si)", address, link_type),
1663                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1664         if (!result) {
1665                 ERR("Proxy call to GetRssiStrength failed");
1666                 if (error) {
1667                         ERR("Dbus Call Error:[%s]", error->message);
1668                         g_error_free(error);
1669                 }
1670                 return BT_STATUS_FAIL;
1671         }
1672
1673         g_variant_unref(result);
1674
1675         DBG("-");
1676         return BT_STATUS_SUCCESS;
1677 }
1678 #endif