Merge branch 'tizen' into tizen_5.5
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / adapter / bt-service-core-adapter.c
1 /*
2  * Copyright (c) 2015 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Contact: Anupam Roy <anupam.r@samsung.com>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <gio/gio.h>
22 #include <glib.h>
23 #include <dlog.h>
24 #include <string.h>
25 #include <vconf.h>
26 #include <vconf-internal-keys.h>
27 #include <bundle.h>
28 #include <bundle_internal.h>
29 #include <eventsystem.h>
30
31 #include "alarm.h"
32
33 /*bt-service headers */
34 #include "bt-internal-types.h"
35 #include "bt-service-common.h"
36 #include "bt-service-util.h"
37 #include "bt-service-main.h"
38 #include "bt-service-core-adapter.h"
39 #include "bt-service-core-device.h"
40 #include "bt-service-event-receiver.h"
41 #include "bt-request-handler.h"
42 #include "bt-service-event.h"
43 #include "bt-service-audio-common.h"
44 #include "bt-service-core-adapter-le.h"
45 #include "bt-service-gatt.h"
46
47 #ifdef TIZEN_FEATURE_BT_DPM
48 #include "bt-service-dpm.h"
49 #endif
50 #include "bt-service-hidhost.h"
51 #include "bt-service-socket.h"
52 #include "bt-service-hdp.h"
53
54 /* OAL headers */
55 #include <oal-event.h>
56 #include <oal-manager.h>
57 #include <oal-adapter-mgr.h>
58
59 #ifdef TIZEN_FEATURE_BT_PAN_NAP
60 #include "bt-service-network.h"
61 #endif
62 /*This file will contain state machines related to adapter and remote device */
63
64 #include "bt-internal-types.h"
65
66 /* Global variables */
67 typedef struct {
68         guint event_id;
69         int timeout;
70         time_t start_time;
71         gboolean alarm_init;
72         int alarm_id;
73 } bt_adapter_timer_t;
74
75 static bt_adapter_timer_t visible_timer;
76
77 static guint timer_id = 0;
78
79 static gboolean a2dp_init_pending = FALSE;
80
81 /* Adapter default states */
82 static bt_status_t adapter_state = BT_DEACTIVATED;
83 static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
84
85 /* Forward declarations */
86 static void __bt_adapter_event_handler(int event_type, gpointer event_data);
87 static void __bt_post_oal_init(void);
88 static void __bt_handle_oal_initialisation(oal_event_t event);
89 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size);
90 static gboolean __bt_adapter_post_set_enabled(gpointer user_data);
91 static gboolean __bt_adapter_post_set_disabled(gpointer user_data);
92 static void __bt_adapter_update_bt_enabled(void);
93 static void __bt_adapter_update_bt_disabled(void);
94 static void __bt_adapter_state_set_status(bt_status_t status);
95 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
96 static void __bt_adapter_state_change_callback(int bt_status);
97 static int __bt_adapter_state_handle_request(gboolean enable);
98 static int __bt_adapter_state_discovery_request(gboolean enable,
99                 unsigned short max_response, unsigned short duration, unsigned int mask,
100                 gboolean is_custom, bt_discovery_role_type_t role);
101 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status);
102 static gboolean __bt_is_service_request_present(int service_function);
103
104 static void __bt_set_visible_mode(void);
105 static void __bt_set_local_name(void);
106
107 /* Initialize BT stack (Initialize OAL layer) */
108 int _bt_stack_init(void)
109 {
110         int ret;
111
112         BT_INFO("[bt-service] Start to initialize BT stack");
113         /* Adapter enable request is successful, setup event handlers */
114         _bt_service_register_event_handler_callback(
115                         BT_ADAPTER_MODULE, __bt_adapter_event_handler);
116
117         ret = _bt_le_init();
118         if (ret != BLUETOOTH_ERROR_NONE) {
119                 BT_ERR("_bt_le_init Failed");
120                 return ret;
121         }
122
123         ret = oal_bt_init(_bt_service_oal_event_receiver);
124
125         if (OAL_STATUS_PENDING == ret) {
126                 BT_INFO("OAL Initialisation Pending, Profiles Init will be done once oal initialised...");
127                 return BLUETOOTH_ERROR_NONE;
128         } else if (OAL_STATUS_SUCCESS != ret) {
129                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
130                 return BLUETOOTH_ERROR_INTERNAL;
131         }
132
133         return BLUETOOTH_ERROR_NONE;
134 }
135
136 int _bt_enable_adapter(void)
137 {
138         return __bt_adapter_state_handle_request(TRUE);
139 }
140
141 int _bt_enable_core(void)
142 {
143         /* TODO_40 : 4.0 merge  */
144         BT_INFO("Not Supported");
145         return BLUETOOTH_ERROR_NOT_SUPPORT;
146 }
147
148 int _bt_recover_adapter(void)
149 {
150         /* TODO_40 : 4.0 merge  */
151         BT_INFO("Not Supported");
152         return BLUETOOTH_ERROR_NOT_SUPPORT;
153 }
154
155 int _bt_reset_adapter(void)
156 {
157         BT_INFO("+");
158         if (OAL_STATUS_SUCCESS != adapter_reset())
159                 return BLUETOOTH_ERROR_INTERNAL;
160
161         /* TODO_40 : 4.0 merge  */
162         /* TODO Currently bt-service is not terminated in tizen next.
163            It should be handled in future patch */
164         if (_bt_adapter_get_status() == BT_DEACTIVATED)
165                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
166
167         return BLUETOOTH_ERROR_NONE;
168 }
169
170 int _bt_check_adapter(int *status)
171 {
172         BT_INFO("+");
173         gboolean powered = FALSE;
174         BT_CHECK_PARAMETER(status, return);
175
176         *status = BT_ADAPTER_DISABLED;
177
178         if (OAL_STATUS_SUCCESS != adapter_get_powered_status(&powered))
179                 return BLUETOOTH_ERROR_INTERNAL;
180         else if (powered) {
181                 BT_INFO("Adapter is in Powered Up state");
182                 *status = BT_ADAPTER_ENABLED;
183         } else
184                 BT_INFO("Adapter is in Powered Down state");
185
186         return BLUETOOTH_ERROR_NONE;
187 }
188
189 int _bt_disable_adapter(void)
190 {
191         return __bt_adapter_state_handle_request(FALSE);
192 }
193
194 int _bt_start_discovery(unsigned short max_response,
195                 unsigned short duration, unsigned int cod_mask)
196 {
197         return __bt_adapter_state_discovery_request(TRUE, max_response, duration,
198                                 cod_mask, FALSE, 0x00);
199 }
200
201 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
202 {
203         return __bt_adapter_state_discovery_request(TRUE, 0, 0, 0, TRUE, role);
204 }
205
206 int _bt_cancel_discovery(void)
207 {
208         return __bt_adapter_state_discovery_request(FALSE, 0, 0, 0, FALSE, 0x00);
209 }
210
211 gboolean _bt_is_discovering(void)
212 {
213         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED
214                         || adapter_discovery_state == ADAPTER_DISCOVERY_STARTING)
215                 return TRUE;
216         else
217                 return FALSE;
218 }
219
220 int _bt_get_local_address(void)
221 {
222         int result;
223
224         BT_DBG("+");
225
226         result =  adapter_get_address();
227         if (result != OAL_STATUS_SUCCESS) {
228                 BT_ERR("adapter_get_address failed: %d", result);
229                 result = BLUETOOTH_ERROR_INTERNAL;
230         } else
231                 result = BLUETOOTH_ERROR_NONE;
232
233         BT_DBG("-");
234         return result;
235 }
236
237 int _bt_get_local_version(void)
238 {
239         int result;
240         BT_DBG("+");
241
242         result =  adapter_get_version();
243         if (result != OAL_STATUS_SUCCESS) {
244                 BT_ERR("adapter_get_version failed: %d", result);
245                 result = BLUETOOTH_ERROR_INTERNAL;
246         } else
247                 result = BLUETOOTH_ERROR_NONE;
248
249         BT_DBG("-");
250         return result;
251 }
252
253 int _bt_get_local_name(void)
254 {
255         int result;
256
257         BT_DBG("+");
258
259         result =  adapter_get_name();
260         if (result != OAL_STATUS_SUCCESS) {
261                 BT_ERR("adapter_get_name failed: %d", result);
262                 result = BLUETOOTH_ERROR_INTERNAL;
263         } else
264                 result = BLUETOOTH_ERROR_NONE;
265
266         BT_DBG("-");
267         return result;
268 }
269
270 int _bt_set_local_name(char *local_name)
271 {
272         int result = BLUETOOTH_ERROR_NONE;
273         BT_DBG("+");
274
275         retv_if(NULL == local_name, BLUETOOTH_ERROR_INVALID_PARAM);
276
277         result =  adapter_set_name(local_name);
278         if (result != OAL_STATUS_SUCCESS) {
279                 BT_ERR("adapter_set_name failed: %d", result);
280                 result = BLUETOOTH_ERROR_INTERNAL;
281         } else
282                 result = BLUETOOTH_ERROR_NONE;
283
284         BT_DBG("-");
285         return result;
286 }
287
288 int _bt_get_discoverable_mode(int *mode)
289 {
290         int scan_mode = 0;
291         int timeout = 0;
292
293         BT_DBG("+");
294
295         retv_if(NULL == mode, BLUETOOTH_ERROR_INVALID_PARAM);
296
297         adapter_is_discoverable(&scan_mode);
298         if (TRUE == scan_mode) {
299                 adapter_get_discoverable_timeout(&timeout);
300                 if (timeout > 0)
301                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
302                 else
303                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
304         } else {
305                 adapter_is_connectable(&scan_mode);
306                 if (scan_mode == TRUE)
307                         *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
308                 else {
309                         /*
310                          * TODO: NON CONNECTABLE is not defined in bluetooth_discoverable_mode_t.
311                          * After adding BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE, set mode as
312                          * BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE. Until then set -1.
313                          */
314                         *mode = -1;
315                 }
316         }
317
318         BT_DBG("-");
319         return BLUETOOTH_ERROR_NONE;
320 }
321
322 int _bt_get_timeout_value(int *timeout)
323 {
324         time_t current_time;
325         int time_diff;
326
327         /* Take current time */
328         time(&current_time);
329         time_diff = difftime(current_time, visible_timer.start_time);
330
331         BT_DBG("Time diff = %d\n", time_diff);
332         *timeout = visible_timer.timeout - time_diff;
333
334         return BLUETOOTH_ERROR_NONE;
335 }
336
337 static void __bt_visibility_alarm_remove()
338 {
339         if (visible_timer.event_id > 0) {
340                 g_source_remove(visible_timer.event_id);
341                 visible_timer.event_id = 0;
342         }
343
344         if (visible_timer.alarm_id > 0) {
345                 alarmmgr_remove_alarm(visible_timer.alarm_id);
346                 visible_timer.alarm_id = 0;
347         }
348 }
349
350 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
351 {
352         int result = BLUETOOTH_ERROR_NONE;
353         int timeout = 0;
354
355         BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
356
357         if (alarm_id != visible_timer.alarm_id)
358                 return 0;
359
360         if (visible_timer.event_id) {
361                 _bt_send_event(BT_ADAPTER_EVENT,
362                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
363                                 g_variant_new("(in)", result, timeout));
364                 g_source_remove(visible_timer.event_id);
365                 visible_timer.event_id = 0;
366                 visible_timer.timeout = 0;
367
368                 if (!TIZEN_PROFILE_WEARABLE) {
369                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
370                                 BT_ERR("Set vconf failed\n");
371                 }
372         }
373         /* Switch Off visibility in Bluez */
374         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
375         visible_timer.alarm_id = 0;
376         return 0;
377 }
378
379 static gboolean __bt_timeout_handler(gpointer user_data)
380 {
381         int result = BLUETOOTH_ERROR_NONE;
382         time_t current_time;
383         int time_diff;
384
385         /* Take current time */
386         time(&current_time);
387         time_diff = difftime(current_time, visible_timer.start_time);
388
389         /* Send event to application */
390         _bt_send_event(BT_ADAPTER_EVENT,
391                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
392                         g_variant_new("(in)", result, time_diff));
393
394         if (visible_timer.timeout <= time_diff) {
395                 g_source_remove(visible_timer.event_id);
396                 visible_timer.event_id = 0;
397                 visible_timer.timeout = 0;
398
399                 if (!TIZEN_PROFILE_WEARABLE) {
400                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
401                                 BT_ERR("Set vconf failed\n");
402                 }
403
404                 return FALSE;
405         }
406
407         return TRUE;
408 }
409
410 static void __bt_visibility_alarm_create()
411 {
412         alarm_id_t alarm_id;
413         int result;
414
415         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
416                         0, NULL, &alarm_id);
417         if (result < 0) {
418                 BT_ERR("Failed to create alarm error = %d\n", result);
419         } else {
420                 BT_DBG("Alarm created = %d\n", alarm_id);
421                 visible_timer.alarm_id = alarm_id;
422         }
423 }
424
425 int _bt_start_visibility_timer(int timeout)
426 {
427         int result;
428 #ifdef TIZEN_FEATURE_BT_DPM
429         int discoverable_state = DPM_BT_ERROR;
430 #endif
431
432         __bt_visibility_alarm_remove();
433
434         visible_timer.timeout = timeout;
435
436 #ifdef TIZEN_FEATURE_BT_DPM
437         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
438         if (discoverable_state != DPM_RESTRICTED) {
439 #endif
440                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
441                         BT_ERR("Set vconf failed");
442 #ifdef TIZEN_FEATURE_BT_DPM
443         }
444 #endif
445
446         if (timeout <= 0)
447                 return BLUETOOTH_ERROR_NONE;
448
449         if (!visible_timer.alarm_init) {
450                 /* Set Alarm timer to switch off BT */
451                 result = alarmmgr_init("bt-service");
452                 if (result != 0)
453                         return BLUETOOTH_ERROR_INTERNAL;
454
455                 visible_timer.alarm_init = TRUE;
456         }
457
458         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
459         if (result != 0)
460                 return BLUETOOTH_ERROR_INTERNAL;
461
462         if (!TIZEN_PROFILE_WEARABLE) {
463                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
464                         BT_ERR("Set vconf failed");
465         }
466
467         /* Take start time */
468         time(&(visible_timer.start_time));
469         visible_timer.event_id = g_timeout_add_seconds(1,
470                         __bt_timeout_handler, NULL);
471
472         visible_timer.timeout = timeout;
473
474         __bt_visibility_alarm_create();
475
476         return BLUETOOTH_ERROR_NONE;
477 }
478
479 int _bt_stop_visibility_timer(void)
480 {
481         __bt_visibility_alarm_remove();
482
483         visible_timer.timeout = 0;
484
485         if (!TIZEN_PROFILE_WEARABLE) {
486                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
487                         BT_ERR("Set vconf failed");
488         }
489
490         return BLUETOOTH_ERROR_NONE;
491 }
492
493 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
494 {
495         int result;
496         int ret = BLUETOOTH_ERROR_NONE;;
497 #ifdef TIZEN_FEATURE_BT_DPM
498         int discoverable_state = DPM_BT_ERROR;
499 #endif
500
501         BT_DBG("+");
502
503         BT_INFO("discoverable_mode: %d, timeout: %d", discoverable_mode, timeout);
504
505 #ifdef TIZEN_FEATURE_BT_DPM
506         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
507         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
508                  discoverable_state == DPM_RESTRICTED) {
509                 if (headed_plugin_info->plugin_headed_enabled)
510                         headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
511                 return BLUETOOTH_ERROR_ACCESS_DENIED;
512         }
513         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE &&
514                 discoverable_state == DPM_RESTRICTED) {
515                 if (headed_plugin_info->plugin_headed_enabled)
516                         headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
517                 return BLUETOOTH_ERROR_ACCESS_DENIED;
518         }
519 #endif
520
521         switch (discoverable_mode) {
522         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
523                 result = adapter_set_connectable(TRUE);
524                 timeout = 0;
525                 break;
526         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
527                 result = adapter_set_discoverable();
528                 timeout = 0;
529                 break;
530         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
531                 result = adapter_set_discoverable();
532                 break;
533         default:
534                 return BLUETOOTH_ERROR_INVALID_PARAM;
535         }
536
537         if (result != OAL_STATUS_SUCCESS) {
538                 BT_ERR("set scan mode failed %d", result);
539                 return BLUETOOTH_ERROR_INTERNAL;
540         }
541
542         result = adapter_set_discoverable_timeout(timeout);
543         if (result != OAL_STATUS_SUCCESS) {
544                 BT_ERR("adapter_set_discoverable_timeout failed %d", result);
545                 return BLUETOOTH_ERROR_INTERNAL;
546         }
547
548         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE) {
549                 ret = _bt_stop_visibility_timer();
550                 if (BLUETOOTH_ERROR_NONE != ret)
551                         BT_ERR("_bt_stop_visibility_timer failed");
552                 if (!TIZEN_PROFILE_WEARABLE) {
553                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, -1) != 0)
554                                  BT_ERR("Set vconf failed");
555                 }
556         } else if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE) {
557                 ret = _bt_start_visibility_timer(timeout);
558                 if (BLUETOOTH_ERROR_NONE != ret)
559                         BT_ERR("_bt_start_visibility_timer failed");
560
561         } else {
562                 ret = _bt_stop_visibility_timer();
563                 if (BLUETOOTH_ERROR_NONE != ret)
564                         BT_ERR("_bt_stop_visibility_timer failed");
565         }
566
567         BT_DBG("-");
568         return result;
569 }
570
571 gboolean _bt_is_connectable(void)
572 {
573         int connectable = 0;
574         int result;
575
576         BT_DBG("+");
577
578         adapter_is_connectable(&connectable);
579         if (connectable)
580                 result = TRUE;
581         else
582                 result = FALSE;
583
584         BT_DBG("Connectable: [%s]", result ? "TRUE" : "FALSE");
585         BT_DBG("-");
586         return result;
587 }
588
589 int _bt_set_connectable(gboolean connectable)
590 {
591         int result = BLUETOOTH_ERROR_NONE;
592
593         BT_DBG("+");
594         result =  adapter_set_connectable(connectable);
595         if (result != OAL_STATUS_SUCCESS) {
596                 BT_ERR("adapter_set_connectable failed: %d", result);
597                 result = BLUETOOTH_ERROR_INTERNAL;
598         } else
599                 result = BLUETOOTH_ERROR_NONE;
600
601         BT_DBG("-");
602         return result;
603 }
604
605 int _bt_is_service_used(void)
606 {
607         int result;
608
609         BT_DBG("+");
610
611         result =  adapter_get_service_uuids();
612         if (result != OAL_STATUS_SUCCESS) {
613                 BT_ERR("adapter_get_service_uuids failed: %d", result);
614                 result = BLUETOOTH_ERROR_INTERNAL;
615         } else {
616                 result = BLUETOOTH_ERROR_NONE;
617         }
618
619         BT_DBG("-");
620         return result;
621 }
622
623 int _bt_adapter_get_bonded_devices(void)
624 {
625         int result = BLUETOOTH_ERROR_NONE;
626
627         BT_DBG("+");
628         result =  adapter_get_bonded_devices();
629         if (result != OAL_STATUS_SUCCESS) {
630                 BT_ERR("adapter_get_bonded_devices failed: %d", result);
631                 result = BLUETOOTH_ERROR_INTERNAL;
632         } else
633                 result = BLUETOOTH_ERROR_NONE;
634
635         BT_DBG("-");
636         return result;
637 }
638
639 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
640 {
641         BT_DBG("+");
642         GDBusConnection *conn;
643         GDBusProxy *manager_proxy;
644         GVariant *result = NULL;
645         GVariant *result1 = NULL;
646         GVariantIter *iter = NULL;
647         GError *error = NULL;
648         char *object_path = NULL;
649         GVariantIter *interface_iter;
650         char *interface_str = NULL;
651         GDBusProxy *device_proxy = NULL;
652         gboolean is_connected = FALSE;
653
654         conn = _bt_gdbus_get_system_gconn();
655         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
656
657         manager_proxy = _bt_get_manager_proxy();
658         retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
659
660         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
661                         NULL,
662                         G_DBUS_CALL_FLAGS_NONE,
663                         -1,
664                         NULL,
665                         NULL);
666
667         if (!result) {
668                 if (error != NULL) {
669                         BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
670                         g_clear_error(&error);
671                         error = NULL;
672                 } else
673                         BT_ERR("Failed to Failed to GetManagedObjects");
674                 return BLUETOOTH_ERROR_INTERNAL;
675         }
676
677         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
678         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
679
680         /* Parse the signature:  oa{sa{sv}}} */
681         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
682                 if (object_path == NULL)
683                         continue;
684
685                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
686                                         &interface_str, NULL)) {
687                         if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
688                                 BT_DBG("Found a device: %s", object_path);
689                                 g_free(interface_str);
690
691                                 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
692                                                 NULL, BT_BLUEZ_NAME,
693                                                 object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
694
695                                 if (device_proxy == NULL) {
696                                         BT_DBG("Device don't have this service");
697                                         break;
698                                 }
699
700                                 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
701                                                 g_variant_new("(s)", profile_uuid),
702                                                 G_DBUS_CALL_FLAGS_NONE,
703                                                 -1,
704                                                 NULL,
705                                                 &error);
706
707                                 if (result1 == NULL) {
708                                         BT_ERR("Error occured in Proxy call");
709                                         if (error) {
710                                                 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
711                                                 g_error_free(error);
712                                                 error = NULL;
713                                         }
714                                         g_object_unref(device_proxy);
715                                         break;
716                                 }
717                                 g_variant_get(result1, "(b)", &is_connected);
718
719                                 if (is_connected == TRUE) {
720                                         char address[BT_ADDRESS_STRING_SIZE];
721                                         bluetooth_device_address_t *addr = NULL;
722
723                                         _bt_convert_device_path_to_address(object_path, address);
724
725                                         addr = g_malloc0(sizeof(bluetooth_device_address_t));
726                                         _bt_convert_addr_string_to_type(addr->addr, address);
727
728                                         g_array_append_vals(*addr_list, addr,
729                                                         sizeof(bluetooth_device_address_t));
730                                 }
731
732                                 g_variant_unref(result1);
733                                 g_object_unref(device_proxy);
734
735                                 break;
736                         }
737                 }
738         }
739
740         g_variant_unref(result);
741         g_variant_iter_free(iter);
742
743         BT_DBG("-");
744         return BLUETOOTH_ERROR_NONE;
745 }
746
747 static void __bt_handle_pending_a2dp_init(service_uuid_t *service_list, unsigned int count)
748 {
749         int ret;
750         unsigned int i;
751         unsigned char *uuid;
752         char uuid_str[BT_UUID_STRING_SIZE];
753
754         if (!a2dp_init_pending)
755                 return;
756
757         BT_DBG("+");
758         a2dp_init_pending = FALSE;
759         for (i = 0; i < count; i++) {
760                 uuid = service_list[i].uuid;
761                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
762                 BT_INFO("Adapter Service: [%s]", uuid_str);
763                 if (!strcasecmp(uuid_str, A2DP_SINK_UUID)) {
764                         BT_INFO("Enable A2DP Sink role");
765                         /* Initialize A2DP Sink */
766                         ret = _bt_audio_initialize(BT_A2DP_SINK_MODULE);
767                         if (ret != BLUETOOTH_ERROR_NONE)
768                                 BT_ERR("_bt_audio_initialize(BT_A2DP_SINK_MODULE) Failed");
769
770                         /* Initialize AVRCP Controller */
771                         ret = _bt_audio_initialize(BT_AVRCP_CTRL_MODULE);
772                         if (ret != BLUETOOTH_ERROR_NONE)
773                                 BT_ERR("_bt_audio_initialize(BT_AVRCP_CTRL_MODULE) Failed");
774
775                         _bt_audio_set_current_role(BLUETOOTH_A2DP_SINK);
776                         return;
777                 }
778         }
779
780         BT_INFO("Enable A2DP Source role by default");
781         /* Initialize A2DP Source */
782         ret = _bt_audio_initialize(BT_A2DP_SOURCE_MODULE);
783         if (ret != BLUETOOTH_ERROR_NONE)
784                 BT_ERR("_bt_audio_initialize(BT_A2DP_SOURCE_MODULE) Failed");
785
786         /* Initialize AVRCP Target */
787         ret = _bt_audio_initialize(BT_AVRCP_MODULE);
788         if (ret != BLUETOOTH_ERROR_NONE)
789                 BT_ERR("_bt_audio_initialize(BT_AVRCP_MODULE) Failed");
790
791         _bt_audio_set_current_role(BLUETOOTH_A2DP_SOURCE);
792         BT_DBG("-");
793 }
794
795 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
796 {
797         int result = BLUETOOTH_ERROR_NONE;
798
799         BT_DBG("+");
800
801         switch (event_type) {
802         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
803         case OAL_EVENT_OAL_INITIALISED_FAILED:
804                 __bt_handle_oal_initialisation(event_type);
805                 break;
806         case OAL_EVENT_ADAPTER_ENABLED:
807                 __bt_adapter_state_change_callback(BT_ACTIVATED);
808                 break;
809         case OAL_EVENT_ADAPTER_DISABLED:
810                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
811                 break;
812         case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
813                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STARTED);
814                 break;
815         case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
816                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STOPPED);
817                 break;
818         case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
819                 bt_address_t *bd_addr = event_data;
820                 bluetooth_device_address_t local_address;
821
822                 /* Copy data */
823                 memcpy(local_address.addr, bd_addr->addr, BT_ADDRESS_LENGTH_MAX);
824                 BT_DBG("Adapter address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]",
825                                 local_address.addr[0], local_address.addr[1], local_address.addr[2],
826                                 local_address.addr[3], local_address.addr[4], local_address.addr[5]);
827
828                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
829                                 (void *) &local_address, sizeof(bluetooth_device_address_t));
830                 break;
831         }
832         case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
833                 char *name = event_data;
834                 BT_DBG("Adapter Name: %s", name);
835
836                 if (__bt_is_service_request_present(BT_GET_LOCAL_NAME)) {
837                         bluetooth_device_name_t local_name;
838
839                         memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
840                         g_strlcpy(local_name.name,
841                                 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
842                         __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
843                                 (void *) &local_name, sizeof(bluetooth_device_name_t));
844                 } else {
845                         /* Send event to application */
846                         _bt_send_event(BT_ADAPTER_EVENT,
847                                         BLUETOOTH_EVENT_LOCAL_NAME_CHANGED,
848                                         g_variant_new("(is)", result, name));
849                 }
850                 break;
851         }
852         case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
853                 char *ver = event_data;
854                 bluetooth_version_t local_version;
855
856                 memset(&local_version, 0x00, sizeof(bluetooth_version_t));
857                 g_strlcpy(local_version.version,
858                                 (const gchar *)ver, BLUETOOTH_VERSION_LENGTH_MAX);
859                 BT_DBG("BT Version: %s", local_version.version);
860
861                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
862                                 (void *) &local_version, sizeof(bluetooth_version_t));
863                 break;
864         }
865         case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
866                 int mode = -1;
867                 gboolean connectable = FALSE;
868
869                 BT_INFO("Adapter discoverable mode:"
870                                 " BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
871                 _bt_send_event(BT_ADAPTER_EVENT,
872                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
873                                 g_variant_new("(b)", connectable));
874
875                 _bt_send_event(BT_ADAPTER_EVENT,
876                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
877                                 g_variant_new("(in)", result, mode));
878                 break;
879         }
880         case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
881                 int mode;
882                 gboolean connectable = TRUE;
883
884                 BT_INFO("Adapter discoverable mode:"
885                                 " BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
886                 _bt_send_event(BT_ADAPTER_EVENT,
887                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
888                                 g_variant_new("(b)", connectable));
889
890                 mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
891                 _bt_send_event(BT_ADAPTER_EVENT,
892                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
893                                 g_variant_new("(in)", result, mode));
894                 break;
895         }
896         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
897                 int mode;
898
899                 BT_INFO("Adapter discoverable mode:"
900                                 " BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
901
902                 /* Send event to application */
903                 mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
904                 _bt_send_event(BT_ADAPTER_EVENT,
905                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
906                                 g_variant_new("(in)", result, mode));
907
908                 break;
909         }
910         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
911                 int *timeout = event_data;
912                 int mode;
913
914                 BT_INFO("Discoverable timeout: [%d]", *timeout);
915
916                 /* Send event to application */
917                 _bt_get_discoverable_mode(&mode);
918                 _bt_send_event(BT_ADAPTER_EVENT,
919                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
920                                 g_variant_new("(in)", result, mode));
921                 break;
922         }
923         case OAL_EVENT_ADAPTER_PROPERTY_SERVICES: {
924                 int count;
925                 service_uuid_t *service_list;
926                 event_adapter_services_t *list = event_data;
927
928                 count = list->num;
929                 service_list = list->service_list;
930                 __bt_handle_pending_a2dp_init(service_list, count);
931                 __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
932                 break;
933         }
934         case OAL_EVENT_ADAPTER_BONDED_DEVICE_LIST: {
935                 int i;
936                 int count;
937                 bluetooth_device_address_t *addr_list;
938
939                 event_device_list_t *bonded_device_list = event_data;
940                 count = bonded_device_list->num;
941
942                 addr_list = g_malloc0(count * sizeof(bluetooth_device_address_t));
943                 for (i = 0; i < count; i++) {
944                         memcpy(addr_list[i].addr,
945                                         bonded_device_list->devices[i].addr,
946                                         BLUETOOTH_ADDRESS_LENGTH);
947                 }
948
949                 BT_INFO("Adapter Bonded device List count: [%d]", count);
950                 _bt_device_handle_paired_address_list(addr_list, bonded_device_list->num);
951                 g_free(addr_list);
952                 break;
953         }
954         default:
955                 BT_ERR("Unhandled event..");
956                 break;
957         }
958
959         BT_DBG("-");
960 }
961
962 int _bt_init_profiles()
963 {
964         int ret;
965         BT_INFO("+");
966
967         /*TODO: Init bluetooth profiles */
968         ret = _bt_hidhost_initialize();
969         if (ret != BLUETOOTH_ERROR_NONE)
970                 BT_ERR("_bt_hidhost_initialize Failed");
971
972         ret = _bt_socket_init();
973         if (ret != BLUETOOTH_ERROR_NONE)
974                 BT_ERR("_bt_socket_init Failed");
975
976         /*
977          * Query local adapter services and based on a2dp service uuids initialized
978          * in bluetooth stack, enable A2DP sourec or A2DP sink role.
979          */
980         ret =  adapter_get_service_uuids();
981         if (ret != OAL_STATUS_SUCCESS)
982                 BT_ERR("adapter_get_service_uuids failed: %d", ret);
983         else
984                 a2dp_init_pending = TRUE;
985
986
987         /* Initialize HFP Audio Gateway */
988         ret = _bt_audio_initialize(BT_AG_MODULE);
989         if (ret != BLUETOOTH_ERROR_NONE)
990                 BT_ERR("_bt_audio_initialize(BT_AG_MODULE) Failed");
991
992         /* Registering callback for receiving audio services searched */
993         ret = _bt_audio_initialize(BT_AUDIO_ALL_MODULE);
994         if (ret != BLUETOOTH_ERROR_NONE)
995                 BT_ERR("_bt_audio_initialize(BT_AUDIO_ALL_MODULE) Failed");
996
997         ret = _bt_hdp_init();
998         if (ret != BLUETOOTH_ERROR_NONE)
999                 BT_ERR("_bt_hdp_init Failed");
1000
1001         ret = _bt_gatt_init();
1002         if (ret != BLUETOOTH_ERROR_NONE)
1003                 BT_ERR("_bt_gatt_init Failed");
1004
1005         /* Initialize HF Client */
1006         ret = _bt_audio_initialize(BT_HFP_MODULE);
1007         if (ret != BLUETOOTH_ERROR_NONE)
1008                 BT_ERR("_bt_audio_initialize(BT_HFP_MODULE) Failed");
1009
1010         return BLUETOOTH_ERROR_NONE;
1011 }
1012
1013 int _bt_cleanup_profiles(void)
1014 {
1015         /* TODO: Cleanup bluetooth profiles */
1016         _bt_hidhost_deinitialize();
1017         _bt_socket_deinit();
1018 #if 0
1019         /* TODO: Cleanup bluetooth audio profiles */
1020         //_bt_audio_deinitialize(BT_A2DP_SOURCE_MODULE);
1021         //_bt_audio_deinitialize(BT_AVRCP_MODULE);
1022         //_bt_audio_deinitialize(BT_A2DP_SINK_MODULE);
1023         //_bt_audio_deinitialize(BT_AG_MODULE);
1024         //_bt_audio_deinitialize(BT_AVRCP_CTRL_MODULE);
1025         //_bt_audio_deinitialize(BT_AUDIO_ALL_MODULE);
1026 #endif
1027         _bt_hdp_deinit();
1028         _bt_gatt_deinit();
1029
1030         return BLUETOOTH_ERROR_NONE;
1031 }
1032
1033 /* OAL post initialization handler */
1034 static void __bt_post_oal_init(void)
1035 {
1036         int ret;
1037         int status = VCONFKEY_BT_STATUS_OFF;
1038
1039         BT_DBG("OAL initialized");
1040         if (vconf_get_int(VCONFKEY_BT_STATUS, &status) != 0)
1041                 BT_ERR("Fail to get the enabled value");
1042
1043 #if 0
1044         /* Update Bluetooth Status to OFF */
1045         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1046                 BT_ERR("Set vconf failed\n");
1047 #endif
1048
1049         if (status & VCONFKEY_BT_STATUS_ON) {
1050                 ret = _bt_enable_adapter();
1051                 if (ret != BLUETOOTH_ERROR_NONE)
1052                         BT_ERR("_bt_enable_adapter failed with error: %d", ret);
1053         }
1054 }
1055
1056 /* OAL initialization handler */
1057 static void __bt_handle_oal_initialisation(oal_event_t event)
1058 {
1059         BT_DBG("");
1060
1061         switch (event) {
1062         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
1063                 __bt_post_oal_init();
1064                 break;
1065         case OAL_EVENT_OAL_INITIALISED_FAILED:
1066                 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
1067                 g_idle_add(_bt_terminate_service, NULL);
1068                 break;
1069         default:
1070                 BT_ERR("Unknown Event");
1071                 break;
1072         }
1073 }
1074
1075 static gboolean __bt_is_service_request_present(int service_function)
1076 {
1077         GSList *l;
1078         invocation_info_t *req_info;
1079
1080         BT_DBG("+");
1081
1082         /* Get method invocation context */
1083         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1084                 req_info = l->data;
1085                 if (req_info && req_info->service_function == service_function)
1086                         return TRUE;
1087         }
1088
1089         BT_DBG("-");
1090         return FALSE;
1091 }
1092
1093 /* Internal functions of core adapter service */
1094 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
1095 {
1096         GSList *l;
1097         GArray *out_param;
1098         invocation_info_t *req_info;
1099         BT_INFO("+");
1100
1101         /* Get method invocation context */
1102         for (l = _bt_get_invocation_list(); l != NULL; ) {
1103                 req_info = l->data;
1104                 l = g_slist_next(l);
1105                 if (req_info == NULL || req_info->service_function != service_function)
1106                         continue;
1107
1108                 /* Create out param */
1109                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1110
1111                 switch (service_function) {
1112                 case BT_ENABLE_ADAPTER:
1113                 case BT_DISABLE_ADAPTER: {
1114                         gboolean done = TRUE;
1115                         g_array_append_vals(out_param, &done, sizeof(gboolean));
1116                         break;
1117                 }
1118                 case BT_GET_LOCAL_NAME:
1119                 case BT_GET_LOCAL_ADDRESS:
1120                 case BT_GET_LOCAL_VERSION:
1121                         g_array_append_vals(out_param, user_data, size);
1122                         break;
1123                 case BT_IS_SERVICE_USED: {
1124                         unsigned int i;
1125                         gboolean used = FALSE;
1126                         unsigned char *uuid;
1127                         char uuid_str[BT_UUID_STRING_SIZE];
1128                         char *request_uuid = req_info->user_data;
1129                         service_uuid_t *service_list = user_data;
1130
1131                         BT_INFO("Check for service uuid: %s", request_uuid);
1132                         for (i = 0; i < size; i++) {
1133                                 uuid = service_list[i].uuid;
1134                                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
1135                                 BT_INFO("Adapter Service: [%s]", uuid_str);
1136                                 if (strcasecmp(uuid_str, request_uuid) == 0) {
1137                                         BT_INFO("UUID matched!!");
1138                                         used = TRUE;
1139                                         break;
1140                                 }
1141                         }
1142
1143                         g_array_append_vals(out_param, &used, sizeof(gboolean));
1144                         break;
1145                 }
1146                 default:
1147                         BT_ERR("Unknown service function[%d]", service_function);
1148                 }
1149
1150                 _bt_service_method_return(req_info->context, out_param, req_info->result);
1151                 g_array_free(out_param, TRUE);
1152                 /* Now free invocation info for this request*/
1153                 _bt_free_info_from_invocation_list(req_info);
1154         }
1155 }
1156
1157 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
1158 {
1159         char *phone_name = NULL;
1160         char *ptr = NULL;
1161
1162         if (node == NULL)
1163                 return;
1164
1165         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
1166                 phone_name = vconf_keynode_get_str(node);
1167
1168                 if (phone_name && strlen(phone_name) != 0) {
1169                         if (!g_utf8_validate(phone_name, -1,
1170                                         (const char **)&ptr))
1171                                 *ptr = '\0';
1172
1173                         _bt_set_local_name(phone_name);
1174                 }
1175         }
1176 }
1177
1178 /* Request return handlings */
1179 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
1180 {
1181         BT_INFO("__bt_adapter_post_set_enabled>>");
1182
1183         if (TIZEN_PROFILE_TV || !headed_plugin_info->plugin_headed_enabled) {
1184                 if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
1185                                 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0))
1186                         BT_ERR("Fail to set discoverable mode");
1187         } else {
1188                 __bt_set_visible_mode();
1189         }
1190
1191         /* add the vconf noti handler */
1192         if (0 != vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1193                         (vconf_callback_fn)__bt_phone_name_changed_cb, NULL))
1194                 BT_ERR("DEVICE_NAME key changed notification registration failed");
1195
1196         __bt_set_local_name();
1197
1198         /* Get All properties */
1199         if (OAL_STATUS_SUCCESS != adapter_get_properties())
1200                 BT_ERR("adapter_get_properties failed");
1201
1202         /* Add Adapter enabled post processing codes */
1203         return FALSE;
1204 }
1205
1206 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
1207 {
1208         BT_INFO("_bt_adapter_post_set_disabled>>");
1209
1210         if (!TIZEN_PROFILE_TV) {
1211                 /* Add Adapter disabled post processing codes */
1212                 if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1213                                 (vconf_callback_fn)__bt_phone_name_changed_cb) != 0)
1214                         BT_ERR("vconf_ignore_key_changed failed");
1215         }
1216
1217         /* bt-service should be terminated when BT is off */
1218         if (!TIZEN_FEATURE_BT_USB_DONGLE) {
1219                 /* TODO: Implement to check if it is the recovery mode or not */
1220                 _bt_reliable_terminate_service(NULL);
1221         }
1222
1223         return FALSE;
1224 }
1225
1226 static void __bt_adapter_update_bt_enabled(void)
1227 {
1228         int result = BLUETOOTH_ERROR_NONE;
1229
1230         BT_INFO("_bt_adapter_update_bt_enabled >> Init profiles...");
1231         if (BLUETOOTH_ERROR_NONE != _bt_init_profiles())
1232                 BT_ERR("Bluetooth profile init failed");
1233
1234         _bt_device_handle_adapter_state(TRUE);
1235
1236         /* Update Bluetooth Status to notify other modules */
1237         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
1238                 BT_ERR("Set vconf failed\n");
1239
1240         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1241                 BT_ERR("Set vconf failed\n");
1242
1243         /* TODO:Add timer function to handle any further post processing */
1244         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
1245
1246         /*Return BT_ADAPTER_ENABLE Method invocation context */
1247         __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
1248         /*Send BT Enabled event to application */
1249         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
1250                         g_variant_new("(i)", result));
1251 }
1252
1253 static void __bt_adapter_update_bt_disabled(void)
1254 {
1255         int result = BLUETOOTH_ERROR_NONE;
1256         int power_off_status = 0;
1257         int ret;
1258
1259         BT_INFO("_bt_adapter_update_bt_disabled >> Cleanup profiles...");
1260         _bt_cleanup_profiles();
1261
1262         _bt_device_handle_adapter_state(FALSE);
1263
1264         /* Update the vconf BT status in normal Deactivation case only */
1265         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1266         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1267
1268         /* Update Bluetooth Status to notify other modules */
1269         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1270                 BT_ERR("Set vconf failed");
1271
1272         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1273                 BT_ERR("Set vconf failed\n");
1274
1275         /* TODO:Add timer function to handle any further post processing */
1276         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
1277
1278         /* Return BT_ADAPTER_DISABLE Method invocation context */
1279         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
1280
1281         /* Send BT Disabled event to application */
1282         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1283                         g_variant_new("(i)", result));
1284 }
1285
1286 static void __bt_adapter_state_set_status(bt_status_t status)
1287 {
1288         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1289         adapter_state = status;
1290 }
1291
1292 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
1293 {
1294         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
1295         adapter_discovery_state = status;
1296 }
1297
1298 static void __bt_adapter_state_change_callback(int bt_status)
1299 {
1300         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
1301
1302         switch (bt_status) {
1303         case BT_DEACTIVATED:
1304                 __bt_adapter_state_set_status(bt_status);
1305
1306                 /* Adapter is disabled, unregister event handlers */
1307                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
1308                 //_bt_deinit_device_event_handler();
1309
1310                 /* Add Adapter disabled post processing codes */
1311                 __bt_adapter_update_bt_disabled();
1312                 break;
1313         case BT_ACTIVATED:
1314                 __bt_adapter_state_set_status(bt_status);
1315                 /* Add Adapter enabled post processing codes */
1316                 if (timer_id > 0) {
1317                         BT_DBG("g_source is removed");
1318                         g_source_remove(timer_id);
1319                         timer_id = 0;
1320                 }
1321                 __bt_adapter_update_bt_enabled();
1322                 break;
1323         default:
1324                 BT_ERR("Incorrect Bluetooth adapter state changed status");
1325
1326         }
1327 }
1328
1329 int _bt_set_adapter_request_state(int enable)
1330 {
1331         return oal_set_adapter_request_state(enable);
1332 }
1333
1334 int _bt_set_le_request_state(int enable)
1335 {
1336         return oal_set_le_request_state(enable);
1337 }
1338
1339 static int __bt_adapter_state_handle_request(gboolean enable)
1340 {
1341         int result = BLUETOOTH_ERROR_NONE;
1342         BT_DBG("");
1343
1344         switch (adapter_state) {
1345         case BT_ACTIVATING: {
1346                 BT_INFO("Adapter is currently in activating state, state [%d]",
1347                                 adapter_state);
1348                 if (enable) {
1349                         return BLUETOOTH_ERROR_IN_PROGRESS;
1350                 } else {
1351                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
1352                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
1353                                 /*TODO Stop Discovery*/
1354                                 __bt_adapter_update_discovery_status(FALSE);
1355                         }
1356                         result = adapter_disable();
1357                         if (result != OAL_STATUS_SUCCESS) {
1358                                 BT_ERR("adapter_enable failed: [%d]", result);
1359                                 result = BLUETOOTH_ERROR_INTERNAL;
1360                                 /*TODO: perform if anything more needs to be done to handle failure */
1361                         } else {
1362                                 /* TODO: To be handled */
1363                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1364                                 result = BLUETOOTH_ERROR_NONE;
1365                         }
1366                 }
1367                 break;
1368         }
1369         case BT_ACTIVATED: {
1370                 BT_INFO("Adapter is currently in activated state, state [%d]",
1371                                 adapter_state);
1372                 if (enable) {
1373                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1374                 } else {
1375                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
1376                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
1377                                 /*TODO Stop Discovery*/
1378                                 __bt_adapter_update_discovery_status(FALSE);
1379                         }
1380                         result = adapter_disable();
1381                         if (result != OAL_STATUS_SUCCESS) {
1382                                 BT_ERR("adapter_enable failed: [%d]", result);
1383                                 result = BLUETOOTH_ERROR_INTERNAL;
1384                                 /*TODO: perform if anything more needs to be done to handle failure */
1385                         } else {
1386                                 /* TODO: To be handled */
1387                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1388                                 result = BLUETOOTH_ERROR_NONE;
1389                         }
1390                 }
1391                 break;
1392         }
1393         case BT_DEACTIVATING: {
1394                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
1395                                 adapter_state);
1396                 if (!enable) {
1397                         return BLUETOOTH_ERROR_IN_PROGRESS;
1398
1399                 } else {
1400                         result = adapter_enable();
1401                         if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
1402                                 BT_ERR("adapter_enable failed: [%d]", result);
1403                                 adapter_disable();
1404                                 result = BLUETOOTH_ERROR_INTERNAL;
1405                                 /*TODO: perform if anything more needs to be done to handle failure */
1406                         } else {
1407                                 /* TODO: To be handled */
1408                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1409                                 result = BLUETOOTH_ERROR_NONE;
1410                         }
1411                 }
1412                 break;
1413         }
1414         case BT_DEACTIVATED: {
1415                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
1416                                 adapter_state);
1417                 if (!enable) {
1418                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1419                 } else {
1420                         result = adapter_enable();
1421                         if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
1422                                 BT_ERR("adapter_enable failed: [%d]", result);
1423                                 adapter_disable();
1424                                 result = BLUETOOTH_ERROR_INTERNAL;
1425                                 /*TODO: perform if anything more needs to be done to handle failure */
1426                         } else {
1427                                 /* TODO: To be handled */
1428                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1429                                 result = BLUETOOTH_ERROR_NONE;
1430                         }
1431                 }
1432                 break;
1433         }
1434         default:
1435                 BT_ERR("Unknown state: %d", adapter_state);
1436                 break;
1437         }
1438
1439         if (enable && result == BLUETOOTH_ERROR_NONE) {
1440                 /* Adapter enable request is successful, setup event handlers */
1441                 _bt_service_register_event_handler_callback(
1442                                 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
1443                 _bt_device_state_handle_callback_set_request();
1444         }
1445         return result;
1446 }
1447
1448 static int __bt_adapter_state_discovery_request(gboolean enable,
1449                 unsigned short max_response, unsigned short duration,
1450                 unsigned int mask, gboolean is_custom,
1451                 bt_discovery_role_type_t role)
1452 {
1453         int result = BLUETOOTH_ERROR_NONE;
1454
1455         BT_DBG("+");
1456         switch (adapter_discovery_state) {
1457         case ADAPTER_DISCOVERY_STARTED: {
1458                 BT_INFO("Adapter is currently in discovery started state, state [%d]",
1459                                 adapter_discovery_state);
1460                 if (enable) {
1461                         return BLUETOOTH_ERROR_IN_PROGRESS;
1462                 } else {
1463                         result = adapter_stop_inquiry();
1464                         if (result != OAL_STATUS_SUCCESS) {
1465                                 BT_ERR("Discover stop failed: %d", result);
1466                                 result = BLUETOOTH_ERROR_INTERNAL;
1467                         } else {
1468                                 BT_ERR("Stop Discovery Triggered successfully");
1469                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1470                                 result = BLUETOOTH_ERROR_NONE;
1471                         }
1472                 }
1473                 break;
1474         }
1475         case ADAPTER_DISCOVERY_STARTING: {
1476                 BT_INFO("Adapter is currently in discovery starting state, state [%d]",
1477                                 adapter_discovery_state);
1478
1479                 result = enable ?  BLUETOOTH_ERROR_IN_PROGRESS :
1480                                         BLUETOOTH_ERROR_DEVICE_BUSY;
1481
1482                 break;
1483         }
1484         case ADAPTER_DISCOVERY_STOPPED: {
1485                 BT_INFO("Adapter is currently in discovery stopped state, state [%d]",
1486                                 adapter_discovery_state);
1487                 if (!enable)
1488                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1489                 else {
1490                         BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
1491
1492                         if (!is_custom)
1493                                 result = adapter_start_inquiry(duration);
1494                         else
1495                                 result = adapter_start_custom_inquiry(role);
1496
1497                         if (result != OAL_STATUS_SUCCESS) {
1498                                 BT_ERR("Start Discovery failed: %d", result);
1499                                 result = BLUETOOTH_ERROR_INTERNAL;
1500                         } else {
1501                                 BT_ERR("Start Discovery Triggered successfully");
1502                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1503                                 result = BLUETOOTH_ERROR_NONE;
1504                         }
1505                 }
1506                 break;
1507         }
1508         case ADAPTER_DISCOVERY_STOPPING: {
1509                 BT_INFO("Adapter is currently in discovery stopping state, state [%d]",
1510                                 adapter_discovery_state);
1511
1512                 result = enable ?  BLUETOOTH_ERROR_DEVICE_BUSY :
1513                                         BLUETOOTH_ERROR_NOT_IN_OPERATION;
1514
1515                 break;
1516         }
1517         default:
1518                 BT_ERR("Unknown state: %d", adapter_discovery_state);
1519                 break;
1520         }
1521
1522         BT_DBG("-");
1523         return result;
1524 }
1525
1526 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status)
1527 {
1528         BT_INFO("__bt_adapter_discovery_state_change_callback: status [%d]", bt_discovery_status);
1529         GVariant *param = NULL;
1530         int result = BLUETOOTH_ERROR_NONE;
1531
1532         switch (bt_discovery_status) {
1533         case ADAPTER_DISCOVERY_STOPPED:
1534         {
1535                 __bt_adapter_update_discovery_status(bt_discovery_status);
1536                 param = g_variant_new("(i)", result);
1537                 _bt_send_event(BT_ADAPTER_EVENT,
1538                                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
1539                                 param);
1540                 break;
1541         }
1542         case ADAPTER_DISCOVERY_STARTED:
1543         {
1544                 __bt_adapter_update_discovery_status(bt_discovery_status);
1545                 param = g_variant_new("(i)", result);
1546                 _bt_send_event(BT_ADAPTER_EVENT,
1547                                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
1548                                 param);
1549                 break;
1550         }
1551         default:
1552                 BT_ERR("Incorrect Bluetooth adapter Discovery state changed status");
1553         }
1554 }
1555
1556 static void __bt_set_visible_mode(void)
1557 {
1558         int timeout = 0;
1559 #ifdef TIZEN_FEATURE_BT_DPM
1560         int discoverable_state = DPM_BT_ERROR;
1561 #endif
1562
1563         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
1564                 BT_ERR("Fail to get the timeout value");
1565
1566 #ifdef TIZEN_FEATURE_BT_DPM
1567         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1568         if (timeout == -1 || discoverable_state == DPM_RESTRICTED) {
1569                 if (_bt_set_discoverable_mode(
1570                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
1571                                         timeout) != BLUETOOTH_ERROR_NONE) {
1572                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
1573                                 BT_ERR("Set vconf failed");
1574                 }
1575         } else {
1576                 if (_bt_set_discoverable_mode(
1577                                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
1578                                         timeout) != BLUETOOTH_ERROR_NONE) {
1579                         BT_ERR("Set connectable mode failed");
1580                 }
1581         }
1582 #else
1583         if (timeout == -1) {
1584                 if (_bt_set_discoverable_mode(
1585                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
1586                                         timeout) != BLUETOOTH_ERROR_NONE) {
1587                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
1588                                 BT_ERR("Set vconf failed");
1589                 }
1590         } else {
1591                 if (_bt_set_discoverable_mode(
1592                                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
1593                                         timeout) != BLUETOOTH_ERROR_NONE) {
1594                         BT_ERR("Set connectable mode failed");
1595                 }
1596         }
1597 #endif
1598 }
1599
1600 static void __bt_set_local_name(void)
1601 {
1602         char *phone_name = NULL;
1603         char *ptr = NULL;
1604
1605         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1606
1607         if (!phone_name)
1608                 return;
1609
1610         if (strlen(phone_name) != 0) {
1611                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
1612                         *ptr = '\0';
1613
1614                 _bt_set_local_name(phone_name);
1615         }
1616         free(phone_name);
1617 }
1618
1619 void _bt_adapter_set_status(bt_status_t status)
1620 {
1621         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1622         adapter_state = status;
1623 }
1624
1625 bt_status_t _bt_adapter_get_status(void)
1626 {
1627         return adapter_state;
1628 }
1629
1630 void _bt_set_disabled(int result)
1631 {
1632         int power_off_status = 0;
1633         int ret;
1634         int ret_pm_ignore;
1635         int pm_ignore_mode = 0;
1636
1637         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1638         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1639
1640         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
1641
1642         /* Update the vconf BT status in normal Deactivation case only */
1643         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
1644                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
1645
1646                 BT_DBG("Update vconf for BT normal Deactivation");
1647
1648                 if (result == BLUETOOTH_ERROR_TIMEOUT)
1649                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
1650                                 BT_ERR("Set vconf failed");
1651
1652                 /* Update Bluetooth Status to notify other modules */
1653                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1654                         BT_ERR("Set vconf failed");
1655
1656                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
1657                                                         EVT_VAL_BT_OFF) != ES_R_OK)
1658                         BT_ERR("Fail to set value");
1659         }
1660
1661         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1662                 BT_ERR("Set vconf failed\n");
1663
1664         _bt_adapter_set_status(BT_DEACTIVATED);
1665         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPED);
1666
1667         BT_INFO("Adapter disabled");
1668 }
1669