Fix : Some properties of adapter couldn't be handled
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-emul / bt-service-adapter.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <alarm.h>
19 #include <vconf.h>
20 #include <bundle.h>
21 #include <eventsystem.h>
22
23 #include "bluetooth-api.h"
24 #include "bt-internal-types.h"
25
26 #include "bt-service-common.h"
27 #include "bt-service-event.h"
28 #include "bt-service-event-manager.h"
29 #include "bt-service-adapter.h"
30 #include "bt-service-util.h"
31 #include "bt-service-main.h"
32
33 typedef struct {
34         guint event_id;
35         int timeout;
36         time_t start_time;
37         gboolean alarm_init;
38         int alarm_id;
39 } bt_adapter_timer_t;
40
41 bt_adapter_timer_t visible_timer = {0, };
42
43 static gboolean is_discovering;
44 static gboolean cancel_by_user;
45 static bt_status_t adapter_status = BT_DEACTIVATED;
46 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
47 static guint timer_id = 0;
48 static guint le_timer_id = 0;
49
50 static uint status_reg_id;
51
52 static char *g_local_name;
53 static gboolean g_is_discoverable;
54 static int found_cnt;
55
56 #define BT_DISABLE_TIME 500 /* 500 ms */
57 #define BT_DEFAULT_NAME "Tizen Emulator"
58
59 static gboolean __bt_adapter_enable_cb(gpointer user_data);
60 static gboolean __bt_adapter_disable_cb(gpointer user_data);
61
62 static gboolean __bt_timeout_handler(gpointer user_data)
63 {
64         int result = BLUETOOTH_ERROR_NONE;
65         time_t current_time;
66         int time_diff;
67
68         /* Take current time */
69         time(&current_time);
70         time_diff = difftime(current_time, visible_timer.start_time);
71
72         /* Send event to application */
73         _bt_send_event(BT_ADAPTER_EVENT,
74                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
75                         g_variant_new("(in)", result, time_diff));
76
77         if (visible_timer.timeout <= time_diff) {
78                 g_source_remove(visible_timer.event_id);
79                 visible_timer.event_id = 0;
80                 visible_timer.timeout = 0;
81
82                 if (!TIZEN_PROFILE_WEARABLE) {
83                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
84                                 BT_ERR("Set vconf failed\n");
85                 }
86                 return FALSE;
87         }
88
89         return TRUE;
90 }
91
92 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
93 {
94         BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
95
96         int result = BLUETOOTH_ERROR_NONE;
97         int timeout = 0;
98
99         if (alarm_id != visible_timer.alarm_id)
100                 return 0;
101
102         if (visible_timer.event_id) {
103                 _bt_send_event(BT_ADAPTER_EVENT,
104                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
105                                 g_variant_new("(in)", result, timeout));
106                 g_source_remove(visible_timer.event_id);
107                 visible_timer.event_id = 0;
108                 visible_timer.timeout = 0;
109
110                 if (!TIZEN_PROFILE_WEARABLE) {
111                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
112                                 BT_ERR("Set vconf failed\n");
113                 }
114         }
115         /* Switch Off visibility in Bluez */
116         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
117         visible_timer.alarm_id = 0;
118         return 0;
119 }
120
121 static void __bt_visibility_alarm_create()
122 {
123         alarm_id_t alarm_id;
124         int result;
125
126         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
127                                                 0, NULL, &alarm_id);
128         if (result < 0) {
129                 BT_ERR("Failed to create alarm error = %d\n", result);
130         } else {
131                 BT_DBG("Alarm created = %d\n", alarm_id);
132                 visible_timer.alarm_id = alarm_id;
133         }
134 }
135
136 static void __bt_visibility_alarm_remove()
137 {
138         if (visible_timer.event_id > 0) {
139                 g_source_remove(visible_timer.event_id);
140                 visible_timer.event_id = 0;
141         }
142
143         if (visible_timer.alarm_id > 0) {
144                 alarmmgr_remove_alarm(visible_timer.alarm_id);
145                 visible_timer.alarm_id = 0;
146         }
147 }
148
149 int __bt_set_visible_time(int timeout)
150 {
151         int result;
152
153         __bt_visibility_alarm_remove();
154
155         visible_timer.timeout = timeout;
156
157         if (!TIZEN_PROFILE_WEARABLE) {
158                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
159                         BT_ERR("Set vconf failed");
160         }
161
162         if (timeout <= 0)
163                 return BLUETOOTH_ERROR_NONE;
164
165         if (!visible_timer.alarm_init) {
166                 /* Set Alarm timer to switch off BT */
167                 result = alarmmgr_init("bt-service");
168                 if (result != 0)
169                         return BLUETOOTH_ERROR_INTERNAL;
170
171                 visible_timer.alarm_init = TRUE;
172         }
173
174         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
175         if (result != 0)
176                 return BLUETOOTH_ERROR_INTERNAL;
177
178         /* Take start time */
179         time(&(visible_timer.start_time));
180         visible_timer.event_id = g_timeout_add_seconds(1,
181                                 __bt_timeout_handler, NULL);
182
183         __bt_visibility_alarm_create();
184
185         return BLUETOOTH_ERROR_NONE;
186 }
187
188 void _bt_set_discovery_status(gboolean mode)
189 {
190         is_discovering = mode;
191 }
192
193 void _bt_set_cancel_by_user(gboolean value)
194 {
195         cancel_by_user = value;
196 }
197
198 gboolean _bt_get_cancel_by_user(void)
199 {
200         return cancel_by_user;
201 }
202
203 void _bt_adapter_set_status(bt_status_t status)
204 {
205         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
206         adapter_status = status;
207 }
208
209 bt_status_t _bt_adapter_get_status(void)
210 {
211         return adapter_status;
212 }
213
214 void _bt_adapter_set_le_status(bt_le_status_t status)
215 {
216         BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
217         adapter_le_status = status;
218 }
219
220 bt_le_status_t _bt_adapter_get_le_status(void)
221 {
222         return adapter_le_status;
223 }
224
225 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
226 {
227         char *phone_name = NULL;
228         char *ptr = NULL;
229
230         if (node == NULL)
231                 return;
232
233         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
234                 phone_name = vconf_keynode_get_str(node);
235
236                 if (phone_name && strlen(phone_name) != 0) {
237                         if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
238                                 *ptr = '\0';
239
240                         _bt_set_local_name(phone_name);
241                 }
242         }
243 }
244
245 static void __bt_set_visible_mode(void)
246 {
247         int timeout = 0;
248
249         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
250                 BT_ERR("Fail to get the timeout value");
251
252         if (timeout == -1) {
253                 if (_bt_set_discoverable_mode(
254                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
255                         timeout) != BLUETOOTH_ERROR_NONE) {
256                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
257                                 BT_ERR("Set vconf failed");
258                 }
259         } else {
260                 if (_bt_set_discoverable_mode(
261                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
262                         timeout) != BLUETOOTH_ERROR_NONE) {
263                                 BT_ERR("Set connectable mode failed");
264                 }
265         }
266 }
267
268 static void __bt_set_local_name(void)
269 {
270         char *phone_name = NULL;
271         char *ptr = NULL;
272
273         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
274
275         if (!phone_name)
276                 return;
277
278         if (strlen(phone_name) != 0) {
279                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
280                         *ptr = '\0';
281
282                 _bt_set_local_name(phone_name);
283         }
284         free(phone_name);
285 }
286
287 static int __bt_set_enabled(void)
288 {
289         BT_DBG("+");
290         int result = BLUETOOTH_ERROR_NONE;
291
292         if (TIZEN_PROFILE_MOBILE) {
293                 __bt_set_visible_mode();
294         } else if (TIZEN_PROFILE_TV) {
295                 if (_bt_set_discoverable_mode(
296                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
297                                 BT_ERR("Fail to set discoverable mode");
298         }
299         __bt_set_local_name();
300
301         /* Update Bluetooth Status to notify other modules */
302         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
303                 BT_ERR("Set vconf failed\n");
304
305         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
306                 BT_ERR("Set vconf failed\n");
307 #if 0
308         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
309                                                 EVT_VAL_BT_ON) != ES_R_OK)
310                 BT_ERR("Fail to set value");
311 #endif
312
313         /* Send enabled event to API */
314         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
315                                 g_variant_new("(i)", result));
316         BT_DBG("-");
317
318         return BLUETOOTH_ERROR_NONE;
319 }
320
321 void _bt_set_disabled(int result)
322 {
323         int power_off_status = 0;
324         int ret;
325         int ret_pm_ignore;
326         int pm_ignore_mode = 0;
327
328         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
329         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
330
331         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
332
333         /* Update the vconf BT status in normal Deactivation case only */
334         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
335                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
336
337                 BT_DBG("Update vconf for BT normal Deactivation");
338
339                 if (result == BLUETOOTH_ERROR_TIMEOUT)
340                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
341                                 BT_ERR("Set vconf failed");
342
343                 /* Update Bluetooth Status to notify other modules */
344                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
345                         BT_ERR("Set vconf failed");
346
347                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
348                                                         EVT_VAL_BT_OFF) != ES_R_OK)
349                         BT_ERR("Fail to set value");
350         }
351
352         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
353                 BT_ERR("Set vconf failed\n");
354
355         _bt_adapter_set_status(BT_DEACTIVATED);
356
357         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
358                         g_variant_new("(i)", result));
359
360         BT_INFO("Adapter disabled");
361 }
362
363 static int __bt_set_le_enabled(void)
364 {
365         BT_DBG("+");
366         int result = BLUETOOTH_ERROR_NONE;
367         bt_status_t status;
368
369         __bt_set_local_name();
370
371         /* Update Bluetooth Status to notify other modules */
372         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
373                 BT_ERR("Set vconf failed\n");
374
375         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
376                                                 EVT_VAL_BT_LE_ON) != ES_R_OK)
377                 BT_ERR("Fail to set value");
378
379         /* Send enabled event to API */
380         /*
381         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
382                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
383         */
384         status = _bt_adapter_get_status();
385         if (status == BT_DEACTIVATED) {
386                 BT_INFO("BREDR is off, turn off PSCAN");
387                 _bt_set_connectable(FALSE);
388         }
389         if (le_timer_id > 0) {
390                 g_source_remove(le_timer_id);
391                 le_timer_id = 0;
392         }
393
394         /* Send enabled event to API */
395         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
396                                 g_variant_new("(i)", result));
397
398         BT_DBG("-");
399         return BLUETOOTH_ERROR_NONE;
400 }
401
402 void _bt_set_le_disabled(int result)
403 {
404         int power_off_status;
405         int ret;
406
407         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
408         BT_DBG("ret : %d", ret);
409         BT_DBG("power_off_status : %d", power_off_status);
410
411         /* Update Bluetooth Status to notify other modules */
412         BT_DBG("Update vconf for BT LE normal Deactivation");
413         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
414                 BT_ERR("Set vconf failed\n");
415         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
416
417         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
418                                                 EVT_VAL_BT_LE_OFF) != ES_R_OK)
419                 BT_ERR("Fail to set value");
420
421         /* Send disabled event */
422         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
423                         g_variant_new_int32(result));
424 }
425
426 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
427 {
428         gboolean flight_mode = FALSE;
429         int power_saving_mode = 0;
430         int type;
431
432         DBG_SECURE("key=%s", vconf_keynode_get_name(node));
433         type = vconf_keynode_get_type(node);
434         if (type == VCONF_TYPE_BOOL) {
435                 flight_mode = vconf_keynode_get_bool(node);
436                 if (flight_mode != TRUE) {
437                         BT_ERR("Ignore the event");
438                         return;
439                 }
440         } else if (type == VCONF_TYPE_INT) {
441                 power_saving_mode = vconf_keynode_get_int(node);
442                 if (power_saving_mode != 2) {
443                         BT_ERR("Ignore the event");
444                         return;
445                 }
446         } else {
447                 BT_ERR("Invaild vconf key type : %d", type);
448                 return;
449         }
450 }
451
452 void _bt_service_register_vconf_handler(void)
453 {
454         BT_DBG("+");
455
456         if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
457                 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
458                                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
459                         BT_ERR("Unable to register key handler");
460         } else {
461                 BT_DBG("Telephony is disabled");
462         }
463
464 #ifdef ENABLE_TIZEN_2_4
465         if (!TIZEN_PROFILE_WEARABLE && vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
466                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
467                 BT_ERR("Unable to register key handler");
468 #endif
469 }
470
471 void _bt_service_unregister_vconf_handler(void)
472 {
473         BT_DBG("+");
474
475         if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
476                 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
477                                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
478         }
479
480 #ifdef ENABLE_TIZEN_2_4
481         if (!TIZEN_PROFILE_WEARABLE)
482                 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
483                                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
484 #endif
485 }
486
487 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
488 {
489 #ifdef ENABLE_TIZEN_2_4
490         const char *bt_status = NULL;
491         const char *bt_le_status = NULL;
492         BT_DBG("bt state set event(%s) received", event_name);
493         bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
494         BT_DBG("bt_state: (%s)", bt_status);
495
496         bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
497         BT_DBG("bt_state: (%s)", bt_le_status);
498 #endif
499 }
500
501 static gboolean __bt_adapter_enable_cb(gpointer user_data)
502 {
503         BT_DBG("+");
504         bt_status_t status;
505         bt_le_status_t le_status;
506         int ret;
507
508         if (timer_id > 0) {
509                 BT_DBG("g_source is removed");
510                 g_source_remove(timer_id);
511                 timer_id = 0;
512         }
513
514         status = _bt_adapter_get_status();
515         le_status = _bt_adapter_get_le_status();
516         BT_DBG("status : %d", status);
517         BT_DBG("le_status : %d", le_status);
518
519         /* add the vconf noti handler */
520         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
521                                         __bt_phone_name_changed_cb, NULL);
522         if (ret < 0)
523                 BT_ERR("Unable to register key handler");
524
525         if (le_status == BT_LE_ACTIVATING ||
526                  status == BT_ACTIVATING) {
527                 __bt_set_le_enabled();
528                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
529         }
530
531         if (status == BT_ACTIVATING) {
532                 __bt_set_enabled();
533                 _bt_adapter_set_status(BT_ACTIVATED);
534         }
535 #ifdef ENABLE_TIZEN_2_4
536         journal_bt_on();
537 #endif
538
539         _bt_service_register_vconf_handler();
540
541         /* eventsystem */
542         if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
543                         (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
544                 BT_ERR("Fail to register system event");
545         }
546
547         _bt_delete_event_timer(BT_EVENT_TIMER_ENABLE);
548
549         return FALSE;
550 }
551
552 static gboolean __bt_adapter_disable_cb(gpointer user_data)
553 {
554         int ret;
555
556         _bt_adapter_set_status(BT_DEACTIVATED);
557 #ifdef ENABLE_TIZEN_2_4
558         journal_bt_off();
559 #endif
560
561         __bt_visibility_alarm_remove();
562
563         if (visible_timer.alarm_init) {
564                 alarmmgr_fini();
565                 visible_timer.alarm_init = FALSE;
566         }
567
568         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
569                                 (vconf_callback_fn)__bt_phone_name_changed_cb);
570         if (0 != ret)
571                 BT_ERR("vconf_ignore_key_changed failed\n");
572
573         _bt_reliable_terminate_service(NULL);
574
575         if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
576                 BT_ERR("Fail to unregister system event");
577
578         _bt_delete_event_timer(BT_EVENT_TIMER_DISABLE);
579
580         return FALSE;
581 }
582
583 static gboolean __bt_adapter_device_found_cb(gpointer user_data)
584 {
585         int i = 0;
586         int result = BLUETOOTH_ERROR_NONE;
587         GVariant *param = NULL;
588         GVariant *uuids = NULL;
589         GVariant *manufacturer_data = NULL;
590         GVariantBuilder *builder = NULL;
591         bt_remote_dev_info_t *dev_info;
592
593         BT_DBG("+");
594
595         BT_DBG("found count: %d", found_cnt);
596
597         if (found_cnt >= _bt_get_sample_device_number()) {
598                 BT_DBG("Finish creating devices");
599                 goto done;
600         }
601
602         BT_DBG("[%d] device found", found_cnt);
603
604         dev_info = _bt_get_sample_device(found_cnt);
605         if (dev_info == NULL) {
606                 BT_DBG("Fail to get the sample device");
607                 goto done;
608         }
609
610         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
611         for (i = 0; i < dev_info->uuid_count; i++) {
612                 g_variant_builder_add(builder, "s",
613                         dev_info->uuids[i]);
614         }
615         uuids = g_variant_new("as", builder);
616         g_variant_builder_unref(builder);
617
618         manufacturer_data = g_variant_new_from_data(
619                                 G_VARIANT_TYPE_BYTESTRING,
620                                 dev_info->manufacturer_data,
621                                 dev_info->manufacturer_data_len,
622                                 TRUE, NULL, NULL);
623
624         param = g_variant_new("(isunsbub@asn@ay)", result,
625                                 dev_info->address,
626                                 dev_info->class,
627                                 dev_info->rssi,
628                                 dev_info->name,
629                                 dev_info->paired,
630                                 dev_info->connected,
631                                 dev_info->trust,
632                                 uuids,
633                                 dev_info->manufacturer_data_len,
634                                 manufacturer_data);
635
636         _bt_send_event(BT_ADAPTER_EVENT,
637                 BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
638                  param);
639
640         _bt_free_device_info(dev_info);
641
642         found_cnt++;
643
644         return TRUE;
645 done:
646         _bt_delete_event_timer(BT_EVENT_TIMER_FOUND_DEVICE);
647
648         param = g_variant_new("(i)", result);
649
650         _bt_send_event(BT_ADAPTER_EVENT,
651                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
652                 param);
653
654         is_discovering = FALSE;
655         found_cnt = 0;
656
657         return FALSE;
658 }
659
660 static gboolean __bt_adapter_start_discovery_cb(gpointer user_data)
661 {
662         int result = BLUETOOTH_ERROR_NONE;
663         GVariant *param = NULL;
664
665         BT_DBG("Discovery started");
666
667         param = g_variant_new("(i)", result);
668
669         _bt_send_event(BT_ADAPTER_EVENT,
670                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
671                 param);
672
673         _bt_delete_event_timer(BT_EVENT_TIMER_START_DISCOVERY);
674
675         found_cnt = 0;
676
677         _bt_create_event_timer(BT_EVENT_TIMER_FOUND_DEVICE, 500,
678                                 __bt_adapter_device_found_cb, NULL);
679
680         return FALSE;
681 }
682
683 static gboolean __bt_adapter_stop_discovery_cb(gpointer user_data)
684 {
685         int result = BLUETOOTH_ERROR_NONE;
686         GVariant *param = NULL;
687
688         BT_DBG("Discovery stopped");
689
690         param = g_variant_new("(i)", result);
691
692         _bt_send_event(BT_ADAPTER_EVENT,
693                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
694                 param);
695
696         _bt_delete_event_timer(BT_EVENT_TIMER_FOUND_DEVICE);
697         _bt_delete_event_timer(BT_EVENT_TIMER_STOP_DISCOVERY);
698
699         return FALSE;
700 }
701
702 static gboolean __bt_enable_timeout_cb(gpointer user_data)
703 {
704         timer_id = 0;
705
706         retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
707
708         BT_ERR("EnableAdapter is failed");
709
710         _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
711
712         _bt_terminate_service(NULL);
713
714         return FALSE;
715 }
716
717 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
718 {
719         le_timer_id = 0;
720
721         retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
722
723         BT_ERR("EnableAdapterLE is failed");
724
725         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
726
727         _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
728
729         if (_bt_adapter_get_status() == BT_DEACTIVATED)
730                 _bt_terminate_service(NULL);
731
732         return FALSE;
733 }
734
735 void _bt_adapter_start_le_enable_timer(void)
736 {
737         if (le_timer_id > 0) {
738                 g_source_remove(le_timer_id);
739                 le_timer_id = 0;
740         }
741
742         le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
743                         __bt_enable_le_timeout_cb, NULL);
744
745         return;
746 }
747
748 void _bt_adapter_start_enable_timer(void)
749 {
750         if (timer_id > 0) {
751                 g_source_remove(timer_id);
752                 timer_id = 0;
753         }
754
755         timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
756                         __bt_enable_timeout_cb, NULL);
757
758         return;
759 }
760
761 int _bt_enable_adapter(void)
762 {
763         bt_status_t status = _bt_adapter_get_status();
764         bt_le_status_t le_status = _bt_adapter_get_le_status();
765
766         BT_DBG("");
767
768         if (status == BT_ACTIVATING) {
769                 BT_ERR("Enabling in progress");
770                 return BLUETOOTH_ERROR_IN_PROGRESS;
771         }
772
773         if (status == BT_ACTIVATED) {
774                 BT_ERR("Already enabled");
775                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
776         }
777
778         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
779                 BT_ERR("Disabling in progress");
780                 return BLUETOOTH_ERROR_DEVICE_BUSY;
781         }
782
783         _bt_adapter_set_status(BT_ACTIVATING);
784
785         _bt_create_event_timer(BT_EVENT_TIMER_ENABLE, 2000,
786                                         __bt_adapter_enable_cb, NULL);
787
788         return BLUETOOTH_ERROR_NONE;
789 }
790
791 int _bt_disable_adapter(void)
792 {
793         BT_DBG("+");
794
795         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
796                 BT_DBG("Disabling in progress");
797                 return BLUETOOTH_ERROR_IN_PROGRESS;
798         }
799
800         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
801                 BT_DBG("Already disabled");
802                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
803         }
804
805         if (timer_id > 0) {
806                 g_source_remove(timer_id);
807                 timer_id = 0;
808         }
809
810         _bt_adapter_set_status(BT_DEACTIVATING);
811
812         _bt_create_event_timer(BT_EVENT_TIMER_DISABLE, 1000,
813                                         __bt_adapter_disable_cb, NULL);
814
815         BT_DBG("-");
816         return BLUETOOTH_ERROR_NONE;
817 }
818
819 int _bt_recover_adapter(void)
820 {
821         return BLUETOOTH_ERROR_NOT_SUPPORT;
822 }
823
824 int _bt_reset_adapter(void)
825 {
826         if (timer_id > 0) {
827                 g_source_remove(timer_id);
828                 timer_id = 0;
829         }
830
831         _bt_create_event_timer(BT_EVENT_TIMER_DISABLE, 1000,
832                                 __bt_adapter_disable_cb, NULL);
833
834         return BLUETOOTH_ERROR_NONE;
835 }
836
837 int _bt_check_adapter(int *status)
838 {
839
840         BT_CHECK_PARAMETER(status, return);
841
842         *status = adapter_status;
843
844         return BLUETOOTH_ERROR_NONE;
845 }
846
847 int _bt_enable_adapter_le(void)
848 {
849         BT_DBG("+");
850         bt_status_t status = _bt_adapter_get_status();
851         bt_le_status_t le_status = _bt_adapter_get_le_status();
852
853         if (le_status == BT_LE_ACTIVATING) {
854                 BT_ERR("Enabling in progress");
855                 return BLUETOOTH_ERROR_IN_PROGRESS;
856         }
857
858         if (le_status == BT_LE_ACTIVATED) {
859                 BT_ERR("Already enabled");
860                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
861         }
862
863         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
864                 BT_ERR("Disabling in progress");
865                 return BLUETOOTH_ERROR_DEVICE_BUSY;
866         }
867
868         __bt_set_le_enabled();
869
870         BT_DBG("le status : %d", _bt_adapter_get_le_status());
871         BT_DBG("-");
872         return BLUETOOTH_ERROR_NONE;
873 }
874
875 int _bt_disable_adapter_le(void)
876 {
877         BT_DBG("+");
878         bt_le_status_t bt_le_state;
879
880         bt_le_state = _bt_adapter_get_le_status();
881         if (bt_le_state == BT_LE_DEACTIVATING) {
882                 BT_DBG("Disabling in progress");
883                 return BLUETOOTH_ERROR_IN_PROGRESS;
884         }
885
886         if (bt_le_state == BT_LE_DEACTIVATED) {
887                 BT_DBG("Already disabled");
888                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
889         }
890
891         _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
892
893         BT_DBG("le status : %d", _bt_adapter_get_le_status());
894         BT_DBG("-");
895         return BLUETOOTH_ERROR_NONE;
896 }
897
898 int _bt_get_local_address(bluetooth_device_address_t *local_address)
899 {
900         const char *address = "11:22:33:44:55:66";
901
902         BT_CHECK_PARAMETER(local_address, return);
903
904         BT_DBG("Address:%s", address);
905
906         _bt_convert_addr_string_to_type(local_address->addr, address);
907
908         return BLUETOOTH_ERROR_NONE;
909 }
910
911 int _bt_get_local_version(bluetooth_version_t *local_version)
912 {
913         const char *ver = "Tizen BT emul v0.1";
914
915         BT_CHECK_PARAMETER(local_version, return);
916
917         g_strlcpy(local_version->version, ver, BLUETOOTH_VERSION_LENGTH_MAX + 1);
918
919         return BLUETOOTH_ERROR_NONE;
920 }
921
922 int _bt_get_local_name(bluetooth_device_name_t *local_name)
923 {
924         BT_CHECK_PARAMETER(local_name, return);
925
926         if (g_local_name != NULL)
927                 g_local_name = g_strdup(BT_DEFAULT_NAME);
928
929         g_strlcpy(local_name->name, g_local_name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
930
931         return BLUETOOTH_ERROR_NONE;
932 }
933
934 int _bt_set_local_name(char *local_name)
935 {
936         BT_CHECK_PARAMETER(local_name, return);
937
938         g_free(g_local_name);
939         g_local_name = g_strdup(local_name);
940
941         return BLUETOOTH_ERROR_NONE;
942 }
943
944 int _bt_is_service_used(char *service_uuid, gboolean *used)
945 {
946         BT_CHECK_PARAMETER(service_uuid, return);
947         BT_CHECK_PARAMETER(used, return);
948
949         *used = FALSE;
950
951         return BLUETOOTH_ERROR_NOT_SUPPORT;
952 }
953
954 int _bt_get_discoverable_mode(int *mode)
955 {
956         BT_CHECK_PARAMETER(mode, return);
957
958         if (g_is_discoverable == TRUE) {
959                 if (visible_timer.timeout == 0)
960                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
961                 else
962                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
963         } else {
964                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
965         }
966         return BLUETOOTH_ERROR_NONE;
967 }
968
969
970 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
971 {
972         int ret = BLUETOOTH_ERROR_NONE;
973
974         switch (discoverable_mode) {
975         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
976                 g_is_discoverable = FALSE;
977                 timeout = 0;
978                 break;
979         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
980                 timeout = 0;
981                 g_is_discoverable = TRUE;
982                 break;
983         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
984                 g_is_discoverable = TRUE;
985                 break;
986         default:
987                 return BLUETOOTH_ERROR_INVALID_PARAM;
988         }
989
990         BT_INFO("Req. discoverable_mode : %d, timeout : %d",
991                         discoverable_mode, timeout);
992
993         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
994                 timeout = -1;
995
996         ret = __bt_set_visible_time(timeout);
997
998         return ret;
999 }
1000
1001 int _bt_start_discovery(void)
1002 {
1003         return _bt_start_custom_discovery(DISCOVERY_ROLE_LE_BREDR);
1004 }
1005
1006 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1007 {
1008         BT_DBG("+");
1009
1010         if (_bt_is_discovering() == TRUE) {
1011                 BT_ERR("BT is already in discovering");
1012                 return BLUETOOTH_ERROR_IN_PROGRESS;
1013         }
1014
1015         is_discovering = TRUE;
1016         cancel_by_user = FALSE;
1017
1018         _bt_create_event_timer(BT_EVENT_TIMER_START_DISCOVERY, 100,
1019                                         __bt_adapter_start_discovery_cb, NULL);
1020
1021         return BLUETOOTH_ERROR_NONE;
1022 }
1023
1024 int _bt_cancel_discovery(void)
1025 {
1026         if (_bt_is_discovering() == FALSE) {
1027                 BT_ERR("BT is not in discovering");
1028                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1029         }
1030
1031         is_discovering = FALSE;
1032         cancel_by_user = TRUE;
1033         found_cnt = 0;
1034
1035         _bt_delete_event_timer(BT_EVENT_TIMER_START_DISCOVERY);
1036         _bt_delete_event_timer(BT_EVENT_TIMER_FOUND_DEVICE);
1037
1038         _bt_create_event_timer(BT_EVENT_TIMER_STOP_DISCOVERY, 100,
1039                                         __bt_adapter_stop_discovery_cb, NULL);
1040
1041         return BLUETOOTH_ERROR_NONE;
1042 }
1043
1044 gboolean _bt_is_discovering(void)
1045 {
1046         return is_discovering;
1047 }
1048
1049 gboolean _bt_is_connectable(void)
1050 {
1051         return FALSE;
1052 }
1053
1054 int _bt_set_connectable(gboolean is_connectable)
1055 {
1056         return BLUETOOTH_ERROR_NOT_SUPPORT;
1057 }
1058
1059 int _bt_get_bonded_devices(GArray **dev_list)
1060 {
1061         /* Should implement this */
1062
1063         return BLUETOOTH_ERROR_NONE;
1064 }
1065
1066 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
1067                                 bluetooth_device_info_t *dev_info)
1068 {
1069         BT_CHECK_PARAMETER(device_address, return);
1070         BT_CHECK_PARAMETER(dev_info, return);
1071
1072         /* Should implement this */
1073         return BLUETOOTH_ERROR_NONE;
1074 }
1075
1076 int _bt_get_timeout_value(int *timeout)
1077 {
1078         time_t current_time;
1079         int time_diff;
1080
1081         /* Take current time */
1082         time(&current_time);
1083         time_diff = difftime(current_time, visible_timer.start_time);
1084
1085         BT_DBG("Time diff = %d\n", time_diff);
1086
1087         *timeout = visible_timer.timeout - time_diff;
1088
1089         return BLUETOOTH_ERROR_NONE;
1090 }
1091
1092 int _bt_set_le_privacy(gboolean set_privacy)
1093 {
1094         return BLUETOOTH_ERROR_NOT_SUPPORT;
1095 }
1096
1097 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
1098 {
1099         BT_CHECK_PARAMETER(m_data, return);
1100
1101         return BLUETOOTH_ERROR_NOT_SUPPORT;
1102 }