void _bt_cb_visibility_mode_changed
(int result, bt_adapter_visibility_mode_e visibility_mode, void *user_data);
+#ifdef TIZEN_FEATURE_BT_HOG
+void _bt_cb_gatt_connection_state_changed(int result, bool connected, char *remote_address, void *user_data);
+
+void _bt_cb_new_le_device_found(int result, bt_adapter_le_device_scan_result_info_s *info, void *data);
+#endif
+
void _bt_cb_bonding_created(int result, bt_device_info_s *device_info,
void *user_data);
bool aul_launching_req;
bool aul_pairing_req;
bool is_discovery_started;
+#ifdef TIZEN_FEATURE_BT_HOG
+ bool is_le_discovery_started;
+#endif
unsigned int op_status;
unsigned int ug_status;
unsigned int help_status;
void _bt_main_disconnect_device(bt_ug_data *ugd, bt_dev_t *dev);
+#ifdef TIZEN_FEATURE_BT_HOG
+int _bt_main_request_connect_with_effect(bt_ug_data *ugd, Elm_Object_Item *seleted_item);
+
+bt_dev_t *_bt_main_create_searched_le_device_item(void *data);
+#endif
+
int _bt_main_request_pairing_with_effect(bt_ug_data *ugd,
Elm_Object_Item *seleted_item);
BT_NETWORK_CONNECTED = 0x08,
BT_NETWORK_SERVER_CONNECTED = 0x10,
BT_MUSIC_PLAYER_CONNECTED = 0x20,
+#ifdef TIZEN_FEATURE_BT_HOG
+ BT_LE_HID_CONNECTED = 0x40,
+#endif
} bt_connected_mask_t;
/**
gboolean hid_checked;
gboolean network_checked;
gboolean highlighted;
+#ifdef TIZEN_FEATURE_BT_HOG
+ gboolean is_le_device;
+#endif
void *ugd;
int pan_connection_result;
} bt_dev_t;
#include "bt-resource.h"
#include "bt-net-connection.h"
#include "syspopup_caller.h"
+#include "bt-callback.h"
/**********************************************************************
* Static Functions
_bt_main_remove_all_searched_devices(ugd);
+#ifdef TIZEN_FEATURE_BT_HOG
+ ret = bt_adapter_le_start_scan((bt_adapter_le_scan_result_cb)_bt_cb_new_le_device_found, (void *)ugd);
+ if (!ret) {
+ ugd->is_le_discovery_started = TRUE;
+ BT_DBG("LE Discovery started");
+ } else {
+ BT_ERR("LE Discovery failed : Error Cause[%d]", ret);
+ }
+#endif
+
ret = bt_adapter_start_device_discovery();
if (!ret) {
ugd->op_status = BT_SEARCHING;
FN_END;
}
-
static bool __bt_cb_match_discovery_type(unsigned int major_class,
unsigned int service_class,
unsigned int mask)
__bt_cb_disable(result, user_data);
}
+#ifdef TIZEN_FEATURE_BT_HOG
+void _bt_cb_new_le_device_found(int result, bt_adapter_le_device_scan_result_info_s *info, void *data)
+{
+ FN_START;
+
+ bt_ug_data *ugd = NULL;
+ bt_dev_t *dev = NULL;
+ char *remote_name = NULL;
+ int ret;
+
+ ret_if(info == NULL);
+ ret_if(data == NULL);
+
+ ugd = (bt_ug_data *)data;
+ ret_if(ugd->op_status != BT_SEARCHING);
+
+ ret = bt_adapter_le_get_scan_result_device_name(info, BT_ADAPTER_LE_PACKET_ADVERTISING, &remote_name);
+ if (ret != BT_ERROR_NONE)
+ BT_ERR("Fail to get le device name");
+
+ if(ugd->searched_device == NULL)
+ _bt_update_genlist_item(ugd->searched_title);
+
+ if (_bt_main_check_and_update_device(ugd->searched_device,
+ info->remote_address,
+ remote_name) >= 0) {
+ _bt_update_device_list(ugd);
+ } else {
+ dev = _bt_main_create_searched_le_device_item((void *)info);
+ if (NULL == dev) {
+ BT_ERR("Create new device item failed");
+ return;
+ }
+
+ if (_bt_main_add_searched_device(ugd, dev) == NULL) {
+ BT_ERR("Fail to add the searched device");
+ return;
+ }
+
+ ugd->searched_device =
+ eina_list_append(ugd->searched_device, dev);
+ }
+
+ FN_END;
+}
+#endif
+
void _bt_cb_discovery_state_changed(int result,
- bt_adapter_device_discovery_state_e discovery_state,
+ bt_adapter_device_discovery_state_e discovery_state,
bt_adapter_device_discovery_info_s *discovery_info,
void *user_data)
{
bt_ug_data *ugd = NULL;
+#ifdef TIZEN_FEATURE_BT_HOG
+ int ret;
+#endif
+
ret_if(user_data == NULL);
ugd = (bt_ug_data *)user_data;
__bt_cb_new_device_found(discovery_info, user_data);
else if (discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_FINISHED) {
BT_INFO("BR/EDR discovery finished");
+#ifndef TIZEN_FEATURE_BT_HOG
ret_if(ugd->is_discovery_started == FALSE);
+#else
+ ret_if((ugd->is_discovery_started == FALSE) && (ugd->is_le_discovery_started == FALSE));
+ if (ugd->is_le_discovery_started == TRUE) {
+ ret = bt_adapter_le_stop_scan();
+ if (!ret)
+ ugd->is_le_discovery_started = FALSE;
+ }
+#endif
__bt_cb_search_completed(result, user_data);
if (ugd->op_status == BT_PAIRING)
elm_object_disabled_set(ugd->scan_btn, EINA_TRUE);
FN_END;
}
+#ifdef TIZEN_FEATURE_BT_HOG
+void _bt_cb_gatt_connection_state_changed(int result, bool connected, char *remote_address, void *user_data)
+{
+ FN_START;
+
+ bt_ug_data *ugd = NULL;
+ bt_dev_t *dev = NULL;
+ int connected_type;
+ bt_address_t address = { { 0 } };
+
+ ret_if(user_data == NULL);
+ _bt_util_addr_string_to_addr_type(address.bd_addr, remote_address);
+
+ /* TODO : Other GATT scenario should be considered.
+ In this case, only HOG scenario is considered */
+ connected_type = BT_LE_HID_CONNECTED;
+
+
+ ugd = (bt_ug_data *)user_data;
+ ret_if(ugd->op_status == BT_DEACTIVATING);
+
+ if (ugd->op_status == BT_PAIRING)
+ ugd->op_status = BT_ACTIVATED;
+ /* In the NFC cas, we don't need to display the paired device */
+ if (ugd->bt_launch_mode == BT_LAUNCH_USE_NFC)
+ return;
+
+ dev = _bt_main_get_dev_info_by_address(ugd->searched_device, remote_address);
+ if (dev == NULL && ugd->searched_item != NULL)
+ dev = _bt_main_get_dev_info(ugd->searched_device, ugd->searched_item);
+
+ elm_object_disabled_set(ugd->scan_btn, EINA_FALSE);
+
+ if (connected) {
+ if (result != BT_ERROR_NONE) {
+ BT_ERR("Failed to GATT connect with device [%d]", result);
+ } else {
+ BT_DBG("LE Connected");
+ }
+ } else {
+ BT_DBG("LE Disconnected");
+ }
+
+ _bt_ipc_update_connected_status(ugd, connected_type,
+ connected, result, &address);
+}
+#endif
+
void _bt_cb_bonding_created(int result, bt_device_info_s *dev_info,
void *user_data)
{
if (dev == NULL && ugd->searched_item != NULL)
dev = _bt_main_get_dev_info(ugd->searched_device, ugd->searched_item);
+#ifdef TIZEN_FEATURE_BT_HOG
+ if (dev) {
+ if (dev->is_le_device)
+ BT_DBG("it is the le device");
+ else
+ BT_DBG("it is not le device");
+ } else {
+ BT_DBG("dev is null");
+ return;
+ }
+#endif
+
elm_object_disabled_set(ugd->scan_btn, EINA_FALSE);
if (result != BT_ERROR_NONE) {
BT_ERR("new_dev is NULL");
return;
}
+
+#ifdef TIZEN_FEATURE_BT_HOG
+ if (dev->is_le_device)
+ new_dev->is_le_device = TRUE;
+ else
+ new_dev->is_le_device = FALSE;
+#endif
+
#ifndef TIZEN_BT_A2DP_SINK_ENABLE
profile = _bt_get_registered_net_profile(ugd->connection,
new_dev->bd_addr);
/* Don't try to auto-connect in the network case */
if (profile == NULL && ugd->searched_item != NULL) {
- if (_bt_main_is_connectable_device(new_dev))
- _bt_main_connect_device(ugd, new_dev);
+ if (_bt_main_is_connectable_device(new_dev)) {
+ _bt_main_connect_device(ugd, new_dev);
+ }
} else {
BT_DBG("Net profile exists");
int connected = _bt_util_is_profile_connected(
if (item == NULL)
item = _bt_main_get_dev_info(ugd->paired_device, ugd->paired_item);
+#ifdef TIZEN_FEATURE_BT_HOG
+ /* In GATT connection case, connection failed event is recieved before the pairing is completed.
+ So, it can get device info from searched device list */
+ if ((item == NULL) && (connected_type == BT_LE_HID_CONNECTED))
+ item = _bt_main_get_dev_info_by_address(ugd->searched_device, addr_str);
+#endif
+
if (item == NULL)
return;
case BT_HID_CONNECTED:
profile = BT_PROFILE_HID;
break;
+#ifdef TIZEN_FEATURE_BT_HOG
+ case BT_LE_HID_CONNECTED:
+ profile = BT_PROFILE_GATT;
+ break;
+#endif
case BT_NETWORK_CONNECTED:
profile = BT_PROFILE_NAP;
break;
if (connected)
goto done;
}
+
+#ifdef TIZEN_FEATURE_BT_HOG
+ /* TODO : other GATT device scenario should be considered.
+ In this case, only HOG device scenario is considered. */
+ if (dev->is_le_device) {
+ connected = _bt_util_is_profile_connected(BT_LE_HID_CONNECTED,
+ dev->bd_addr);
+ if (connected)
+ goto done;
+ }
+#endif
+
FN_END;
done:
return connected;
if (ret != BT_ERROR_NONE)
BT_ERR("adapter set device discovery state callback failed");
+#ifdef TIZEN_FEATURE_BT_HOG
+ ret = bt_gatt_set_connection_state_changed_cb
+ ((bt_gatt_connection_state_changed_cb)_bt_cb_gatt_connection_state_changed, (void *)ugd);
+ if (ret != BT_ERROR_NONE)
+ BT_ERR("gatt set connection state callback failed");
+#endif
+
ret = bt_adapter_set_visibility_mode_changed_cb
- (_bt_cb_visibility_mode_changed, (void *)ugd);
+ (_bt_cb_visibility_mode_changed, (void *)ugd);
if (ret != BT_ERROR_NONE)
BT_ERR("adapter set device visibility mode callback failed");
/* In the NFC case, we don't need to display the paired device */
if (ugd->op_status == BT_ACTIVATED &&
- ugd->bt_launch_mode != BT_LAUNCH_USE_NFC &&
- ugd->bt_launch_mode != BT_LAUNCH_ONOFF) {
+ ugd->bt_launch_mode != BT_LAUNCH_USE_NFC &&
+ ugd->bt_launch_mode != BT_LAUNCH_ONOFF) {
if (_bt_util_is_battery_low() == FALSE) {
+
+#ifdef TIZEN_FEATURE_BT_HOG
+ ret = bt_adapter_le_start_scan((bt_adapter_le_scan_result_cb)_bt_cb_new_le_device_found, (void *)ugd);
+ if (!ret) {
+ ugd->is_le_discovery_started = TRUE;
+ BT_DBG("LE Discovery started");
+ } else {
+ BT_ERR("LE Discovery failed : Error Cause[%d]", ret);
+ }
+#endif
ret = bt_adapter_start_device_discovery();
if (!ret) {
ugd->op_status = BT_SEARCHING;
elm_object_text_set(ugd->scan_btn,
- BT_STR_STOP);
+ BT_STR_STOP);
if (ugd->searched_title == NULL)
_bt_main_add_searched_title
#define SHARE_CONTACT_ITEM_SHARE_MODE "http://tizen.org/appcontrol/data/social/namecard_share_mode"
#define HELP_SETUP_BLUETOOTH_URI "tizen-help://ug-bluetooth-efl/setupbluetooth"
+#ifdef TIZEN_FEATURE_BT_HOG
+/* GATT Services */
+#define HOGP_SERVICE_UUID "1812"
+#endif
+
/**********************************************************************
* Static Functions declaration
***********************************************************************/
retv_if(dev == NULL, FALSE);
+#ifdef TIZEN_FEATURE_BT_HOG
+ /* For LE Device */
+ if (dev->is_le_device) {
+ BT_DBG("It is LE Device");
+ return TRUE;
+ }
+#endif
+
if (dev->service_list == 0) {
if (bt_adapter_get_bonded_device_info
((const char *)dev->addr_str,
FN_START;
bt_ug_data *ugd = NULL;
+#ifdef TIZEN_FEATURE_BT_HOG
+ int ret;
+#endif
retm_if(data == NULL, "Invalid argument: bt_ug_data is NULL");
if (ugd->op_status == BT_SEARCHING) {
if (ugd->is_discovery_started) {
+
+#ifdef TIZEN_FEATURE_BT_HOG
+ if (ugd->is_le_discovery_started == TRUE) {
+ ret = bt_adapter_le_stop_scan();
+ if (!ret)
+ ugd->is_le_discovery_started = FALSE;
+ }
+#endif
if (bt_adapter_stop_device_discovery() == BT_ERROR_NONE) {
elm_object_disabled_set(ugd->scan_btn, EINA_TRUE);
elm_object_text_set(ugd->scan_btn, BT_STR_STOP);
ugd->paired_item = item;
+#ifndef TIZEN_FEATURE_BT_HOG
if (dev->service_list == 0) {
- if (bt_device_start_service_search
- ((const char *)dev->addr_str) == BT_ERROR_NONE) {
-
- dev->status = BT_SERVICE_SEARCHING;
- ugd->waiting_service_response = TRUE;
- ugd->request_timer =
- ecore_timer_add(BT_SEARCH_SERVICE_TIMEOUT,
- (Ecore_Task_Cb)
- _bt_main_service_request_cb,
- ugd);
-
- _bt_update_genlist_item(ugd->paired_item);
- return;
- } else {
- BT_ERR("service search error");
- return;
- }
+#else
+ if ((dev->service_list == 0) && (!dev->is_le_device)) {
+#endif
+ if (bt_device_start_service_search
+ ((const char *)dev->addr_str) == BT_ERROR_NONE) {
+
+ dev->status = BT_SERVICE_SEARCHING;
+ ugd->waiting_service_response = TRUE;
+ ugd->request_timer =
+ ecore_timer_add(BT_SEARCH_SERVICE_TIMEOUT,
+ (Ecore_Task_Cb)
+ _bt_main_service_request_cb,
+ ugd);
+
+ _bt_update_genlist_item(ugd->paired_item);
+ return;
+ } else {
+ BT_ERR("service search error");
+ return;
+ }
}
if (dev->is_connected == 0) {
}
if (ugd->op_status == BT_SEARCHING) {
+#ifdef TIZEN_FEATURE_BT_HOG
+ if (ugd->is_le_discovery_started == TRUE) {
+ ret = bt_adapter_le_stop_scan();
+ if (!ret)
+ ugd->is_le_discovery_started = FALSE;
+ }
+#endif
ret = bt_adapter_stop_device_discovery();
if (ret != BT_ERROR_NONE)
BT_ERR("Fail to stop discovery");
return;
}
+#ifndef TIZEN_FEATURE_BT_HOG
if (_bt_main_request_pairing_with_effect(ugd, item) != BT_UG_ERROR_NONE)
ugd->searched_item = NULL;
+#else
+ if (dev->is_le_device) {
+ if (_bt_main_request_connect_with_effect(ugd, item) != BT_UG_ERROR_NONE)
+ ugd->searched_item = NULL;
+
+ } else {
+ if (_bt_main_request_pairing_with_effect(ugd, item) != BT_UG_ERROR_NONE)
+ ugd->searched_item = NULL;
+ }
+
+#endif
FN_END;
}
return TRUE;
}
+#ifdef TIZEN_FEATURE_BT_HOG
+bt_dev_t *_bt_main_create_searched_le_device_item(void *data)
+{
+ FN_START;
+
+ int ret;
+ unsigned char bd_addr[BT_ADDRESS_LENGTH_MAX];
+ bt_dev_t *dev = NULL;
+ bt_adapter_le_device_scan_result_info_s *dev_info = NULL;
+ char *remote_name = NULL;
+ int count;
+ char **uuids;
+ int i;
+ int is_hog = 0;
+
+ retv_if(data == NULL, NULL);
+
+ dev_info = (bt_adapter_le_device_scan_result_info_s *) data;
+ ret = bt_adapter_le_get_scan_result_device_name(dev_info, BT_ADAPTER_LE_PACKET_ADVERTISING, &remote_name);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("Fail to get LE device name");
+ return NULL;
+ }
+
+ if (strlen(remote_name) == 0)
+ return NULL;
+
+ /* only HOG Device will be shown in searched list */
+ if (bt_adapter_le_get_scan_result_service_uuids(
+ dev_info, BT_ADAPTER_LE_PACKET_ADVERTISING, &uuids, &count) == BT_ERROR_NONE) {
+ for (i = 0; i < count; i++) {
+ BT_DBG("UUID[%d] = %s", i + 1, uuids[i]);
+ if (g_strcmp0(HOGP_SERVICE_UUID, uuids[i]) == 0)
+ is_hog++;
+
+ }
+ } else
+ BT_ERR("Fail to get LE service uuids");
+
+ if (!is_hog)
+ return NULL;
+
+ dev = calloc(1, sizeof(bt_dev_t));
+ retv_if(dev == NULL, NULL);
+
+ strncpy(dev->name, remote_name, DEVICE_NAME_MAX_LEN);
+
+ dev->rssi = dev_info->rssi;
+ dev->is_le_device = TRUE;
+
+ _bt_util_addr_string_to_addr_type(bd_addr, dev_info->remote_address);
+
+ memcpy(dev->addr_str, dev_info->remote_address, BT_ADDRESS_STR_LEN);
+
+ memcpy(dev->bd_addr, bd_addr, BT_ADDRESS_LENGTH_MAX);
+
+ BT_DBG("device name [%s]", dev->name);
+ BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", dev->bd_addr[0],
+ dev->bd_addr[1], dev->bd_addr[2], dev->bd_addr[3],
+ dev->bd_addr[4], dev->bd_addr[5]);
+
+ FN_END;
+ return dev;
+}
+#endif
+
/**********************************************************************
* Common Functions
***********************************************************************/
if (!ret)
elm_object_disabled_set(ugd->scan_btn, EINA_TRUE);
} else {
+#ifdef TIZEN_FEATURE_BT_HOG
+ ret = bt_adapter_le_start_scan((bt_adapter_le_scan_result_cb)_bt_cb_new_le_device_found, (void *)ugd);
+ if (!ret) {
+ ugd->is_le_discovery_started = TRUE;
+ BT_DBG("LE Discovery started");
+ } else {
+ BT_ERR("LE Discovery failed : Error Cause[%d]", ret);
+ }
+#endif
ret = bt_adapter_start_device_discovery();
if (!ret) {
/* Disable the Scan button till the BLUETOOTH_EVENT_DISCOVERY_STARTED is received */
ugd->paired_device =
eina_list_append(ugd->paired_device, dev);
+#ifndef TIZEN_FEATURE_BT_HOG
if (dev->service_list == 0) {
+#else
+ if ((dev->service_list == 0) && (!dev->is_le_device)) {
+#endif
if (bt_device_start_service_search
((const char *)dev->addr_str) == BT_ERROR_NONE) {
}
}
}
+#ifndef TIZEN_FEATURE_BT_HOG
}
-
+#else
+ } else if ((dev->is_le_device) && (ugd->connect_req == FALSE)) {
+ if (bt_gatt_connect(dev->addr_str, false) == BT_ERROR_NONE) {
+ ugd->connect_req = TRUE;
+ dev->status = BT_CONNECTING;
+ } else {
+ BT_ERR("Fail to connect le device");
+ }
+ }
+#endif
_bt_update_genlist_item((Elm_Object_Item *) dev->genlist_item);
FN_END;
} else {
BT_ERR("Failed to disconnect pan server");
}
- } else {
+#ifdef TIZEN_FEATURE_BT_HOG
+ } else if (dev->is_le_device) {
+ if (bt_gatt_disconnect(dev->addr_str) == BT_UG_ERROR_NONE) {
+ ugd->connect_req = true;
+ dev->status = BT_DISCONNECTING;
+ } else {
+ BT_ERR("Failed to disconnect gatt");
+ }
+#endif
+ } else {
void *net_profile;
gboolean connected = FALSE;
FN_END;
}
+#ifdef TIZEN_FEATURE_BT_HOG
+int _bt_main_request_connect_with_effect(bt_ug_data *ugd,
+ Elm_Object_Item *seleted_item)
+{
+ FN_START;
+
+ bt_dev_t *dev;
+
+ retvm_if(ugd == NULL, BT_UG_FAIL, "Invalid argument: ugd is NULL");
+ retvm_if(seleted_item == NULL, BT_UG_FAIL,
+ "Invalid argument: object is NULL");
+
+ dev = _bt_main_get_dev_info(ugd->searched_device, seleted_item);
+ retvm_if(dev == NULL, BT_UG_FAIL, "Invalid argument: dev is NULL");
+
+ if (bt_gatt_connect(dev->addr_str, false) == BT_ERROR_NONE) {
+ dev->status = BT_DEV_PAIRING;
+ ugd->op_status = BT_PAIRING;
+ ugd->connect_req = TRUE;
+
+ elm_object_disabled_set(ugd->scan_btn, EINA_TRUE);
+ _bt_update_genlist_item(seleted_item);
+ } else {
+ return BT_UG_FAIL;
+ }
+
+ FN_END;
+ return BT_UG_ERROR_NONE;
+}
+#endif
+
int _bt_main_request_pairing_with_effect(bt_ug_data *ugd,
Elm_Object_Item *seleted_item)
{
&dev->major_class, &dev->minor_class);
}
+#ifdef TIZEN_FEATURE_BT_HOG
+ /* TODO : modify for checking LE device */
+ if ((dev->major_class == 0) && (dev->minor_class == 0)) {
+ BT_DBG("there are no major and minor class");
+ dev->is_le_device = TRUE;
+ }
+#endif
+
FN_END;
return dev;
}
dev->minor_class = dev_info->bt_class.minor_device_class;
dev->service_class = dev_info->bt_class.major_service_class_mask;
dev->rssi = dev_info->rssi;
+#ifdef TIZEN_FEATURE_BT_HOG
+ dev->is_le_device = FALSE;
+#endif
if (dev_info->service_uuid != NULL && dev_info->service_count > 0) {
dev->uuids = g_new0(char *, dev_info->service_count + 1);
%if "%{?profile}" == "mobile"
export CFLAGS="$CFLAGS -DTIZEN_HID"
+#export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_HOG"
%endif
%if "%{?profile}" == "common"