Merge "bt-api: Do not log the _bt_check_privilege() using macro" into tizen_3.0
[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 #ifndef TIZEN_PROFILE_WEARABLE
83                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
84                         BT_ERR("Set vconf failed\n");
85 #endif
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 #ifndef TIZEN_PROFILE_WEARABLE
111                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
112                         BT_ERR("Set vconf failed\n");
113 #endif
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 #ifndef TIZEN_PROFILE_WEARABLE
158         if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
159                 BT_ERR("Set vconf failed");
160 #endif
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 #ifdef TIZEN_PROFILE_MOBILE
246 static void __bt_set_visible_mode(void)
247 {
248         int timeout = 0;
249
250         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
251                 BT_ERR("Fail to get the timeout value");
252
253         if (timeout == -1) {
254                 if (_bt_set_discoverable_mode(
255                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
256                         timeout) != BLUETOOTH_ERROR_NONE) {
257                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
258                                 BT_ERR("Set vconf failed");
259                 }
260         } else {
261                 if (_bt_set_discoverable_mode(
262                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
263                         timeout) != BLUETOOTH_ERROR_NONE) {
264                                 BT_ERR("Set connectable mode failed");
265                 }
266         }
267 }
268 #endif
269
270 static void __bt_set_local_name(void)
271 {
272         char *phone_name = NULL;
273         char *ptr = NULL;
274
275         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
276
277         if (!phone_name)
278                 return;
279
280         if (strlen(phone_name) != 0) {
281                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
282                         *ptr = '\0';
283
284                 _bt_set_local_name(phone_name);
285         }
286         free(phone_name);
287 }
288
289 static int __bt_set_enabled(void)
290 {
291         BT_DBG("+");
292         int result = BLUETOOTH_ERROR_NONE;
293
294 #ifdef TIZEN_PROFILE_MOBILE
295         __bt_set_visible_mode();
296 #else
297 #ifdef TIZEN_PROFILE_TV
298         if (_bt_set_discoverable_mode(
299                 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
300                         BT_ERR("Fail to set discoverable mode");
301 #endif
302 #endif
303         __bt_set_local_name();
304
305         /* Update Bluetooth Status to notify other modules */
306         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
307                 BT_ERR("Set vconf failed\n");
308
309         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
310                 BT_ERR("Set vconf failed\n");
311 #if 0
312         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
313                                                 EVT_VAL_BT_ON) != ES_R_OK)
314                 BT_ERR("Fail to set value");
315 #endif
316
317         /* Send enabled event to API */
318         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
319                                 g_variant_new("(i)", result));
320         BT_DBG("-");
321
322         return BLUETOOTH_ERROR_NONE;
323 }
324
325 void _bt_set_disabled(int result)
326 {
327         int power_off_status = 0;
328         int ret;
329         int ret_pm_ignore;
330         int pm_ignore_mode = 0;
331
332         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
333         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
334
335         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
336
337         /* Update the vconf BT status in normal Deactivation case only */
338         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
339                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
340
341                 BT_DBG("Update vconf for BT normal Deactivation");
342
343                 if (result == BLUETOOTH_ERROR_TIMEOUT)
344                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
345                                 BT_ERR("Set vconf failed");
346
347                 /* Update Bluetooth Status to notify other modules */
348                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
349                         BT_ERR("Set vconf failed");
350
351                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
352                                                         EVT_VAL_BT_OFF) != ES_R_OK)
353                         BT_ERR("Fail to set value");
354         }
355
356         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
357                 BT_ERR("Set vconf failed\n");
358
359         _bt_adapter_set_status(BT_DEACTIVATED);
360
361         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
362                         g_variant_new("(i)", result));
363
364         BT_INFO("Adapter disabled");
365 }
366
367 static int __bt_set_le_enabled(void)
368 {
369         BT_DBG("+");
370         int result = BLUETOOTH_ERROR_NONE;
371         bt_status_t status;
372
373         __bt_set_local_name();
374
375         /* Update Bluetooth Status to notify other modules */
376         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
377                 BT_ERR("Set vconf failed\n");
378
379         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
380                                                 EVT_VAL_BT_LE_ON) != ES_R_OK)
381                 BT_ERR("Fail to set value");
382
383         /* Send enabled event to API */
384         /*
385         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
386                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
387         */
388         status = _bt_adapter_get_status();
389         if (status == BT_DEACTIVATED) {
390                 BT_INFO("BREDR is off, turn off PSCAN");
391                 _bt_set_connectable(FALSE);
392         }
393         if (le_timer_id > 0) {
394                 g_source_remove(le_timer_id);
395                 le_timer_id = 0;
396         }
397
398         /* Send enabled event to API */
399         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
400                                 g_variant_new("(i)", result));
401
402         BT_DBG("-");
403         return BLUETOOTH_ERROR_NONE;
404 }
405
406 void _bt_set_le_disabled(int result)
407 {
408         int power_off_status;
409         int ret;
410
411         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
412         BT_DBG("ret : %d", ret);
413         BT_DBG("power_off_status : %d", power_off_status);
414
415         /* Update Bluetooth Status to notify other modules */
416         BT_DBG("Update vconf for BT LE normal Deactivation");
417         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
418                 BT_ERR("Set vconf failed\n");
419         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
420
421         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
422                                                 EVT_VAL_BT_LE_OFF) != ES_R_OK)
423                 BT_ERR("Fail to set value");
424
425         /* Send disabled event */
426         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
427                         g_variant_new_int32(result));
428 }
429
430 #if defined(TIZEN_FEATURE_FLIGHTMODE_ENABLED) || (!defined(TIZEN_PROFILE_WEARABLE) && defined(ENABLE_TIZEN_2_4))
431 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
432 {
433         gboolean flight_mode = FALSE;
434         int power_saving_mode = 0;
435         int type;
436
437         DBG_SECURE("key=%s", vconf_keynode_get_name(node));
438         type = vconf_keynode_get_type(node);
439         if (type == VCONF_TYPE_BOOL) {
440                 flight_mode = vconf_keynode_get_bool(node);
441                 if (flight_mode != TRUE) {
442                         BT_ERR("Ignore the event");
443                         return;
444                 }
445         } else if (type == VCONF_TYPE_INT) {
446                 power_saving_mode = vconf_keynode_get_int(node);
447                 if (power_saving_mode != 2) {
448                         BT_ERR("Ignore the event");
449                         return;
450                 }
451         } else {
452                 BT_ERR("Invaild vconf key type : %d", type);
453                 return;
454         }
455 }
456 #endif
457
458 void _bt_service_register_vconf_handler(void)
459 {
460         BT_DBG("+");
461
462 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
463         if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
464                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
465                 BT_ERR("Unable to register key handler");
466 #else
467         BT_DBG("Telephony is disabled");
468 #endif
469
470 #ifndef TIZEN_PROFILE_WEARABLE
471 #ifdef ENABLE_TIZEN_2_4
472         if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
473                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
474                 BT_ERR("Unable to register key handler");
475 #endif
476 #endif
477 }
478
479 void _bt_service_unregister_vconf_handler(void)
480 {
481         BT_DBG("+");
482
483 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
484         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
485                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
486 #endif
487
488 #ifndef TIZEN_PROFILE_WEARABLE
489 #ifdef ENABLE_TIZEN_2_4
490         vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
491                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
492 #endif
493 #endif
494 }
495
496 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
497 {
498 #ifdef ENABLE_TIZEN_2_4
499         const char *bt_status = NULL;
500         const char *bt_le_status = NULL;
501         BT_DBG("bt state set event(%s) received", event_name);
502         bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
503         BT_DBG("bt_state: (%s)", bt_status);
504
505         bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
506         BT_DBG("bt_state: (%s)", bt_le_status);
507 #endif
508 }
509
510 static gboolean __bt_adapter_enable_cb(gpointer user_data)
511 {
512         BT_DBG("+");
513         bt_status_t status;
514         bt_le_status_t le_status;
515         int ret;
516
517         if (timer_id > 0) {
518                 BT_DBG("g_source is removed");
519                 g_source_remove(timer_id);
520                 timer_id = 0;
521         }
522
523         status = _bt_adapter_get_status();
524         le_status = _bt_adapter_get_le_status();
525         BT_DBG("status : %d", status);
526         BT_DBG("le_status : %d", le_status);
527
528         /* add the vconf noti handler */
529         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
530                                         __bt_phone_name_changed_cb, NULL);
531         if (ret < 0)
532                 BT_ERR("Unable to register key handler");
533
534         if (le_status == BT_LE_ACTIVATING ||
535                  status == BT_ACTIVATING) {
536                 __bt_set_le_enabled();
537                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
538         }
539
540         if (status == BT_ACTIVATING) {
541                 __bt_set_enabled();
542                 _bt_adapter_set_status(BT_ACTIVATED);
543         }
544 #ifdef ENABLE_TIZEN_2_4
545         journal_bt_on();
546 #endif
547
548         _bt_service_register_vconf_handler();
549
550         /* eventsystem */
551         if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
552                         (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
553                 BT_ERR("Fail to register system event");
554         }
555
556         _bt_delete_event_timer(BT_EVENT_TIMER_ENABLE);
557
558         return FALSE;
559 }
560
561 static gboolean __bt_adapter_disable_cb(gpointer user_data)
562 {
563         int ret;
564
565         _bt_adapter_set_status(BT_DEACTIVATED);
566 #ifdef ENABLE_TIZEN_2_4
567         journal_bt_off();
568 #endif
569
570         __bt_visibility_alarm_remove();
571
572         if (visible_timer.alarm_init) {
573                 alarmmgr_fini();
574                 visible_timer.alarm_init = FALSE;
575         }
576
577         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
578                                 (vconf_callback_fn)__bt_phone_name_changed_cb);
579         if (0 != ret)
580                 BT_ERR("vconf_ignore_key_changed failed\n");
581
582         _bt_reliable_terminate_service(NULL);
583
584         if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
585                 BT_ERR("Fail to unregister system event");
586
587         _bt_delete_event_timer(BT_EVENT_TIMER_DISABLE);
588
589         return FALSE;
590 }
591
592 static gboolean __bt_adapter_device_found_cb(gpointer user_data)
593 {
594         int i = 0;
595         int result = BLUETOOTH_ERROR_NONE;
596         GVariant *param = NULL;
597         GVariant *uuids = NULL;
598         GVariant *manufacturer_data = NULL;
599         GVariantBuilder *builder = NULL;
600         bt_remote_dev_info_t *dev_info;
601
602         BT_DBG("+");
603
604         BT_DBG("found count: %d", found_cnt);
605
606         if (found_cnt >= _bt_get_sample_device_number()) {
607                 BT_DBG("Finish creating devices");
608                 goto done;
609         }
610
611         BT_DBG("[%d] device found", found_cnt);
612
613         dev_info = _bt_get_sample_device(found_cnt);
614         if (dev_info == NULL) {
615                 BT_DBG("Fail to get the sample device");
616                 goto done;
617         }
618
619         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
620         for (i = 0; i < dev_info->uuid_count; i++) {
621                 g_variant_builder_add(builder, "s",
622                         dev_info->uuids[i]);
623         }
624         uuids = g_variant_new("as", builder);
625         g_variant_builder_unref(builder);
626
627         manufacturer_data = g_variant_new_from_data(
628                                 G_VARIANT_TYPE_BYTESTRING,
629                                 dev_info->manufacturer_data,
630                                 dev_info->manufacturer_data_len,
631                                 TRUE, NULL, NULL);
632
633         param = g_variant_new("(isunsbub@asn@ay)", result,
634                                 dev_info->address,
635                                 dev_info->class,
636                                 dev_info->rssi,
637                                 dev_info->name,
638                                 dev_info->paired,
639                                 dev_info->connected,
640                                 dev_info->trust,
641                                 uuids,
642                                 dev_info->manufacturer_data_len,
643                                 manufacturer_data);
644
645         _bt_send_event(BT_ADAPTER_EVENT,
646                 BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
647                  param);
648
649         _bt_free_device_info(dev_info);
650
651         found_cnt++;
652
653         return TRUE;
654 done:
655         _bt_delete_event_timer(BT_EVENT_TIMER_FOUND_DEVICE);
656
657         param = g_variant_new("(i)", result);
658
659         _bt_send_event(BT_ADAPTER_EVENT,
660                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
661                 param);
662
663         is_discovering = FALSE;
664         found_cnt = 0;
665
666         return FALSE;
667 }
668
669 static gboolean __bt_adapter_start_discovery_cb(gpointer user_data)
670 {
671         int result = BLUETOOTH_ERROR_NONE;
672         GVariant *param = NULL;
673
674         BT_DBG("Discovery started");
675
676         param = g_variant_new("(i)", result);
677
678         _bt_send_event(BT_ADAPTER_EVENT,
679                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
680                 param);
681
682         _bt_delete_event_timer(BT_EVENT_TIMER_START_DISCOVERY);
683
684         found_cnt = 0;
685
686         _bt_create_event_timer(BT_EVENT_TIMER_FOUND_DEVICE, 500,
687                                 __bt_adapter_device_found_cb, NULL);
688
689         return FALSE;
690 }
691
692 static gboolean __bt_adapter_stop_discovery_cb(gpointer user_data)
693 {
694         int result = BLUETOOTH_ERROR_NONE;
695         GVariant *param = NULL;
696
697         BT_DBG("Discovery stopped");
698
699         param = g_variant_new("(i)", result);
700
701         _bt_send_event(BT_ADAPTER_EVENT,
702                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
703                 param);
704
705         _bt_delete_event_timer(BT_EVENT_TIMER_FOUND_DEVICE);
706         _bt_delete_event_timer(BT_EVENT_TIMER_STOP_DISCOVERY);
707
708         return FALSE;
709 }
710
711 static gboolean __bt_enable_timeout_cb(gpointer user_data)
712 {
713         timer_id = 0;
714
715         retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
716
717         BT_ERR("EnableAdapter is failed");
718
719         _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
720
721         _bt_terminate_service(NULL);
722
723         return FALSE;
724 }
725
726 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
727 {
728         le_timer_id = 0;
729
730         retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
731
732         BT_ERR("EnableAdapterLE is failed");
733
734         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
735
736         _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
737
738         if (_bt_adapter_get_status() == BT_DEACTIVATED)
739                 _bt_terminate_service(NULL);
740
741         return FALSE;
742 }
743
744 void _bt_adapter_start_le_enable_timer(void)
745 {
746         if (le_timer_id > 0) {
747                 g_source_remove(le_timer_id);
748                 le_timer_id = 0;
749         }
750
751         le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
752                         __bt_enable_le_timeout_cb, NULL);
753
754         return;
755 }
756
757 void _bt_adapter_start_enable_timer(void)
758 {
759         if (timer_id > 0) {
760                 g_source_remove(timer_id);
761                 timer_id = 0;
762         }
763
764         timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
765                         __bt_enable_timeout_cb, NULL);
766
767         return;
768 }
769
770 int _bt_enable_adapter(void)
771 {
772         bt_status_t status = _bt_adapter_get_status();
773         bt_le_status_t le_status = _bt_adapter_get_le_status();
774
775         BT_DBG("");
776
777         if (status == BT_ACTIVATING) {
778                 BT_ERR("Enabling in progress");
779                 return BLUETOOTH_ERROR_IN_PROGRESS;
780         }
781
782         if (status == BT_ACTIVATED) {
783                 BT_ERR("Already enabled");
784                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
785         }
786
787         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
788                 BT_ERR("Disabling in progress");
789                 return BLUETOOTH_ERROR_DEVICE_BUSY;
790         }
791
792         _bt_adapter_set_status(BT_ACTIVATING);
793
794         _bt_create_event_timer(BT_EVENT_TIMER_ENABLE, 2000,
795                                         __bt_adapter_enable_cb, NULL);
796
797         return BLUETOOTH_ERROR_NONE;
798 }
799
800 int _bt_disable_adapter(void)
801 {
802         BT_DBG("+");
803
804         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
805                 BT_DBG("Disabling in progress");
806                 return BLUETOOTH_ERROR_IN_PROGRESS;
807         }
808
809         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
810                 BT_DBG("Already disabled");
811                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
812         }
813
814         if (timer_id > 0) {
815                 g_source_remove(timer_id);
816                 timer_id = 0;
817         }
818
819         _bt_adapter_set_status(BT_DEACTIVATING);
820
821         _bt_create_event_timer(BT_EVENT_TIMER_DISABLE, 1000,
822                                         __bt_adapter_disable_cb, NULL);
823
824         BT_DBG("-");
825         return BLUETOOTH_ERROR_NONE;
826 }
827
828 int _bt_recover_adapter(void)
829 {
830         return BLUETOOTH_ERROR_NOT_SUPPORT;
831 }
832
833 int _bt_reset_adapter(void)
834 {
835         if (timer_id > 0) {
836                 g_source_remove(timer_id);
837                 timer_id = 0;
838         }
839
840         _bt_create_event_timer(BT_EVENT_TIMER_DISABLE, 1000,
841                                 __bt_adapter_disable_cb, NULL);
842
843         return BLUETOOTH_ERROR_NONE;
844 }
845
846 int _bt_check_adapter(int *status)
847 {
848
849         BT_CHECK_PARAMETER(status, return);
850
851         *status = adapter_status;
852
853         return BLUETOOTH_ERROR_NONE;
854 }
855
856 int _bt_enable_adapter_le(void)
857 {
858         BT_DBG("+");
859         bt_status_t status = _bt_adapter_get_status();
860         bt_le_status_t le_status = _bt_adapter_get_le_status();
861
862         if (le_status == BT_LE_ACTIVATING) {
863                 BT_ERR("Enabling in progress");
864                 return BLUETOOTH_ERROR_IN_PROGRESS;
865         }
866
867         if (le_status == BT_LE_ACTIVATED) {
868                 BT_ERR("Already enabled");
869                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
870         }
871
872         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
873                 BT_ERR("Disabling in progress");
874                 return BLUETOOTH_ERROR_DEVICE_BUSY;
875         }
876
877         __bt_set_le_enabled();
878
879         BT_DBG("le status : %d", _bt_adapter_get_le_status());
880         BT_DBG("-");
881         return BLUETOOTH_ERROR_NONE;
882 }
883
884 int _bt_disable_adapter_le(void)
885 {
886         BT_DBG("+");
887         bt_le_status_t bt_le_state;
888
889         bt_le_state = _bt_adapter_get_le_status();
890         if (bt_le_state == BT_LE_DEACTIVATING) {
891                 BT_DBG("Disabling in progress");
892                 return BLUETOOTH_ERROR_IN_PROGRESS;
893         }
894
895         if (bt_le_state == BT_LE_DEACTIVATED) {
896                 BT_DBG("Already disabled");
897                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
898         }
899
900         _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
901
902         BT_DBG("le status : %d", _bt_adapter_get_le_status());
903         BT_DBG("-");
904         return BLUETOOTH_ERROR_NONE;
905 }
906
907 int _bt_get_local_address(bluetooth_device_address_t *local_address)
908 {
909         const char *address = "11:22:33:44:55:66";
910
911         BT_CHECK_PARAMETER(local_address, return);
912
913         BT_DBG("Address:%s", address);
914
915         _bt_convert_addr_string_to_type(local_address->addr, address);
916
917         return BLUETOOTH_ERROR_NONE;
918 }
919
920 int _bt_get_local_version(bluetooth_version_t *local_version)
921 {
922         const char *ver = "Tizen BT emul v0.1";
923
924         BT_CHECK_PARAMETER(local_version, return);
925
926         g_strlcpy(local_version->version, ver, BLUETOOTH_VERSION_LENGTH_MAX + 1);
927
928         return BLUETOOTH_ERROR_NONE;
929 }
930
931 int _bt_get_local_name(bluetooth_device_name_t *local_name)
932 {
933         BT_CHECK_PARAMETER(local_name, return);
934
935         if (g_local_name != NULL)
936                 g_local_name = g_strdup(BT_DEFAULT_NAME);
937
938         g_strlcpy(local_name->name, g_local_name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
939
940         return BLUETOOTH_ERROR_NONE;
941 }
942
943 int _bt_set_local_name(char *local_name)
944 {
945         BT_CHECK_PARAMETER(local_name, return);
946
947         g_free(g_local_name);
948         g_local_name = g_strdup(local_name);
949
950         return BLUETOOTH_ERROR_NONE;
951 }
952
953 int _bt_is_service_used(char *service_uuid, gboolean *used)
954 {
955         BT_CHECK_PARAMETER(service_uuid, return);
956         BT_CHECK_PARAMETER(used, return);
957
958         *used = FALSE;
959
960         return BLUETOOTH_ERROR_NOT_SUPPORT;
961 }
962
963 int _bt_get_discoverable_mode(int *mode)
964 {
965         BT_CHECK_PARAMETER(mode, return);
966
967         if (g_is_discoverable == TRUE) {
968                 if (visible_timer.timeout == 0)
969                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
970                 else
971                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
972         } else {
973                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
974         }
975         return BLUETOOTH_ERROR_NONE;
976 }
977
978
979 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
980 {
981         int ret = BLUETOOTH_ERROR_NONE;
982
983         switch (discoverable_mode) {
984         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
985                 g_is_discoverable = FALSE;
986                 timeout = 0;
987                 break;
988         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
989                 timeout = 0;
990                 g_is_discoverable = TRUE;
991                 break;
992         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
993                 g_is_discoverable = TRUE;
994                 break;
995         default:
996                 return BLUETOOTH_ERROR_INVALID_PARAM;
997         }
998
999         BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1000                         discoverable_mode, timeout);
1001
1002         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1003                 timeout = -1;
1004
1005         ret = __bt_set_visible_time(timeout);
1006
1007         return ret;
1008 }
1009
1010 int _bt_start_discovery(void)
1011 {
1012         return _bt_start_custom_discovery(DISCOVERY_ROLE_LE_BREDR);
1013 }
1014
1015 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1016 {
1017         BT_DBG("+");
1018
1019         if (_bt_is_discovering() == TRUE) {
1020                 BT_ERR("BT is already in discovering");
1021                 return BLUETOOTH_ERROR_IN_PROGRESS;
1022         }
1023
1024         is_discovering = TRUE;
1025         cancel_by_user = FALSE;
1026
1027         _bt_create_event_timer(BT_EVENT_TIMER_START_DISCOVERY, 100,
1028                                         __bt_adapter_start_discovery_cb, NULL);
1029
1030         return BLUETOOTH_ERROR_NONE;
1031 }
1032
1033 int _bt_cancel_discovery(void)
1034 {
1035         if (_bt_is_discovering() == FALSE) {
1036                 BT_ERR("BT is not in discovering");
1037                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1038         }
1039
1040         is_discovering = FALSE;
1041         cancel_by_user = TRUE;
1042         found_cnt = 0;
1043
1044         _bt_delete_event_timer(BT_EVENT_TIMER_START_DISCOVERY);
1045         _bt_delete_event_timer(BT_EVENT_TIMER_FOUND_DEVICE);
1046
1047         _bt_create_event_timer(BT_EVENT_TIMER_STOP_DISCOVERY, 100,
1048                                         __bt_adapter_stop_discovery_cb, NULL);
1049
1050         return BLUETOOTH_ERROR_NONE;
1051 }
1052
1053 gboolean _bt_is_discovering(void)
1054 {
1055         return is_discovering;
1056 }
1057
1058 gboolean _bt_is_connectable(void)
1059 {
1060         return FALSE;
1061 }
1062
1063 int _bt_set_connectable(gboolean is_connectable)
1064 {
1065         return BLUETOOTH_ERROR_NOT_SUPPORT;
1066 }
1067
1068 int _bt_get_bonded_devices(GArray **dev_list)
1069 {
1070         /* Should implement this */
1071
1072         return BLUETOOTH_ERROR_NONE;
1073 }
1074
1075 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
1076                                 bluetooth_device_info_t *dev_info)
1077 {
1078         BT_CHECK_PARAMETER(device_address, return);
1079         BT_CHECK_PARAMETER(dev_info, return);
1080
1081         /* Should implement this */
1082         return BLUETOOTH_ERROR_NONE;
1083 }
1084
1085 int _bt_get_timeout_value(int *timeout)
1086 {
1087         time_t current_time;
1088         int time_diff;
1089
1090         /* Take current time */
1091         time(&current_time);
1092         time_diff = difftime(current_time, visible_timer.start_time);
1093
1094         BT_DBG("Time diff = %d\n", time_diff);
1095
1096         *timeout = visible_timer.timeout - time_diff;
1097
1098         return BLUETOOTH_ERROR_NONE;
1099 }
1100
1101 int _bt_set_le_privacy(gboolean set_privacy)
1102 {
1103         return BLUETOOTH_ERROR_NOT_SUPPORT;
1104 }
1105
1106 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
1107 {
1108         BT_CHECK_PARAMETER(m_data, return);
1109
1110         return BLUETOOTH_ERROR_NOT_SUPPORT;
1111 }