Code synchronization with latest tizen 4.0 codes
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / adapter / bt-service-core-adapter.c
1 /*
2  * Copyright (c) 2015 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Contact: Anupam Roy <anupam.r@samsung.com>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <gio/gio.h>
22 #include <glib.h>
23 #include <dlog.h>
24 #include <string.h>
25 #include <vconf.h>
26 #include <vconf-internal-keys.h>
27 #include <bundle.h>
28 #include <bundle_internal.h>
29 #include <eventsystem.h>
30
31 #include "alarm.h"
32
33 /*bt-service headers */
34 #include "bt-internal-types.h"
35 #include "bt-service-common.h"
36 #include "bt-service-util.h"
37 #include "bt-service-main.h"
38 #include "bt-service-core-adapter.h"
39 #include "bt-service-core-device.h"
40 #include "bt-service-event-receiver.h"
41 #include "bt-request-handler.h"
42 #include "bt-service-event.h"
43 #include "bt-service-audio-common.h"
44 #include "bt-service-core-adapter-le.h"
45 #include "bt-service-gatt.h"
46
47 #ifdef TIZEN_FEATURE_BT_DPM
48 #include "bt-service-dpm.h"
49 #endif
50 #include "bt-service-hidhost.h"
51 #include "bt-service-socket.h"
52 #include "bt-service-hdp.h"
53
54 /* OAL headers */
55 #include <oal-event.h>
56 #include <oal-manager.h>
57 #include <oal-adapter-mgr.h>
58
59 #ifdef TIZEN_FEATURE_BT_PAN_NAP
60 #include "bt-service-network.h"
61 #endif
62 /*This file will contain state machines related to adapter and remote device */
63
64 #include "bt-internal-types.h"
65
66 /* Global variables */
67 typedef struct {
68         guint event_id;
69         int timeout;
70         time_t start_time;
71         gboolean alarm_init;
72         int alarm_id;
73 } bt_adapter_timer_t;
74
75 static bt_adapter_timer_t visible_timer;
76
77 static guint timer_id = 0;
78
79 static gboolean a2dp_init_pending = FALSE;
80
81
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 #ifdef TIZEN_FEATURE_BT_DPM
381         int discoverable_state = DPM_BT_ERROR;
382 #endif
383
384         __bt_visibility_alarm_remove();
385
386         visible_timer.timeout = timeout;
387
388 #ifdef TIZEN_FEATURE_BT_DPM
389         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
390         if (discoverable_state != DPM_RESTRICTED) {
391 #endif
392                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
393                         BT_ERR("Set vconf failed");
394 #ifdef TIZEN_FEATURE_BT_DPM
395         }
396 #endif
397
398         if (timeout <= 0)
399                 return BLUETOOTH_ERROR_NONE;
400
401         if (!visible_timer.alarm_init) {
402                 /* Set Alarm timer to switch off BT */
403                 result = alarmmgr_init("bt-service");
404                 if (result != 0)
405                         return BLUETOOTH_ERROR_INTERNAL;
406
407                 visible_timer.alarm_init = TRUE;
408         }
409
410         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
411         if (result != 0)
412                 return BLUETOOTH_ERROR_INTERNAL;
413
414         /* Take start time */
415         time(&(visible_timer.start_time));
416         visible_timer.event_id = g_timeout_add_seconds(1,
417                         __bt_timeout_handler, NULL);
418
419         __bt_visibility_alarm_create();
420
421         return BLUETOOTH_ERROR_NONE;
422 }
423
424 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
425 {
426         int result;
427 #ifdef TIZEN_FEATURE_BT_DPM
428         int discoverable_state = DPM_BT_ERROR;
429 #endif
430
431         BT_DBG("+");
432
433         BT_INFO("discoverable_mode: %d, timeout: %d", discoverable_mode, timeout);
434
435 #ifdef TIZEN_FEATURE_BT_DPM
436         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
437         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
438                  discoverable_state == DPM_RESTRICTED) {
439                 if (headed_plugin_info->plugin_headed_enabled)
440                         headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
441                 return BLUETOOTH_ERROR_ACCESS_DENIED;
442         }
443         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
444                 discoverable_state == DPM_RESTRICTED) {
445                 if (headed_plugin_info->plugin_headed_enabled)
446                         headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
447                 return BLUETOOTH_ERROR_ACCESS_DENIED;
448         }
449 #endif
450
451         switch (discoverable_mode) {
452         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
453                 result = adapter_set_connectable(TRUE);
454                 timeout = 0;
455                 break;
456         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
457                 result = adapter_set_discoverable();
458                 timeout = 0;
459                 break;
460         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
461                 result = adapter_set_discoverable();
462                 break;
463         default:
464                 return BLUETOOTH_ERROR_INVALID_PARAM;
465         }
466
467         if (result != OAL_STATUS_SUCCESS) {
468                 BT_ERR("set scan mode failed %d", result);
469                 return BLUETOOTH_ERROR_INTERNAL;
470         }
471
472         result = adapter_set_discoverable_timeout(timeout);
473         if (result != OAL_STATUS_SUCCESS) {
474                 BT_ERR("adapter_set_discoverable_timeout failed %d", result);
475                 return BLUETOOTH_ERROR_INTERNAL;
476         }
477
478         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
479                 timeout = -1;
480
481         result = __bt_set_visible_time(timeout);
482
483         BT_DBG("-");
484         return result;
485 }
486
487 gboolean _bt_is_connectable(void)
488 {
489         int connectable = 0;
490         int result;
491
492         BT_DBG("+");
493
494         adapter_is_connectable(&connectable);
495         if (connectable)
496                 result = TRUE;
497         else
498                 result = FALSE;
499
500         BT_DBG("Connectable: [%s]", result ? "TRUE":"FALSE");
501         BT_DBG("-");
502         return result;
503 }
504
505 int _bt_set_connectable(gboolean connectable)
506 {
507         int result = BLUETOOTH_ERROR_NONE;
508
509         BT_DBG("+");
510         result =  adapter_set_connectable(connectable);
511         if (result != OAL_STATUS_SUCCESS) {
512                 BT_ERR("adapter_set_connectable failed: %d", result);
513                 result = BLUETOOTH_ERROR_INTERNAL;
514         } else
515                 result = BLUETOOTH_ERROR_NONE;
516
517         BT_DBG("-");
518         return result;
519 }
520
521 int _bt_is_service_used(void)
522 {
523         int result;
524
525         BT_DBG("+");
526
527         result =  adapter_get_service_uuids();
528         if (result != OAL_STATUS_SUCCESS) {
529                 BT_ERR("adapter_get_service_uuids failed: %d", result);
530                 result = BLUETOOTH_ERROR_INTERNAL;
531         } else {
532                 result = BLUETOOTH_ERROR_NONE;
533         }
534
535         BT_DBG("-");
536         return result;
537 }
538
539 int _bt_adapter_get_bonded_devices(void)
540 {
541         int result = BLUETOOTH_ERROR_NONE;
542
543         BT_DBG("+");
544         result =  adapter_get_bonded_devices();
545         if (result != OAL_STATUS_SUCCESS) {
546                 BT_ERR("adapter_get_bonded_devices failed: %d", result);
547                 result = BLUETOOTH_ERROR_INTERNAL;
548         } else
549                 result = BLUETOOTH_ERROR_NONE;
550
551         BT_DBG("-");
552         return result;
553 }
554
555 static void __bt_handle_pending_a2dp_init(service_uuid_t *service_list, unsigned int count)
556 {
557         int ret;
558         unsigned int i;
559         unsigned char *uuid;
560         char uuid_str[BT_UUID_STRING_SIZE];
561
562         if (!a2dp_init_pending)
563                 return;
564
565         BT_DBG("+");
566         a2dp_init_pending = FALSE;
567         for (i = 0; i < count; i++) {
568                 uuid = service_list[i].uuid;
569                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
570                 BT_INFO("Adapter Service: [%s]", uuid_str);
571                 if (!strcasecmp(uuid_str, A2DP_SINK_UUID)) {
572                         BT_INFO("Enable A2DP Sink role");
573                         /* Initialize A2DP Sink */
574                         ret = _bt_audio_initialize(BT_A2DP_SINK_MODULE);
575                         if (ret != BLUETOOTH_ERROR_NONE)
576                                 BT_ERR("_bt_audio_initialize(BT_A2DP_SINK_MODULE) Failed");
577
578                         /* Initialize AVRCP Controller */
579                         ret = _bt_audio_initialize(BT_AVRCP_CTRL_MODULE);
580                         if (ret != BLUETOOTH_ERROR_NONE)
581                                 BT_ERR("_bt_audio_initialize(BT_AVRCP_CTRL_MODULE) Failed");
582
583                         _bt_audio_set_current_role(BLUETOOTH_A2DP_SINK);
584                         return;
585                 }
586         }
587
588         BT_INFO("Enable A2DP Source role by default");
589         /* Initialize A2DP Source */
590         ret = _bt_audio_initialize(BT_A2DP_SOURCE_MODULE);
591         if (ret != BLUETOOTH_ERROR_NONE)
592                 BT_ERR("_bt_audio_initialize(BT_A2DP_SOURCE_MODULE) Failed");
593
594         /* Initialize AVRCP Target */
595         ret = _bt_audio_initialize(BT_AVRCP_MODULE);
596         if (ret != BLUETOOTH_ERROR_NONE)
597                 BT_ERR("_bt_audio_initialize(BT_AVRCP_MODULE) Failed");
598
599         _bt_audio_set_current_role(BLUETOOTH_A2DP_SOURCE);
600         BT_DBG("-");
601 }
602
603 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
604 {
605         int result = BLUETOOTH_ERROR_NONE;
606
607         BT_DBG("+");
608
609         switch(event_type) {
610         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
611         case OAL_EVENT_OAL_INITIALISED_FAILED:
612                 __bt_handle_oal_initialisation(event_type);
613                 break;
614         case OAL_EVENT_ADAPTER_ENABLED:
615                 __bt_adapter_state_change_callback(BT_ACTIVATED);
616                 break;
617         case OAL_EVENT_ADAPTER_DISABLED:
618                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
619                 break;
620         case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
621                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STARTED);
622                 break;
623         case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
624                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STOPPED);
625                 break;
626         case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
627                 bt_address_t *bd_addr = event_data;
628                 bluetooth_device_address_t local_address;
629
630                 /* Copy data */
631                 memcpy(local_address.addr, bd_addr->addr, BT_ADDRESS_LENGTH_MAX);
632                 BT_DBG("Adapter address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]",
633                                 local_address.addr[0], local_address.addr[1], local_address.addr[2],
634                                 local_address.addr[3], local_address.addr[4], local_address.addr[5]);
635
636                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
637                                 (void *) &local_address, sizeof(bluetooth_device_address_t));
638                 break;
639         }
640         case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
641                 char *name = event_data;
642                 BT_DBG("Adapter Name: %s", name);
643
644                 if (__bt_is_service_request_present(BT_GET_LOCAL_NAME)) {
645                         bluetooth_device_name_t local_name;
646
647                         memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
648                         g_strlcpy(local_name.name,
649                                 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
650                         __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
651                                 (void *) &local_name, sizeof(bluetooth_device_name_t));
652                 } else {
653                         /* Send event to application */
654                         _bt_send_event(BT_ADAPTER_EVENT,
655                                         BLUETOOTH_EVENT_LOCAL_NAME_CHANGED,
656                                         g_variant_new("(is)", result, name));
657                 }
658                 break;
659         }
660         case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
661                 char *ver = event_data;
662                 bluetooth_version_t local_version;
663
664                 memset(&local_version, 0x00, sizeof(bluetooth_version_t));
665                 g_strlcpy(local_version.version,
666                                 (const gchar *)ver, BLUETOOTH_VERSION_LENGTH_MAX);
667                 BT_DBG("BT Version: %s", local_version.version);
668
669                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
670                                 (void *) &local_version, sizeof(bluetooth_version_t));
671                 break;
672         }
673         case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
674                 int mode = -1;
675                 gboolean connectable = FALSE;
676
677                 BT_INFO("Adapter discoverable mode:"
678                                 " BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
679                 _bt_send_event(BT_ADAPTER_EVENT,
680                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
681                                 g_variant_new("(b)", connectable));
682
683                 _bt_send_event(BT_ADAPTER_EVENT,
684                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
685                                 g_variant_new("(in)", result, mode));
686                 break;
687         }
688         case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
689                 int mode;
690                 gboolean connectable = TRUE;
691
692                 BT_INFO("Adapter discoverable mode:"
693                                 " BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
694                 _bt_send_event(BT_ADAPTER_EVENT,
695                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
696                                 g_variant_new("(b)", connectable));
697
698                 mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
699                 _bt_send_event(BT_ADAPTER_EVENT,
700                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
701                                 g_variant_new("(in)", result, mode));
702                 break;
703         }
704         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
705                 int mode;
706
707                 BT_INFO("Adapter discoverable mode:"
708                                 " BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
709
710                 /* Send event to application */
711                 mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
712                 _bt_send_event(BT_ADAPTER_EVENT,
713                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
714                                 g_variant_new("(in)", result, mode));
715
716                 break;
717         }
718         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
719                 int *timeout = event_data;
720                 int mode;
721
722                 BT_INFO("Discoverable timeout: [%d]", *timeout);
723
724                 /* Send event to application */
725                 _bt_get_discoverable_mode(&mode);
726                 _bt_send_event(BT_ADAPTER_EVENT,
727                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
728                                 g_variant_new("(in)", result, mode));
729                 break;
730         }
731         case OAL_EVENT_ADAPTER_PROPERTY_SERVICES: {
732                 int count;
733                 service_uuid_t *service_list;
734                 event_adapter_services_t *list = event_data;
735
736                 count = list->num;
737                 service_list = list->service_list;
738                 __bt_handle_pending_a2dp_init(service_list, count);
739                 __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
740                 break;
741         }
742         case OAL_EVENT_ADAPTER_BONDED_DEVICE_LIST: {
743                 int i;
744                 int count;
745                 bluetooth_device_address_t *addr_list;
746
747                 event_device_list_t *bonded_device_list = event_data;
748                 count = bonded_device_list->num;
749
750                 addr_list = g_malloc0(count * sizeof(bluetooth_device_address_t));
751                 for (i = 0; i < count; i++) {
752                         memcpy(addr_list[i].addr,
753                                         bonded_device_list->devices[i].addr,
754                                         BLUETOOTH_ADDRESS_LENGTH);
755                 }
756
757                 BT_INFO("Adapter Bonded device List count: [%d]", count);
758                 __bt_adapter_handle_pending_requests(BT_GET_BONDED_DEVICES,
759                                 (void *)addr_list, bonded_device_list->num);
760                 break;
761         }
762         default:
763                 BT_ERR("Unhandled event..");
764                 break;
765         }
766
767         BT_DBG("-");
768 }
769
770 int _bt_init_profiles()
771 {
772         int ret;
773
774         /*TODO: Init bluetooth profiles */
775         ret = _bt_hidhost_initialize();
776         if (ret != BLUETOOTH_ERROR_NONE) {
777                 BT_ERR("_bt_hidhost_initialize Failed");
778                 return ret;
779         }
780
781         ret = _bt_socket_init();
782         if (ret != BLUETOOTH_ERROR_NONE) {
783                 BT_ERR("_bt_socket_init Failed");
784                 return ret;
785         }
786
787         /*
788          * Query local adapter services and based on a2dp service uuids initialized
789          * in bluetooth stack, enable A2DP sourec or A2DP sink role.
790          */
791         ret =  adapter_get_service_uuids();
792         if (ret != OAL_STATUS_SUCCESS) {
793                 BT_ERR("adapter_get_service_uuids failed: %d", ret);
794                 return BLUETOOTH_ERROR_INTERNAL;
795         } else {
796                 a2dp_init_pending = TRUE;
797         }
798
799         /* Initialize HFP Audio Gateway */
800         ret = _bt_audio_initialize(BT_AG_MODULE);
801         if (ret != BLUETOOTH_ERROR_NONE) {
802                 BT_ERR("_bt_audio_initialize(BT_AG_MODULE) Failed");
803                 return ret;
804         }
805         /* Registering callback for receiving audio services searched */
806         ret = _bt_audio_initialize(BT_AUDIO_ALL_MODULE);
807         if (ret != BLUETOOTH_ERROR_NONE) {
808                 BT_ERR("_bt_audio_initialize(BT_AUDIO_ALL_MODULE) Failed");
809                 return ret;
810         }
811
812         ret = _bt_hdp_init();
813         if (ret != BLUETOOTH_ERROR_NONE) {
814                 BT_ERR("_bt_hdp_init Failed");
815                 return ret;
816         }
817
818         ret = _bt_le_init();
819         if (ret != BLUETOOTH_ERROR_NONE) {
820                 BT_ERR("_bt_le_init Failed");
821                 return ret;
822         }
823
824         ret = _bt_gatt_init();
825         if (ret != BLUETOOTH_ERROR_NONE) {
826                 BT_ERR("_bt_gatt_init Failed");
827                 return ret;
828         }
829
830         return BLUETOOTH_ERROR_NONE;
831 }
832
833 int _bt_cleanup_profiles(void)
834 {
835         /* TODO: Cleanup bluetooth profiles */
836         _bt_hidhost_deinitialize();
837         _bt_socket_deinit();
838 #if 0
839         /* TODO: Cleanup bluetooth audio profiles */
840         //_bt_audio_deinitialize(BT_A2DP_SOURCE_MODULE);
841         //_bt_audio_deinitialize(BT_AVRCP_MODULE);
842         //_bt_audio_deinitialize(BT_A2DP_SINK_MODULE);
843         //_bt_audio_deinitialize(BT_AG_MODULE);
844         //_bt_audio_deinitialize(BT_AVRCP_CTRL_MODULE);
845         //_bt_audio_deinitialize(BT_AUDIO_ALL_MODULE);
846 #endif
847         _bt_hdp_deinit();
848         _bt_gatt_deinit();
849
850         return BLUETOOTH_ERROR_NONE;
851 }
852
853 /* OAL post initialization handler */
854 static void __bt_post_oal_init(void)
855 {
856         int ret;
857         int status = VCONFKEY_BT_STATUS_OFF;
858
859         BT_DBG("OAL initialized");
860         if (vconf_get_int(VCONFKEY_BT_STATUS, &status) != 0) {
861                 BT_ERR("Fail to get the enabled value");
862         }
863
864         /* Update Bluetooth Status to OFF */
865         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
866                 BT_ERR("Set vconf failed\n");
867
868         if (status & VCONFKEY_BT_STATUS_ON) {
869                 ret = _bt_enable_adapter();
870                 if (ret != BLUETOOTH_ERROR_NONE)
871                         BT_ERR("_bt_enable_adapter failed with error: %d", ret);
872         }
873 }
874
875 /* OAL initialization handler */
876 static void __bt_handle_oal_initialisation(oal_event_t event)
877 {
878         BT_DBG("");
879
880         switch(event) {
881         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
882                 __bt_post_oal_init();
883                 break;
884         case OAL_EVENT_OAL_INITIALISED_FAILED:
885                 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
886                 g_idle_add(_bt_terminate_service, NULL);
887                 break;
888         default:
889                 BT_ERR("Unknown Event");
890                 break;
891         }
892 }
893
894 static gboolean __bt_is_service_request_present(int service_function)
895 {
896         GSList *l;
897         invocation_info_t *req_info;
898
899         BT_DBG("+");
900
901         /* Get method invocation context */
902         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
903                 req_info = l->data;
904                 if (req_info && req_info->service_function == service_function)
905                         return TRUE;
906         }
907
908         BT_DBG("-");
909         return FALSE;
910 }
911
912 /* Internal functions of core adapter service */
913 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
914 {
915         GSList *l;
916         GArray *out_param;
917         invocation_info_t *req_info;
918         BT_INFO("+");
919
920         /* Get method invocation context */
921         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
922                 req_info = l->data;
923                 if (req_info == NULL || req_info->service_function != service_function)
924                         continue;
925
926                 /* Create out param */
927                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
928
929                 switch(service_function) {
930                 case BT_ENABLE_ADAPTER:
931                 case BT_DISABLE_ADAPTER: {
932                         gboolean done = TRUE;
933                         g_array_append_vals(out_param, &done, sizeof(gboolean));
934                         break;
935                 }
936                 case BT_GET_LOCAL_NAME:
937                 case BT_GET_LOCAL_ADDRESS:
938                 case BT_GET_LOCAL_VERSION:
939                         g_array_append_vals(out_param, user_data, size);
940                         break;
941                 case BT_IS_SERVICE_USED: {
942                         unsigned int i;
943                         gboolean used = FALSE;
944                         unsigned char *uuid;
945                         char uuid_str[BT_UUID_STRING_SIZE];
946                         char *request_uuid = req_info->user_data;
947                         service_uuid_t *service_list = user_data;
948
949                         BT_INFO("Check for service uuid: %s", request_uuid);
950                         for (i = 0; i < size; i++) {
951                                 uuid = service_list[i].uuid;
952                                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
953                                 BT_INFO("Adapter Service: [%s]", uuid_str);
954                                 if (strcasecmp(uuid_str, request_uuid) == 0) {
955                                         BT_INFO("UUID matched!!");
956                                         used = TRUE;
957                                         break;
958                                 }
959                         }
960
961                         g_array_append_vals(out_param, &used, sizeof(gboolean));
962                         break;
963                 }
964                 case BT_GET_BONDED_DEVICES: {
965                         bluetooth_device_address_t *addr_list = user_data;
966                         bonded_devices_req_info_t *bonded_devices_req_info;
967                         char address[BT_ADDRESS_STRING_SIZE];
968                         int count = size;
969                         int res = BLUETOOTH_ERROR_NONE;
970
971                         /*
972                          * BT_GET_BONDED_DEVICES is already processed for this request,
973                          * continue for next BT_GET_BONDED_DEVICES request if any
974                          */
975                         if (NULL != req_info->user_data)
976                                 continue;
977
978                         BT_DBG("BT_GET_BONDED_DEVICES: count = [%d]", count);
979                         /* No bonded devices, return method invocation */
980                         if (0 == count || !addr_list)
981                                 break;
982
983                         /* Save address list in user data  for futur reference. */
984                         bonded_devices_req_info = g_malloc0(sizeof(bonded_devices_req_info));
985                         if (!bonded_devices_req_info) {
986                                 BT_ERR("Memory allocation failed");
987                                 req_info->result = BLUETOOTH_ERROR_MEMORY_ALLOCATION;
988                                 g_free(addr_list);
989                                 break;
990                         }
991
992                         bonded_devices_req_info->count = count;
993                         bonded_devices_req_info->addr_list = addr_list;
994                         bonded_devices_req_info->out_param = out_param;
995                         req_info->user_data = bonded_devices_req_info;
996
997                         while (bonded_devices_req_info->count > 0) {
998                                 bonded_devices_req_info->count -= 1;
999                                 res = _bt_device_get_bonded_device_info(
1000                                                 &addr_list[bonded_devices_req_info->count]);
1001                                 if (BLUETOOTH_ERROR_NONE == res)
1002                                         return;
1003                                 else {
1004                                         _bt_convert_addr_type_to_string((char *)address,
1005                                                         addr_list[bonded_devices_req_info->count].addr);
1006                                         BT_ERR("_bt_device_get_bonded_device_info Failed for [%s]", address);
1007                                         if (bonded_devices_req_info->count == 0) {
1008                                                 g_free(bonded_devices_req_info->addr_list);
1009                                                 g_free(bonded_devices_req_info);
1010                                                 req_info->user_data = NULL;
1011                                         }
1012                                 }
1013                         }
1014                         break;
1015                 }
1016                 default:
1017                         BT_ERR("Unknown service function[%d]", service_function);
1018                 }
1019
1020                 _bt_service_method_return(req_info->context, out_param, req_info->result);
1021                 g_array_free(out_param, TRUE);
1022                 /* Now free invocation info for this request*/
1023                 _bt_free_info_from_invocation_list(req_info);
1024         }
1025 }
1026
1027 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
1028 {
1029         char *phone_name = NULL;
1030         char *ptr = NULL;
1031
1032         if (node == NULL)
1033                 return;
1034
1035         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
1036                 phone_name = vconf_keynode_get_str(node);
1037
1038                 if (phone_name && strlen(phone_name) != 0) {
1039                         if (!g_utf8_validate(phone_name, -1,
1040                                         (const char **)&ptr))
1041                                 *ptr = '\0';
1042
1043                         _bt_set_local_name(phone_name);
1044                 }
1045         }
1046 }
1047
1048 /* Request return handlings */
1049 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
1050 {
1051         BT_INFO("__bt_adapter_post_set_enabled>>");
1052
1053         if (!TIZEN_PROFILE_TV) {
1054                 __bt_set_visible_mode();
1055
1056                 /* add the vconf noti handler */
1057                 if (0 != vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1058                                 (vconf_callback_fn)__bt_phone_name_changed_cb, NULL))
1059                         BT_ERR("DEVICE_NAME key changed notification registration failed");
1060
1061                 __bt_set_local_name();
1062         } else {
1063                 if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
1064                                 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0))
1065                         BT_ERR("Fail to set discoverable mode");
1066         }
1067
1068         /* Get All properties */
1069         if (OAL_STATUS_SUCCESS != adapter_get_properties())
1070                 BT_ERR("adapter_get_properties failed");
1071
1072         /* Add Adapter enabled post processing codes */
1073         return FALSE;
1074 }
1075
1076 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
1077 {
1078         BT_INFO("_bt_adapter_post_set_disabled>>");
1079
1080         if (!TIZEN_PROFILE_TV) {
1081                 /* Add Adapter disabled post processing codes */
1082                 if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1083                                 (vconf_callback_fn)__bt_phone_name_changed_cb) != 0)
1084                         BT_ERR("vconf_ignore_key_changed failed");
1085         }
1086
1087         return FALSE;
1088 }
1089
1090 static void __bt_adapter_update_bt_enabled(void)
1091 {
1092         int result = BLUETOOTH_ERROR_NONE;
1093         BT_INFO("_bt_adapter_update_bt_enabled >> Init profiles...");
1094         if (BLUETOOTH_ERROR_NONE != _bt_init_profiles())
1095                 BT_ERR("Bluetooth profile init failed");
1096
1097         /* Update Bluetooth Status to notify other modules */
1098         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
1099                 BT_ERR("Set vconf failed\n");
1100
1101         /* TODO:Add timer function to handle any further post processing */
1102         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
1103
1104         /*Return BT_ADAPTER_ENABLE Method invocation context */
1105         __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
1106         /*Send BT Enabled event to application */
1107         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
1108                         g_variant_new("(i)", result));
1109 }
1110
1111 static void __bt_adapter_update_bt_disabled(void)
1112 {
1113         int result = BLUETOOTH_ERROR_NONE;
1114         BT_INFO("_bt_adapter_update_bt_disabled >> Cleanup profiles...");
1115         _bt_cleanup_profiles();
1116
1117         int power_off_status = 0;
1118         int ret;
1119
1120         /* Update the vconf BT status in normal Deactivation case only */
1121         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1122         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1123
1124         /* Update Bluetooth Status to notify other modules */
1125         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1126                 BT_ERR("Set vconf failed");
1127
1128         /* TODO:Add timer function to handle any further post processing */
1129         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
1130
1131         /* Return BT_ADAPTER_DISABLE Method invocation context */
1132         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
1133
1134         /* Send BT Disabled event to application */
1135         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1136                         g_variant_new("(i)", result));
1137 }
1138
1139 static void __bt_adapter_state_set_status(bt_status_t status)
1140 {
1141         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1142         adapter_state = status;
1143 }
1144
1145 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
1146 {
1147         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
1148         adapter_discovery_state = status;
1149 }
1150
1151 static void __bt_adapter_state_change_callback(int bt_status)
1152 {
1153         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
1154
1155         switch (bt_status) {
1156         case BT_DEACTIVATED:
1157                 __bt_adapter_state_set_status(bt_status);
1158
1159                 /* Adapter is disabled, unregister event handlers */
1160                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
1161                 //_bt_deinit_device_event_handler();
1162
1163                 /* Add Adapter disabled post processing codes */
1164                 __bt_adapter_update_bt_disabled();
1165                 break;
1166         case BT_ACTIVATED:
1167                 __bt_adapter_state_set_status(bt_status);
1168                 /* Add Adapter enabled post processing codes */
1169                 if (timer_id > 0) {
1170                         BT_DBG("g_source is removed");
1171                         g_source_remove(timer_id);
1172                         timer_id = 0;
1173                 }
1174                 __bt_adapter_update_bt_enabled();
1175                 break;
1176         default:
1177                 BT_ERR("Incorrect Bluetooth adapter state changed status");
1178
1179         }
1180 }
1181
1182 static int __bt_adapter_state_handle_request(gboolean enable)
1183 {
1184         int result = BLUETOOTH_ERROR_NONE;
1185         BT_DBG("");
1186
1187         switch (adapter_state) {
1188         case BT_ACTIVATING: {
1189                 BT_INFO("Adapter is currently in activating state, state [%d]",
1190                                 adapter_state);
1191                 if (enable) {
1192                         return BLUETOOTH_ERROR_IN_PROGRESS;
1193                 } else {
1194                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
1195                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
1196                                 /*TODO Stop Discovery*/
1197                                 if (result != OAL_STATUS_SUCCESS)
1198                                         BT_ERR("Discover stop failed: %d", result);
1199                                 __bt_adapter_update_discovery_status(FALSE);
1200                         }
1201                         result = adapter_disable();
1202                         if (result != OAL_STATUS_SUCCESS) {
1203                                 BT_ERR("adapter_enable failed: [%d]", result);
1204                                 result = BLUETOOTH_ERROR_INTERNAL;
1205                                 /*TODO: perform if anything more needs to be done to handle failure */
1206                         } else {
1207                                 /* TODO: To be handled */
1208                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1209                                 result = BLUETOOTH_ERROR_NONE;
1210                         }
1211                 }
1212                 break;
1213         }
1214         case BT_ACTIVATED: {
1215                 BT_INFO("Adapter is currently in activated state, state [%d]",
1216                                 adapter_state);
1217                 if (enable) {
1218                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1219                 } else {
1220                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
1221                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
1222                                 /*TODO Stop Discovery*/
1223                                 if (result != OAL_STATUS_SUCCESS)
1224                                         BT_ERR("Discover stop failed: %d", result);
1225                                 __bt_adapter_update_discovery_status(FALSE);
1226                         }
1227                         result = adapter_disable();
1228                         if (result != OAL_STATUS_SUCCESS) {
1229                                 BT_ERR("adapter_enable failed: [%d]", result);
1230                                 result = BLUETOOTH_ERROR_INTERNAL;
1231                                 /*TODO: perform if anything more needs to be done to handle failure */
1232                         } else {
1233                                 /* TODO: To be handled */
1234                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1235                                 result = BLUETOOTH_ERROR_NONE;
1236                         }
1237                 }
1238                 break;
1239         }
1240         case BT_DEACTIVATING: {
1241                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
1242                                 adapter_state);
1243                 if (!enable) {
1244                         return BLUETOOTH_ERROR_IN_PROGRESS;
1245
1246                 } else {
1247                         result = adapter_enable();
1248                         if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
1249                                 BT_ERR("adapter_enable failed: [%d]", result);
1250                                 adapter_disable();
1251                                 result = BLUETOOTH_ERROR_INTERNAL;
1252                                 /*TODO: perform if anything more needs to be done to handle failure */
1253                         } else {
1254                                 /* TODO: To be handled */
1255                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1256                                 result = BLUETOOTH_ERROR_NONE;
1257                         }
1258                 }
1259                 break;
1260         }
1261         case BT_DEACTIVATED: {
1262                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
1263                                 adapter_state);
1264                 if (!enable) {
1265                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1266                 } else {
1267                         result = adapter_enable();
1268                         if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
1269                                 BT_ERR("adapter_enable failed: [%d]", result);
1270                                 adapter_disable();
1271                                 result = BLUETOOTH_ERROR_INTERNAL;
1272                                 /*TODO: perform if anything more needs to be done to handle failure */
1273                         } else {
1274                                 /* TODO: To be handled */
1275                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1276                                 result = BLUETOOTH_ERROR_NONE;
1277                         }
1278                 }
1279                 break;
1280         }
1281         default:
1282                 BT_ERR("Unknown state: %d", adapter_state);
1283                 break;
1284         }
1285
1286         if (enable && result == BLUETOOTH_ERROR_NONE) {
1287                 /* Adapter enable request is successful, setup event handlers */
1288                 _bt_service_register_event_handler_callback(
1289                                 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
1290                 _bt_device_state_handle_callback_set_request();
1291         }
1292         return result;
1293 }
1294
1295 static int __bt_adapter_state_discovery_request(gboolean enable,
1296                 unsigned short max_response, unsigned short duration, unsigned int mask)
1297 {
1298         int result = BLUETOOTH_ERROR_NONE;
1299
1300         BT_DBG("+");
1301         switch (adapter_discovery_state) {
1302         case ADAPTER_DISCOVERY_STARTED: {
1303                 BT_INFO("Adapter is currently in discovery started state, state [%d]",
1304                                 adapter_discovery_state);
1305                 if (enable) {
1306                         return BLUETOOTH_ERROR_IN_PROGRESS;
1307                 } else {
1308                         result = adapter_stop_inquiry();
1309                         if (result != OAL_STATUS_SUCCESS) {
1310                                 BT_ERR("Discover stop failed: %d", result);
1311                                 result = BLUETOOTH_ERROR_INTERNAL;
1312                         } else {
1313                                 BT_ERR("Stop Discovery Triggered successfully");
1314                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1315                                 result = BLUETOOTH_ERROR_NONE;
1316                         }
1317                 }
1318                 break;
1319         }
1320         case ADAPTER_DISCOVERY_STARTING: {
1321                 BT_INFO("Adapter is currently in discovery starting state, state [%d]",
1322                                 adapter_discovery_state);
1323                 if (enable) {
1324                         return BLUETOOTH_ERROR_IN_PROGRESS;
1325                 } else {
1326                         result = adapter_stop_inquiry();
1327                         if (result != OAL_STATUS_SUCCESS) {
1328                                 BT_ERR("Discover stop failed: %d", result);
1329                                 result = BLUETOOTH_ERROR_INTERNAL;
1330                         } else {
1331                                 BT_ERR("Stop Discovery Triggered successfully");
1332                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1333                                 result = BLUETOOTH_ERROR_NONE;
1334                         }
1335                 }
1336                 break;
1337         }
1338         case ADAPTER_DISCOVERY_STOPPED: {
1339                 BT_INFO("Adapter is currently in discovery stopped state, state [%d]",
1340                                 adapter_discovery_state);
1341                 if (!enable)
1342                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1343                 else {
1344                         BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
1345                         result = adapter_start_inquiry(duration);
1346                         if (result != OAL_STATUS_SUCCESS) {
1347                                 BT_ERR("Start Discovery failed: %d", result);
1348                                 result = BLUETOOTH_ERROR_INTERNAL;
1349                         } else {
1350                                 BT_ERR("Start Discovery Triggered successfully");
1351                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1352                                 result = BLUETOOTH_ERROR_NONE;
1353                         }
1354                 }
1355                 break;
1356         }
1357         case ADAPTER_DISCOVERY_STOPPING: {
1358                 BT_INFO("Adapter is currently in discovery stopping state, state [%d]",
1359                                 adapter_discovery_state);
1360                 if (!enable)
1361                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1362                 else {
1363                         BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
1364                         result = adapter_start_inquiry(duration);
1365                         if (result != OAL_STATUS_SUCCESS) {
1366                                 BT_ERR("Start Discovery failed: %d", result);
1367                                 result = BLUETOOTH_ERROR_INTERNAL;
1368                         } else {
1369                                 BT_ERR("Start Discovery Triggered successfully");
1370                         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1371                                 result = BLUETOOTH_ERROR_NONE;
1372                         }
1373                 }
1374                 break;
1375         }
1376         default:
1377                 BT_ERR("Unknown state: %d", adapter_discovery_state);
1378                 break;
1379         }
1380
1381         BT_DBG("-");
1382         return result;
1383 }
1384
1385 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status)
1386 {
1387         BT_INFO("__bt_adapter_discovery_state_change_callback: status [%d]", bt_discovery_status);
1388         GVariant *param = NULL;
1389         int result = BLUETOOTH_ERROR_NONE;
1390
1391         switch (bt_discovery_status) {
1392         case ADAPTER_DISCOVERY_STOPPED:
1393         {
1394                 __bt_adapter_update_discovery_status(bt_discovery_status);
1395                 param = g_variant_new("(i)", result);
1396                 _bt_send_event(BT_ADAPTER_EVENT,
1397                                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
1398                                 param);
1399                 break;
1400         }
1401         case ADAPTER_DISCOVERY_STARTED:
1402         {
1403                 __bt_adapter_update_discovery_status(bt_discovery_status);
1404                 param = g_variant_new("(i)", result);
1405                 _bt_send_event(BT_ADAPTER_EVENT,
1406                                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
1407                                 param);
1408                 break;
1409         }
1410         default:
1411                 BT_ERR("Incorrect Bluetooth adapter Discovery state changed status");
1412         }
1413 }
1414
1415 static void __bt_set_visible_mode(void)
1416 {
1417         int timeout = 0;
1418 #ifdef TIZEN_FEATURE_BT_DPM
1419         int discoverable_state = DPM_BT_ERROR;
1420 #endif
1421
1422         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
1423                 BT_ERR("Fail to get the timeout value");
1424
1425 #ifdef TIZEN_FEATURE_BT_DPM
1426         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1427         if (timeout == -1 || discoverable_state == DPM_RESTRICTED) {
1428                 if (_bt_set_discoverable_mode(
1429                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
1430                                         timeout) != BLUETOOTH_ERROR_NONE) {
1431                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
1432                                 BT_ERR("Set vconf failed");
1433                 }
1434         } else {
1435                 if (_bt_set_discoverable_mode(
1436                                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
1437                                         timeout) != BLUETOOTH_ERROR_NONE) {
1438                         BT_ERR("Set connectable mode failed");
1439                 }
1440         }
1441 #else
1442         if (timeout == -1) {
1443                 if (_bt_set_discoverable_mode(
1444                                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
1445                                         timeout) != BLUETOOTH_ERROR_NONE) {
1446                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
1447                                 BT_ERR("Set vconf failed");
1448                 }
1449         } else {
1450                 if (_bt_set_discoverable_mode(
1451                                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
1452                                         timeout) != BLUETOOTH_ERROR_NONE) {
1453                         BT_ERR("Set connectable mode failed");
1454                 }
1455         }
1456 #endif
1457 }
1458
1459 static void __bt_set_local_name(void)
1460 {
1461         char *phone_name = NULL;
1462         char *ptr = NULL;
1463
1464         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1465
1466         if (!phone_name)
1467                 return;
1468
1469         if (strlen(phone_name) != 0) {
1470                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
1471                         *ptr = '\0';
1472
1473                 _bt_set_local_name(phone_name);
1474         }
1475         free(phone_name);
1476 }
1477
1478 void _bt_adapter_set_status(bt_status_t status)
1479 {
1480         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
1481         adapter_state = status;
1482 }
1483
1484 bt_status_t _bt_adapter_get_status(void)
1485 {
1486         return adapter_state;
1487 }
1488
1489 void _bt_set_disabled(int result)
1490 {
1491         int power_off_status = 0;
1492         int ret;
1493         int ret_pm_ignore;
1494         int pm_ignore_mode = 0;
1495
1496         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
1497         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
1498
1499         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
1500
1501         /* Update the vconf BT status in normal Deactivation case only */
1502         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
1503                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
1504
1505                 BT_DBG("Update vconf for BT normal Deactivation");
1506
1507                 if (result == BLUETOOTH_ERROR_TIMEOUT)
1508                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
1509                                 BT_ERR("Set vconf failed");
1510
1511                 /* Update Bluetooth Status to notify other modules */
1512                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1513                         BT_ERR("Set vconf failed");
1514
1515                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
1516                                                         EVT_VAL_BT_OFF) != ES_R_OK)
1517                         BT_ERR("Fail to set value");
1518         }
1519
1520         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
1521                 BT_ERR("Set vconf failed\n");
1522
1523         _bt_cancel_queued_transfers();
1524         _bt_adapter_set_status(BT_DEACTIVATED);
1525         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPED);
1526
1527         BT_INFO("Adapter disabled");
1528 }
1529