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