Modify the initial value for A2DP pending init
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-adapter-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 "bt-hal.h"
33 #include "bt-hal-log.h"
34 #include "bt-hal-msg.h"
35 #include "bt-hal-utils.h"
36 #include "bt-hal-adapter-le.h"
37
38 #include <bt-hal-adapter-dbus-handler.h>
39 #include <bt-hal-dbus-common-utils.h>
40
41 #define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
42 #define BT_CORE_NAME "org.projectx.bt_core"
43 #define BT_CORE_PATH "/org/projectx/bt_core"
44 #define BT_CORE_INTERFACE "org.projectx.btcore"
45
46 static GDBusProxy *core_proxy = NULL;
47 static GDBusConnection *system_conn = NULL;
48 static handle_stack_msg event_cb = NULL;
49
50 handle_stack_msg _bt_get_adapter_event_cb(void)
51 {
52         if (!event_cb)
53                 return event_cb;
54         else
55                 return NULL;
56 }
57
58 GDBusConnection *__bt_hal_get_system_gconn(void)
59 {
60         DBG("+");
61         if (system_conn == NULL)
62                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
63
64         DBG("-");
65         return system_conn;
66 }
67
68 GDBusProxy *_bt_init_core_proxy(void)
69 {       GDBusProxy *proxy;
70         GDBusConnection *conn;
71
72         DBG("+");
73         conn = __bt_hal_get_system_gconn();
74         if (!conn)
75                 return NULL;
76
77         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
78                         NULL,
79                         BT_CORE_NAME,
80                         BT_CORE_PATH,
81                         BT_CORE_INTERFACE,
82                         NULL, NULL);
83
84         if (!proxy)
85                 return NULL;
86
87         core_proxy = proxy;
88
89         DBG("-");
90         return proxy;
91 }
92
93 static GDBusProxy *__bt_get_core_proxy(void)
94 {
95         return (core_proxy) ? core_proxy : _bt_init_core_proxy();
96 }
97
98 /* To send stack event to hal-bluetooth handler */
99 void _bt_hal_dbus_store_stack_msg_cb(handle_stack_msg cb)
100 {
101         event_cb = cb;
102 }
103
104 int _bt_hal_enable_core(void)
105 {
106         DBG("");
107         GDBusProxy *proxy;
108         GVariant *result;
109         GError *error = NULL;
110
111         proxy = __bt_get_core_proxy();
112         if(!proxy)
113                 return BT_HAL_ERROR_INTERNAL;
114
115         /* Clean up the process */
116         result = g_dbus_proxy_call_sync(proxy,
117                                "EnableCore",
118                                NULL,
119                                G_DBUS_CALL_FLAGS_NONE,
120                               -1,
121                               NULL,
122                                &error);
123
124         if (!result) {
125                 if (error != NULL) {
126                         ERR("Bt core call failed(Error: %s)", error->message);
127                         g_clear_error(&error);
128                 } else
129                         ERR("Bt core call failed");
130                 return BT_HAL_ERROR_INTERNAL;
131         }
132
133         g_variant_unref(result);
134         return BT_HAL_ERROR_NONE;
135 }
136
137 static gboolean __bt_hal_send_adapter_event(gpointer user_data)
138 {
139         struct hal_ev_adapter_state_changed ev;
140         gboolean *enable = (gboolean *)user_data;
141
142         if (*enable == TRUE)
143                 ev.state = HAL_POWER_ON;
144         else
145                 ev.state = HAL_POWER_OFF;
146
147         if (!event_cb)
148                 event_cb = _bt_get_adapter_event_cb();
149
150         if (event_cb)
151                 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
152
153         g_free(enable);
154         return false;
155 }
156
157 static gboolean __bt_hal_send_le_event(gpointer user_data)
158 {
159         struct hal_ev_le_state_changed ev;
160         gboolean *enable = (gboolean *)user_data;
161
162         if (*enable == TRUE)
163                 ev.state = HAL_POWER_ON;
164         else
165                 ev.state = HAL_POWER_OFF;
166
167         if (!event_cb)
168                 event_cb = _bt_get_adapter_event_cb();
169
170         if (event_cb)
171                 event_cb(HAL_EV_LE_STATE_CHANGED, &ev, sizeof(ev));
172
173         g_free(enable);
174         return false;
175
176 }
177
178 int _bt_hal_dbus_enable_adapter(void)
179 {
180         GDBusProxy *proxy;
181         GError *error = NULL;
182         GVariant *result = NULL;
183         unsigned char powered = 0;
184
185         DBG("+");
186
187         int le_value = VCONFKEY_BT_LE_STATUS_OFF;
188         if (vconf_get_int(VCONFKEY_BT_LE_STATUS, &le_value))
189                 ERR("fail to get vconf key!");
190
191         if (_bt_hal_get_adapter_powered_state(&powered) == BT_STATUS_FAIL)
192                 ERR("_bt_hal_get_adapter_powered_state failed");
193
194         /*if LE is enabled and bluez is UP , send event from here and return.*/
195         if ((le_value == VCONFKEY_BT_LE_STATUS_ON) && (powered == 1)) {
196                 gboolean *user_data = g_new0(int, 1);
197                 *user_data = TRUE;
198                 g_idle_add(__bt_hal_send_adapter_event, (gpointer)user_data);
199                 return BT_STATUS_SUCCESS;
200         }
201         proxy = __bt_get_core_proxy();
202
203         if (!proxy) {
204                 DBG("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
205                 return BT_STATUS_FAIL;
206         }
207
208         _bt_hal_set_adapter_request_state(TRUE);
209         _bt_hal_set_le_request_state(TRUE);
210         result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
211                         NULL,
212                         G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
213                         NULL, &error);
214         if (error) {
215                 DBG("EnableAdapter failed: %s", error->message);
216                 g_clear_error(&error);
217                 error = NULL;
218                 _bt_hal_set_adapter_request_state(FALSE);
219                 _bt_hal_set_le_request_state(FALSE);
220                 result = g_dbus_proxy_call_sync(proxy,
221                                 "DisableAdapter",
222                                 NULL,
223                                 G_DBUS_CALL_FLAGS_NONE,
224                                 -1,
225                                 NULL,
226                                 &error);
227
228                 if (error != NULL) {
229                         DBG("Bt core call failed(Error: %s)", error->message);
230                         g_clear_error(&error);
231                 }
232                 g_variant_unref(result);
233                 /*Terminate myself*/
234                 /* TODO: Terminate bluetooth service or not, need to check */
235                 /*g_idle_add((GSourceFunc)_bt_terminate_service, NULL);*/
236                 return BT_STATUS_FAIL;
237         }
238
239         DBG("-");
240         g_variant_unref(result);
241         return BT_STATUS_SUCCESS;
242 }
243
244 int _bt_hal_dbus_disable_adapter(void)
245 {
246         GDBusProxy *proxy;
247         GError *error = NULL;
248         GVariant *result = NULL;
249
250         DBG("+");
251         proxy = __bt_get_core_proxy();
252
253         if (!proxy) {
254                 DBG("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
255                 return BT_STATUS_FAIL;
256         }
257
258         result = g_dbus_proxy_call_sync(proxy, "DisableAdapter",
259                         NULL,
260                         G_DBUS_CALL_FLAGS_NONE, -1,
261                         NULL, &error);
262         if (error) {
263                 DBG("DisableAdapter failed: %s", error->message);
264                 g_clear_error(&error);
265                 error = NULL;
266                 g_variant_unref(result);
267                 /*Terminate myself*/
268                 /* TODO: Terminate bluetooth service or not, need to check */
269                 /*g_idle_add((GSourceFunc)_bt_terminate_service, NULL);*/
270                 return BT_STATUS_FAIL;
271         }
272
273         DBG("-");
274         g_variant_unref(result);
275         return BT_STATUS_SUCCESS;
276 }
277
278 #ifdef TIZEN_BT_HAL
279 int _bt_hal_dbus_enable_le(void)
280 {
281         GDBusProxy *proxy;
282         GError *error = NULL;
283         GVariant *result = NULL;
284         int adapter_value = VCONFKEY_BT_STATUS_OFF;
285         unsigned char powered = 0;
286
287         DBG("+");
288
289         if (vconf_get_int(VCONFKEY_BT_STATUS, &adapter_value) != 0)
290                 ERR("fail to get vconf key!");
291
292         if (_bt_hal_get_adapter_powered_state(&powered) == BT_STATUS_FAIL)
293                 ERR("_bt_hal_get_adapter_powered_state failed");
294
295         if ((adapter_value == VCONFKEY_BT_STATUS_ON) && (powered == 1)) {
296                 gboolean *user_data = g_new0(int, 1);
297                 *user_data = TRUE;
298                 g_idle_add(__bt_hal_send_le_event, (gpointer)user_data);
299                 return BT_STATUS_SUCCESS;
300         }
301
302         proxy = __bt_get_core_proxy();
303
304         if (!proxy) {
305                 DBG("_bt_hal_dbus_enable_le: Core proxy get failed!!!");
306                 return BT_STATUS_FAIL;
307         }
308         _bt_hal_set_le_request_state(TRUE);
309
310         result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
311                         NULL,
312                         G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
313                         NULL, &error);
314         if (error) {
315                 DBG("EnableAdapter failed: %s", error->message);
316                 g_clear_error(&error);
317                 error = NULL;
318                 result = g_dbus_proxy_call_sync(proxy,
319                                 "DisableAdapter",
320                                 NULL,
321                                 G_DBUS_CALL_FLAGS_NONE,
322                                 -1,
323                                 NULL,
324                                 &error);
325
326                 _bt_hal_set_le_request_state(FALSE);
327                 if (error != NULL) {
328                         DBG("Bt core call failed(Error: %s)", error->message);
329                         g_clear_error(&error);
330                 }
331                 g_variant_unref(result);
332
333                 return BT_STATUS_FAIL;
334         }
335
336         DBG("-");
337         g_variant_unref(result);
338         return BT_STATUS_SUCCESS;
339 }
340
341 int _bt_hal_dbus_disable_le(void)
342 {
343         GDBusProxy *proxy;
344         GError *error = NULL;
345         GVariant *result = NULL;
346         int adapter_value = VCONFKEY_BT_STATUS_OFF;
347
348         DBG("+");
349         if (vconf_get_int(VCONFKEY_BT_STATUS, &adapter_value) != 0)
350                 ERR("fail to get vconf key!");
351
352         if (adapter_value == VCONFKEY_BT_STATUS_ON) {
353                 gboolean *user_data = g_new0(int, 1);
354                 *user_data = FALSE;
355                 g_idle_add(__bt_hal_send_le_event, (gpointer)user_data);
356                 return BT_STATUS_SUCCESS;
357         }
358
359         proxy = __bt_get_core_proxy();
360
361         if (!proxy) {
362                 DBG("_bt_hal_dbus_disable_le: Core proxy get failed!!!");
363                 return BT_STATUS_FAIL;
364         }
365
366         result = g_dbus_proxy_call_sync(proxy, "DisableAdapterLe",
367                         NULL,
368                         G_DBUS_CALL_FLAGS_NONE, -1,
369                         NULL, &error);
370         if (error) {
371                 DBG("DisableAdapter failed: %s", error->message);
372                 g_clear_error(&error);
373                 error = NULL;
374                 g_variant_unref(result);
375                 return BT_STATUS_FAIL;
376         }
377
378
379
380         DBG("-");
381         g_variant_unref(result);
382         return BT_STATUS_SUCCESS;
383 }
384 #endif
385
386 #ifdef TIZEN_BT_HAL
387 int _bt_hal_dbus_reset_adapter(void)
388 {
389         GDBusProxy *proxy;
390         GVariant *result;
391         GError *error = NULL;
392         INFO("+");
393
394         proxy = __bt_get_core_proxy();
395         if (!proxy)
396                 return BT_STATUS_FAIL;
397
398         result = g_dbus_proxy_call_sync(proxy,
399                         "ResetAdapter",
400                         NULL,
401                         G_DBUS_CALL_FLAGS_NONE,
402                         -1,
403                         NULL,
404                         &error);
405
406         if (!result) {
407                 if (error != NULL) {
408                         ERR("Failed to ResetAdapter (Error: %s)", error->message);
409                         g_clear_error(&error);
410                 } else
411                         ERR("Failed to ResetAdapter");
412                 return BT_STATUS_FAIL;
413         }
414
415         g_variant_unref(result);
416         return BT_STATUS_SUCCESS;
417 }
418 #endif
419
420 int _bt_hal_dbus_start_discovery(gboolean is_custom,
421                                         bt_disc_role_type_t role)
422 {
423         GDBusProxy *proxy;
424         GError *error = NULL;
425         GVariant *result;
426         const gchar *disc_type;
427         DBG("Discovery Type: Is Custom : [%s]", is_custom ? "TRUE" : "FALSE");
428
429         proxy = _bt_hal_get_adapter_proxy();
430         if (!proxy) {
431                 DBG("Adapter proxy get failed!!!");
432                 return BT_STATUS_FAIL;
433         }
434
435         if (is_custom) {
436                 if (role == BT_DISC_ROLE_BREDR)
437                         disc_type = "BREDR";
438                 else if (role == BT_DISC_ROLE_LE)
439                         disc_type = "LE";
440                 else if (role == BT_DISC_ROLE_DUAL)
441                         disc_type = "LE_BREDR";
442                 else
443                         return BT_STATUS_PARM_INVALID;
444
445                 result = g_dbus_proxy_call_sync(proxy,
446                                 "StartCustomDiscovery",
447                                 g_variant_new("s", disc_type),
448                                 G_DBUS_CALL_FLAGS_NONE,
449                                 -1,
450                                 NULL,
451                                 &error);
452         } else
453                 result = g_dbus_proxy_call_sync(proxy,
454                                 "StartDiscovery",
455                                 NULL,
456                                 G_DBUS_CALL_FLAGS_NONE,
457                                 -1,
458                                 NULL,
459                                 &error);
460
461         if (!result) {
462                 if (error != NULL) {
463                         ERR("StartDiscovery failed (Error: %s)", error->message);
464                         g_clear_error(&error);
465                 } else
466                         ERR("StartDiscovery failed");
467                 return BT_STATUS_FAIL;
468         }
469
470         /* discovery status will be change in event */
471         DBG("-");
472         g_variant_unref(result);
473         return BT_STATUS_SUCCESS;
474 }
475
476 int _bt_hal_dbus_stop_discovery(void)
477 {
478         GDBusProxy *proxy;
479         GError *error = NULL;
480         GVariant *result;
481         DBG("+");
482
483         proxy = _bt_hal_get_adapter_proxy();
484         if (!proxy) {
485                 DBG("_bt_hal_dbus_stop_discovery: Adapter proxy get failed!!!");
486                 return BT_STATUS_FAIL;
487         }
488
489         result = g_dbus_proxy_call_sync(proxy,
490                         "StopDiscovery",
491                         NULL,
492                         G_DBUS_CALL_FLAGS_NONE,
493                         -1,
494                         NULL,
495                         &error);
496
497         if (!result) {
498                 if (error != NULL) {
499                         ERR("StopDiscovery failed (Error: %s)", error->message);
500                         g_clear_error(&error);
501                 } else
502                         ERR("StopDiscovery failed");
503                 return BT_STATUS_FAIL;
504         }
505
506         /* discovery status will be change in event */
507         DBG("-");
508         g_variant_unref(result);
509         return BT_STATUS_SUCCESS;
510 }
511
512 static gboolean __bt_adapter_all_properties_cb(gpointer user_data)
513 {
514         GVariant *result = user_data;
515         GVariantIter *property_iter;
516         const gchar *key;
517         GVariant *value;
518
519         /* Buffer and propety count management */
520         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
521         struct hal_ev_adapter_props_changed *ev = (void*) buf;
522         size_t size = 0;
523         gchar *address = NULL;
524         gchar *name = NULL;
525         unsigned int cod = 0;
526         gboolean discoverable;
527         gboolean connectable;
528         unsigned int scan_mode = BT_SCAN_MODE_NONE;
529         unsigned int disc_timeout;
530         gchar *version;
531         gboolean is_discovering;
532         gboolean is_le_discovering;
533         uint8_t ipsp_initialized;
534         gboolean powered;
535         uint8_t pairable;
536         unsigned int pairable_timeout;
537         gboolean scan_mode_property_update = FALSE;
538
539         DBG("+");
540
541         memset(buf, 0, sizeof(buf));
542         size = sizeof(*ev);
543         ev->num_props = 0;
544         ev->status = BT_STATUS_SUCCESS;
545
546         DBG("@@Start parsing properties");
547         g_variant_get(result, "(a{sv})", &property_iter);
548         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
549                 if (!g_strcmp0(key, "Address")) {
550                         uint8_t bdaddr[6];
551
552                         address = (gchar *) g_variant_get_string(value, NULL);
553                         DBG("Address [%s]", address);
554                         _bt_hal_convert_addr_string_to_type(bdaddr, address);
555                         size += __bt_insert_hal_properties(buf + size,
556                                         HAL_PROP_ADAPTER_ADDR, sizeof(bdaddr), bdaddr);
557                         ev->num_props++;
558                 } else if (!g_strcmp0(key, "Alias")) {
559                         name = (gchar *) g_variant_get_string(value, NULL);
560                         DBG("Alias [%s]", name);
561                         size += __bt_insert_hal_properties(buf + size,
562                                         HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
563                         ev->num_props++;
564                 } else if (!g_strcmp0(key, "Class")) {
565                         cod = g_variant_get_uint32(value);
566                         DBG("Class [%d]", cod);
567                         size += __bt_insert_hal_properties(buf + size,
568                                         HAL_PROP_ADAPTER_CLASS, sizeof(unsigned int), &cod);
569                         ev->num_props++;
570                 } else if (!g_strcmp0(key, "Discoverable")) {
571                         discoverable = g_variant_get_boolean(value);
572                         DBG("Discoverable [%d]", discoverable);
573                         if (discoverable)
574                                 scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
575                         scan_mode_property_update = TRUE;
576                 } else if (!g_strcmp0(key, "DiscoverableTimeout")) {
577                         disc_timeout = g_variant_get_uint32(value);
578                         DBG("Discoverable Timeout [%d]", disc_timeout);
579                         size += __bt_insert_hal_properties(buf + size,
580                                         HAL_PROP_ADAPTER_DISC_TIMEOUT, sizeof(unsigned int), &disc_timeout);
581                         ev->num_props++;
582                 } else if (!g_strcmp0(key, "Connectable")) {
583                         connectable = g_variant_get_boolean(value);
584                         DBG("Connectable [%d]", connectable);
585                         if (scan_mode == BT_SCAN_MODE_NONE)
586                                 scan_mode = BT_SCAN_MODE_CONNECTABLE;
587                         scan_mode_property_update = TRUE;
588                 } else if (!g_strcmp0(key, "Version")) {
589                         version = (gchar *) g_variant_get_string(value, NULL);
590                         DBG("Version [%s]", version);
591                         size += __bt_insert_hal_properties(buf + size,
592                                         HAL_PROP_ADAPTER_VERSION, strlen(version) + 1, version);
593                         ev->num_props++;
594                 } else if (!g_strcmp0(key, "Name")) {
595                         name = (gchar *) g_variant_get_string(value, NULL);
596                         DBG("Name [%s]", name);
597                         size += __bt_insert_hal_properties(buf + size,
598                                         HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
599                         ev->num_props++;
600                 } else if (!g_strcmp0(key, "Powered")) {
601                         powered = g_variant_get_boolean(value);
602                         DBG("Powered = [%d]", powered);
603                 } else if (!g_strcmp0(key, "Pairable")) {
604                         pairable = (g_variant_get_boolean(value) ? 1 : 0);
605                         DBG("Pairable [%d]", pairable);
606                         size += __bt_insert_hal_properties(buf + size,
607                                         HAL_PROP_ADAPTER_PAIRABLE, sizeof(uint8_t), &pairable);
608                         ev->num_props++;
609                 } else if (!g_strcmp0(key, "PairableTimeout")) {
610                         pairable_timeout = g_variant_get_uint32(value);
611                         DBG("Pairable Timeout = [%d]", pairable_timeout);
612                         size += __bt_insert_hal_properties(buf + size,
613                                         HAL_PROP_ADAPTER_PAIRABLE_TIMEOUT, sizeof(unsigned int), &pairable_timeout);
614                         ev->num_props++;
615                 } else if (!g_strcmp0(key, "UUIDs")) {
616                         char **uuid_value;
617                         int uuid_count = 0;
618                         gsize size1 = 0;
619                         int i = 0;
620                         size1 = g_variant_get_size(value);
621                         int num_props_tmp = ev->num_props;
622                         if (size1 > 0) {
623                                 uuid_value = (char **)g_variant_get_strv(value, &size1);
624                                 for (i = 0; uuid_value[i] != NULL; i++)
625                                         uuid_count++;
626                                 /* UUID collection */
627                                 uint8_t uuids[HAL_UUID_LEN * uuid_count];
628                                 for (i = 0; uuid_value[i] != NULL; i++) {
629                                         char *uuid_str = NULL;
630                                         uint8_t uuid[HAL_UUID_LEN];
631                                         uuid_str = g_strdup(uuid_value[i]);
632                                         DBG("UUID string [%s]\n", uuid_str);
633                                         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
634                                         memcpy(uuids + i * HAL_UUID_LEN, uuid, HAL_UUID_LEN);
635                                         g_free(uuid_str);
636                                 }
637                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
638                                                 (HAL_UUID_LEN * uuid_count),
639                                                 uuids);
640                                 ev->num_props = num_props_tmp + 1;
641                                 g_free(uuid_value);
642                         }
643                 } else if (!g_strcmp0(key, "Discovering")) {
644                         is_discovering = g_variant_get_boolean(value);
645                         DBG("Discovering = [%d]", is_discovering);
646                 } else if (!g_strcmp0(key, "LEDiscovering")) {
647                         is_le_discovering = g_variant_get_boolean(value);
648                         DBG("LE Discovering = [%d]", is_le_discovering);
649                 } else if (!g_strcmp0(key, "Modalias")) {
650                         char *modalias = NULL;
651                         g_variant_get(value, "s", &modalias);
652                         DBG("Adapter ModAlias [%s]", modalias);
653                         size += __bt_insert_hal_properties(buf + size,
654                                         HAL_PROP_ADAPTER_MODALIAS, strlen(modalias) + 1, modalias);
655                         ev->num_props++;
656                         g_free(modalias);
657                 } else if (!g_strcmp0(key, "SupportedLEFeatures")) {
658                         DBG("LE Supported features");
659                         char *name = NULL;
660                         char *val = NULL;
661                         GVariantIter *iter = NULL;
662                         bt_local_le_features_t le_features;
663                         gboolean le_features_present = FALSE;
664
665                         memset(&le_features, 0x00, sizeof(le_features));
666
667                         g_variant_get(value, "as", &iter);
668                         if (iter) {
669                                 while (g_variant_iter_loop(iter, "s", &name)) {
670                                         DBG("name = %s", name);
671                                         g_variant_iter_loop(iter, "s", &val);
672                                         DBG("Value = %s", val);
673                                         _bt_hal_update_le_feature_support(name, val, &le_features);
674                                         le_features_present = TRUE;
675                                 }
676                                 g_variant_iter_free(iter);
677
678                                 if (le_features_present) {
679                                         size += __bt_insert_hal_properties(buf + size,
680                                                         HAL_PROP_ADAPTER_LOCAL_LE_FEAT, sizeof(le_features), &le_features);
681                                         ev->num_props++;
682                                 } else {
683                                         DBG("le supported features values are NOT provided by Stack");
684                                 }
685                         }
686                 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
687                         ipsp_initialized = (g_variant_get_boolean(value) ? 1 : 0);
688                         DBG("IPSP Initialized = %d", ipsp_initialized);
689                         size += __bt_insert_hal_properties(buf + size,
690                                         HAL_PROP_ADAPTER_IPSP_INITIALIZED, sizeof(uint8_t), &ipsp_initialized);
691                         ev->num_props++;
692                 } else {
693                         ERR("Unhandled Property:[%s]", key);
694                 }
695         }
696
697         if (scan_mode_property_update) {
698                 size += __bt_insert_hal_properties(buf + size,
699                                 HAL_PROP_ADAPTER_SCAN_MODE, sizeof(int), &scan_mode);
700                 ev->num_props++;
701         }
702
703         if (!event_cb)
704                 event_cb = _bt_get_adapter_event_cb();
705         if (!event_cb) {
706                 ERR("event_cb is NULL");
707                 goto done;
708         }
709
710         if (size > 2) {
711                 DBG("Send Adapter properties changed event to HAL user,"
712                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
713                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
714         }
715 done:
716         g_variant_unref(result);
717         return FALSE;
718 }
719
720 static int __bt_hal_dbus_get_all_adapter_properties(void)
721 {
722         GDBusProxy *proxy;
723         GVariant *result;
724         GError *error = NULL;
725
726         DBG("+");
727
728         proxy = _bt_hal_get_adapter_properties_proxy();
729         if (!proxy) {
730                 DBG("Adapter Properties proxy get failed!!!");
731                 return BT_STATUS_FAIL;
732         }
733
734         result = g_dbus_proxy_call_sync(proxy,
735                         "GetAll",
736                         g_variant_new("(s)", BT_HAL_ADAPTER_INTERFACE),
737                         G_DBUS_CALL_FLAGS_NONE,
738                         -1,
739                         NULL,
740                         &error);
741
742         if (!result) {
743                 if (error != NULL) {
744                         ERR("Failed to get all adapter properties (Error: %s)", error->message);
745                         g_clear_error(&error);
746                 } else
747                         ERR("Failed to get all adapter properties");
748                 return BT_STATUS_FAIL;
749         }
750
751         DBG("Got All properties from Bluez Stack!!, time to start parsing");
752         /*
753          * As we need to provide async callback to user from HAL, simply schedule a
754          * callback method which will carry actual result
755          */
756         g_idle_add(__bt_adapter_all_properties_cb, (gpointer)result);
757
758         DBG("-");
759         return BT_STATUS_SUCCESS;
760 }
761
762 int _bt_hal_dbus_get_adapter_properties(void)
763 {
764         DBG("+");
765
766         return __bt_hal_dbus_get_all_adapter_properties();
767 }
768
769 int _bt_hal_get_adapter_powered_state(uint8_t *state)
770 {
771         char *adapter_path = NULL;
772         gboolean powered = FALSE;
773         int ret = BT_STATUS_FAIL;
774
775         /* Check Valid Adapter Path, followed by Adapter Powered state.
776            If any of these fails, adapter will be considered Disabled */
777         adapter_path = _bt_hal_get_adapter_path();
778
779         if (adapter_path == NULL) {
780                 INFO("Adapter is not powered");
781                 g_free(adapter_path);
782                 *state = 0;
783                 return ret;
784         }
785
786         /* Check Adapter Powered Status */
787         ret = _bt_hal_is_adapter_powered(&powered);
788         if (BT_STATUS_FAIL == ret) {
789                 INFO("Adapter is not powered");
790                 g_free(adapter_path);
791                 *state = 0;
792                 return ret;
793         }
794
795         if (powered)
796                 *state = 1;
797         else
798                 *state = 0;
799
800         return ret;
801 }
802
803 /* Get Discoverable timeout API and callback */
804 static gboolean __bt_adapter_discovery_timeout_cb(gpointer user_data)
805 {
806         /* Buffer and propety count management */
807         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
808         struct hal_ev_adapter_props_changed *ev = (void*) buf;;
809         size_t size = 0;
810         unsigned int *timeout = user_data;
811
812         memset(buf, 0, sizeof(buf));
813         size = sizeof(*ev);
814         ev->num_props = 0;
815         ev->status = BT_STATUS_SUCCESS;
816
817         DBG("Discovery timeout in callback: [%d]", *timeout);
818
819         size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_DISC_TIMEOUT,
820                         sizeof(unsigned int), timeout);
821
822         ev->num_props++;
823         DBG("Timeout value [%d] property Num [%d]", *timeout, ev->num_props);
824
825         if (!event_cb)
826                 event_cb = _bt_get_adapter_event_cb();
827         if (!event_cb) {
828                 ERR("event_cb is NULL");
829                 goto done;
830         }
831
832         if (size > 2) {
833                 DBG("Send Adapter Properties changed event to HAL user,"
834                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
835                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
836         }
837 done:
838         g_free(timeout);
839         return FALSE;
840 }
841
842 int _bt_hal_dbus_get_discovery_timeout(void)
843 {
844         GDBusProxy *proxy;
845         GVariant *result;
846         GVariant *temp;
847         GError *error = NULL;
848         unsigned int *timeout;
849         DBG("+");
850
851         proxy = _bt_hal_get_adapter_properties_proxy();
852         if (!proxy) {
853                 DBG("Adapter Properties proxy get failed!!!");
854                 return BT_STATUS_FAIL;
855         }
856
857         result = g_dbus_proxy_call_sync(proxy,
858                         "Get",
859                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
860                                 "DiscoverableTimeout"),
861                         G_DBUS_CALL_FLAGS_NONE,
862                         -1,
863                         NULL,
864                         &error);
865
866         if (!result) {
867                 if (error != NULL) {
868                         ERR("Failed to get local version (Error: %s)", error->message);
869                         g_clear_error(&error);
870                 } else
871                         ERR("Failed to get local version");
872                 return BT_STATUS_FAIL;
873         }
874
875         timeout = g_malloc0(sizeof(int));
876         if (!timeout) {
877                 ERR("Memory allocation failed");
878                 g_variant_unref(result);
879                 return BT_STATUS_FAIL;
880         }
881
882         g_variant_get(result, "(v)", &temp);
883         *timeout = g_variant_get_uint32(temp);
884         DBG("Timeout value: [%d]", *timeout);
885
886         g_variant_unref(result);
887         g_variant_unref(temp);
888
889         /*
890          * As we need to provide async callback to user from HAL, simply schedule a
891          * callback method which will carry actual result
892          */
893         g_idle_add(__bt_adapter_discovery_timeout_cb, (gpointer) timeout);
894
895         DBG("-");
896         return BT_STATUS_SUCCESS;
897 }
898
899 /* Get Discoverable Mode API and callback */
900 static gboolean __bt_adapter_scan_mode_cb(gpointer user_data)
901 {
902         /* Buffer and propety count management */
903         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
904         struct hal_ev_adapter_props_changed *ev = (void*) buf;;
905         size_t size = 0;
906         int *mode = user_data;
907
908         memset(buf, 0, sizeof(buf));
909         size = sizeof(*ev);
910         ev->num_props = 0;
911         ev->status = BT_STATUS_SUCCESS;
912
913         DBG("Scan mode callback: [%d]", *mode);
914
915         size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_SCAN_MODE,
916                         sizeof(int), mode);
917
918         ev->num_props++;
919         DBG("Scan mode [%d] property Num [%d]", *mode, ev->num_props);
920
921         if (!event_cb)
922                 event_cb = _bt_get_adapter_event_cb();
923         if (!event_cb) {
924                 ERR("event_cb is NULL");
925                 goto done;
926         }
927
928         if (size > 2) {
929                 DBG("Send Adapter Properties changed event to HAL user,"
930                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
931                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
932         }
933 done:
934         g_free(mode);
935         return FALSE;
936 }
937
938 int _bt_hal_dbus_get_scan_mode(void)
939 {
940         GDBusProxy *proxy;
941         gboolean discoverable;
942         gboolean connectable;
943         GVariant *result;
944         GVariant *temp;
945         GError *error = NULL;
946         int *scan_mode;
947                 ;
948         DBG("+");
949
950         proxy = _bt_hal_get_adapter_properties_proxy();
951         if (!proxy) {
952                 DBG("Adapter Properties proxy get failed!!!");
953                 return BT_STATUS_FAIL;
954         }
955
956         result = g_dbus_proxy_call_sync(proxy,
957                         "Get",
958                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
959                                 "Discoverable"),
960                         G_DBUS_CALL_FLAGS_NONE,
961                         -1,
962                         NULL,
963                         &error);
964
965         if (!result) {
966                 if (error != NULL) {
967                         ERR("Failed to get discoverable mode (Error: %s)", error->message);
968                         g_clear_error(&error);
969                 } else
970                         ERR("Failed to get discoverable mode");
971                 return BT_STATUS_FAIL;
972         }
973
974         g_variant_get(result, "(v)", &temp);
975         discoverable = g_variant_get_boolean(temp);
976         DBG("discoverable:%d", discoverable);
977
978         g_variant_unref(result);
979         g_variant_unref(temp);
980
981         if (!discoverable) {
982                 result = g_dbus_proxy_call_sync(proxy,
983                                 "Get",
984                                 g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
985                                         "Connectable"),
986                                 G_DBUS_CALL_FLAGS_NONE,
987                                 -1,
988                                 NULL,
989                                 &error);
990                 if (!result) {
991                         if (error != NULL) {
992                                 ERR("Failed to get connectable mode (Error: %s)", error->message);
993                                 g_clear_error(&error);
994                         } else
995                                 ERR("Failed to get connectable mode");
996                         return BT_STATUS_FAIL;
997                 }
998
999                 g_variant_get(result, "(v)", &temp);
1000                 connectable = g_variant_get_boolean(temp);
1001                 DBG("connectable:%d", connectable);
1002
1003                 g_variant_unref(result);
1004                 g_variant_unref(temp);
1005         }
1006
1007         scan_mode = g_malloc0(sizeof(int));
1008         if (!scan_mode) {
1009                 ERR("Memory allocation failed");
1010                 return BT_STATUS_FAIL;
1011         }
1012
1013         if (discoverable)
1014                 *scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
1015         else if (connectable)
1016                 *scan_mode = BT_SCAN_MODE_CONNECTABLE;
1017         else
1018                 *scan_mode = BT_SCAN_MODE_NONE;
1019
1020         /*
1021          * As we need to provide async callback to user from HAL, simply schedule a
1022          * callback method which will carry actual result
1023          */
1024         g_idle_add(__bt_adapter_scan_mode_cb, (gpointer) scan_mode);
1025
1026         DBG("-");
1027         return BT_STATUS_SUCCESS;
1028 }
1029
1030 /* Get Local Version API and callback */
1031 static gboolean __bt_adapter_local_version_cb(gpointer user_data)
1032 {
1033         /* Buffer and propety count management */
1034         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1035         struct hal_ev_adapter_props_changed *ev = (void*) buf;;
1036         size_t size = 0;
1037         char *version = NULL;
1038
1039         memset(buf, 0, sizeof(buf));
1040         size = sizeof(*ev);
1041         ev->num_props = 0;
1042         ev->status = BT_STATUS_SUCCESS;
1043
1044         version = (char*) user_data;
1045         DBG("Local Version in callback: [%s]", version);
1046
1047         size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_VERSION,
1048                         (strlen(version) + 1), version);
1049
1050         ev->num_props++;
1051         DBG("Device version [%s] property Num [%d]", version, ev->num_props);
1052
1053         if (!event_cb)
1054                 event_cb = _bt_get_adapter_event_cb();
1055         if (!event_cb) {
1056                 ERR("event_cb is NULL");
1057                 goto done;
1058         }
1059
1060         if (size > 2) {
1061                 DBG("Send Adapter Properties changed event to HAL user,"
1062                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
1063                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
1064         }
1065 done:
1066         g_free(version);
1067         return FALSE;
1068 }
1069
1070 int _bt_hal_dbus_get_local_version(void)
1071 {
1072         GDBusProxy *proxy;
1073         const char *version = NULL;
1074         GVariant *result;
1075         GVariant *temp;
1076         GError *error = NULL;
1077         DBG("+");
1078
1079         proxy = _bt_hal_get_adapter_properties_proxy();
1080         if (!proxy) {
1081                 DBG("Adapter Properties proxy get failed!!!");
1082                 return BT_STATUS_FAIL;
1083         }
1084
1085         result = g_dbus_proxy_call_sync(proxy,
1086                         "Get",
1087                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
1088                                 "Version"),
1089                         G_DBUS_CALL_FLAGS_NONE,
1090                         -1,
1091                         NULL,
1092                         &error);
1093
1094         if (!result) {
1095                 if (error != NULL) {
1096                         ERR("Failed to get local version (Error: %s)", error->message);
1097                         g_clear_error(&error);
1098                 } else
1099                         ERR("Failed to get local version");
1100                 return BT_STATUS_FAIL;
1101         }
1102
1103         g_variant_get(result, "(v)", &temp);
1104         version = g_variant_dup_string(temp, NULL);
1105         DBG("Local Version: [%s]", version);
1106
1107         g_variant_unref(result);
1108         g_variant_unref(temp);
1109
1110         /*
1111          * As we need to provide async callback to user from HAL, simply schedule a
1112          * callback method which will carry actual result
1113          */
1114         g_idle_add(__bt_adapter_local_version_cb, (gpointer) version);
1115
1116         DBG("-");
1117         return BT_STATUS_SUCCESS;
1118 }
1119
1120 /* Get Local Name API and callback */
1121 static gboolean __bt_adapter_local_name_cb(gpointer user_data)
1122 {
1123         /* Buffer and propety count management */
1124         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1125         struct hal_ev_adapter_props_changed *ev = (void*) buf;;
1126         size_t size = 0;
1127         char *name = NULL;
1128
1129         memset(buf, 0, sizeof(buf));
1130         size = sizeof(*ev);
1131         ev->num_props = 0;
1132         ev->status = BT_STATUS_SUCCESS;
1133
1134         name = (char*) user_data;
1135         DBG("Local Name in callback: [%s]", name);
1136
1137         size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_NAME,
1138                         strlen(name) + 1, name);
1139
1140         ev->num_props++;
1141         DBG("Device name [%s] property Num [%d]", name, ev->num_props);
1142
1143         if (!event_cb)
1144                 event_cb = _bt_get_adapter_event_cb();
1145         if (!event_cb) {
1146                 ERR("event_cb is NULL");
1147                 goto done;
1148         }
1149
1150         if (size > 2) {
1151                 DBG("Send Adapter Properties changed event to HAL user,"
1152                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
1153                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
1154         }
1155 done:
1156         g_free(name);
1157         return FALSE;
1158 }
1159
1160 int _bt_hal_dbus_get_local_name(void)
1161 {
1162         GDBusProxy *proxy;
1163         const char *name = NULL;
1164         GVariant *result;
1165         GVariant *temp;
1166         GError *error = NULL;
1167         DBG("+");
1168
1169         proxy = _bt_hal_get_adapter_properties_proxy();
1170         if (!proxy) {
1171                 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1172                 return BT_STATUS_FAIL;
1173         }
1174
1175         result = g_dbus_proxy_call_sync(proxy,
1176                         "Get",
1177                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
1178                                 "Alias"),
1179                         G_DBUS_CALL_FLAGS_NONE,
1180                         -1,
1181                         NULL,
1182                         &error);
1183
1184         if (!result) {
1185                 if (error != NULL) {
1186                         ERR("Failed to get local name (Error: %s)", error->message);
1187                         g_clear_error(&error);
1188                 } else
1189                         ERR("Failed to get local name");
1190                 return BT_STATUS_FAIL;
1191         }
1192
1193         g_variant_get(result, "(v)", &temp);
1194         name = g_variant_dup_string(temp, NULL);
1195         DBG("Local Name: [%s]", name);
1196
1197         g_variant_unref(result);
1198         g_variant_unref(temp);
1199
1200         /*
1201          * As we need to provide async callback to user from HAL, simply schedule a
1202          * callback method which will carry actual result
1203          */
1204         g_idle_add(__bt_adapter_local_name_cb, (gpointer) name);
1205
1206         DBG("-");
1207         return BT_STATUS_SUCCESS;
1208 }
1209
1210 /* Get Local Address API and callback */
1211 static gboolean __bt_adapter_local_address_cb(gpointer user_data)
1212 {
1213         /* Buffer and propety count management */
1214         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1215         struct hal_ev_adapter_props_changed *ev = (void*) buf;
1216         size_t size = 0;
1217         char * address = NULL;
1218
1219         memset(buf, 0, sizeof(buf));
1220         size = sizeof(*ev);
1221         ev->num_props = 0;
1222         ev->status = BT_STATUS_SUCCESS;
1223
1224         address = (char*) user_data;
1225
1226         uint8_t bdaddr[6];
1227         _bt_hal_convert_addr_string_to_type(bdaddr, address);
1228
1229         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
1230                         sizeof(bdaddr), bdaddr);
1231
1232         ev->num_props++;
1233         DBG("Device address [%s] property Num [%d]", address, ev->num_props);
1234
1235         size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_ADDR,
1236                         sizeof(bdaddr), bdaddr);
1237
1238         if (!event_cb)
1239                 event_cb = _bt_get_adapter_event_cb();
1240         if (!event_cb) {
1241                 ERR("event_cb is NULL");
1242                 goto done;
1243         }
1244
1245         if (size > 1) {
1246                 DBG("Send Device found event to HAL user,"
1247                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
1248                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
1249         }
1250 done:
1251         g_free(address);
1252         return FALSE;
1253 }
1254
1255 int _bt_hal_dbus_get_local_address(void)
1256 {
1257         GDBusProxy *proxy;
1258         GError *error = NULL;
1259         const char *address;
1260         GVariant *result;
1261         GVariant *temp;
1262
1263         DBG("+");
1264
1265         proxy = _bt_hal_get_adapter_properties_proxy();
1266         if (!proxy) {
1267                 DBG("_bt_hal_dbus_get_local_address: Adapter Properties proxy get failed!!!");
1268                 return BT_STATUS_FAIL;
1269         }
1270
1271         result = g_dbus_proxy_call_sync(proxy,
1272                         "Get",
1273                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
1274                                 "Address"),
1275                         G_DBUS_CALL_FLAGS_NONE,
1276                         -1,
1277                         NULL,
1278                         &error);
1279
1280         if (!result) {
1281                 ERR("Failed to get local address");
1282                 if (error != NULL) {
1283                         ERR("Failed to get local address (Error: %s)", error->message);
1284                         g_clear_error(&error);
1285                 }
1286                 return BT_STATUS_FAIL;
1287         }
1288
1289         g_variant_get(result, "(v)", &temp);
1290         address = g_variant_dup_string(temp, NULL);
1291
1292         if (address)
1293                 DBG("Address:%s", address);
1294         else
1295                 return BT_STATUS_FAIL;
1296
1297         g_variant_unref(result);
1298         g_variant_unref(temp);
1299
1300         /*
1301          * As we need to provide async callback to user from HAL, simply schedule a
1302          * callback method which will carry actual result
1303          */
1304         g_idle_add(__bt_adapter_local_address_cb, (gpointer) address);
1305
1306         DBG("-");
1307         return BT_STATUS_SUCCESS;
1308 }
1309
1310 /* Get Local services API and callback */
1311 static gboolean __bt_adapter_service_uuids_cb(gpointer user_data)
1312 {
1313         GVariant *result = user_data;
1314         GVariant *temp;
1315         GVariantIter *iter = NULL;
1316         gchar *uuid_str;
1317
1318         /* Buffer and propety count management */
1319         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1320         struct hal_ev_adapter_props_changed *ev = (void*) buf;
1321         size_t size = 0;
1322
1323         /* UUID collection */
1324         uint8_t uuids[HAL_UUID_LEN * MAX_UUID_COUNT];
1325         int uuid_count = 0;
1326
1327         memset(buf, 0, sizeof(buf));
1328         size = sizeof(*ev);
1329         ev->num_props = 0;
1330         ev->status = BT_STATUS_SUCCESS;
1331
1332         g_variant_get(result, "(v)", &temp);
1333         g_variant_get(temp, "as", &iter);
1334         if (iter == NULL) {
1335                 ERR("Failed to get UUIDs");
1336                 goto fail;
1337         }
1338
1339         while (g_variant_iter_loop(iter, "s", &uuid_str)) {
1340                 uint8_t uuid[HAL_UUID_LEN];
1341
1342                 DBG("UUID string [%s]\n", uuid_str);
1343                 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
1344                 memcpy(uuids + uuid_count * HAL_UUID_LEN, uuid, HAL_UUID_LEN);
1345                 uuid_count++;
1346         }
1347
1348         size += __bt_insert_hal_properties(buf + size,
1349                         HAL_PROP_ADAPTER_UUIDS,
1350                         (HAL_UUID_LEN * uuid_count),
1351                         uuids);
1352         ev->num_props++;
1353
1354         if (!event_cb)
1355                 event_cb = _bt_get_adapter_event_cb();
1356         if (!event_cb) {
1357                 ERR("event_cb is NULL");
1358                 goto done;
1359         }
1360
1361         if (size > 2) {
1362                 DBG("Send Adapter properties changed event to HAL user,"
1363                                 " Num Prop [%d] total size [%zd]", ev->num_props, size);
1364                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
1365         }
1366 done:
1367         g_variant_iter_free(iter);
1368         g_variant_unref(result);
1369         g_variant_unref(temp);
1370         return FALSE;
1371 fail:
1372         if (!event_cb)
1373                 event_cb = _bt_get_adapter_event_cb();
1374         if (event_cb) {
1375                 ev->status = BT_STATUS_FAIL;
1376                 ev->num_props = 0;
1377                 DBG("Send Adapter properties changed event to HAL user,"
1378                                 " Num Prop [%d] total size [%zd]", ev->num_props, size);
1379                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
1380         }
1381
1382         g_variant_unref(result);
1383         return FALSE;
1384 }
1385
1386 int _bt_hal_dbus_get_adapter_supported_uuids(void)
1387 {
1388         GDBusProxy *proxy;
1389         GError *error = NULL;
1390         GVariant *result;
1391
1392         DBG("+");
1393
1394         proxy = _bt_hal_get_adapter_properties_proxy();
1395
1396         if (!proxy) {
1397                 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1398                 return BT_STATUS_FAIL;
1399         }
1400
1401         result = g_dbus_proxy_call_sync(proxy,
1402                         "Get",
1403                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
1404                                 "UUIDs"),
1405                         G_DBUS_CALL_FLAGS_NONE,
1406                         -1,
1407                         NULL,
1408                         &error);
1409
1410         if (!result) {
1411                 if (error != NULL) {
1412                         ERR("Failed to get UUIDs (Error: %s)", error->message);
1413                         g_clear_error(&error);
1414                 } else
1415                         ERR("Failed to get UUIDs");
1416                 return BT_STATUS_FAIL;
1417         }
1418
1419
1420         DBG("Got All Adaptr service UUID's from Bluez Stack!!, time to start parsing");
1421
1422         /*
1423          * As we need to provide async callback to user from HAL, simply schedule a
1424          * callback method which will carry actual result
1425          */
1426         g_idle_add(__bt_adapter_service_uuids_cb, (gpointer)result);
1427
1428         DBG("-");
1429         return BT_STATUS_SUCCESS;
1430 }
1431
1432 static gboolean __is_device_paired(GVariantIter *item_iter)
1433 {
1434         gboolean paired = FALSE;
1435         GVariant *value;
1436         gchar *key;
1437
1438         while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
1439                 if (NULL == key || g_strcmp0(key, "Paired"))
1440                         continue;
1441
1442                 paired = g_variant_get_boolean(value);
1443                 g_variant_unref(value);
1444                 g_free(key);
1445                 break;
1446         }
1447
1448         return paired;
1449 }
1450
1451 static gboolean __bt_adapter_bonded_devices_cb(gpointer user_data)
1452 {
1453         /* Buffer and propety count management */
1454         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1455         uint8_t addresses[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1456         struct hal_ev_adapter_props_changed *ev = (void*) buf;;
1457         size_t size = 0;
1458         size_t count = 0;
1459
1460         GVariant *result = user_data;
1461         GVariantIter *iter;
1462         GVariantIter *interface_iter;
1463         GVariantIter *svc_iter;
1464         char *object_path = NULL;
1465         char *interface_str = NULL;
1466
1467         char device_address[BT_HAL_ADDRESS_STRING_SIZE];
1468         uint8_t bdaddr[BT_HAL_ADDRESS_LENGTH_MAX];
1469
1470         memset(buf, 0, sizeof(buf));
1471         size = sizeof(*ev);
1472         ev->num_props = 0;
1473         ev->status = BT_STATUS_SUCCESS;
1474
1475         INFO("Size [%zd]", size);
1476
1477         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
1478         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1479
1480         /* Parse the signature: {oa{sa{sv}}} */
1481         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
1482                 if (object_path == NULL)
1483                         continue;
1484
1485                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
1486                                         &interface_str, &svc_iter)) {
1487                         if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
1488                                 DBG("Found a device: %s", object_path);
1489                                 if (__is_device_paired(svc_iter)) {
1490                                         _bt_hal_convert_device_path_to_address(object_path, device_address);
1491                                         DBG("Paired Device Address: [%s]", device_address);
1492
1493                                         _bt_hal_convert_addr_string_to_type(bdaddr, device_address);
1494                                         memcpy((addresses + (count * BT_HAL_ADDRESS_LENGTH_MAX)),
1495                                                         bdaddr, BT_HAL_ADDRESS_LENGTH_MAX);
1496                                         count++;
1497                                 }
1498                                 g_variant_iter_free(svc_iter);
1499                                 g_free(interface_str);
1500                                 interface_str = NULL;
1501                                 break;
1502                         }
1503                 }
1504         }
1505
1506         g_variant_iter_free(iter);
1507         g_variant_unref(result);
1508
1509         size += __bt_insert_hal_properties((buf + size),
1510                         HAL_PROP_ADAPTER_BONDED_DEVICES,
1511                         (count * BT_HAL_ADDRESS_LENGTH_MAX), addresses);
1512         ev->num_props++;
1513
1514         if (!event_cb)
1515                 event_cb = _bt_get_adapter_event_cb();
1516         if (!event_cb) {
1517                 ERR("event_cb is NULL");
1518                 goto done;
1519         }
1520
1521         if (size > 2) {
1522                 DBG("Send Adapter properties changed event to HAL user,"
1523                         " Num Prop [%d] total size [%zd]", ev->num_props, size);
1524                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, (void*) buf, size);
1525         }
1526 done:
1527         return FALSE;
1528 }
1529
1530 int _bt_hal_dbus_get_bonded_devices(void)
1531 {
1532         GDBusProxy *manager_proxy;
1533         GVariant *result = NULL;
1534
1535         DBG("+");
1536
1537         manager_proxy = _bt_hal_get_manager_proxy();
1538         if (manager_proxy == NULL)
1539                 return  BT_STATUS_FAIL;
1540
1541         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1542                         NULL,
1543                         G_DBUS_CALL_FLAGS_NONE,
1544                         -1,
1545                         NULL,
1546                         NULL);
1547         if (!result) {
1548                 ERR("Can't get managed objects");
1549                 return BT_STATUS_FAIL;
1550         }
1551
1552         /*
1553          * As we need to provide async callback to user from HAL, simply schedule a
1554          * callback method which will carry actual result
1555          */
1556         g_idle_add(__bt_adapter_bonded_devices_cb, (gpointer) result);
1557
1558         DBG("-");
1559         return BT_STATUS_SUCCESS;
1560 }
1561
1562 int _bt_hal_dbus_get_adapter_property(bt_property_type_t property_type)
1563 {
1564         DBG("+");
1565
1566         INFO("property_type: %d", property_type);
1567
1568         switch (property_type) {
1569         case BT_PROPERTY_BDADDR:
1570                 return _bt_hal_dbus_get_local_address();
1571         case BT_PROPERTY_BDNAME:
1572                 return _bt_hal_dbus_get_local_name();
1573         case BT_PROPERTY_VERSION:
1574                 return _bt_hal_dbus_get_local_version();
1575         case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
1576                 return _bt_hal_dbus_get_discovery_timeout();
1577         case BT_PROPERTY_ADAPTER_SCAN_MODE:
1578                 return _bt_hal_dbus_get_scan_mode();
1579         case BT_PROPERTY_CLASS_OF_DEVICE:
1580                 return BT_STATUS_UNSUPPORTED;
1581         case BT_PROPERTY_UUIDS:
1582                 return _bt_hal_dbus_get_adapter_supported_uuids();
1583         case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
1584                 return _bt_hal_dbus_get_bonded_devices();
1585         default:
1586                 return BT_STATUS_UNSUPPORTED;
1587         }
1588
1589         DBG("-");
1590 }
1591
1592 static int __bt_hal_dbus_set_local_name(void *data)
1593 {
1594         GDBusProxy *proxy;
1595         const char *name = data;
1596         GVariant *result;
1597         GError *error = NULL;
1598
1599         DBG("+");
1600         DBG("Local Name: [%s]", name);
1601         proxy = _bt_hal_get_adapter_properties_proxy();
1602         if (!proxy) {
1603                 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1604                 return BT_STATUS_FAIL;
1605         }
1606
1607         result = g_dbus_proxy_call_sync(proxy,
1608                         "Set",
1609                         g_variant_new("(ssv)", BT_HAL_ADAPTER_INTERFACE,
1610                                 "Alias", g_variant_new("s", name)),
1611                         G_DBUS_CALL_FLAGS_NONE,
1612                         -1,
1613                         NULL,
1614                         &error);
1615         if (!result) {
1616                 if (error != NULL) {
1617                         ERR("Failed to set local name (Error: %s)", error->message);
1618                         g_clear_error(&error);
1619                 } else
1620                         ERR("Failed to set local name");
1621                 return BT_STATUS_FAIL;
1622         }
1623         g_variant_unref(result);
1624
1625         DBG("-");
1626         return BT_STATUS_SUCCESS;
1627 }
1628
1629 static int __bt_hal_dbus_set_scan_mode(void *data)
1630 {
1631         GDBusProxy *proxy;
1632         int *mode = data;
1633         GVariant *result;
1634         GError *error = NULL;
1635         gboolean pg_scan;
1636         gboolean inq_scan;
1637
1638         DBG("+");
1639         DBG("Scan mode: [%d]", *mode);
1640         proxy = _bt_hal_get_adapter_properties_proxy();
1641         if (!proxy) {
1642                 DBG("Adapter Properties proxy get failed!!!");
1643                 return BT_STATUS_FAIL;
1644         }
1645
1646         switch (*mode) {
1647         case BT_SCAN_MODE_NONE:
1648                 pg_scan = FALSE;
1649                 inq_scan = FALSE;
1650                 break;
1651         case BT_SCAN_MODE_CONNECTABLE:
1652                 pg_scan = TRUE;
1653                 inq_scan = FALSE;
1654                 break;
1655         case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
1656                 pg_scan = TRUE;
1657                 inq_scan = TRUE;
1658                 break;
1659         default:
1660                 ERR("Invalid scan mode");
1661                 return BT_STATUS_FAIL;
1662         }
1663
1664         result = g_dbus_proxy_call_sync(proxy,
1665                         "Set",
1666                         g_variant_new("(ssv)", BT_HAL_ADAPTER_INTERFACE,
1667                                 "Connectable", g_variant_new("b", pg_scan)),
1668                         G_DBUS_CALL_FLAGS_NONE,
1669                         -1,
1670                         NULL,
1671                         &error);
1672         if (!result) {
1673                 if (error != NULL) {
1674                         ERR("Failed to set connectable property (Error: %s)", error->message);
1675                         g_clear_error(&error);
1676                 } else
1677                         ERR("Failed to set connectable property");
1678                 return BT_STATUS_FAIL;
1679         }
1680         g_variant_unref(result);
1681
1682         result = g_dbus_proxy_call_sync(proxy,
1683                         "Set",
1684                         g_variant_new("(ssv)", BT_HAL_ADAPTER_INTERFACE, "Discoverable",
1685                                 g_variant_new("b", inq_scan)),
1686                         G_DBUS_CALL_FLAGS_NONE,
1687                         -1,
1688                         NULL,
1689                         &error);
1690         if (!result) {
1691                 if (error != NULL) {
1692                         ERR("Failed to set Discoverable property (Error: %s)", error->message);
1693                         g_clear_error(&error);
1694                 } else
1695                         ERR("Failed to set Discoverable property");
1696                 return BT_STATUS_FAIL;
1697         }
1698         g_variant_unref(result);
1699
1700         DBG("-");
1701         return BT_STATUS_SUCCESS;
1702 }
1703
1704 static int __bt_hal_dbus_set_discovery_timeout(void *data)
1705 {
1706         GDBusProxy *proxy;
1707         unsigned int *timeout = data;
1708         GVariant *result;
1709         GError *error = NULL;
1710
1711
1712         DBG("+");
1713
1714         DBG("Discovery Timeout: [%d]", *timeout);
1715         proxy = _bt_hal_get_adapter_properties_proxy();
1716         if (!proxy) {
1717                 DBG("Adapter Properties proxy get failed!!!");
1718                 return BT_STATUS_FAIL;
1719         }
1720
1721         result = g_dbus_proxy_call_sync(proxy,
1722                         "Set",
1723                         g_variant_new("(ssv)", BT_HAL_ADAPTER_INTERFACE,
1724                                 "DiscoverableTimeout", g_variant_new("u", *timeout)),
1725                         G_DBUS_CALL_FLAGS_NONE,
1726                         -1,
1727                         NULL,
1728                         &error);
1729         if (!result) {
1730                 if (error != NULL) {
1731                         ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1732                         g_clear_error(&error);
1733                 } else
1734                         ERR("Failed to set DiscoverableTimeout property");
1735                 return BT_STATUS_FAIL;
1736         }
1737         g_variant_unref(result);
1738
1739         DBG("-");
1740         return BT_STATUS_SUCCESS;
1741 }
1742
1743 /* Set Adapter Properties */
1744 int _bt_hal_dbus_set_adapter_property(const bt_property_t *property)
1745 {
1746         int result;
1747
1748         DBG("");
1749
1750         if (property == NULL || property->val == NULL) {
1751                 ERR("Invalid parameters received");
1752                 return BT_STATUS_FAIL;
1753         }
1754
1755         switch (property->type) {
1756         case BT_PROPERTY_BDNAME:
1757                 result =  __bt_hal_dbus_set_local_name(property->val);
1758                 break;
1759         case BT_PROPERTY_ADAPTER_SCAN_MODE:
1760                 result =  __bt_hal_dbus_set_scan_mode(property->val);
1761                 break;
1762         case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
1763                 result =  __bt_hal_dbus_set_discovery_timeout(property->val);
1764                 break;
1765         default:
1766                 result = BT_STATUS_UNSUPPORTED;
1767         }
1768
1769         DBG("Result= [%d]", result);
1770         return result;
1771 }