4 * Copyright 2012 Samsung Electronics Co., Ltd
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Injun Yang <injun.yang@samsung.com>
8 * Seungyoun Ju <sy39.ju@samsung.com>
10 * Licensed under the Flora License, Version 1.1 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.tizenopensource.org/license
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
25 #include <bluetooth.h>
28 #include "bt-connection-main.h"
29 #include "bt-connection-view.h"
30 #include "bt-connection-handler.h"
32 #define VCONFKEY_SAP_STATUS "memory/private/sap/conn_status"
33 #define BT_ADDRESS_LENGTH 18
35 static bool is_le_disconnecting;
37 static int __bt_app_destory_cb(void *data)
39 bt_app_data_t *ad = NULL;
43 ad = (bt_app_data_t *)data;
50 ecore_timer_del(ad->timer);
59 static void __bt_wms_status_handler(keynode_t *key, void *data)
65 ad = (bt_app_data_t *)data;
71 type = vconf_keynode_get_type(key);
72 if (type == VCONF_TYPE_BOOL)
73 status = vconf_keynode_get_bool(key);
75 ERR("Invalid vconf type : %d", type);
79 DBG("WMS is %s", status == WMS_CONNECTED ?
80 "connected" : "disconnected" );
82 if (status == WMS_CONNECTED) {
83 /* To show connected view, create new popup */
84 /* or update edc part */
85 /* See _bt_update_connect_status_popup() */
87 ecore_timer_del(ad->timer);
90 _bt_create_connected_popup(ad);
92 _bt_send_result(ad, KEY_VAL_CONNECTED);
94 ad->timer = ecore_timer_add(APP_DESTORY_TIMEOUT,
95 (Ecore_Task_Cb) __bt_app_destory_cb, ad);
101 static void __bt_hf_connection_state_changed(int result, bool connected, const char *remote_address, bt_audio_profile_type_e type, void *user_data)
103 if (connected == true) {
104 DBG("Bluetooth HF is connected");
107 DBG("Bluetooth HF is disconnected");
111 static bool __bt_adapter_bonded_device_cb(bt_device_info_s *device_info, void *user_data)
114 bool is_connected = false;
115 char* remote_address = (char*)user_data;
117 if (!(device_info->bt_class.major_device_class & BT_MAJOR_DEVICE_CLASS_COMPUTER) &&
118 !(device_info->bt_class.major_device_class & BT_MAJOR_DEVICE_CLASS_PHONE))
121 memcpy(remote_address, device_info->remote_address, BT_ADDRESS_LENGTH);
122 ret = bt_device_is_profile_connected(device_info->remote_address, BT_PROFILE_AG, &is_connected);
123 if (ret == BT_ERROR_NONE && is_connected) {
124 remote_address[0] = '\0';
131 static gboolean __bt_hf_is_connected(const char* remote_address)
134 gboolean is_connected = FALSE;
136 ret = bt_adapter_foreach_bonded_device(__bt_adapter_bonded_device_cb, (void*)remote_address);
137 if (ret != BT_ERROR_NONE) {
138 ERR("bt_adapter_foreach_bonded_device is failed 0x%X", ret);
142 if (remote_address[0] == '\0')
144 DBG("Aleady HF is %s", is_connected ? "connected" : "disconnected");
149 static void __bt_adapter_state_changed(int result,
150 bt_adapter_state_e adapter_state, void *user_data)
153 char remote_address[BT_ADDRESS_LENGTH] = { 0, };
155 if (user_data == NULL) {
156 ERR("Invalid param");
160 if (result != BT_ERROR_NONE) {
161 ERR("BT Adapter operation is failed : %d", result);
165 DBG("BT Adapter is %s", adapter_state == BT_ADAPTER_ENABLED ?
166 "enabled" : "disabled");
168 if (adapter_state == BT_ADAPTER_ENABLED) {
169 if (__bt_hf_is_connected(&remote_address[0]) == FALSE) {
170 DBG("Make a HF connection");
171 ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG);
172 if (ret != BT_ERROR_NONE) {
173 ERR("HF Connection is failed");
182 int _bt_get_wms_status(void)
185 int status = WMS_DISCONNECTED;
187 ret = vconf_get_bool(VCONFKEY_WMS_WMANAGER_CONNECTED, &status);
189 ERR("Vconf get failed");
190 return WMS_DISCONNECTED;
193 DBG("WMS status : %d", status);
198 void _bt_get_sap_status(void)
203 ret = vconf_get_int(VCONFKEY_SAP_STATUS, &status);
205 ERR("Vconf get failed");
208 DBG("SAP status : %d", status);
213 gboolean _bt_send_result(bt_app_data_t *ad, const char *val)
221 static gboolean is_sent = FALSE;
225 if (ad->service_clone == NULL) {
226 ERR("Invalid param");
230 if (is_sent == TRUE) {
231 ERR("Aleady send response !!!");
235 ret = service_to_bundle(ad->service_clone, &kb);
236 if (ret != SERVICE_ERROR_NONE) {
237 ERR("service is failed : %d", ret);
241 aul_create_result_bundle(kb, &res_b);
245 bundle_add(res_b, "__BT_CONNECTION__", val);
247 aul_send_service_result(res_b);
253 DBG("Send result : %s", val);
258 bool __device_check_gatt_cb(bt_profile_e profile, void *user_data)
260 bool *is_connected = (bool *)user_data;
262 if (profile == BT_PROFILE_GATT) {
263 *is_connected = true;
270 bool __bt_le_is_connected(const char *remote_address)
273 bool is_connected = false;
275 if (remote_address == NULL) {
279 ret = bt_device_foreach_connected_profiles(remote_address,
280 __device_check_gatt_cb, &is_connected);
281 if (ret != BT_ERROR_NONE) {
282 ERR("bt_device_foreach_connected_profiles fail (0x%08x)", ret);
289 void __bt_gatt_disconnected_cb(int result, void *user_data)
292 if (result != BT_ERROR_NONE) {
293 ERR("GATT disconnect fail (0x%08x)", result);
294 is_le_disconnecting = false;
299 char remote_address[BT_ADDRESS_LENGTH] = { 0, };
300 bool is_advertising = false;
303 if (result != BT_ERROR_NONE) {
304 ERR("GATT disconnect fail (0x%08x)", result);
308 if (__bt_hf_is_connected(&remote_address[0]) == TRUE) {
309 DBG("Handsfree is already connected");
313 ret = bt_adapter_is_advertising(&is_advertising);
314 if (ret == BT_ERROR_NONE && is_advertising) {
315 ret = bt_adapter_stop_advertising();
316 if (ret != BT_ERROR_NONE) {
317 ERR("bt_adapter_stop_advertising failed (0x%08x)", ret);
321 DBG("Make a HF connection");
322 ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG);
323 if (ret != BT_ERROR_NONE) {
324 ERR("HF Connection is failed");
332 static void __bt_device_connection_state_changed_cb(bool connected,
333 const char *remote_address,
336 bool is_advertising = false;
338 char remote_add[BT_ADDRESS_LENGTH] = { 0, };
340 DBG("address: %s, connected: %d", remote_address, connected);
342 if (is_le_disconnecting == false || connected == true) {
343 DBG("is_le_disconnecting IS FALSE");
346 is_le_disconnecting = false;
348 if (__bt_hf_is_connected(&remote_add[0]) == true) {
349 DBG("Handsfree is already connected");
353 if (strncmp(remote_address, remote_add, BT_ADDRESS_LENGTH-1) != 0) {
354 DBG("remote address is different");
358 ret = bt_adapter_is_advertising(&is_advertising);
359 if (ret == BT_ERROR_NONE && is_advertising) {
360 ret = bt_adapter_stop_advertising();
361 if (ret != BT_ERROR_NONE) {
362 ERR("bt_adapter_stop_advertising failed (0x%08x)", ret);
366 DBG("Make a HF connection");
367 ret = bt_audio_connect(&remote_add[0], BT_AUDIO_PROFILE_TYPE_AG);
368 if (ret != BT_ERROR_NONE) {
369 ERR("HF Connection is failed");
376 gboolean _bt_init(void *data)
379 bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
380 char remote_address[BT_ADDRESS_LENGTH] = { 0, };
381 bool is_advertising = false;
384 ad = (bt_app_data_t *)data;
386 is_le_disconnecting = false;
392 if (ad->initialize == TRUE) {
393 DBG("bt_initialize already done");
397 ret = bt_initialize();
398 if (ret != BT_ERROR_NONE) {
399 ERR("bt_initialize is failed : %d", ret);
403 ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, data);
404 if (ret != BT_ERROR_NONE) {
405 ERR("bt_adapter_set_state_changed_cb is failed : %d", ret);
410 ret = bt_device_set_connection_state_changed_cb(__bt_device_connection_state_changed_cb,
412 if (ret != BT_ERROR_NONE) {
413 ERR("bt_device_set_connection_state_changed_cb is failed : %d", ret);
417 ret = bt_adapter_get_state(&adapter_state);
418 if (ret != BT_ERROR_NONE) {
419 ERR("bt_adapter_get_state is failed : %d", ret);
423 ret = bt_audio_initialize();
424 if (ret != BT_ERROR_NONE) {
425 ERR("bt_audio_initialize is failed : %d", ret);
429 ret = bt_audio_set_connection_state_changed_cb(__bt_hf_connection_state_changed, NULL);
430 if (ret != BT_ERROR_NONE) {
431 ERR("bt_audio_set_connection_state_changed_cb is failed : %d", ret);
432 bt_hf_deinitialize();
436 if (adapter_state == BT_ADAPTER_ENABLED) {
437 DBG("Aleady BT enabled");
438 #ifdef FEATURE_TIZENW
439 if (__bt_hf_is_connected(&remote_address[0]) == FALSE) {
440 DBG("Make a HF connection");
441 ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG);
442 if (ret != BT_ERROR_NONE) {
443 ERR("HF Connection is failed");
448 if (__bt_hf_is_connected(&remote_address[0]) == FALSE) {
449 if (__bt_le_is_connected(&remote_address[0])) {
451 ret = bt_adapter_is_advertising(&is_advertising);
452 if (ret == BT_ERROR_NONE && is_advertising) {
453 ret = bt_adapter_stop_advertising();
454 if (ret != BT_ERROR_NONE) {
455 ERR("bt_adapter_stop_advertising failed (0x%08x)",
460 ret = bt_device_disconnect_le(__bt_gatt_disconnected_cb, &remote_address[0]);
461 if (ret == BT_ERROR_NONE)
462 is_le_disconnecting = true;
466 DBG("Make a HF connection");
467 ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG);
468 if (ret != BT_ERROR_NONE) {
469 ERR("HF Connection is failed");
473 #endif /* FEATURE_TIZENW */
476 DBG("Enable BT adapter");
477 ret = bt_adapter_enable();
478 if (ret != BT_ERROR_NONE) {
479 ERR("bt_adapter_enable is failed : %d", ret);
487 void _bt_deinit(void *data)
490 char remote_address[BT_ADDRESS_LENGTH] = { 0, };
491 bool is_advertising = FALSE;
493 ad = (bt_app_data_t *)data;
495 if (ad == NULL) return;
497 if (ad->initialize == FALSE) {
498 DBG("bt_deinitialize already done");
502 if (__bt_hf_is_connected(&remote_address[0]) == FALSE) {
503 ret = bt_adapter_is_advertising(&is_advertising);
504 if (ret == BT_ERROR_NONE && !is_advertising) {
505 ret = bt_adapter_start_advertising(NULL);
506 if (ret != BT_ERROR_NONE) {
507 ERR("bt_adapter_stop_advertising failed (0x%08x)", ret);
512 ret = bt_audio_unset_connection_state_changed_cb();
513 if (ret != BT_ERROR_NONE)
514 ERR("bt_audio_unset_connection_state_changed_cb is failed : %d", ret);
516 ret = bt_audio_deinitialize();
517 if (ret != BT_ERROR_NONE)
518 ERR("bt_audio_deinitialize is failed : %d", ret);
520 ret = bt_hf_deinitialize();
521 if (ret != BT_ERROR_NONE)
522 ERR("bt_hf_deinitialize is failed : %d", ret);
524 ret = bt_device_unset_connection_state_changed_cb();
525 if (ret != BT_ERROR_NONE)
526 ERR("bt_device_unset_connection_state_changed_cb is failed : %d", ret);
528 ret = bt_adapter_unset_state_changed_cb();
529 if (ret != BT_ERROR_NONE)
530 ERR("bt_adapter_unset_state_changed_cb is failed : %d", ret);
532 ret = bt_deinitialize();
533 if (ret != BT_ERROR_NONE)
534 ERR("bt_deinitialize is failed : %d", ret);
539 gboolean _bt_register_vconf_handler(void *data)
544 vconf_notify_key_changed(VCONFKEY_WMS_WMANAGER_CONNECTED,
545 (vconf_callback_fn) __bt_wms_status_handler, data);
547 ERR("Unable to register key handler");
554 void _bt_unregister_vconf_handler(void)
556 vconf_ignore_key_changed(VCONFKEY_WMS_WMANAGER_CONNECTED,
557 (vconf_callback_fn) __bt_wms_status_handler);