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