Change visibility settings for DA devices
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / 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-mesh-main.h"
39 #include "bt-service-core-adapter.h"
40 #include "bt-service-core-device.h"
41 #include "bt-service-event-receiver.h"
42 #include "bt-request-handler.h"
43 #include "bt-service-event.h"
44 #include "bt-service-audio-common.h"
45 #include "bt-service-core-adapter-le.h"
46 #include "bt-service-gatt.h"
47 #include "bt-service-dpm.h"
48 #include "bt-service-hidhost.h"
49 #include "bt-service-hiddevice.h"
50 #include "bt-service-socket.h"
51 #include "bt-service-hdp.h"
52 #include "bt-service-tds.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 typedef enum {
78         BT_ADAPTER_FLIGHT_MODE_NONE = -1,
79         BT_ADAPTER_FLIGHT_MODE_OFF,
80         BT_ADAPTER_FLIGHT_MODE_ON,
81 } bt_adapter_flightmode_req_e;
82
83 static bt_adapter_flightmode_req_e flightmode_request = BT_ADAPTER_FLIGHT_MODE_NONE;
84
85 static guint timer_id = 0;
86
87 static gboolean a2dp_init_pending = TRUE;
88
89 /* Adapter default states */
90 static bt_status_t adapter_state = BT_DEACTIVATED;
91 static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
92
93 /* Below masking value will be delivered from bluez */
94 typedef enum {
95         BT_ADAPTER_A2DP_ROLE_SOURCE = 0x01,
96         BT_ADAPTER_A2DP_ROLE_SINK = 0x02,
97 } bt_adapter_a2dp_role_e;
98
99 /* Forward declarations */
100 static void __bt_adapter_event_handler(int event_type, gpointer event_data);
101 static void __bt_post_oal_init(void);
102 static void __bt_handle_oal_initialisation(oal_event_t event);
103 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size);
104 static gboolean __bt_adapter_post_set_enabled(gpointer user_data);
105 static gboolean __bt_adapter_post_set_disabled(gpointer user_data);
106 static void __bt_adapter_update_bt_enabled(void);
107 static void __bt_adapter_update_bt_disabled(void);
108 static void __bt_adapter_state_set_status(bt_status_t status);
109 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
110 static void __bt_adapter_state_change_callback(int bt_status);
111 static int __bt_adapter_state_handle_request(gboolean enable);
112 static int __bt_adapter_state_discovery_request(gboolean enable,
113                 unsigned short max_response, unsigned short duration, unsigned int mask,
114                 gboolean is_custom, bt_discovery_role_type_t role);
115 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status);
116 static gboolean __bt_is_service_request_present(int service_function);
117
118 static void __bt_set_visible_mode(void);
119 static void __bt_set_local_name(void);
120
121 static gboolean __bt_disconnect_all(void);
122
123 /* Initialize BT stack (Initialize OAL layer) */
124 int _bt_stack_init(void)
125 {
126         int ret;
127
128         BT_INFO("[bt-service] Start to initialize BT stack");
129         /* Adapter enable request is successful, setup event handlers */
130         _bt_service_register_event_handler_callback(
131                         BT_ADAPTER_MODULE, __bt_adapter_event_handler);
132
133         ret = _bt_le_init();
134         if (ret != BLUETOOTH_ERROR_NONE) {
135                 BT_ERR("_bt_le_init Failed");
136                 return ret;
137         }
138
139         ret = oal_bt_init(_bt_service_oal_event_receiver);
140
141         if (OAL_STATUS_PENDING == ret) {
142                 BT_INFO("OAL Initialisation Pending, Profiles Init will be done once oal initialised...");
143                 return BLUETOOTH_ERROR_NONE;
144         } else if (OAL_STATUS_SUCCESS != ret) {
145                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
146                 return _bt_convert_oal_status_to_bt_error(ret);
147         }
148
149         return BLUETOOTH_ERROR_NONE;
150 }
151
152 int _bt_enable_adapter(void)
153 {
154         bt_le_status_t le_status = BT_LE_DEACTIVATED;
155
156         le_status = _bt_adapter_get_le_status();
157
158         BT_INFO("Current state [%d], LE [%d]", adapter_state, le_status);
159
160         if (adapter_state == BT_ACTIVATING || le_status == BT_LE_ACTIVATING) {
161                 BT_ERR("Enabling in progress");
162                 return BLUETOOTH_ERROR_IN_PROGRESS;
163         }
164
165         if (adapter_state == BT_ACTIVATED) {
166                 BT_ERR("Already enabled");
167                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
168         }
169
170         if (adapter_state == BT_DEACTIVATING ||
171                  adapter_state == BT_TERMINATING ||
172                   le_status == BT_LE_DEACTIVATING) {
173                 BT_ERR("Disabling in progress");
174                 return BLUETOOTH_ERROR_DEVICE_BUSY;
175         }
176
177         return __bt_adapter_state_handle_request(TRUE);
178 }
179
180 int _bt_recover_adapter(void)
181 {
182         int result = BLUETOOTH_ERROR_NONE;
183
184         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
185                 BT_ERR("Disabling in progress");
186                 return BLUETOOTH_ERROR_IN_PROGRESS;
187         }
188
189         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
190                 BT_ERR("Already Disabled");
191                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
192         }
193
194         _bt_adapter_set_status(BT_DEACTIVATING);
195
196         result = adapter_recover();
197
198         if (result != OAL_STATUS_SUCCESS)
199                 return _bt_convert_oal_status_to_bt_error(result);
200
201         __bt_disconnect_all();
202
203         return result;
204 }
205
206 int _bt_reset_adapter(void)
207 {
208         int result;
209         BT_INFO("+");
210         result = adapter_reset();
211         if (result != OAL_STATUS_SUCCESS)
212                 return _bt_convert_oal_status_to_bt_error(result);
213
214         /* TODO_40 : 4.0 merge  */
215         /* TODO Currently bt-service is not terminated in tizen next.
216            It should be handled in future patch */
217         if (_bt_adapter_get_status() == BT_DEACTIVATED)
218                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
219
220         return BLUETOOTH_ERROR_NONE;
221 }
222
223 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
224 void _bt_start_log_dump(const char *path)
225 {
226         GDBusProxy *proxy;
227         GVariant *result;
228         GError *error = NULL;
229
230         ret_if(path == NULL);
231
232         BT_INFO("Start log_dump(path = %s)", path);
233
234         _bt_send_dump_signal(BT_DUMP_SERVICE_START_SIGNAL);
235
236         proxy = __bt_get_core_proxy();
237         ret_if(proxy == NULL);
238
239         result = g_dbus_proxy_call_sync(proxy, "LogDump",
240                                 g_variant_new("(s)", path),
241                                 G_DBUS_CALL_FLAGS_NONE,
242                                 -1, NULL, &error);
243
244         if (!result) {
245                 if (error != NULL) {
246                         BT_ERR("Bt core call failed(Error: %s)", error->message);
247                         g_clear_error(&error);
248                 } else {
249                         BT_ERR("Bt core call failed");
250                 }
251         } else {
252                 g_variant_unref(result);
253         }
254
255         _bt_send_dump_signal(BT_DUMP_SERVICE_FINISH_SIGNAL);
256 }
257 #endif
258
259 int _bt_check_adapter(int *status)
260 {
261         BT_INFO("+");
262         gboolean powered = FALSE;
263         int result;
264         BT_CHECK_PARAMETER(status, return);
265
266         *status = BT_ADAPTER_DISABLED;
267
268         result = adapter_get_powered_status(&powered);
269         if (result != OAL_STATUS_SUCCESS)
270                 return _bt_convert_oal_status_to_bt_error(result);
271         else if (powered) {
272                 BT_INFO("Adapter is in Powered Up state");
273                 *status = BT_ADAPTER_ENABLED;
274         } else
275                 BT_INFO("Adapter is in Powered Down state");
276
277         return BLUETOOTH_ERROR_NONE;
278 }
279
280 int _bt_disable_adapter(void)
281 {
282         bt_le_status_t le_status = BT_LE_DEACTIVATED;
283
284         le_status = _bt_adapter_get_le_status();
285
286         BT_INFO("Current state [%d], LE [%d]", adapter_state, le_status);
287
288         if (adapter_state == BT_DEACTIVATING ||
289                  adapter_state == BT_TERMINATING ||
290                   le_status == BT_LE_DEACTIVATING) {
291                 BT_DBG("Disabling in progress");
292                 return BLUETOOTH_ERROR_IN_PROGRESS;
293         }
294
295         if (adapter_state == BT_DEACTIVATED) {
296                 BT_DBG("Already disabled");
297                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
298         }
299
300         if (adapter_state == BT_ACTIVATING || le_status == BT_LE_ACTIVATING) {
301                 BT_ERR("Enabling in progress");
302                 return BLUETOOTH_ERROR_DEVICE_BUSY;
303         }
304
305         /* TODO: Need to add the function to disconnect all devices */
306         /* __bt_disconnect_all(); */
307
308         return __bt_adapter_state_handle_request(FALSE);
309 }
310
311 int _bt_start_discovery(unsigned short max_response,
312                 unsigned short duration, unsigned int cod_mask)
313 {
314         return __bt_adapter_state_discovery_request(TRUE, max_response, duration,
315                                 cod_mask, FALSE, 0x00);
316 }
317
318 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
319 {
320         return __bt_adapter_state_discovery_request(TRUE, 0, 0, 0, TRUE, role);
321 }
322
323 int _bt_cancel_discovery(void)
324 {
325         return __bt_adapter_state_discovery_request(FALSE, 0, 0, 0, FALSE, 0x00);
326 }
327
328 gboolean _bt_is_discovering(void)
329 {
330         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED
331                         || adapter_discovery_state == ADAPTER_DISCOVERY_STARTING)
332                 return TRUE;
333         else
334                 return FALSE;
335 }
336
337 static void __bt_set_flightmode_request(int value)
338 {
339         BT_INFO("Setting flightmode request to %d", value);
340         flightmode_request = value;
341 }
342
343 static int __bt_is_flightmode_request(void)
344 {
345         return flightmode_request;
346 }
347
348 static void __bt_service_handle_flight_mode(gboolean flight_mode, bt_status_t adapter_status)
349 {
350         int flight_mode_value = 0;
351         int ps_mode_value = 0;
352
353         if (flight_mode == TRUE) {
354                 BT_INFO_C("### Flight mode on. Turn off BT");
355
356                 if (adapter_status != BT_ACTIVATED) {
357                         BT_INFO("No need to control bt status");
358                         if (vconf_get_int(BT_OFF_DUE_TO_POWER_SAVING_MODE, &ps_mode_value))
359                                 BT_ERR("Fail get PS mode value");
360
361                         BT_DBG("ps_mode_value %d", ps_mode_value);
362                         if (ps_mode_value > 0) {
363                                 if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 1) != 0)
364                                         BT_ERR("Set vconf failed");
365                         }
366                         return;
367                 }
368
369                 __bt_set_flightmode_request(BT_ADAPTER_FLIGHT_MODE_ON);
370
371                 if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 1) != 0)
372                         BT_ERR("Set vconf failed");
373
374                 if (adapter_status == BT_ACTIVATED)
375                         _bt_disable_adapter();
376
377         } else {
378                 BT_INFO_C("### Flight mode off. Turn on BT");
379
380                 if (adapter_status == BT_ACTIVATED)
381                         return;
382
383                 if (vconf_get_int(BT_OFF_DUE_TO_FLIGHT_MODE, &flight_mode_value))
384                         BT_ERR("Fail get flight mode value");
385
386                 BT_DBG("flight_mode_value %d", flight_mode_value);
387                 if (flight_mode_value == 0)
388                         return;
389
390                 if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
391                         BT_ERR("Set vconf failed");
392
393                 if (vconf_get_int(BT_OFF_DUE_TO_POWER_SAVING_MODE, &ps_mode_value))
394                         BT_ERR("Fail get PS mode value");
395
396                 BT_DBG("ps_mode_value %d", ps_mode_value);
397                 if (ps_mode_value > 0) {
398                         BT_DBG("Bt should not turn on");
399                         return;
400                 }
401
402                 if (adapter_status == BT_DEACTIVATING) {
403                         BT_INFO("BT adapter is deactivating. Turn on BT after deactivation");
404                         __bt_set_flightmode_request(BT_ADAPTER_FLIGHT_MODE_OFF);
405                         return;
406                 }
407
408                 if (adapter_status != BT_DEACTIVATED) {
409                         BT_INFO("No need to control bt status");
410                         return;
411                 }
412                 _bt_service_initialize();
413
414                 if (adapter_status == BT_DEACTIVATED)
415                         _bt_enable_adapter();
416
417         }
418 }
419
420 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
421 {
422         int type;
423         bt_status_t adapter_status = BT_DEACTIVATED;
424         gboolean flight_mode = FALSE;
425
426         adapter_status = _bt_adapter_get_status();
427         BT_INFO("Flight mode changed. Current bt status is %d", adapter_status);
428
429         DBG_SECURE("key=%s", vconf_keynode_get_name(node));
430         type = vconf_keynode_get_type(node);
431
432         if (type == VCONF_TYPE_BOOL) {
433                 flight_mode = vconf_keynode_get_bool(node);
434                 __bt_service_handle_flight_mode(flight_mode, adapter_status);
435         } else {
436                 BT_ERR("Invaild vconf key type : %d", type);
437         }
438 }
439
440 void _bt_service_register_vconf_handler(void)
441 {
442         BT_DBG("+");
443
444         if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
445                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
446                         BT_ERR("Unable to register key handler");
447         if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
448                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
449                         BT_ERR("Unable to register key handler");
450 }
451
452 void _bt_service_unregister_vconf_handler(void)
453 {
454         BT_DBG("+");
455
456         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
457                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
458
459         vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
460                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
461 }
462
463 static gboolean __bt_enable_timeout_cb(gpointer user_data)
464 {
465         int ret;
466         timer_id = 0;
467
468         ret = adapter_disable();
469         if (TIZEN_FEATURE_FHUB_REFERENCE)
470                 if (ret != OAL_STATUS_SUCCESS)
471                         _bt_adapter_set_status(BT_DEACTIVATED);
472
473         _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
474 #ifndef USB_BLUETOOTH
475         _bt_terminate_service(NULL);
476 #endif
477         return FALSE;
478 }
479
480 void _bt_adapter_start_enable_timer(void)
481 {
482         if (timer_id > 0) {
483                 g_source_remove(timer_id);
484                 timer_id = 0;
485         }
486
487         timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
488                         __bt_enable_timeout_cb, NULL);
489
490         return;
491 }
492
493 int _bt_get_local_address(void)
494 {
495         int result;
496
497         BT_DBG("+");
498
499         result = adapter_get_address();
500         if (result != OAL_STATUS_SUCCESS) {
501                 BT_ERR("adapter_get_address failed: %d", result);
502                 result = _bt_convert_oal_status_to_bt_error(result);
503         } else
504                 result = BLUETOOTH_ERROR_NONE;
505
506         BT_DBG("-");
507         return result;
508 }
509
510 int _bt_get_local_version(void)
511 {
512         int result;
513         BT_DBG("+");
514
515         result = adapter_get_version();
516         if (result != OAL_STATUS_SUCCESS) {
517                 BT_ERR("adapter_get_version failed: %d", result);
518                 result = _bt_convert_oal_status_to_bt_error(result);
519         } else
520                 result = BLUETOOTH_ERROR_NONE;
521
522         BT_DBG("-");
523         return result;
524 }
525
526 int _bt_get_local_name(void)
527 {
528         int result;
529
530         BT_DBG("+");
531
532         result = adapter_get_name();
533         if (result != OAL_STATUS_SUCCESS) {
534                 BT_ERR("adapter_get_name failed: %d", result);
535                 result = _bt_convert_oal_status_to_bt_error(result);
536         } else
537                 result = BLUETOOTH_ERROR_NONE;
538
539         BT_DBG("-");
540         return result;
541 }
542
543 int _bt_set_local_name(char *local_name)
544 {
545         int result = BLUETOOTH_ERROR_NONE;
546         BT_DBG("+");
547
548         retv_if(NULL == local_name, BLUETOOTH_ERROR_INVALID_PARAM);
549
550         result = adapter_set_name(local_name);
551         if (result != OAL_STATUS_SUCCESS) {
552                 BT_ERR("adapter_set_name failed: %d", result);
553                 result = _bt_convert_oal_status_to_bt_error(result);
554         } else
555                 result = BLUETOOTH_ERROR_NONE;
556
557         BT_DBG("-");
558         return result;
559 }
560
561 int _bt_get_discoverable_mode(int *mode)
562 {
563         int scan_mode = 0;
564         int timeout = 0;
565
566         BT_DBG("+");
567
568         retv_if(NULL == mode, BLUETOOTH_ERROR_INVALID_PARAM);
569
570         adapter_is_discoverable(&scan_mode);
571         if (TRUE == scan_mode) {
572                 adapter_get_discoverable_timeout(&timeout);
573                 if (timeout > 0)
574                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
575                 else
576                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
577         } else {
578                 adapter_is_connectable(&scan_mode);
579                 if (scan_mode == TRUE)
580                         *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
581                 else {
582                         /*
583                          * TODO: NON CONNECTABLE is not defined in bluetooth_discoverable_mode_t.
584                          * After adding BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE, set mode as
585                          * BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE. Until then set -1.
586                          */
587                         *mode = -1;
588                 }
589         }
590
591         BT_DBG("-");
592         return BLUETOOTH_ERROR_NONE;
593 }
594
595 int _bt_get_timeout_value(int *timeout)
596 {
597         time_t current_time;
598         int time_diff;
599
600         /* Take current time */
601         time(&current_time);
602         time_diff = difftime(current_time, visible_timer.start_time);
603
604         BT_DBG("Time diff = %d\n", time_diff);
605         *timeout = visible_timer.timeout - time_diff;
606
607         return BLUETOOTH_ERROR_NONE;
608 }
609
610 int _bt_get_energy_info(unsigned int *tx_time, unsigned int *rx_time,
611                                         unsigned int *idle_time, unsigned int *energy_used)
612 {
613         int result;
614         BT_INFO("+");
615
616         BT_CHECK_PARAMETER(tx_time, return);
617         BT_CHECK_PARAMETER(rx_time, return);
618         BT_CHECK_PARAMETER(idle_time, return);
619         BT_CHECK_PARAMETER(energy_used, return);
620
621         *tx_time = 0;
622         *rx_time = 0;
623         *idle_time = 0;
624         *energy_used = 0;
625
626         result = adapter_get_energy_info(tx_time, rx_time, idle_time, energy_used);
627         if (result != OAL_STATUS_SUCCESS)
628                 return _bt_convert_oal_status_to_bt_error(result);
629
630         return BLUETOOTH_ERROR_NONE;
631 }
632
633
634 static void __bt_visibility_alarm_remove()
635 {
636         if (visible_timer.event_id > 0) {
637                 g_source_remove(visible_timer.event_id);
638                 visible_timer.event_id = 0;
639         }
640
641         if (visible_timer.alarm_id > 0) {
642                 alarmmgr_remove_alarm(visible_timer.alarm_id);
643                 visible_timer.alarm_id = 0;
644         }
645 }
646
647 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
648 {
649         int result = BLUETOOTH_ERROR_NONE;
650         int timeout = 0;
651
652         BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
653
654         if (alarm_id != visible_timer.alarm_id)
655                 return 0;
656
657         if (visible_timer.event_id) {
658                 _bt_send_event(BT_ADAPTER_EVENT,
659                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
660                                 g_variant_new("(in)", result, timeout));
661                 g_source_remove(visible_timer.event_id);
662                 visible_timer.event_id = 0;
663                 visible_timer.timeout = 0;
664
665                 if (!TIZEN_PROFILE_WEARABLE) {
666                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
667                                 BT_ERR("Set vconf failed\n");
668                 }
669         }
670         /* Switch Off visibility in Bluez */
671         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
672         visible_timer.alarm_id = 0;
673         return 0;
674 }
675
676 static gboolean __bt_timeout_handler(gpointer user_data)
677 {
678         int result = BLUETOOTH_ERROR_NONE;
679         time_t current_time;
680         int time_diff;
681
682         /* Take current time */
683         time(&current_time);
684         time_diff = difftime(current_time, visible_timer.start_time);
685
686         /* Send event to application */
687         _bt_send_event(BT_ADAPTER_EVENT,
688                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
689                         g_variant_new("(in)", result, time_diff));
690
691         if (visible_timer.timeout <= time_diff) {
692                 g_source_remove(visible_timer.event_id);
693                 visible_timer.event_id = 0;
694                 visible_timer.timeout = 0;
695
696                 if (!TIZEN_PROFILE_WEARABLE) {
697                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
698                                 BT_ERR("Set vconf failed\n");
699                 }
700
701                 return FALSE;
702         }
703
704         return TRUE;
705 }
706
707 static void __bt_visibility_alarm_create()
708 {
709         alarm_id_t alarm_id;
710         int result;
711
712         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
713                         0, NULL, &alarm_id);
714         if (result < 0) {
715                 BT_ERR("Failed to create alarm error = %d\n", result);
716         } else {
717                 BT_DBG("Alarm created = %d\n", alarm_id);
718                 visible_timer.alarm_id = alarm_id;
719         }
720 }
721
722 int _bt_start_visibility_timer(int timeout)
723 {
724         int result;
725         int discoverable_state = DPM_BT_ERROR;
726
727         __bt_visibility_alarm_remove();
728
729         visible_timer.timeout = timeout;
730
731         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
732         if (discoverable_state != DPM_RESTRICTED) {
733                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
734                         BT_ERR("Set vconf failed");
735         }
736
737         if (timeout <= 0)
738                 return BLUETOOTH_ERROR_NONE;
739
740         if (!visible_timer.alarm_init) {
741                 /* Set Alarm timer to switch off BT */
742                 result = alarmmgr_init("bt-service");
743                 if (result != 0)
744                         return BLUETOOTH_ERROR_INTERNAL;
745
746                 visible_timer.alarm_init = TRUE;
747         }
748
749         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
750         if (result != 0)
751                 return BLUETOOTH_ERROR_INTERNAL;
752
753         if (!TIZEN_PROFILE_WEARABLE) {
754                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
755                         BT_ERR("Set vconf failed");
756         }
757
758         /* Take start time */
759         time(&(visible_timer.start_time));
760         visible_timer.event_id = g_timeout_add_seconds(1,
761                         __bt_timeout_handler, NULL);
762
763         visible_timer.timeout = timeout;
764
765         __bt_visibility_alarm_create();
766
767         return BLUETOOTH_ERROR_NONE;
768 }
769
770 int _bt_stop_visibility_timer(void)
771 {
772         __bt_visibility_alarm_remove();
773
774         visible_timer.timeout = 0;
775
776         if (!TIZEN_PROFILE_WEARABLE) {
777                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
778                         BT_ERR("Set vconf failed");
779         }
780
781         return BLUETOOTH_ERROR_NONE;
782 }
783
784 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
785 {
786         int result;
787         int ret = BLUETOOTH_ERROR_NONE;;
788         int discoverable_state = DPM_BT_ERROR;
789
790         BT_DBG("+");
791
792         BT_INFO("discoverable_mode: %d, timeout: %d", discoverable_mode, timeout);
793
794         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
795         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
796                  discoverable_state == DPM_RESTRICTED) {
797                 if (headed_plugin_info->plugin_headed_enabled)
798                         headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
799                 return BLUETOOTH_ERROR_ACCESS_DENIED;
800         }
801         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE &&
802                 discoverable_state == DPM_RESTRICTED) {
803                 if (headed_plugin_info->plugin_headed_enabled)
804                         headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
805                 return BLUETOOTH_ERROR_ACCESS_DENIED;
806         }
807
808         switch (discoverable_mode) {
809         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
810                 result = adapter_set_connectable(TRUE);
811                 timeout = 0;
812                 break;
813         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
814                 result = adapter_set_discoverable();
815                 timeout = 0;
816                 break;
817         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
818                 result = adapter_set_discoverable();
819                 break;
820         default:
821                 return BLUETOOTH_ERROR_INVALID_PARAM;
822         }
823
824         if (result != OAL_STATUS_SUCCESS) {
825                 BT_ERR("set scan mode failed %d", result);
826                 return _bt_convert_oal_status_to_bt_error(result);
827         }
828
829         result = adapter_set_discoverable_timeout(timeout);
830         if (result != OAL_STATUS_SUCCESS) {
831                 BT_ERR("adapter_set_discoverable_timeout failed %d", result);
832                 return _bt_convert_oal_status_to_bt_error(result);
833         }
834
835         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE) {
836                 ret = _bt_stop_visibility_timer();
837                 if (BLUETOOTH_ERROR_NONE != ret)
838                         BT_ERR("_bt_stop_visibility_timer failed");
839                 if (!TIZEN_PROFILE_WEARABLE) {
840                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, -1) != 0)
841                                  BT_ERR("Set vconf failed");
842                 }
843         } else if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE) {
844                 ret = _bt_start_visibility_timer(timeout);
845                 if (BLUETOOTH_ERROR_NONE != ret)
846                         BT_ERR("_bt_start_visibility_timer failed");
847
848         } else {
849                 ret = _bt_stop_visibility_timer();
850                 if (BLUETOOTH_ERROR_NONE != ret)
851                         BT_ERR("_bt_stop_visibility_timer failed");
852         }
853
854         BT_DBG("-");
855         return result;
856 }
857
858 gboolean _bt_is_connectable(void)
859 {
860         int connectable = 0;
861         int result;
862
863         BT_DBG("+");
864
865         adapter_is_connectable(&connectable);
866         if (connectable)
867                 result = TRUE;
868         else
869                 result = FALSE;
870
871         BT_DBG("Connectable: [%s]", result ? "TRUE" : "FALSE");
872         BT_DBG("-");
873         return result;
874 }
875
876 int _bt_set_connectable(gboolean connectable)
877 {
878         int result = BLUETOOTH_ERROR_NONE;
879
880         BT_DBG("+");
881         result = adapter_set_connectable(connectable);
882         if (result != OAL_STATUS_SUCCESS) {
883                 BT_ERR("adapter_set_connectable failed: %d", result);
884                 result = _bt_convert_oal_status_to_bt_error(result);
885         } else
886                 result = BLUETOOTH_ERROR_NONE;
887
888         BT_DBG("-");
889         return result;
890 }
891
892 int _bt_get_connectable(void)
893 {
894         int result;
895
896         BT_DBG("+");
897
898         result = adapter_get_connectable();
899         if (result != OAL_STATUS_SUCCESS) {
900                 BT_ERR("adapter_get_connectable failed: %d", result);
901                 result = _bt_convert_oal_status_to_bt_error(result);
902         } else
903                 result = BLUETOOTH_ERROR_NONE;
904
905         BT_DBG("-");
906         return result;
907 }
908
909 int _bt_is_service_used(void)
910 {
911         int result;
912
913         BT_DBG("+");
914
915         result = adapter_get_service_uuids();
916         if (result != OAL_STATUS_SUCCESS) {
917                 BT_ERR("adapter_get_service_uuids failed: %d", result);
918                 result = _bt_convert_oal_status_to_bt_error(result);
919         } else {
920                 result = BLUETOOTH_ERROR_NONE;
921         }
922
923         BT_DBG("-");
924         return result;
925 }
926
927 int _bt_adapter_get_bonded_devices(void)
928 {
929         int result = BLUETOOTH_ERROR_NONE;
930
931         BT_DBG("+");
932         result = adapter_get_bonded_devices();
933         if (result != OAL_STATUS_SUCCESS) {
934                 BT_ERR("adapter_get_bonded_devices failed: %d", result);
935                 result = _bt_convert_oal_status_to_bt_error(result);
936         } else
937                 result = BLUETOOTH_ERROR_NONE;
938
939         BT_DBG("-");
940         return result;
941 }
942
943 int _bt_get_profile_connected_devices(const char *profile_uuid)
944 {
945         int result = BLUETOOTH_ERROR_NONE;
946
947         BT_DBG("+");
948         result = adapter_get_profile_connected_devices(profile_uuid);
949         if (result != OAL_STATUS_SUCCESS) {
950                 BT_ERR("adapter_get_profile_connected_devices failed: %d", result);
951                 result = _bt_convert_oal_status_to_bt_error(result);
952         } else
953                 result = BLUETOOTH_ERROR_NONE;
954
955         BT_DBG("-");
956         return result;
957 }
958
959 static gboolean __bt_disconnect_all(void)
960 {
961         int i;
962         gboolean ret = FALSE;
963         GArray *device_list;
964         guint size;
965         int result;
966         bluetooth_device_info_t *info;
967
968         BT_DBG("");
969         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
970
971         BT_DBG("The length of device list after the initialisation is [%d]", device_list->len);
972
973         _bt_service_get_bonded_dev_list(&device_list);
974
975         size = (device_list->len) / sizeof(bluetooth_device_info_t);
976
977         for (i = 0; i < size; i++) {
978                 info = &g_array_index(device_list,
979                                 bluetooth_device_info_t, i);
980                 if (info->connected != BLUETOOTH_CONNECTED_LINK_NONE) {
981                         BT_DBG("Found Connected Device");
982                         result = _bt_disconnect_device(&info->device_address);
983                         if (result != BLUETOOTH_ERROR_NONE) {
984                                 BT_ERR("Cannot disconnect all the devices. bt_disconnect_device Failed");
985                                 g_array_free(device_list, TRUE);
986                                 return ret;
987                         }
988                 }
989         }
990         ret = TRUE;
991         g_array_free(device_list, TRUE);
992
993         return ret;
994 }
995
996 static void __bt_handle_pending_a2dp_init(unsigned int a2dp_role)
997 {
998         int ret;
999
1000         if (!a2dp_init_pending)
1001                 return;
1002
1003         BT_DBG("+");
1004         a2dp_init_pending = FALSE;
1005
1006         if (a2dp_role & BT_ADAPTER_A2DP_ROLE_SINK) {
1007                 BT_INFO("Enable A2DP Sink role");
1008                 /* Initialize A2DP Sink */
1009                 ret = _bt_audio_initialize(BT_A2DP_SINK_MODULE);
1010                 if (ret != BLUETOOTH_ERROR_NONE)
1011                         BT_ERR("_bt_audio_initialize(BT_A2DP_SINK_MODULE) Failed");
1012
1013                 /* Initialize AVRCP Controller */
1014                 ret = _bt_audio_initialize(BT_AVRCP_CTRL_MODULE);
1015                 if (ret != BLUETOOTH_ERROR_NONE)
1016                         BT_ERR("_bt_audio_initialize(BT_AVRCP_CTRL_MODULE) Failed");
1017
1018                 _bt_audio_set_current_role(BLUETOOTH_A2DP_SINK);
1019         }
1020
1021         if (a2dp_role & BT_ADAPTER_A2DP_ROLE_SOURCE) {
1022                 BT_INFO("Enable A2DP Source role");
1023                 /* Initialize A2DP Source */
1024                 ret = _bt_audio_initialize(BT_A2DP_SOURCE_MODULE);
1025                 if (ret != BLUETOOTH_ERROR_NONE)
1026                         BT_ERR("_bt_audio_initialize(BT_A2DP_SOURCE_MODULE) Failed");
1027
1028                 /* Initialize AVRCP Target */
1029                 ret = _bt_audio_initialize(BT_AVRCP_MODULE);
1030                 if (ret != BLUETOOTH_ERROR_NONE)
1031                         BT_ERR("_bt_audio_initialize(BT_AVRCP_MODULE) Failed");
1032
1033                 _bt_audio_set_current_role(BLUETOOTH_A2DP_SOURCE);
1034         }
1035
1036         BT_DBG("-");
1037 }
1038
1039 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
1040 {
1041         int result = BLUETOOTH_ERROR_NONE;
1042
1043         BT_DBG("+");
1044
1045         switch (event_type) {
1046         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
1047         case OAL_EVENT_OAL_INITIALISED_FAILED:
1048                 __bt_handle_oal_initialisation(event_type);
1049                 break;
1050         case OAL_EVENT_ADAPTER_ENABLED:
1051                 __bt_adapter_state_change_callback(BT_ACTIVATED);
1052                 break;
1053         case OAL_EVENT_ADAPTER_DISABLED:
1054                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
1055                 break;
1056         case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
1057                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STARTED);
1058                 break;
1059         case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
1060                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STOPPED);
1061                 break;
1062         case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
1063                 bt_address_t *bd_addr = event_data;
1064                 bluetooth_device_address_t local_address;
1065
1066                 /* Copy data */
1067                 memcpy(local_address.addr, bd_addr->addr, BT_ADDRESS_LENGTH_MAX);
1068                 BT_DBG("Adapter address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]",
1069                                 local_address.addr[0], local_address.addr[1], local_address.addr[2],
1070                                 local_address.addr[3], local_address.addr[4], local_address.addr[5]);
1071
1072                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
1073                                 (void *) &local_address, sizeof(bluetooth_device_address_t));
1074                 break;
1075         }
1076         case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
1077                 char *name = event_data;
1078                 BT_DBG("Adapter Name: %s", name);
1079
1080                 if (__bt_is_service_request_present(BT_GET_LOCAL_NAME)) {
1081                         bluetooth_device_name_t local_name;
1082
1083                         memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
1084                         g_strlcpy(local_name.name,
1085                                 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
1086                         __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
1087                                 (void *) &local_name, sizeof(bluetooth_device_name_t));
1088                 } else {
1089                         /* Send event to application */
1090                         _bt_send_event(BT_ADAPTER_EVENT,
1091                                         BLUETOOTH_EVENT_LOCAL_NAME_CHANGED,
1092                                         g_variant_new("(is)", result, name));
1093                 }
1094                 break;
1095         }
1096         case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
1097                 char *ver = event_data;
1098                 bluetooth_version_t local_version;
1099
1100                 memset(&local_version, 0x00, sizeof(bluetooth_version_t));
1101                 g_strlcpy(local_version.version,
1102                                 (const gchar *)ver, BLUETOOTH_VERSION_LENGTH_MAX);
1103                 BT_DBG("BT Version: %s", local_version.version);
1104
1105                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
1106                                 (void *) &local_version, sizeof(bluetooth_version_t));
1107                 break;
1108         }
1109         case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
1110                 int mode = -1;
1111                 gboolean connectable = FALSE;
1112
1113                 BT_INFO("Adapter discoverable mode:"
1114                                 " BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
1115
1116                 if (__bt_is_service_request_present(BT_GET_CONNECTABLE)) {
1117                         __bt_adapter_handle_pending_requests(BT_GET_CONNECTABLE,
1118                                 (void *) &connectable, sizeof(gboolean));
1119
1120                 } else {
1121                         _bt_send_event(BT_ADAPTER_EVENT,
1122                                         BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
1123                                         g_variant_new("(b)", connectable));
1124
1125                         _bt_send_event(BT_ADAPTER_EVENT,
1126                                         BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
1127                                         g_variant_new("(in)", result, mode));
1128                 }
1129                 break;
1130         }
1131         case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
1132                 int mode;
1133                 gboolean connectable = TRUE;
1134
1135                 BT_INFO("Adapter discoverable mode:"
1136                                 " BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
1137
1138                 if (__bt_is_service_request_present(BT_GET_CONNECTABLE)) {
1139                         __bt_adapter_handle_pending_requests(BT_GET_CONNECTABLE,
1140                                 (void *) &connectable, sizeof(gboolean));
1141
1142                 } else {
1143
1144                         _bt_send_event(BT_ADAPTER_EVENT,
1145                                         BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
1146                                         g_variant_new("(b)", connectable));
1147
1148                         mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1149                         _bt_send_event(BT_ADAPTER_EVENT,
1150                                         BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
1151                                         g_variant_new("(in)", result, mode));
1152                 }
1153                 break;
1154         }
1155         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
1156                 int mode;
1157                 gboolean connectable = TRUE;
1158
1159                 BT_INFO("Adapter discoverable mode:"
1160                                 " BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
1161
1162                 if (__bt_is_service_request_present(BT_GET_CONNECTABLE)) {
1163                         __bt_adapter_handle_pending_requests(BT_GET_CONNECTABLE,
1164                                 (void *) &connectable, sizeof(gboolean));
1165
1166                 } else {
1167                         /* Send event to application */
1168                         mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1169                         _bt_send_event(BT_ADAPTER_EVENT,
1170                                         BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
1171                                         g_variant_new("(in)", result, mode));
1172                 }
1173                 break;
1174         }
1175         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
1176                 int *timeout = event_data;
1177                 int mode;
1178
1179                 BT_INFO("Discoverable timeout: [%d]", *timeout);
1180
1181                 /* Send event to application */
1182                 _bt_get_discoverable_mode(&mode);
1183                 _bt_send_event(BT_ADAPTER_EVENT,
1184                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
1185                                 g_variant_new("(in)", result, mode));
1186                 break;
1187         }
1188         case OAL_EVENT_ADAPTER_PROPERTY_SERVICES: {
1189                 int count;
1190                 service_uuid_t *service_list;
1191                 event_adapter_services_t *list = event_data;
1192
1193                 count = list->num;
1194                 service_list = list->service_list;
1195                 __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
1196
1197                 char uuids[512] = {0,};
1198                 char standard_prefix[2] = {0,};
1199                 int index = 0;
1200                 for (int i = 0; i < count; i++) {
1201                         if (i > 0)
1202                                 g_snprintf(uuids + (index++), 2, ",");
1203                         if (memcmp(service_list[i].uuid, standard_prefix, 2) == 0) {
1204                                 g_snprintf(uuids + index, 5, "%.2x%.2x",
1205                                         service_list[i].uuid[2], service_list[i].uuid[3]);
1206                                 index += 4;
1207                         } else {
1208                                 g_snprintf(uuids + index, 9, "%.2x%.2x..%.2x,",
1209                                         service_list[i].uuid[0], service_list[i].uuid[1], service_list[i].uuid[15]);
1210                                 index += 8;
1211                         }
1212                 }
1213                 BT_PERMANENT_LOG("UUIDs %s", uuids);
1214                 break;
1215         }
1216         case OAL_EVENT_ADAPTER_BONDED_DEVICE_LIST: {
1217                 int i;
1218                 int count;
1219                 bluetooth_device_address_t *addr_list;
1220
1221                 event_device_list_t *bonded_device_list = event_data;
1222                 count = bonded_device_list->num;
1223
1224                 addr_list = g_malloc0(count * sizeof(bluetooth_device_address_t));
1225                 for (i = 0; i < count; i++) {
1226                         memcpy(addr_list[i].addr,
1227                                         bonded_device_list->devices[i].addr,
1228                                         BLUETOOTH_ADDRESS_LENGTH);
1229                 }
1230
1231                 BT_INFO("Adapter Bonded device List count: [%d]", count);
1232                 _bt_device_handle_paired_address_list(addr_list, bonded_device_list->num);
1233                 g_free(addr_list);
1234                 break;
1235         }
1236         case OAL_EVENT_ADAPTER_PROPERTY_A2DP_ROLE: {
1237                 unsigned int *a2dp_role = event_data;
1238
1239                 BT_INFO("a2dp role: [%u]", *a2dp_role);
1240
1241                 /* In Fhub case, both role(Source|Sink, 0x03) can be delivered */
1242                 __bt_handle_pending_a2dp_init(*a2dp_role);
1243
1244                 break;
1245         }
1246         case OAL_EVENT_CONTROLLER_ERROR_RECEIVED: {
1247                 uint8_t *error_code = event_data;
1248
1249                 BT_INFO("OAL_EVENT_CONTROLLER_ERROR_RECEIVED: [%d]", *error_code);
1250
1251 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
1252                 _bt_start_log_dump("syslog");
1253 #endif
1254
1255 #ifdef TIZEN_FEATURE_BT_VENDOR_OPERATION
1256                 _bt_recover_adapter();
1257 #endif
1258                 break;
1259         }
1260         case OAL_EVENT_ADAPTER_PROFILE_CONNECTED_DEVICES:
1261                 BT_DBG("OAL_EVENT_ADAPTER_PROFILE_CONNECTED_DEVICES");
1262                 __bt_adapter_handle_pending_requests(BT_GET_PROFILE_CONNECTED_DEVICES,
1263                                 event_data, sizeof(event_adapter_profile_connected_devices));
1264                 break;
1265         default:
1266                 BT_ERR("Unhandled event..");
1267                 break;
1268         }
1269
1270         BT_DBG("-");
1271 }
1272
1273 int _bt_init_profiles()
1274 {
1275         int ret;
1276         BT_INFO("+");
1277
1278         /*TODO: Init bluetooth profiles */
1279         ret = _bt_hidhost_initialize();
1280         if (ret != BLUETOOTH_ERROR_NONE)
1281                 BT_ERR("_bt_hidhost_initialize Failed");
1282
1283         ret = _bt_hiddevice_initialize();
1284         if (ret != BLUETOOTH_ERROR_NONE)
1285                 BT_ERR("_bt_hiddevice_initialize Failed");
1286
1287         ret = _bt_socket_init();
1288         if (ret != BLUETOOTH_ERROR_NONE)
1289                 BT_ERR("_bt_socket_init Failed");
1290
1291         /* Initialize HFP Audio Gateway */
1292         ret = _bt_audio_initialize(BT_AG_MODULE);
1293         if (ret != BLUETOOTH_ERROR_NONE)
1294                 BT_ERR("_bt_audio_initialize(BT_AG_MODULE) Failed");
1295
1296         /* Registering callback for receiving audio services searched */
1297         ret = _bt_audio_initialize(BT_AUDIO_ALL_MODULE);
1298         if (ret != BLUETOOTH_ERROR_NONE)
1299                 BT_ERR("_bt_audio_initialize(BT_AUDIO_ALL_MODULE) Failed");
1300
1301         ret = _bt_hdp_init();
1302         if (ret != BLUETOOTH_ERROR_NONE)
1303                 BT_ERR("_bt_hdp_init Failed");
1304
1305         ret = _bt_gatt_init();
1306         if (ret != BLUETOOTH_ERROR_NONE)
1307                 BT_ERR("_bt_gatt_init Failed");
1308
1309         ret = _bt_tds_init();
1310         if (ret != BLUETOOTH_ERROR_NONE)
1311                 BT_ERR("_bt_tds_init Failed");
1312
1313         /* Initialize HF Client */
1314         ret = _bt_audio_initialize(BT_HFP_MODULE);
1315         if (ret != BLUETOOTH_ERROR_NONE)
1316                 BT_ERR("_bt_audio_initialize(BT_HFP_MODULE) Failed");
1317
1318         return BLUETOOTH_ERROR_NONE;
1319 }
1320
1321 int _bt_cleanup_profiles(void)
1322 {
1323         /* TODO: Cleanup bluetooth profiles */
1324         _bt_hidhost_deinitialize();
1325         _bt_socket_deinit();
1326
1327         /* TODO: Cleanup bluetooth audio profiles
1328         //_bt_audio_deinitialize(BT_A2DP_SOURCE_MODULE);
1329         //_bt_audio_deinitialize(BT_AVRCP_MODULE);
1330         //_bt_audio_deinitialize(BT_A2DP_SINK_MODULE);
1331         //_bt_audio_deinitialize(BT_AG_MODULE);
1332         //_bt_audio_deinitialize(BT_AVRCP_CTRL_MODULE);
1333         //_bt_audio_deinitialize(BT_AUDIO_ALL_MODULE);
1334
1335         a2dp_init_pending = TRUE;
1336         */
1337         _bt_hdp_deinit();
1338         _bt_gatt_deinit();
1339
1340         return BLUETOOTH_ERROR_NONE;
1341 }
1342
1343 /* OAL post initialization handler */
1344 static void __bt_post_oal_init(void)
1345 {
1346         int ret;
1347         int status = VCONFKEY_BT_STATUS_OFF;
1348
1349         BT_DBG("OAL initialized");
1350         if (vconf_get_int(VCONFKEY_BT_STATUS, &status) != 0)
1351                 BT_ERR("Fail to get the enabled value");
1352
1353         if (status & VCONFKEY_BT_STATUS_ON) {
1354                 ret = _bt_enable_adapter();
1355                 if (ret != BLUETOOTH_ERROR_NONE)
1356                         BT_ERR("_bt_enable_adapter failed with error: %d", ret);
1357         }
1358 }
1359
1360 /* OAL initialization handler */
1361 static void __bt_handle_oal_initialisation(oal_event_t event)
1362 {
1363         BT_DBG("");
1364
1365         switch (event) {
1366         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
1367                 __bt_post_oal_init();
1368                 break;
1369         case OAL_EVENT_OAL_INITIALISED_FAILED:
1370                 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
1371                 g_idle_add(_bt_terminate_service, NULL);
1372                 break;
1373         default:
1374                 BT_ERR("Unknown Event");
1375                 break;
1376         }
1377 }
1378
1379 static gboolean __bt_is_service_request_present(int service_function)
1380 {
1381         GSList *l;
1382         invocation_info_t *req_info;
1383
1384         BT_DBG("+");
1385
1386         /* Get method invocation context */
1387         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
1388                 req_info = l->data;
1389                 if (req_info && req_info->service_function == service_function)
1390                         return TRUE;
1391         }
1392
1393         BT_DBG("-");
1394         return FALSE;
1395 }
1396
1397 /* Internal functions of core adapter service */
1398 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
1399 {
1400         GSList *l;
1401         GArray *out_param;
1402         invocation_info_t *req_info;
1403         BT_INFO("+");
1404
1405         /* Get method invocation context */
1406         for (l = _bt_get_invocation_list(); l != NULL; ) {
1407                 req_info = l->data;
1408                 l = g_slist_next(l);
1409                 if (req_info == NULL || req_info->service_function != service_function)
1410                         continue;
1411
1412                 /* Create out param */
1413                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1414
1415                 switch (service_function) {
1416                 case BT_ENABLE_ADAPTER:
1417                 case BT_DISABLE_ADAPTER: {
1418                         gboolean done = TRUE;
1419                         g_array_append_vals(out_param, &done, sizeof(gboolean));
1420                         break;
1421                 }
1422                 case BT_GET_CONNECTABLE:
1423                 case BT_GET_LOCAL_NAME:
1424                 case BT_GET_LOCAL_ADDRESS:
1425                 case BT_GET_LOCAL_VERSION:
1426                         g_array_append_vals(out_param, user_data, size);
1427                         break;
1428                 case BT_IS_SERVICE_USED: {
1429                         unsigned int i;
1430                         gboolean used = FALSE;
1431                         unsigned char *uuid;
1432                         char uuid_str[BT_UUID_STRING_SIZE];
1433                         char *request_uuid = req_info->user_data;
1434                         service_uuid_t *service_list = user_data;
1435
1436                         BT_INFO("Check for service uuid: %s", request_uuid);
1437                         for (i = 0; i < size; i++) {
1438                                 uuid = service_list[i].uuid;
1439                                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
1440                                 BT_INFO("Adapter Service: [%s]", uuid_str);
1441                                 if (strcasecmp(uuid_str, request_uuid) == 0) {
1442                                         BT_INFO("UUID matched!!");
1443                                         used = TRUE;
1444                                         break;
1445                                 }
1446                         }
1447
1448                         g_array_append_vals(out_param, &used, sizeof(gboolean));
1449                         break;
1450                 }
1451                 case BT_GET_PROFILE_CONNECTED_DEVICES: {
1452                         event_adapter_profile_connected_devices *event_data = user_data;
1453                         bluetooth_device_address_t addr;
1454                         int i;
1455                         for (i = 0; i < event_data->count; i++) {
1456                                 memcpy(&addr, &event_data->addr_list[i], sizeof(bluetooth_device_address_t));
1457                                 g_array_append_vals(out_param, &addr, sizeof(bluetooth_device_address_t));
1458                         }
1459                         break;
1460                 }
1461                 default:
1462                         BT_ERR("Unknown service function[%d]", service_function);
1463                 }
1464
1465                 _bt_service_method_return(req_info->context, out_param, req_info->result);
1466                 g_array_free(out_param, TRUE);
1467                 /* Now free invocation info for this request*/
1468                 _bt_free_info_from_invocation_list(req_info);
1469         }
1470 }
1471
1472 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
1473 {
1474         char *phone_name = NULL;
1475         char *ptr = NULL;
1476
1477         if (node == NULL)
1478                 return;
1479
1480         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
1481                 phone_name = vconf_keynode_get_str(node);
1482
1483                 if (phone_name && strlen(phone_name) != 0) {
1484                         if (!g_utf8_validate(phone_name, -1,
1485                                         (const char **)&ptr))
1486                                 *ptr = '\0';
1487
1488                         _bt_set_local_name(phone_name);
1489                 }
1490         }
1491 }
1492
1493 /* Request return handlings */
1494 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
1495 {
1496         int result = BLUETOOTH_ERROR_NONE;
1497
1498         BT_INFO("__bt_adapter_post_set_enabled>>");
1499
1500         if (TIZEN_FEATURE_FHUB_REFERENCE) {
1501                 _bt_set_connectable(TRUE);
1502                 __bt_set_visible_mode();
1503         } else if (TIZEN_FEATURE_DA_REFERENCE) {
1504                 if (headed_plugin_info->plugin_headed_enabled) {
1505                         BT_DBG("DA Headed devices. Set General Discoverable Mode");
1506                         if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
1507                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0))
1508                                 BT_ERR("Fail to set discoverable mode");
1509                 } else {
1510                         BT_DBG("DA Headless devices. Set Connectable Mode");
1511                         if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
1512                                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0))
1513                                 BT_ERR("Fail to set connectable mode");
1514                 }
1515         } else if (TIZEN_PROFILE_TV || TIZEN_FEATURE_ROBOT_REFERENCE ||
1516                          !headed_plugin_info->plugin_headed_enabled) {
1517                 if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
1518                                 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0))
1519                         BT_ERR("Fail to set discoverable mode");
1520         } else if (TIZEN_PROFILE_IOT || TIZEN_PROFILE_COMMON) {
1521                 /* Tizen IOT Speaker - The default visible mode is off */
1522                 if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
1523                                 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0))
1524                         BT_ERR("Fail to set connectable mode");
1525         } else {
1526                 __bt_set_visible_mode();
1527         }
1528
1529         /* add the vconf noti handler */
1530         if (0 != vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1531                         (vconf_callback_fn)__bt_phone_name_changed_cb, NULL))
1532                 BT_ERR("DEVICE_NAME key changed notification registration failed");
1533
1534         __bt_set_local_name();
1535
1536         /* Get All properties */
1537         if (OAL_STATUS_SUCCESS != adapter_get_properties())
1538                 BT_ERR("adapter_get_properties failed");
1539
1540         __bt_adapter_state_set_status(BT_ACTIVATED);
1541
1542         /*Send BT Enabled event to application */
1543         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
1544                         g_variant_new("(i)", result));
1545
1546         BT_PERMANENT_LOG("BT Enabled");
1547
1548         return FALSE;
1549 }
1550
1551 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
1552 {
1553         BT_INFO("_bt_adapter_post_set_disabled>>");
1554
1555         if (!TIZEN_PROFILE_TV) {
1556                 /* Add Adapter disabled post processing codes */
1557                 if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1558                                 (vconf_callback_fn)__bt_phone_name_changed_cb) != 0)
1559                         BT_ERR("vconf_ignore_key_changed failed");
1560         }
1561
1562         /* bt-service should be terminated when BT is off */
1563         if (!TIZEN_FEATURE_BT_USB_DONGLE) {
1564                 /* TODO: Implement to check if it is the recovery mode or not */
1565                 if (__bt_is_flightmode_request() == BT_ADAPTER_FLIGHT_MODE_ON) {
1566                         /* Keep bt-service to handle Flight mode OFF */
1567                         BT_DBG("Deactived due to flight mode. Keep bt-service");
1568                         _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1569                         __bt_set_flightmode_request(BT_ADAPTER_FLIGHT_MODE_NONE);
1570                 } else if (__bt_is_flightmode_request() == BT_ADAPTER_FLIGHT_MODE_OFF) {
1571                         BT_DBG("Durning deactivation, receive Flight mode Off. Enable BT adapter");
1572                         _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1573                         _bt_service_initialize();
1574                         _bt_enable_adapter();
1575                         __bt_set_flightmode_request(BT_ADAPTER_FLIGHT_MODE_NONE);
1576                 } else
1577                         _bt_reliable_terminate_service(NULL);
1578         } else {
1579                 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1580         }
1581
1582         return FALSE;
1583 }
1584
1585 static void __bt_adapter_update_bt_enabled(void)
1586 {
1587         BT_INFO("_bt_adapter_update_bt_enabled >> Init profiles...");
1588         if (BLUETOOTH_ERROR_NONE != _bt_init_profiles())
1589                 BT_ERR("Bluetooth profile init failed");
1590
1591         _bt_device_state_handle_callback_set_request();
1592
1593         _bt_device_handle_adapter_state(TRUE);
1594
1595         /* Update Bluetooth Status to notify other modules */
1596         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
1597                 BT_ERR("Set vconf failed\n");
1598
1599         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1600                 BT_ERR("Set vconf failed\n");
1601
1602         /* TODO:Add timer function to handle any further post processing */
1603         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
1604 }
1605
1606 static void __bt_adapter_update_bt_disabled(void)
1607 {
1608         int power_off_status = 0;
1609         int ret;
1610
1611         BT_INFO("_bt_adapter_update_bt_disabled >> Cleanup profiles...");
1612         _bt_cleanup_profiles();
1613
1614         _bt_device_handle_adapter_state(FALSE);
1615
1616         /* Send the information to Absolute Volume Controller */
1617         _bt_audio_handle_adapter_disabled();
1618
1619         /* Update the vconf BT status in normal Deactivation case only */
1620         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1621         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1622
1623         /* Update Bluetooth Status to notify other modules */
1624         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1625                 BT_ERR("Set vconf failed");
1626
1627         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1628                 BT_ERR("Set vconf failed\n");
1629
1630         /* TODO:Add timer function to handle any further post processing */
1631         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
1632
1633         /* Pending BT Disabled event before bt-service's termination */
1634 }
1635
1636 static void __bt_adapter_state_set_status(bt_status_t status)
1637 {
1638         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1639         adapter_state = status;
1640 }
1641
1642 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
1643 {
1644         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
1645         adapter_discovery_state = status;
1646 }
1647
1648 static void __bt_adapter_state_change_callback(int bt_status)
1649 {
1650         BT_INFO("BT adapter status changed [%d]", bt_status);
1651
1652         switch (bt_status) {
1653         case BT_DEACTIVATED:
1654                 __bt_adapter_state_set_status(BT_TERMINATING);
1655
1656                 /* Adapter is disabled, unregister event handlers */
1657                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
1658                 //_bt_deinit_device_event_handler();
1659
1660                 /* Add Adapter disabled post processing codes */
1661                 __bt_adapter_update_bt_disabled();
1662                 break;
1663         case BT_ACTIVATED:
1664                 /* Add Adapter enabled post processing codes */
1665                 if (timer_id > 0) {
1666                         BT_DBG("g_source is removed");
1667                         g_source_remove(timer_id);
1668                         timer_id = 0;
1669                 }
1670
1671                 /*If adapter gets activated when flight mode is ON*/
1672                 if (__bt_is_flightmode_request() == BT_ADAPTER_FLIGHT_MODE_ON) {
1673                         BT_DBG("Receive Flight mode On. Disable BT adapter");
1674                         _bt_disable_adapter();
1675                         return;
1676                 }
1677
1678                 __bt_adapter_update_bt_enabled();
1679                 break;
1680         default:
1681                 BT_ERR("Incorrect Bluetooth adapter state changed status");
1682
1683         }
1684 }
1685
1686 int _bt_set_adapter_request_state(int enable)
1687 {
1688         return oal_set_adapter_request_state(enable);
1689 }
1690
1691 int _bt_set_le_request_state(int enable)
1692 {
1693         return oal_set_le_request_state(enable);
1694 }
1695
1696 static int __bt_adapter_state_handle_request(gboolean enable)
1697 {
1698         int result = BLUETOOTH_ERROR_NONE;
1699
1700         switch (adapter_state) {
1701         case BT_ACTIVATING:
1702         case BT_DEACTIVATING:
1703                 BT_INFO("Should not be callded : state [%d]", adapter_state);
1704                 return BLUETOOTH_ERROR_INTERNAL;
1705                 break;
1706         case BT_ACTIVATED: {
1707                 BT_INFO("Adapter is currently in activated state, state [%d]",
1708                                 adapter_state);
1709                 if (enable) {
1710                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1711                 } else {
1712                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
1713                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
1714                                 /*TODO Stop Discovery*/
1715                                 __bt_adapter_update_discovery_status(FALSE);
1716                         }
1717                         result = adapter_disable();
1718                         if (result != OAL_STATUS_SUCCESS) {
1719                                 BT_ERR("adapter_disable failed: [%d]", result);
1720                                 result = _bt_convert_oal_status_to_bt_error(result);
1721                                 /*TODO: perform if anything more needs to be done to handle failure */
1722                         } else {
1723                                 /* TODO: To be handled */
1724                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1725                                 result = BLUETOOTH_ERROR_NONE;
1726                         }
1727                 }
1728                 break;
1729         }
1730         case BT_DEACTIVATED: {
1731                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
1732                                 adapter_state);
1733                 if (!enable) {
1734                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1735                 } else {
1736                         result = adapter_enable();
1737                         if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
1738                                 BT_ERR("adapter_enable failed: [%d]", result);
1739                                 adapter_disable();
1740                                 result = _bt_convert_oal_status_to_bt_error(result);
1741                                 /*TODO: perform if anything more needs to be done to handle failure */
1742                         } else {
1743                                 /* TODO: To be handled */
1744                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1745                                 result = BLUETOOTH_ERROR_NONE;
1746                         }
1747                 }
1748                 break;
1749         }
1750         default:
1751                 BT_ERR("Unknown state: %d", adapter_state);
1752                 break;
1753         }
1754
1755         if (enable && result == BLUETOOTH_ERROR_NONE) {
1756                 /* Adapter enable request is successful, setup event handlers */
1757                 _bt_service_register_event_handler_callback(
1758                                 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
1759         }
1760         return result;
1761 }
1762
1763 static int __bt_adapter_state_discovery_request(gboolean enable,
1764                 unsigned short max_response, unsigned short duration,
1765                 unsigned int mask, gboolean is_custom,
1766                 bt_discovery_role_type_t role)
1767 {
1768         int result = BLUETOOTH_ERROR_NONE;
1769
1770         BT_DBG("+");
1771         switch (adapter_discovery_state) {
1772         case ADAPTER_DISCOVERY_STARTED: {
1773                 BT_INFO("Adapter is currently in discovery started state, state [%d]",
1774                                 adapter_discovery_state);
1775                 if (enable) {
1776                         return BLUETOOTH_ERROR_IN_PROGRESS;
1777                 } else {
1778                         result = adapter_stop_inquiry();
1779                         if (result != OAL_STATUS_SUCCESS) {
1780                                 BT_ERR("Discover stop failed: %d", result);
1781                                 result = _bt_convert_oal_status_to_bt_error(result);
1782                         } else {
1783                                 BT_ERR("Stop Discovery Triggered successfully");
1784                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1785                                 result = BLUETOOTH_ERROR_NONE;
1786                         }
1787                 }
1788                 break;
1789         }
1790         case ADAPTER_DISCOVERY_STARTING: {
1791                 BT_INFO("Adapter is currently in discovery starting state, state [%d]",
1792                                 adapter_discovery_state);
1793
1794                 result = enable ?  BLUETOOTH_ERROR_IN_PROGRESS :
1795                                         BLUETOOTH_ERROR_DEVICE_BUSY;
1796
1797                 break;
1798         }
1799         case ADAPTER_DISCOVERY_STOPPED: {
1800                 BT_INFO("Adapter is currently in discovery stopped state, state [%d]",
1801                                 adapter_discovery_state);
1802                 if (!enable)
1803                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1804                 else {
1805                         BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
1806
1807                         if (!is_custom)
1808                                 result = adapter_start_inquiry(duration);
1809                         else
1810                                 result = adapter_start_custom_inquiry(role);
1811
1812                         if (result != OAL_STATUS_SUCCESS) {
1813                                 BT_ERR("Start Discovery failed: %d", result);
1814                                 result = _bt_convert_oal_status_to_bt_error(result);
1815                         } else {
1816                                 BT_ERR("Start Discovery Triggered successfully");
1817                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1818                                 result = BLUETOOTH_ERROR_NONE;
1819                         }
1820                 }
1821                 break;
1822         }
1823         case ADAPTER_DISCOVERY_STOPPING: {
1824                 BT_INFO("Adapter is currently in discovery stopping state, state [%d]",
1825                                 adapter_discovery_state);
1826
1827                 result = enable ?  BLUETOOTH_ERROR_DEVICE_BUSY :
1828                                         BLUETOOTH_ERROR_NOT_IN_OPERATION;
1829
1830                 break;
1831         }
1832         default:
1833                 BT_ERR("Unknown state: %d", adapter_discovery_state);
1834                 break;
1835         }
1836
1837         BT_DBG("-");
1838         return result;
1839 }
1840
1841 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status)
1842 {
1843         BT_INFO("__bt_adapter_discovery_state_change_callback: status [%d]", bt_discovery_status);
1844         GVariant *param = NULL;
1845         int result = BLUETOOTH_ERROR_NONE;
1846
1847         switch (bt_discovery_status) {
1848         case ADAPTER_DISCOVERY_STOPPED:
1849         {
1850                 __bt_adapter_update_discovery_status(bt_discovery_status);
1851                 param = g_variant_new("(i)", result);
1852                 _bt_send_event(BT_ADAPTER_EVENT,
1853                                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
1854                                 param);
1855                 break;
1856         }
1857         case ADAPTER_DISCOVERY_STARTED:
1858         {
1859                 __bt_adapter_update_discovery_status(bt_discovery_status);
1860                 param = g_variant_new("(i)", result);
1861                 _bt_send_event(BT_ADAPTER_EVENT,
1862                                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
1863                                 param);
1864                 break;
1865         }
1866         default:
1867                 BT_ERR("Incorrect Bluetooth adapter Discovery state changed status");
1868         }
1869 }
1870
1871 static void __bt_set_visible_mode(void)
1872 {
1873         int timeout = 0;
1874         int discoverable_state = DPM_BT_ERROR;
1875
1876         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
1877                 BT_ERR("Fail to get the timeout value");
1878
1879         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1880         if (timeout == -1 || discoverable_state == DPM_RESTRICTED) {
1881                 if (_bt_set_discoverable_mode(
1882                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
1883                                         timeout) != BLUETOOTH_ERROR_NONE) {
1884                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
1885                                 BT_ERR("Set vconf failed");
1886                 }
1887         }
1888 }
1889
1890 static void __bt_set_local_name(void)
1891 {
1892         char *phone_name = NULL;
1893         char *ptr = NULL;
1894
1895         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1896
1897         if (!phone_name)
1898                 return;
1899
1900         if (strlen(phone_name) != 0) {
1901                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
1902                         *ptr = '\0';
1903
1904                 _bt_set_local_name(phone_name);
1905         }
1906         free(phone_name);
1907 }
1908
1909 void _bt_adapter_set_status(bt_status_t status)
1910 {
1911         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1912         adapter_state = status;
1913 }
1914
1915 bt_status_t _bt_adapter_get_status(void)
1916 {
1917         return adapter_state;
1918 }
1919
1920 void _bt_set_disabled(int result)
1921 {
1922         int power_off_status = 0;
1923         int ret;
1924         int ret_pm_ignore;
1925         int pm_ignore_mode = 0;
1926
1927         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1928         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1929
1930         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
1931
1932         /* Update the vconf BT status in normal Deactivation case only */
1933         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
1934                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
1935
1936                 BT_DBG("Update vconf for BT normal Deactivation");
1937
1938                 if (result == BLUETOOTH_ERROR_TIMEOUT)
1939                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
1940                                 BT_ERR("Set vconf failed");
1941
1942                 /* Update Bluetooth Status to notify other modules */
1943                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1944                         BT_ERR("Set vconf failed");
1945
1946                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
1947                                                         EVT_VAL_BT_OFF) != ES_R_OK)
1948                         BT_ERR("Fail to set value");
1949         }
1950
1951         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1952                 BT_ERR("Set vconf failed\n");
1953
1954         _bt_adapter_set_status(BT_DEACTIVATED);
1955         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPED);
1956
1957         /* Send BT Disabled event to application */
1958         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1959                         g_variant_new("(i)", result));
1960
1961         BT_INFO("Adapter disabled");
1962         BT_PERMANENT_LOG("BT Disabled");
1963 }
1964