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