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