[Adapt] Send local property changed events to Apps
[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 <syspopup_caller.h>
28 #include <aul.h>
29 #include <eventsystem.h>
30 #include <bundle_internal.h>
31
32 #include "alarm.h"
33
34 /*bt-service headers */
35 #include "bt-internal-types.h"
36 #include "bt-service-common.h"
37 #include "bt-service-util.h"
38 #include "bt-service-main.h"
39 #include "bt-service-core-adapter.h"
40 #include "bt-service-core-device.h"
41 #include "bt-service-event-receiver.h"
42 #include "bt-request-handler.h"
43 #include "bt-service-event.h"
44 #ifdef TIZEN_DPM_ENABLE
45 #include "bt-service-dpm.h"
46 #endif
47
48 /* OAL headers */
49 #include <oal-event.h>
50 #include <oal-manager.h>
51 #include <oal-adapter-mgr.h>
52
53 #define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
54
55 /*This file will contain state machines related to adapter and remote device */
56
57 /* Global variables */
58 typedef struct {
59         guint event_id;
60         int timeout;
61         time_t start_time;
62         gboolean alarm_init;
63         int alarm_id;
64 } bt_adapter_timer_t;
65
66 static bt_adapter_timer_t visible_timer;
67
68 static guint timer_id = 0;
69
70 /* Adapter default states */
71 static bt_status_t adapter_state = BT_DEACTIVATED;
72 static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
73
74 /* Forward declarations */
75 static void __bt_adapter_event_handler(int event_type, gpointer event_data);
76 static void __bt_post_oal_init(void);
77 static void __bt_handle_oal_initialisation(oal_event_t event);
78 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size);
79 static gboolean __bt_adapter_post_set_enabled(gpointer user_data);
80 static gboolean __bt_adapter_post_set_disabled(gpointer user_data);
81 static void __bt_adapter_update_bt_enabled(void);
82 static void __bt_adapter_update_bt_disabled(void);
83 static void __bt_adapter_state_set_status(bt_status_t status);
84 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
85 static void __bt_adapter_state_change_callback(int bt_status);
86 static int __bt_adapter_state_handle_request(gboolean enable);
87 static int __bt_adapter_state_discovery_request(gboolean enable);
88 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status);
89 static gboolean __bt_is_service_request_present(int service_function);
90
91 /* Initialize BT stack (Initialize OAL layer) */
92 int _bt_stack_init(void)
93 {
94         int ret;
95
96         BT_INFO("[bt-service] Start to initialize BT stack");
97         /* Adapter enable request is successful, setup event handlers */
98         _bt_service_register_event_handler_callback(
99                         BT_ADAPTER_MODULE, __bt_adapter_event_handler);
100
101         ret = oal_bt_init(_bt_service_oal_event_receiver);
102
103         if (OAL_STATUS_PENDING == ret) {
104                 BT_INFO("OAL Initialisation Pending, Profiles Init will be done once oal initialised...");
105                 return BLUETOOTH_ERROR_NONE;
106         } else if (OAL_STATUS_SUCCESS != ret) {
107                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
108                 return BLUETOOTH_ERROR_INTERNAL;
109         }
110
111         __bt_post_oal_init();
112         return BLUETOOTH_ERROR_NONE;
113 }
114
115 int _bt_enable_adapter(void)
116 {
117         return __bt_adapter_state_handle_request(TRUE);
118 }
119
120 int _bt_disable_adapter(void)
121 {
122         return __bt_adapter_state_handle_request(FALSE);
123 }
124
125
126 int _bt_start_discovery(void)
127 {
128         return __bt_adapter_state_discovery_request(TRUE);
129 }
130
131 int _bt_cancel_discovery(void)
132 {
133         return __bt_adapter_state_discovery_request(FALSE);
134 }
135
136 gboolean _bt_is_discovering(void)
137 {
138         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED
139                         || adapter_discovery_state == ADAPTER_DISCOVERY_STARTING)
140                 return TRUE;
141         else
142                 return FALSE;
143 }
144
145 int _bt_get_local_address(void)
146 {
147         int result;
148
149         BT_DBG("+");
150
151         result =  adapter_get_address();
152         if (result != OAL_STATUS_SUCCESS) {
153                 BT_ERR("adapter_get_address failed: %d", result);
154                 result = BLUETOOTH_ERROR_INTERNAL;
155         } else
156                 result = BLUETOOTH_ERROR_NONE;
157
158         BT_DBG("-");
159         return result;
160 }
161
162 int _bt_get_local_version(void)
163 {
164         int result;
165         BT_DBG("+");
166
167         result =  adapter_get_version();
168         if (result != OAL_STATUS_SUCCESS) {
169                 BT_ERR("adapter_get_address failed: %d", result);
170                 result = BLUETOOTH_ERROR_INTERNAL;
171         } else
172                 result = BLUETOOTH_ERROR_NONE;
173
174         BT_DBG("-");
175         return result;
176 }
177
178 int _bt_get_local_name(void)
179 {
180         int result;
181
182         BT_DBG("+");
183
184         result =  adapter_get_name();
185         if (result != OAL_STATUS_SUCCESS) {
186                 BT_ERR("adapter_get_name failed: %d", result);
187                 result = BLUETOOTH_ERROR_INTERNAL;
188         } else
189                 result = BLUETOOTH_ERROR_NONE;
190
191         BT_DBG("-");
192         return result;
193 }
194
195 int _bt_set_local_name(char *local_name)
196 {
197         int result = BLUETOOTH_ERROR_NONE;
198         BT_DBG("+");
199
200         retv_if(NULL == local_name, BLUETOOTH_ERROR_INVALID_PARAM);
201
202         result =  adapter_set_name(local_name);
203         if (result != OAL_STATUS_SUCCESS) {
204                 BT_ERR("adapter_set_name 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_discoverable_mode(int *mode)
214 {
215         int scan_mode = 0;
216         int timeout = 0;
217
218         BT_DBG("+");
219
220         retv_if(NULL == mode, BLUETOOTH_ERROR_INVALID_PARAM);
221
222         adapter_is_discoverable(&scan_mode);
223         if (TRUE == scan_mode) {
224                 adapter_get_discoverable_timeout(&timeout);
225                 if (timeout > 0)
226                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
227                 else
228                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
229         } else {
230                 adapter_is_connectable(&scan_mode);
231                 if(scan_mode == TRUE)
232                         *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
233                 else {
234                         /*
235                          * TODO: NON CONNECTABLE is not defined in bluetooth_discoverable_mode_t.
236                          * After adding BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE, set mode as
237                          * BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE. Until then return -1.
238                          */
239                         return -1;
240                 }
241         }
242
243         BT_DBG("-");
244         return BLUETOOTH_ERROR_NONE;
245 }
246
247 int _bt_get_timeout_value(int *timeout)
248 {
249         time_t current_time;
250         int time_diff;
251
252         /* Take current time */
253         time(&current_time);
254         time_diff = difftime(current_time, visible_timer.start_time);
255
256         BT_DBG("Time diff = %d\n", time_diff);
257         *timeout = visible_timer.timeout - time_diff;
258
259         return BLUETOOTH_ERROR_NONE;
260 }
261
262 static void __bt_visibility_alarm_remove()
263 {
264         if (visible_timer.event_id > 0) {
265                 g_source_remove(visible_timer.event_id);
266                 visible_timer.event_id = 0;
267         }
268
269         if (visible_timer.alarm_id > 0) {
270                 alarmmgr_remove_alarm(visible_timer.alarm_id);
271                 visible_timer.alarm_id = 0;
272         }
273 }
274
275 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
276 {
277         int result = BLUETOOTH_ERROR_NONE;
278         int timeout = 0;
279
280         BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
281
282         if (alarm_id != visible_timer.alarm_id)
283                 return 0;
284
285         if (visible_timer.event_id) {
286                 _bt_send_event(BT_ADAPTER_EVENT,
287                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
288                                 g_variant_new("(in)", result, timeout));
289                 g_source_remove(visible_timer.event_id);
290                 visible_timer.event_id = 0;
291                 visible_timer.timeout = 0;
292
293 #ifndef TIZEN_WEARABLE
294                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
295                         BT_ERR("Set vconf failed\n");
296 #endif
297         }
298         /* Switch Off visibility in Bluez */
299         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
300         visible_timer.alarm_id = 0;
301         return 0;
302 }
303
304 static gboolean __bt_timeout_handler(gpointer user_data)
305 {
306         int result = BLUETOOTH_ERROR_NONE;
307         time_t current_time;
308         int time_diff;
309
310         /* Take current time */
311         time(&current_time);
312         time_diff = difftime(current_time, visible_timer.start_time);
313
314         /* Send event to application */
315         _bt_send_event(BT_ADAPTER_EVENT,
316                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
317                         g_variant_new("(in)", result, time_diff));
318
319         if (visible_timer.timeout <= time_diff) {
320                 g_source_remove(visible_timer.event_id);
321                 visible_timer.event_id = 0;
322                 visible_timer.timeout = 0;
323
324 #ifndef TIZEN_WEARABLE
325                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
326                         BT_ERR("Set vconf failed\n");
327 #endif
328                 return FALSE;
329         }
330
331         return TRUE;
332 }
333
334 static void __bt_visibility_alarm_create()
335 {
336         alarm_id_t alarm_id;
337         int result;
338
339         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
340                         0, NULL, &alarm_id);
341         if (result < 0) {
342                 BT_ERR("Failed to create alarm error = %d\n", result);
343         } else {
344                 BT_DBG("Alarm created = %d\n", alarm_id);
345                 visible_timer.alarm_id = alarm_id;
346         }
347 }
348
349 static int __bt_set_visible_time(int timeout)
350 {
351         int result;
352
353         __bt_visibility_alarm_remove();
354
355         visible_timer.timeout = timeout;
356
357 #ifndef TIZEN_WEARABLE
358 #ifdef TIZEN_DPM_ENABLE
359         if (_bt_dpm_get_bluetooth_limited_discoverable_state() != DPM_RESTRICTED) {
360 #endif
361                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
362                         BT_ERR("Set vconf failed");
363 #ifdef TIZEN_DPM_ENABLE
364         }
365 #endif
366 #endif
367
368         if (timeout <= 0)
369                 return BLUETOOTH_ERROR_NONE;
370
371         if (!visible_timer.alarm_init) {
372                 /* Set Alarm timer to switch off BT */
373                 result = alarmmgr_init("bt-service");
374                 if (result != 0)
375                         return BLUETOOTH_ERROR_INTERNAL;
376
377                 visible_timer.alarm_init = TRUE;
378         }
379
380         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
381         if (result != 0)
382                 return BLUETOOTH_ERROR_INTERNAL;
383
384         /* Take start time */
385         time(&(visible_timer.start_time));
386         visible_timer.event_id = g_timeout_add_seconds(1,
387                         __bt_timeout_handler, NULL);
388
389         __bt_visibility_alarm_create();
390
391         return BLUETOOTH_ERROR_NONE;
392 }
393
394 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
395 {
396         int result;
397
398         BT_DBG("+");
399
400         BT_INFO("discoverable_mode: %d, timeout: %d", discoverable_mode, timeout);
401
402 #ifdef TIZEN_DPM_ENABLE
403         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
404                         _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
405                 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE");
406                 return BLUETOOTH_ERROR_ACCESS_DENIED;
407         }
408         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
409                         _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
410                 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT");
411                 return BLUETOOTH_ERROR_ACCESS_DENIED;
412         }
413 #endif
414
415         switch (discoverable_mode) {
416         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
417                 result = adapter_set_connectable(TRUE);
418                 timeout = 0;
419                 break;
420         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
421                 result = adapter_set_discoverable();
422                 timeout = 0;
423                 break;
424         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
425                 result = adapter_set_discoverable();
426                 break;
427         default:
428                 return BLUETOOTH_ERROR_INVALID_PARAM;
429         }
430
431         if (result != OAL_STATUS_SUCCESS) {
432                 BT_ERR("set scan mode failed %d", result);
433                 return BLUETOOTH_ERROR_INTERNAL;
434         }
435
436         result = adapter_set_discoverable_timeout(timeout);
437         if (result != OAL_STATUS_SUCCESS) {
438                 BT_ERR("adapter_set_discoverable_timeout failed %d", result);
439                 return BLUETOOTH_ERROR_INTERNAL;
440         }
441
442         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
443                 timeout = -1;
444
445         result = __bt_set_visible_time(timeout);
446
447         BT_DBG("-");
448         return result;
449 }
450
451 gboolean _bt_is_connectable(void)
452 {
453         int connectable = 0;
454         int result;
455
456         BT_DBG("+");
457
458         adapter_is_connectable(&connectable);
459         if (connectable)
460                 result = TRUE;
461         else
462                 result = FALSE;
463
464         BT_DBG("Connectable: [%s]", result ? "TRUE":"FALSE");
465         BT_DBG("-");
466         return result;
467 }
468
469 int _bt_set_connectable(gboolean connectable)
470 {
471         int result = BLUETOOTH_ERROR_NONE;
472
473         BT_DBG("+");
474         result =  adapter_set_connectable(connectable);
475         if (result != OAL_STATUS_SUCCESS) {
476                 BT_ERR("adapter_get_address failed: %d", result);
477                 result = BLUETOOTH_ERROR_INTERNAL;
478         } else
479                 result = BLUETOOTH_ERROR_NONE;
480
481         BT_DBG("-");
482         return result;
483 }
484
485 int _bt_is_service_used(void)
486 {
487         int result;
488
489         BT_DBG("+");
490
491         result =  adapter_get_service_uuids();
492         if (result != OAL_STATUS_SUCCESS) {
493                 BT_ERR("adapter_get_service_uuids failed: %d", result);
494                 result = BLUETOOTH_ERROR_INTERNAL;
495         } else {
496                 result = BLUETOOTH_ERROR_NONE;
497         }
498
499         BT_DBG("-");
500         return result;
501 }
502
503 int _bt_adapter_get_bonded_devices(void)
504 {
505         int result = BLUETOOTH_ERROR_NONE;
506
507         BT_DBG("+");
508         result =  adapter_get_bonded_devices();
509         if (result != OAL_STATUS_SUCCESS) {
510                 BT_ERR("adapter_get_bonded_devices failed: %d", result);
511                 result = BLUETOOTH_ERROR_INTERNAL;
512         } else
513                 result = BLUETOOTH_ERROR_NONE;
514
515         BT_DBG("-");
516         return result;
517 }
518
519 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
520 {
521         int result = BLUETOOTH_ERROR_NONE;
522
523         BT_DBG("+");
524
525         switch(event_type) {
526         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
527         case OAL_EVENT_OAL_INITIALISED_FAILED:
528                 __bt_handle_oal_initialisation(event_type);
529                 break;
530         case OAL_EVENT_ADAPTER_ENABLED:
531                 __bt_adapter_state_change_callback(BT_ACTIVATED);
532                 break;
533         case OAL_EVENT_ADAPTER_DISABLED:
534                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
535                 break;
536         case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
537                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STARTED);
538                 break;
539         case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
540                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STOPPED);
541                 break;
542         case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
543                 bt_address_t *bd_addr = event_data;
544                 bluetooth_device_address_t local_address;
545
546                 /* Copy data */
547                 memcpy(local_address.addr, bd_addr->addr, BT_ADDRESS_LENGTH_MAX);
548                 BT_DBG("Adapter address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]",
549                                 local_address.addr[0], local_address.addr[1], local_address.addr[2],
550                                 local_address.addr[3], local_address.addr[4], local_address.addr[5]);
551
552                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
553                                 (void *) &local_address, sizeof(bluetooth_device_address_t));
554                 break;
555         }
556         case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
557                 char *name = event_data;
558                 BT_DBG("Adapter Name: %s", name);
559
560                 if (__bt_is_service_request_present(BT_GET_LOCAL_NAME)) {
561                         bluetooth_device_name_t local_name;
562
563                         memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
564                         g_strlcpy(local_name.name,
565                                 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
566                         __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
567                                 (void *) &local_name, sizeof(bluetooth_device_name_t));
568                 } else {
569                         /* Send event to application */
570                         _bt_send_event(BT_ADAPTER_EVENT,
571                                         BLUETOOTH_EVENT_LOCAL_NAME_CHANGED,
572                                         g_variant_new("(is)", result, name));
573                 }
574                 break;
575         }
576         case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
577                 char *ver = event_data;
578                 bluetooth_version_t local_version;
579
580                 memset(&local_version, 0x00, sizeof(bluetooth_version_t));
581                 g_strlcpy(local_version.version,
582                                 (const gchar *)ver, BLUETOOTH_VERSION_LENGTH_MAX);
583                 BT_DBG("BT Version: %s", local_version.version);
584
585                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
586                                 (void *) &local_version, sizeof(bluetooth_version_t));
587                 break;
588         }
589         case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
590                 int mode = -1;
591                 gboolean connectable = FALSE;
592
593                 BT_INFO("Adapter discoverable mode:"
594                                 " BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
595                 _bt_send_event(BT_ADAPTER_EVENT,
596                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
597                                 g_variant_new("(b)", connectable));
598
599                 _bt_send_event(BT_ADAPTER_EVENT,
600                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
601                                 g_variant_new("(in)", result, mode));
602                 break;
603         }
604         case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
605                 int mode;
606                 gboolean connectable = TRUE;
607
608                 BT_INFO("Adapter discoverable mode:"
609                                 " BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
610                 _bt_send_event(BT_ADAPTER_EVENT,
611                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
612                                 g_variant_new("(b)", connectable));
613
614                 mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
615                 _bt_send_event(BT_ADAPTER_EVENT,
616                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
617                                 g_variant_new("(in)", result, mode));
618                 break;
619         }
620         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
621                 int mode;
622
623                 BT_INFO("Adapter discoverable mode:"
624                                 " BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
625
626                 /* Send event to application */
627                 mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
628                 _bt_send_event(BT_ADAPTER_EVENT,
629                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
630                                 g_variant_new("(in)", result, mode));
631
632                 break;
633         }
634         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
635                 int *timeout = event_data;
636                 int mode;
637
638                 BT_INFO("Discoverable timeout: [%d]", *timeout);
639
640                 /* Send event to application */
641                 _bt_get_discoverable_mode(&mode);
642                 _bt_send_event(BT_ADAPTER_EVENT,
643                                 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
644                                 g_variant_new("(in)", result, mode));
645                 break;
646         }
647         case OAL_EVENT_ADAPTER_PROPERTY_SERVICES: {
648                 int count;
649                 service_uuid_t *service_list;
650                 event_adapter_services_t *list = event_data;
651
652                 count = list->num;
653                 service_list = list->service_list;
654                 __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
655                 break;
656         }
657         case OAL_EVENT_ADAPTER_BONDED_DEVICE_LIST: {
658                 int i;
659                 int count;
660                 bluetooth_device_address_t *addr_list;
661
662                 event_device_list_t *bonded_device_list = event_data;
663                 count = bonded_device_list->num;
664
665                 addr_list = g_malloc0(count * sizeof(bluetooth_device_address_t));
666                 for (i = 0; i < count; i++) {
667                         memcpy(addr_list[i].addr,
668                                         bonded_device_list->devices[i].addr,
669                                         BLUETOOTH_ADDRESS_LENGTH);
670                 }
671
672                 __bt_adapter_handle_pending_requests(BT_GET_BONDED_DEVICES,
673                                 (void *)addr_list, bonded_device_list->num);
674                 break;
675         }
676         default:
677                 BT_ERR("Unhandled event..");
678                 break;
679         }
680
681         BT_DBG("-");
682 }
683
684 /* OAL post initialization handler */
685 static void __bt_post_oal_init(void)
686 {
687         BT_DBG("OAL initialized, Init profiles..");
688         /*TODO */
689         return;
690 }
691
692 /* OAL initialization handler */
693 static void __bt_handle_oal_initialisation(oal_event_t event)
694 {
695         BT_DBG("");
696
697         switch(event) {
698         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
699                 __bt_post_oal_init();
700                 break;
701         case OAL_EVENT_OAL_INITIALISED_FAILED:
702                 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
703                 g_idle_add(_bt_terminate_service, NULL);
704                 break;
705         default:
706                 BT_ERR("Unknown Event");
707                 break;
708         }
709 }
710
711 static gboolean __bt_is_service_request_present(int service_function)
712 {
713         GSList *l;
714         invocation_info_t *req_info;
715
716         BT_DBG("+");
717
718         /* Get method invocation context */
719         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
720                 req_info = l->data;
721                 if (!req_info && req_info->service_function == service_function)
722                         return TRUE;
723         }
724
725         BT_DBG("-");
726         return FALSE;
727 }
728
729 /* Internal functions of core adapter service */
730 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
731 {
732         GSList *l;
733         GArray *out_param;
734         invocation_info_t *req_info;
735         BT_INFO("+");
736
737         /* Get method invocation context */
738         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
739                 req_info = l->data;
740                 if (req_info == NULL || req_info->service_function != service_function)
741                         continue;
742
743                 /* Create out param */
744                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
745
746                 switch(service_function) {
747                 case BT_ENABLE_ADAPTER:
748                 case BT_DISABLE_ADAPTER: {
749                         gboolean done = TRUE;
750                         g_array_append_vals(out_param, &done, sizeof(gboolean));
751                         break;
752                 }
753                 case BT_GET_LOCAL_NAME:
754                 case BT_GET_LOCAL_ADDRESS:
755                 case BT_GET_LOCAL_VERSION:
756                         g_array_append_vals(out_param, user_data, size);
757                         break;
758                 case BT_IS_SERVICE_USED: {
759                         int i;
760                         gboolean used = FALSE;
761                         unsigned char *uuid;
762                         char uuid_str[BT_UUID_STRING_SIZE];
763                         char *request_uuid = req_info->user_data;
764                         service_uuid_t *service_list = user_data;
765
766                         BT_INFO("Check for service uuid: %s", request_uuid);
767                         for (i = 0; i < size; i++) {
768                                 uuid = service_list[i].uuid;
769                                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
770                                 BT_INFO("Adapter Service: [%s]", uuid_str);
771                                 if (strcasecmp(uuid_str, request_uuid) == 0) {
772                                         BT_INFO("UUID matched!!");
773                                         used = TRUE;
774                                         break;
775                                 }
776                         }
777
778                         g_array_append_vals(out_param, &used, sizeof(gboolean));
779                         break;
780                 }
781                 case BT_GET_BONDED_DEVICES: {
782                         bluetooth_device_address_t *addr_list = user_data;
783                         bonded_devices_req_info_t *bonded_devices_req_info;
784                         char address[BT_ADDRESS_STRING_SIZE];
785                         int count = size;
786                         int res = BLUETOOTH_ERROR_NONE;
787
788                         /*
789                          * BT_GET_BONDED_DEVICES is already processed for this request,
790                          * continue for next BT_GET_BONDED_DEVICES request if any
791                          */
792                         if (NULL != req_info->user_data)
793                                 continue;
794
795                         BT_DBG("BT_GET_BONDED_DEVICES: count = [%d]", count);
796                         /* No bonded devices, return method invocation */
797                         if (0 == count || !addr_list)
798                                 break;
799
800                         /* Save address list in user data  for futur reference. */
801                         bonded_devices_req_info = g_malloc0(sizeof(bonded_devices_req_info));
802                         if (!bonded_devices_req_info) {
803                                 BT_ERR("Memory allocation failed");
804                                 req_info->result = BLUETOOTH_ERROR_MEMORY_ALLOCATION;
805                                 g_free(addr_list);
806                                 break;
807                         }
808
809                         bonded_devices_req_info->count = count;
810                         bonded_devices_req_info->addr_list = addr_list;
811                         bonded_devices_req_info->out_param = out_param;
812                         req_info->user_data = bonded_devices_req_info;
813
814                         while (bonded_devices_req_info->count > 0) {
815                                 bonded_devices_req_info->count -= 1;
816                                 res = _bt_device_get_bonded_device_info(
817                                                 &addr_list[bonded_devices_req_info->count]);
818                                 if (BLUETOOTH_ERROR_NONE == res)
819                                         return;
820                                 else {
821                                         _bt_convert_addr_type_to_string((char *)address,
822                                                         addr_list[bonded_devices_req_info->count].addr);
823                                         BT_ERR("_bt_device_get_bonded_device_info Failed for [%s]", address);
824                                         if (bonded_devices_req_info->count == 0) {
825                                                 g_free(bonded_devices_req_info->addr_list);
826                                                 g_free(bonded_devices_req_info);
827                                                 req_info->user_data = NULL;
828                                         }
829                                 }
830                         }
831                         break;
832                 }
833                 default:
834                         BT_ERR("Unknown service function[%d]", service_function);
835                 }
836
837                 _bt_service_method_return(req_info->context, out_param, req_info->result);
838                 g_array_free(out_param, TRUE);
839                 /* Now free invocation info for this request*/
840                 _bt_free_info_from_invocation_list(req_info);
841         }
842 }
843
844 /* Request return handlings */
845 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
846 {
847         BT_INFO("__bt_adapter_post_set_enabled>>");
848         /*TODO Get All properties */
849         /* Add Adapter enabled post processing codes */
850         return FALSE;
851 }
852
853 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
854 {
855         BT_INFO("_bt_adapter_post_set_disabled>>");
856         /* Add Adapter disabled post processing codes */
857         return FALSE;
858 }
859
860 static void __bt_adapter_update_bt_enabled(void)
861 {
862         int result = BLUETOOTH_ERROR_NONE;
863         BT_INFO("_bt_adapter_update_bt_enabled>>");
864         /* Update Bluetooth Status to notify other modules */
865         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
866                 BT_ERR("Set vconf failed\n");
867
868         /* TODO:Add timer function to handle any further post processing */
869         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
870
871         /*Return BT_ADAPTER_ENABLE Method invocation context */
872         __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
873         /*Send BT Enabled event to application */
874         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
875                         g_variant_new("(i)", result));
876 }
877
878 static void __bt_adapter_update_bt_disabled(void)
879 {
880         int result = BLUETOOTH_ERROR_NONE;
881         BT_INFO("_bt_adapter_update_bt_disabled>>");
882
883         int power_off_status = 0;
884         int ret;
885
886         /* Update the vconf BT status in normal Deactivation case only */
887         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
888         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
889
890         /* TODO:Add timer function to handle any further post processing */
891         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
892
893         /* Return BT_ADAPTER_DISABLE Method invocation context */
894         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
895
896         /* Send BT Disabled event to application */
897         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
898                         g_variant_new("(i)", result));
899 }
900
901
902 static void __bt_adapter_state_set_status(bt_status_t status)
903 {
904         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
905         adapter_state = status;
906 }
907
908 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
909 {
910         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
911         adapter_discovery_state = status;
912 }
913
914 static void __bt_adapter_state_change_callback(int bt_status)
915 {
916         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
917
918         switch (bt_status) {
919         case BT_DEACTIVATED:
920                 __bt_adapter_state_set_status(bt_status);
921
922                 /* Adapter is disabled, unregister event handlers */
923                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
924                 //_bt_deinit_device_event_handler();
925
926                 /* Add Adapter disabled post processing codes */
927                 __bt_adapter_update_bt_disabled();
928                 break;
929         case BT_ACTIVATED:
930                 __bt_adapter_state_set_status(bt_status);
931                 /* Add Adapter enabled post processing codes */
932                 if (timer_id > 0) {
933                         BT_DBG("g_source is removed");
934                         g_source_remove(timer_id);
935                         timer_id = 0;
936                 }
937                 __bt_adapter_update_bt_enabled();
938                 break;
939         default:
940                 BT_ERR("Incorrect Bluetooth adapter state changed status");
941
942         }
943 }
944
945 static int __bt_adapter_state_handle_request(gboolean enable)
946 {
947         int result = BLUETOOTH_ERROR_NONE;
948         BT_DBG("");
949
950         switch (adapter_state) {
951         case BT_ACTIVATING:
952         {
953                 BT_INFO("Adapter is currently in activating state, state [%d]",
954                                 adapter_state);
955                 if (enable) {
956                         return BLUETOOTH_ERROR_IN_PROGRESS;
957                 } else {
958                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
959                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
960                                 /*TODO Stop Discovery*/
961                                 if (result != OAL_STATUS_SUCCESS)
962                                         BT_ERR("Discover stop failed: %d", result);
963                                 __bt_adapter_update_discovery_status(FALSE);
964                         }
965                         result = adapter_disable();
966                         if (result != OAL_STATUS_SUCCESS) {
967                                 BT_ERR("adapter_enable failed: [%d]", result);
968                                 result = BLUETOOTH_ERROR_INTERNAL;
969                                 /*TODO: perform if anything more needs to be done to handle failure */
970                         } else {
971                                 /* TODO: To be handled */
972                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
973                                 result = BLUETOOTH_ERROR_NONE;
974                         }
975                 }
976                 break;
977         }
978         case BT_ACTIVATED:
979         {
980                 BT_INFO("Adapter is currently in activated state, state [%d]",
981                                 adapter_state);
982                 if (enable) {
983                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
984                 } else {
985                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
986                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
987                                 /*TODO Stop Discovery*/
988                                 if (result != OAL_STATUS_SUCCESS)
989                                         BT_ERR("Discover stop failed: %d", result);
990                                 __bt_adapter_update_discovery_status(FALSE);
991                         }
992                         result = adapter_disable();
993                         if (result != OAL_STATUS_SUCCESS) {
994                                 BT_ERR("adapter_enable failed: [%d]", result);
995                                 result = BLUETOOTH_ERROR_INTERNAL;
996                                 /*TODO: perform if anything more needs to be done to handle failure */
997                         } else {
998                                 /* TODO: To be handled */
999                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
1000                                 result = BLUETOOTH_ERROR_NONE;
1001                         }
1002                 }
1003                 break;
1004         }
1005         case BT_DEACTIVATING:
1006         {
1007                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
1008                                 adapter_state);
1009                 if (!enable) {
1010                         return BLUETOOTH_ERROR_IN_PROGRESS;
1011
1012                 } else {
1013                         result = adapter_enable();
1014                         if (result != OAL_STATUS_SUCCESS) {
1015                                 BT_ERR("adapter_enable failed: [%d]", result);
1016                                 adapter_disable();
1017                                 result = BLUETOOTH_ERROR_INTERNAL;
1018                                 /*TODO: perform if anything more needs to be done to handle failure */
1019                         } else {
1020                                 /* TODO: To be handled */
1021                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1022                                 result = BLUETOOTH_ERROR_NONE;
1023                         }
1024                 }
1025                 break;
1026         }
1027         case BT_DEACTIVATED:
1028         {
1029                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
1030                                 adapter_state);
1031                 if (!enable) {
1032                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1033                 } else {
1034                         result = adapter_enable();
1035                         if (result != OAL_STATUS_SUCCESS) {
1036                                 BT_ERR("adapter_enable failed: [%d]", result);
1037                                 adapter_disable();
1038                                 result = BLUETOOTH_ERROR_INTERNAL;
1039                                 /*TODO: perform if anything more needs to be done to handle failure */
1040                         } else {
1041                                 /* TODO: To be handled */
1042                                 __bt_adapter_state_set_status(BT_ACTIVATING);
1043                                 result = BLUETOOTH_ERROR_NONE;
1044                         }
1045                 }
1046                 break;
1047         }
1048         }
1049         if (enable && result == BLUETOOTH_ERROR_NONE) {
1050                 /* Adapter enable request is successful, setup event handlers */
1051                 _bt_service_register_event_handler_callback(
1052                                 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
1053                 _bt_device_state_handle_callback_set_request();
1054         }
1055         return result;
1056 }
1057
1058 static int __bt_adapter_state_discovery_request(gboolean enable)
1059 {
1060         int result = BLUETOOTH_ERROR_NONE;
1061
1062         BT_DBG("+");
1063         switch (adapter_discovery_state) {
1064         case ADAPTER_DISCOVERY_STARTED: {
1065                 BT_INFO("Adapter is currently in discovery started state, state [%d]",
1066                                 adapter_discovery_state);
1067                 if (enable) {
1068                         return BLUETOOTH_ERROR_IN_PROGRESS;
1069                 } else {
1070                         result = adapter_stop_inquiry();
1071                         if (result != OAL_STATUS_SUCCESS) {
1072                                 BT_ERR("Discover stop failed: %d", result);
1073                                 result = BLUETOOTH_ERROR_INTERNAL;
1074                         } else {
1075                                 BT_ERR("Stop Discovery Triggered successfully");
1076                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1077                                 result = BLUETOOTH_ERROR_NONE;
1078                         }
1079                 }
1080                 break;
1081         }
1082         case ADAPTER_DISCOVERY_STARTING: {
1083                 BT_INFO("Adapter is currently in discovery starting state, state [%d]",
1084                                 adapter_discovery_state);
1085                 if (enable) {
1086                         return BLUETOOTH_ERROR_IN_PROGRESS;
1087                 } else {
1088                         result = adapter_stop_inquiry();
1089                         if (result != OAL_STATUS_SUCCESS) {
1090                                 BT_ERR("Discover stop failed: %d", result);
1091                                 result = BLUETOOTH_ERROR_INTERNAL;
1092                         } else {
1093                                 BT_ERR("Stop Discovery Triggered successfully");
1094                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
1095                                 result = BLUETOOTH_ERROR_NONE;
1096                         }
1097                 }
1098                 break;
1099         }
1100         case ADAPTER_DISCOVERY_STOPPED: {
1101                 BT_INFO("Adapter is currently in discovery stopped state, state [%d]",
1102                                 adapter_discovery_state);
1103                 if (!enable)
1104                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1105                 else {
1106                         result = adapter_start_inquiry();
1107                 if (result != OAL_STATUS_SUCCESS) {
1108                                 BT_ERR("Start Discovery failed: %d", result);
1109                                 result = BLUETOOTH_ERROR_INTERNAL;
1110                         } else {
1111                                 BT_ERR("Start Discovery Triggered successfully");
1112                         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1113                                 result = BLUETOOTH_ERROR_NONE;
1114                         }
1115                 }
1116                 break;
1117         }
1118         case ADAPTER_DISCOVERY_STOPPING: {
1119                 BT_INFO("Adapter is currently in discovery stopping state, state [%d]",
1120                                 adapter_discovery_state);
1121                 if (!enable)
1122                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1123                 else {
1124                         result = adapter_start_inquiry();
1125                         if (result != OAL_STATUS_SUCCESS) {
1126                                 BT_ERR("Start Discovery failed: %d", result);
1127                                 result = BLUETOOTH_ERROR_INTERNAL;
1128                         } else {
1129                                 BT_ERR("Start Discovery Triggered successfully");
1130                         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
1131                                 result = BLUETOOTH_ERROR_NONE;
1132                         }
1133                 }
1134                 break;
1135         }
1136         }
1137
1138         BT_DBG("-");
1139         return result;
1140 }
1141
1142 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status)
1143 {
1144         BT_INFO("__bt_adapter_discovery_state_change_callback: status [%d]", bt_discovery_status);
1145         GVariant *param = NULL;
1146         int result = BLUETOOTH_ERROR_NONE;
1147
1148         switch (bt_discovery_status) {
1149         case ADAPTER_DISCOVERY_STOPPED:
1150         {
1151                 __bt_adapter_update_discovery_status(bt_discovery_status);
1152                 param = g_variant_new("(i)", result);
1153                 _bt_send_event(BT_ADAPTER_EVENT,
1154                                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
1155                                 param);
1156                 break;
1157         }
1158         case ADAPTER_DISCOVERY_STARTED:
1159         {
1160                 __bt_adapter_update_discovery_status(bt_discovery_status);
1161                 param = g_variant_new("(i)", result);
1162                 _bt_send_event(BT_ADAPTER_EVENT,
1163                                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
1164                                 param);
1165                 break;
1166         }
1167         default:
1168                 BT_ERR("Incorrect Bluetooth adapter Discovery state changed status");
1169         }
1170 }