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