Merge "Improvements in flight mode patch" into tizen
[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         return BLUETOOTH_ERROR_NONE;
1006 }
1007
1008 int _bt_cleanup_profiles(void)
1009 {
1010         /* TODO: Cleanup bluetooth profiles */
1011         _bt_hidhost_deinitialize();
1012         _bt_socket_deinit();
1013 #if 0
1014         /* TODO: Cleanup bluetooth audio profiles */
1015         //_bt_audio_deinitialize(BT_A2DP_SOURCE_MODULE);
1016         //_bt_audio_deinitialize(BT_AVRCP_MODULE);
1017         //_bt_audio_deinitialize(BT_A2DP_SINK_MODULE);
1018         //_bt_audio_deinitialize(BT_AG_MODULE);
1019         //_bt_audio_deinitialize(BT_AVRCP_CTRL_MODULE);
1020         //_bt_audio_deinitialize(BT_AUDIO_ALL_MODULE);
1021 #endif
1022         _bt_hdp_deinit();
1023         _bt_gatt_deinit();
1024
1025         return BLUETOOTH_ERROR_NONE;
1026 }
1027
1028 /* OAL post initialization handler */
1029 static void __bt_post_oal_init(void)
1030 {
1031         int ret;
1032         int status = VCONFKEY_BT_STATUS_OFF;
1033
1034         BT_DBG("OAL initialized");
1035         if (vconf_get_int(VCONFKEY_BT_STATUS, &status) != 0)
1036                 BT_ERR("Fail to get the enabled value");
1037
1038 #if 0
1039         /* Update Bluetooth Status to OFF */
1040         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1041                 BT_ERR("Set vconf failed\n");
1042 #endif
1043
1044         if (status & VCONFKEY_BT_STATUS_ON) {
1045                 ret = _bt_enable_adapter();
1046                 if (ret != BLUETOOTH_ERROR_NONE)
1047                         BT_ERR("_bt_enable_adapter failed with error: %d", ret);
1048         }
1049 }
1050
1051 /* OAL initialization handler */
1052 static void __bt_handle_oal_initialisation(oal_event_t event)
1053 {
1054         BT_DBG("");
1055
1056         switch (event) {
1057         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
1058                 __bt_post_oal_init();
1059                 break;
1060         case OAL_EVENT_OAL_INITIALISED_FAILED:
1061                 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
1062                 g_idle_add(_bt_terminate_service, NULL);
1063                 break;
1064         default:
1065                 BT_ERR("Unknown Event");
1066                 break;
1067         }
1068 }
1069
1070 static gboolean __bt_is_service_request_present(int service_function)
1071 {
1072         GSList *l;
1073         invocation_info_t *req_info;
1074
1075         BT_DBG("+");
1076
1077         /* Get method invocation context */
1078         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1079                 req_info = l->data;
1080                 if (req_info && req_info->service_function == service_function)
1081                         return TRUE;
1082         }
1083
1084         BT_DBG("-");
1085         return FALSE;
1086 }
1087
1088 /* Internal functions of core adapter service */
1089 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
1090 {
1091         GSList *l;
1092         GArray *out_param;
1093         invocation_info_t *req_info;
1094         BT_INFO("+");
1095
1096         /* Get method invocation context */
1097         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1098                 req_info = l->data;
1099                 if (req_info == NULL || req_info->service_function != service_function)
1100                         continue;
1101
1102                 /* Create out param */
1103                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1104
1105                 switch (service_function) {
1106                 case BT_ENABLE_ADAPTER:
1107                 case BT_DISABLE_ADAPTER: {
1108                         gboolean done = TRUE;
1109                         g_array_append_vals(out_param, &done, sizeof(gboolean));
1110                         break;
1111                 }
1112                 case BT_GET_LOCAL_NAME:
1113                 case BT_GET_LOCAL_ADDRESS:
1114                 case BT_GET_LOCAL_VERSION:
1115                         g_array_append_vals(out_param, user_data, size);
1116                         break;
1117                 case BT_IS_SERVICE_USED: {
1118                         unsigned int i;
1119                         gboolean used = FALSE;
1120                         unsigned char *uuid;
1121                         char uuid_str[BT_UUID_STRING_SIZE];
1122                         char *request_uuid = req_info->user_data;
1123                         service_uuid_t *service_list = user_data;
1124
1125                         BT_INFO("Check for service uuid: %s", request_uuid);
1126                         for (i = 0; i < size; i++) {
1127                                 uuid = service_list[i].uuid;
1128                                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
1129                                 BT_INFO("Adapter Service: [%s]", uuid_str);
1130                                 if (strcasecmp(uuid_str, request_uuid) == 0) {
1131                                         BT_INFO("UUID matched!!");
1132                                         used = TRUE;
1133                                         break;
1134                                 }
1135                         }
1136
1137                         g_array_append_vals(out_param, &used, sizeof(gboolean));
1138                         break;
1139                 }
1140                 default:
1141                         BT_ERR("Unknown service function[%d]", service_function);
1142                 }
1143
1144                 _bt_service_method_return(req_info->context, out_param, req_info->result);
1145                 g_array_free(out_param, TRUE);
1146                 /* Now free invocation info for this request*/
1147                 _bt_free_info_from_invocation_list(req_info);
1148         }
1149 }
1150
1151 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
1152 {
1153         char *phone_name = NULL;
1154         char *ptr = NULL;
1155
1156         if (node == NULL)
1157                 return;
1158
1159         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
1160                 phone_name = vconf_keynode_get_str(node);
1161
1162                 if (phone_name && strlen(phone_name) != 0) {
1163                         if (!g_utf8_validate(phone_name, -1,
1164                                         (const char **)&ptr))
1165                                 *ptr = '\0';
1166
1167                         _bt_set_local_name(phone_name);
1168                 }
1169         }
1170 }
1171
1172 /* Request return handlings */
1173 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
1174 {
1175         BT_INFO("__bt_adapter_post_set_enabled>>");
1176
1177         if (TIZEN_PROFILE_TV || !headed_plugin_info->plugin_headed_enabled) {
1178                 if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
1179                                 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0))
1180                         BT_ERR("Fail to set discoverable mode");
1181         } else {
1182                 __bt_set_visible_mode();
1183         }
1184
1185         /* add the vconf noti handler */
1186         if (0 != vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1187                         (vconf_callback_fn)__bt_phone_name_changed_cb, NULL))
1188                 BT_ERR("DEVICE_NAME key changed notification registration failed");
1189
1190         __bt_set_local_name();
1191
1192         /* Get All properties */
1193         if (OAL_STATUS_SUCCESS != adapter_get_properties())
1194                 BT_ERR("adapter_get_properties failed");
1195
1196         /* Add Adapter enabled post processing codes */
1197         return FALSE;
1198 }
1199
1200 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
1201 {
1202         BT_INFO("_bt_adapter_post_set_disabled>>");
1203
1204         if (!TIZEN_PROFILE_TV) {
1205                 /* Add Adapter disabled post processing codes */
1206                 if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1207                                 (vconf_callback_fn)__bt_phone_name_changed_cb) != 0)
1208                         BT_ERR("vconf_ignore_key_changed failed");
1209         }
1210
1211         /* bt-service should be terminated when BT is off */
1212         if (!TIZEN_FEATURE_BT_USB_DONGLE) {
1213                 /* TODO: Implement to check if it is the recovery mode or not */
1214                 _bt_reliable_terminate_service(NULL);
1215         }
1216
1217         return FALSE;
1218 }
1219
1220 static void __bt_adapter_update_bt_enabled(void)
1221 {
1222         int result = BLUETOOTH_ERROR_NONE;
1223
1224         BT_INFO("_bt_adapter_update_bt_enabled >> Init profiles...");
1225         if (BLUETOOTH_ERROR_NONE != _bt_init_profiles())
1226                 BT_ERR("Bluetooth profile init failed");
1227
1228         _bt_device_handle_adapter_state(TRUE);
1229
1230         /* Update Bluetooth Status to notify other modules */
1231         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
1232                 BT_ERR("Set vconf failed\n");
1233
1234         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1235                 BT_ERR("Set vconf failed\n");
1236
1237         /* TODO:Add timer function to handle any further post processing */
1238         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
1239
1240         /*Return BT_ADAPTER_ENABLE Method invocation context */
1241         __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
1242         /*Send BT Enabled event to application */
1243         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
1244                         g_variant_new("(i)", result));
1245 }
1246
1247 static void __bt_adapter_update_bt_disabled(void)
1248 {
1249         int result = BLUETOOTH_ERROR_NONE;
1250         int power_off_status = 0;
1251         int ret;
1252
1253         BT_INFO("_bt_adapter_update_bt_disabled >> Cleanup profiles...");
1254         _bt_cleanup_profiles();
1255
1256         _bt_device_handle_adapter_state(FALSE);
1257
1258         /* Update the vconf BT status in normal Deactivation case only */
1259         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1260         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1261
1262         /* Update Bluetooth Status to notify other modules */
1263         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1264                 BT_ERR("Set vconf failed");
1265
1266         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1267                 BT_ERR("Set vconf failed\n");
1268
1269         /* TODO:Add timer function to handle any further post processing */
1270         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
1271
1272         /* Return BT_ADAPTER_DISABLE Method invocation context */
1273         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
1274
1275         /* Send BT Disabled event to application */
1276         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1277                         g_variant_new("(i)", result));
1278 }
1279
1280 static void __bt_adapter_state_set_status(bt_status_t status)
1281 {
1282         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1283         adapter_state = status;
1284 }
1285
1286 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
1287 {
1288         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
1289         adapter_discovery_state = status;
1290 }
1291
1292 static void __bt_adapter_state_change_callback(int bt_status)
1293 {
1294         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
1295
1296         switch (bt_status) {
1297         case BT_DEACTIVATED:
1298                 __bt_adapter_state_set_status(bt_status);
1299
1300                 /* Adapter is disabled, unregister event handlers */
1301                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
1302                 //_bt_deinit_device_event_handler();
1303
1304                 /* Add Adapter disabled post processing codes */
1305                 __bt_adapter_update_bt_disabled();
1306                 break;
1307         case BT_ACTIVATED:
1308                 __bt_adapter_state_set_status(bt_status);
1309                 /* Add Adapter enabled post processing codes */
1310                 if (timer_id > 0) {
1311                         BT_DBG("g_source is removed");
1312                         g_source_remove(timer_id);
1313                         timer_id = 0;
1314                 }
1315                 __bt_adapter_update_bt_enabled();
1316                 break;
1317         default:
1318                 BT_ERR("Incorrect Bluetooth adapter state changed status");
1319
1320         }
1321 }
1322
1323 int _bt_set_adapter_request_state(int enable)
1324 {
1325         return oal_set_adapter_request_state(enable);
1326 }
1327
1328 int _bt_set_le_request_state(int enable)
1329 {
1330         return oal_set_le_request_state(enable);
1331 }
1332
1333 static int __bt_adapter_state_handle_request(gboolean enable)
1334 {
1335         int result = BLUETOOTH_ERROR_NONE;
1336         BT_DBG("");
1337
1338         switch (adapter_state) {
1339         case BT_ACTIVATING: {
1340                 BT_INFO("Adapter is currently in activating state, state [%d]",
1341                                 adapter_state);
1342                 if (enable) {
1343                         return BLUETOOTH_ERROR_IN_PROGRESS;
1344                 } else {
1345                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
1346                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
1347                                 /*TODO Stop Discovery*/
1348                                 __bt_adapter_update_discovery_status(FALSE);
1349                         }
1350                         result = adapter_disable();
1351                         if (result != OAL_STATUS_SUCCESS) {
1352                                 BT_ERR("adapter_enable failed: [%d]", result);
1353                                 result = BLUETOOTH_ERROR_INTERNAL;
1354                                 /*TODO: perform if anything more needs to be done to handle failure */
1355                         } else {
1356                                 /* TODO: To be handled */
1357                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1358                                 result = BLUETOOTH_ERROR_NONE;
1359                         }
1360                 }
1361                 break;
1362         }
1363         case BT_ACTIVATED: {
1364                 BT_INFO("Adapter is currently in activated state, state [%d]",
1365                                 adapter_state);
1366                 if (enable) {
1367                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1368                 } else {
1369                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
1370                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
1371                                 /*TODO Stop Discovery*/
1372                                 __bt_adapter_update_discovery_status(FALSE);
1373                         }
1374                         result = adapter_disable();
1375                         if (result != OAL_STATUS_SUCCESS) {
1376                                 BT_ERR("adapter_enable failed: [%d]", result);
1377                                 result = BLUETOOTH_ERROR_INTERNAL;
1378                                 /*TODO: perform if anything more needs to be done to handle failure */
1379                         } else {
1380                                 /* TODO: To be handled */
1381                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1382                                 result = BLUETOOTH_ERROR_NONE;
1383                         }
1384                 }
1385                 break;
1386         }
1387         case BT_DEACTIVATING: {
1388                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
1389                                 adapter_state);
1390                 if (!enable) {
1391                         return BLUETOOTH_ERROR_IN_PROGRESS;
1392
1393                 } else {
1394                         result = adapter_enable();
1395                         if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
1396                                 BT_ERR("adapter_enable failed: [%d]", result);
1397                                 adapter_disable();
1398                                 result = BLUETOOTH_ERROR_INTERNAL;
1399                                 /*TODO: perform if anything more needs to be done to handle failure */
1400                         } else {
1401                                 /* TODO: To be handled */
1402                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1403                                 result = BLUETOOTH_ERROR_NONE;
1404                         }
1405                 }
1406                 break;
1407         }
1408         case BT_DEACTIVATED: {
1409                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
1410                                 adapter_state);
1411                 if (!enable) {
1412                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1413                 } else {
1414                         result = adapter_enable();
1415                         if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
1416                                 BT_ERR("adapter_enable failed: [%d]", result);
1417                                 adapter_disable();
1418                                 result = BLUETOOTH_ERROR_INTERNAL;
1419                                 /*TODO: perform if anything more needs to be done to handle failure */
1420                         } else {
1421                                 /* TODO: To be handled */
1422                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1423                                 result = BLUETOOTH_ERROR_NONE;
1424                         }
1425                 }
1426                 break;
1427         }
1428         default:
1429                 BT_ERR("Unknown state: %d", adapter_state);
1430                 break;
1431         }
1432
1433         if (enable && result == BLUETOOTH_ERROR_NONE) {
1434                 /* Adapter enable request is successful, setup event handlers */
1435                 _bt_service_register_event_handler_callback(
1436                                 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
1437                 _bt_device_state_handle_callback_set_request();
1438         }
1439         return result;
1440 }
1441
1442 static int __bt_adapter_state_discovery_request(gboolean enable,
1443                 unsigned short max_response, unsigned short duration,
1444                 unsigned int mask, gboolean is_custom,
1445                 bt_discovery_role_type_t role)
1446 {
1447         int result = BLUETOOTH_ERROR_NONE;
1448
1449         BT_DBG("+");
1450         switch (adapter_discovery_state) {
1451         case ADAPTER_DISCOVERY_STARTED: {
1452                 BT_INFO("Adapter is currently in discovery started state, state [%d]",
1453                                 adapter_discovery_state);
1454                 if (enable) {
1455                         return BLUETOOTH_ERROR_IN_PROGRESS;
1456                 } else {
1457                         result = adapter_stop_inquiry();
1458                         if (result != OAL_STATUS_SUCCESS) {
1459                                 BT_ERR("Discover stop failed: %d", result);
1460                                 result = BLUETOOTH_ERROR_INTERNAL;
1461                         } else {
1462                                 BT_ERR("Stop Discovery Triggered successfully");
1463                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1464                                 result = BLUETOOTH_ERROR_NONE;
1465                         }
1466                 }
1467                 break;
1468         }
1469         case ADAPTER_DISCOVERY_STARTING: {
1470                 BT_INFO("Adapter is currently in discovery starting state, state [%d]",
1471                                 adapter_discovery_state);
1472                 if (enable) {
1473                         return BLUETOOTH_ERROR_IN_PROGRESS;
1474                 } else {
1475                         result = adapter_stop_inquiry();
1476                         if (result != OAL_STATUS_SUCCESS) {
1477                                 BT_ERR("Discover stop failed: %d", result);
1478                                 result = BLUETOOTH_ERROR_INTERNAL;
1479                         } else {
1480                                 BT_ERR("Stop Discovery Triggered successfully");
1481                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1482                                 result = BLUETOOTH_ERROR_NONE;
1483                         }
1484                 }
1485                 break;
1486         }
1487         case ADAPTER_DISCOVERY_STOPPED: {
1488                 BT_INFO("Adapter is currently in discovery stopped state, state [%d]",
1489                                 adapter_discovery_state);
1490                 if (!enable)
1491                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1492                 else {
1493                         BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
1494
1495                         if (!is_custom)
1496                                 result = adapter_start_inquiry(duration);
1497                         else
1498                                 result = adapter_start_custom_inquiry(role);
1499
1500                         if (result != OAL_STATUS_SUCCESS) {
1501                                 BT_ERR("Start Discovery failed: %d", result);
1502                                 result = BLUETOOTH_ERROR_INTERNAL;
1503                         } else {
1504                                 BT_ERR("Start Discovery Triggered successfully");
1505                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1506                                 result = BLUETOOTH_ERROR_NONE;
1507                         }
1508                 }
1509                 break;
1510         }
1511         case ADAPTER_DISCOVERY_STOPPING: {
1512                 BT_INFO("Adapter is currently in discovery stopping state, state [%d]",
1513                                 adapter_discovery_state);
1514                 if (!enable)
1515                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1516                 else {
1517                         BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
1518                         if (!is_custom)
1519                                 result = adapter_start_inquiry(duration);
1520                         else
1521                                 result = adapter_start_custom_inquiry(role);
1522                         if (result != OAL_STATUS_SUCCESS) {
1523                                 BT_ERR("Start Discovery failed: %d", result);
1524                                 result = BLUETOOTH_ERROR_INTERNAL;
1525                         } else {
1526                                 BT_ERR("Start Discovery Triggered successfully");
1527                         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1528                                 result = BLUETOOTH_ERROR_NONE;
1529                         }
1530                 }
1531                 break;
1532         }
1533         default:
1534                 BT_ERR("Unknown state: %d", adapter_discovery_state);
1535                 break;
1536         }
1537
1538         BT_DBG("-");
1539         return result;
1540 }
1541
1542 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status)
1543 {
1544         BT_INFO("__bt_adapter_discovery_state_change_callback: status [%d]", bt_discovery_status);
1545         GVariant *param = NULL;
1546         int result = BLUETOOTH_ERROR_NONE;
1547
1548         switch (bt_discovery_status) {
1549         case ADAPTER_DISCOVERY_STOPPED:
1550         {
1551                 __bt_adapter_update_discovery_status(bt_discovery_status);
1552                 param = g_variant_new("(i)", result);
1553                 _bt_send_event(BT_ADAPTER_EVENT,
1554                                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
1555                                 param);
1556                 break;
1557         }
1558         case ADAPTER_DISCOVERY_STARTED:
1559         {
1560                 __bt_adapter_update_discovery_status(bt_discovery_status);
1561                 param = g_variant_new("(i)", result);
1562                 _bt_send_event(BT_ADAPTER_EVENT,
1563                                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
1564                                 param);
1565                 break;
1566         }
1567         default:
1568                 BT_ERR("Incorrect Bluetooth adapter Discovery state changed status");
1569         }
1570 }
1571
1572 static void __bt_set_visible_mode(void)
1573 {
1574         int timeout = 0;
1575 #ifdef TIZEN_FEATURE_BT_DPM
1576         int discoverable_state = DPM_BT_ERROR;
1577 #endif
1578
1579         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
1580                 BT_ERR("Fail to get the timeout value");
1581
1582 #ifdef TIZEN_FEATURE_BT_DPM
1583         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1584         if (timeout == -1 || discoverable_state == DPM_RESTRICTED) {
1585                 if (_bt_set_discoverable_mode(
1586                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
1587                                         timeout) != BLUETOOTH_ERROR_NONE) {
1588                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
1589                                 BT_ERR("Set vconf failed");
1590                 }
1591         } else {
1592                 if (_bt_set_discoverable_mode(
1593                                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
1594                                         timeout) != BLUETOOTH_ERROR_NONE) {
1595                         BT_ERR("Set connectable mode failed");
1596                 }
1597         }
1598 #else
1599         if (timeout == -1) {
1600                 if (_bt_set_discoverable_mode(
1601                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
1602                                         timeout) != BLUETOOTH_ERROR_NONE) {
1603                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
1604                                 BT_ERR("Set vconf failed");
1605                 }
1606         } else {
1607                 if (_bt_set_discoverable_mode(
1608                                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
1609                                         timeout) != BLUETOOTH_ERROR_NONE) {
1610                         BT_ERR("Set connectable mode failed");
1611                 }
1612         }
1613 #endif
1614 }
1615
1616 static void __bt_set_local_name(void)
1617 {
1618         char *phone_name = NULL;
1619         char *ptr = NULL;
1620
1621         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1622
1623         if (!phone_name)
1624                 return;
1625
1626         if (strlen(phone_name) != 0) {
1627                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
1628                         *ptr = '\0';
1629
1630                 _bt_set_local_name(phone_name);
1631         }
1632         free(phone_name);
1633 }
1634
1635 void _bt_adapter_set_status(bt_status_t status)
1636 {
1637         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1638         adapter_state = status;
1639 }
1640
1641 bt_status_t _bt_adapter_get_status(void)
1642 {
1643         return adapter_state;
1644 }
1645
1646 void _bt_set_disabled(int result)
1647 {
1648         int power_off_status = 0;
1649         int ret;
1650         int ret_pm_ignore;
1651         int pm_ignore_mode = 0;
1652
1653         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1654         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1655
1656         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
1657
1658         /* Update the vconf BT status in normal Deactivation case only */
1659         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
1660                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
1661
1662                 BT_DBG("Update vconf for BT normal Deactivation");
1663
1664                 if (result == BLUETOOTH_ERROR_TIMEOUT)
1665                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
1666                                 BT_ERR("Set vconf failed");
1667
1668                 /* Update Bluetooth Status to notify other modules */
1669                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1670                         BT_ERR("Set vconf failed");
1671
1672                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
1673                                                         EVT_VAL_BT_OFF) != ES_R_OK)
1674                         BT_ERR("Fail to set value");
1675         }
1676
1677         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1678                 BT_ERR("Set vconf failed\n");
1679
1680         _bt_adapter_set_status(BT_DEACTIVATED);
1681         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPED);
1682
1683         BT_INFO("Adapter disabled");
1684 }
1685