X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-service%2Fbt-service-device.c;h=4709e9d4437e5242f7bbef441e4768370ea3db51;hb=27501b58d0d88b999b8e574591ce7231ab088ea9;hp=792fd5fadf11422fed6b931f46dc92e8557da8d6;hpb=39a6cbc0e0b202a9ec628daacc1cd4128912964d;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-service/bt-service-device.c b/bt-service/bt-service-device.c index 792fd5f..4709e9d 100644 --- a/bt-service/bt-service-device.c +++ b/bt-service/bt-service-device.c @@ -84,12 +84,37 @@ typedef struct { char *pin_code; } bt_pin_code_info_t; +typedef struct { + int req_id; + bluetooth_device_address_t bd_addr; + gboolean auto_connect; +} bt_pending_le_conn_info_s; + +typedef struct { + char *address; + float interval_min; + float interval_max; + GSList *senders; +} bt_connected_le_dev_t; + +typedef struct { + char *sender; + float interval_min; + float interval_max; + guint16 latency; + guint16 time_out; + float key; +} bt_le_conn_param_t; + gboolean is_device_creating; bt_funcion_data_t *bonding_info; bt_funcion_data_t *searching_info; bt_funcion_data_t *att_mtu_req_info; +static GSList *le_connected_dev_list = NULL; static GSList *pin_info_list = NULL; +static bt_pending_le_conn_info_s *pending_le_conn_info = NULL; +static guint pending_le_conn_timer_id = 0; /* This HID Mouse does not support pairing precedure. need to skip it. */ #define SMB_MOUSE_LAP_ADDR "00:12:A1" @@ -97,9 +122,6 @@ static GSList *pin_info_list = NULL; static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data); -static int __bt_retry_bond(void); - - /*static void __bt_decline_pair_request() { GVariant *out_param1; @@ -183,7 +205,7 @@ done: BT_DBG("-"); } */ -#ifdef TIZEN_WEARABLE +#ifdef TIZEN_PROFILE_WEARABLE static gboolean __bt_syspopup_timer_cb(gpointer user_data) { int ret; @@ -209,7 +231,7 @@ static gboolean __bt_launch_unable_to_pairing_syspopup(int result) bundle *b = NULL; GDBusConnection *conn; - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); if (conn == NULL) return FALSE; @@ -350,7 +372,7 @@ bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path( retv_if(object_path == NULL, NULL); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); if (conn == NULL) { BT_ERR("conn == NULL"); return NULL; @@ -389,7 +411,7 @@ bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path( g_variant_unref(tmp_value); } - tmp_value = g_variant_lookup_value (value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN); + tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN); if (tmp_value) { dev_info->is_alias_set = g_variant_get_boolean(tmp_value); g_variant_unref(tmp_value); @@ -447,7 +469,7 @@ bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path( g_variant_unref(tmp_value); } - tmp_value = g_variant_lookup_value(value, "ManufacturerDataLen", G_VARIANT_TYPE_UINT16); + tmp_value = g_variant_lookup_value(value, "LegacyManufacturerDataLen", G_VARIANT_TYPE_UINT16); if (tmp_value) { dev_info->manufacturer_data_len = g_variant_get_uint16(tmp_value); if (dev_info->manufacturer_data_len > BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) { @@ -458,7 +480,7 @@ bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path( } else dev_info->manufacturer_data_len = 0; - tmp_value = g_variant_lookup_value(value, "ManufacturerData", G_VARIANT_TYPE_ARRAY); + tmp_value = g_variant_lookup_value(value, "LegacyManufacturerData", G_VARIANT_TYPE_ARRAY); if (tmp_value) { if ((dev_info->manufacturer_data_len == 0) || dev_info->manufacturer_data_len != g_variant_get_size(tmp_value)) { @@ -482,9 +504,8 @@ bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path( g_variant_get(tmp_value, "s", &address); g_variant_unref(tmp_value); - dev_info->address = g_strdup(address); - dev_info->name = g_strdup(name); - g_free(name); + dev_info->address = address; + dev_info->name = name; g_variant_unref(value); } else { BT_ERR("result is NULL\n"); @@ -495,20 +516,70 @@ bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path( return dev_info; } -char *_bt_get_bonded_device_name(char *address) +char *_bt_get_device_name(const char *bdaddress) { - bluetooth_device_address_t device_address = { {0} }; - bluetooth_device_info_t dev_info; + char *device_path = NULL; + const gchar *name = NULL; + gchar *dev_name = NULL; + gsize name_len = 0; + GVariant *result = NULL; + GError *err = NULL; + GDBusProxy *device_proxy; + GDBusConnection *conn; - retv_if(address == NULL, strdup("")); + retv_if(bdaddress == NULL, NULL); - _bt_convert_addr_string_to_type(device_address.addr, address); + device_path = _bt_get_device_object_path((char *)bdaddress); + retv_if(device_path == NULL, NULL); - memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t)); + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, NULL); + INFO_SECURE("Device_path %s", device_path); + device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, device_path, + BT_PROPERTIES_INTERFACE, NULL, &err); + + g_free(device_path); + retv_if(device_proxy == NULL, NULL); + + result = g_dbus_proxy_call_sync(device_proxy, "Get", + g_variant_new("(ss)", BT_DEVICE_INTERFACE, "Alias"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (err) { + BT_ERR("DBus Error : %s", err->message); + g_clear_error(&err); + } else { + GVariant *value; + g_variant_get(result, "(v)", &value); + name = g_variant_get_string(value, &name_len); + INFO_SECURE("Alias Name [%s]", name); + if (name_len) + dev_name = g_strdup(name); + g_variant_unref(value); + g_variant_unref(result); + } - _bt_get_bonded_device_info(&device_address, &dev_info); + if (name_len == 0) { + GVariant *value; + result = g_dbus_proxy_call_sync(device_proxy, "Get", + g_variant_new("(ss)", BT_DEVICE_INTERFACE, "Name"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (err) { + ERR("DBus Error : %s", err->message); + g_clear_error(&err); + } else { + g_variant_get(result, "(v)", &value); + name = g_variant_get_string(value, &name_len); + INFO_SECURE("Name = %s", name); + if (name_len) + dev_name = g_strdup(name); + g_variant_unref(value); + g_variant_unref(result); + } + } - return g_strdup(dev_info.device_name.name); + g_object_unref(device_proxy); + return dev_name; } static gboolean __ignore_auto_pairing_request(const char *address) @@ -550,12 +621,6 @@ static gboolean __ignore_auto_pairing_request(const char *address) } buffer = g_malloc0(sizeof(char) * size); - /* Fix : NULL_RETURNS */ - if (buffer == NULL) { - BT_ERR("Memory allocation error\n"); - fclose(fp); - return FALSE; - } result = fread((char *)buffer, 1, size, fp); fclose(fp); if (result != size) { @@ -623,95 +688,22 @@ static int __bt_cancel_bonding(void) return BLUETOOTH_ERROR_NONE; } -static int __bt_retry_bond(void) -{ - BT_CHECK_PARAMETER(bonding_info, return); - BT_CHECK_PARAMETER(bonding_info->addr, return); - - g_dbus_proxy_call(bonding_info->device_proxy, "Pair", - g_variant_new("(y)", bonding_info->conn_type), - G_DBUS_CALL_FLAGS_NONE, - BT_MAX_DBUS_TIMEOUT, - NULL, - (GAsyncReadyCallback)__bt_bond_device_cb, - NULL); - - return BLUETOOTH_ERROR_NONE; -} - - -static int __bt_remove_and_bond(void) -{ - GDBusProxy *adapter_proxy; - GVariant *result = NULL; - GError *err = NULL; - char *device_path = NULL; - - BT_CHECK_PARAMETER(bonding_info, return); - BT_CHECK_PARAMETER(bonding_info->addr, return); - - adapter_proxy = _bt_get_adapter_proxy(); - retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - - result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice", - g_variant_new("(s)", bonding_info->addr), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL); - if (result == NULL) - return BLUETOOTH_ERROR_INTERNAL; - - g_variant_get(result , "(o)", &device_path); - g_variant_unref(result); - - retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); - - result = g_dbus_proxy_call_sync(adapter_proxy, "UnpairDevice", - g_variant_new("(o)", device_path), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &err); - g_free(device_path); - if (err != NULL) { - BT_ERR("UnpairDevice Fail: %s", err->message); - g_error_free(err); - return BLUETOOTH_ERROR_INTERNAL; - } - - return __bt_retry_bond(); -} - -static int __bt_cancel_and_bond(void) -{ - int ret = BLUETOOTH_ERROR_NONE; - - ret = _bt_agent_reply_cancellation(); - if (ret != BLUETOOTH_ERROR_NONE) { - BT_ERR("Fail to call reply cancellation"); - return ret; - } - return __bt_retry_bond(); -} - - static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) { int result = BLUETOOTH_ERROR_NONE; GError *err = NULL; + GVariant *reply; GVariant *out_param1; request_info_t *req_info; bluetooth_device_info_t dev_info; - bt_remote_dev_info_t *remote_dev_info; - GVariant *manufacture_data; - GVariant *param; /* Terminate ALL system popup */ syspopup_destroy_all(); - g_dbus_proxy_call_finish(proxy, res, &err); + reply = g_dbus_proxy_call_finish(proxy, res, &err); + if (reply) + g_variant_unref(reply); is_device_creating = FALSE; @@ -734,10 +726,8 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, BT_ERR("Error occured in CreateBonding [%s]", err->message); if (g_strrstr(err->message, "Already Exists")) { - BT_INFO("Existing Bond, remove and retry"); - ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE); - - result = BLUETOOTH_ERROR_PARING_FAILED; + BT_INFO("Existing Bond"); + result = BLUETOOTH_ERROR_ALREADY_CONNECT; } else if (_bt_agent_is_canceled() || g_strrstr(err->message, "Authentication Canceled")) { BT_INFO("Cancelled by USER"); @@ -746,10 +736,8 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, BT_INFO("REJECTED"); result = BLUETOOTH_ERROR_ACCESS_DENIED; } else if (g_strrstr(err->message, "In Progress")) { - BT_INFO("Bond in progress, cancel and retry"); - ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE); - - result = BLUETOOTH_ERROR_PARING_FAILED; + BT_INFO("Bond in progress"); + result = BLUETOOTH_ERROR_IN_PROGRESS; } else if (g_strrstr(err->message, "Authentication Failed")) { BT_INFO("Authentication Failed"); if (bonding_info->is_autopair == TRUE) { @@ -767,7 +755,7 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, result = BLUETOOTH_ERROR_HOST_DOWN; } else if (g_strrstr(err->message, BT_DBUS_TIMEOUT_MESSAGE)) { BT_INFO("Cancel already running bonding"); - if(__bt_cancel_bonding() != BLUETOOTH_ERROR_NONE) { + if (__bt_cancel_bonding() != BLUETOOTH_ERROR_NONE) { BT_INFO("Error while Cancelling bonding"); /* we need to unref proxy so continue */ } @@ -788,7 +776,7 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, result == BLUETOOTH_ERROR_AUTHENTICATION_FAILED || result == BLUETOOTH_ERROR_TIMEOUT || result == BLUETOOTH_ERROR_HOST_DOWN) { -#ifdef TIZEN_WEARABLE +#ifdef TIZEN_PROFILE_WEARABLE int is_sw_running = 0; if (vconf_get_int(VCONFKEY_SETUP_WIZARD_STATE, &is_sw_running)) @@ -845,45 +833,6 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, goto dbus_return; } - remote_dev_info = _bt_get_remote_device_info(bonding_info->addr); - if(!remote_dev_info) - goto dbus_return; - - GVariant *uuids = NULL; - GVariantBuilder *builder = NULL; - int i = 0; - builder = g_variant_builder_new(G_VARIANT_TYPE("as")); - for (i = 0; i < remote_dev_info->uuid_count; i++) { - g_variant_builder_add(builder, "s", - remote_dev_info->uuids[i]); - } - uuids = g_variant_new("as", builder); - g_variant_builder_unref(builder); - manufacture_data = g_variant_new_from_data((const GVariantType *)"ay", - remote_dev_info->manufacturer_data, remote_dev_info->manufacturer_data_len, - TRUE, NULL, NULL); - - param = g_variant_new("(isunsbub@asn@ay)", - result, - bonding_info->addr, - remote_dev_info->class, - remote_dev_info->rssi, - remote_dev_info->name, - remote_dev_info->paired, - remote_dev_info->connected, - remote_dev_info->trust, - uuids, - remote_dev_info->manufacturer_data_len, - manufacture_data); - - - /* Send the event to application */ - _bt_send_event(BT_ADAPTER_EVENT, - BLUETOOTH_EVENT_BONDING_FINISHED, - param); - - _bt_free_device_info(remote_dev_info); - dbus_return: if (req_info->context == NULL) goto done; @@ -945,7 +894,7 @@ int _bt_bond_device(int request_id, return BLUETOOTH_ERROR_DEVICE_BUSY; } - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -1053,13 +1002,16 @@ static void __bt_unbond_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) { GError *err = NULL; + GVariant *reply; GVariant *out_param1; int result = BLUETOOTH_ERROR_NONE; bt_funcion_data_t *unbonding_info; bluetooth_device_info_t dev_info; request_info_t *req_info; - g_dbus_proxy_call_finish(proxy, res, &err); + reply = g_dbus_proxy_call_finish(proxy, res, &err); + if (reply) + g_variant_unref(reply); unbonding_info = user_data; @@ -1127,12 +1079,6 @@ int _bt_unbond_device(int request_id, /* allocate user data so that it can be retrieved in callback */ unbonding_info = g_malloc0(sizeof(bt_funcion_data_t)); - /* Fix : NULL_RETURNS */ - if (unbonding_info == NULL) { - BT_ERR("Memory not allocated !"); - return BLUETOOTH_ERROR_MEMORY_ALLOCATION; - } - unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE); unbonding_info->req_id = request_id; @@ -1147,7 +1093,7 @@ int _bt_unbond_device(int request_id, goto fail; } - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); if (conn == NULL) { BT_ERR("conn is NULL"); result = BLUETOOTH_ERROR_INTERNAL; @@ -1211,6 +1157,7 @@ static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) { GError *err = NULL; + GVariant *reply; GVariant *out_param1; int result = BLUETOOTH_ERROR_NONE; bluetooth_device_info_t dev_info; @@ -1221,7 +1168,9 @@ static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res, GVariantBuilder *builder = NULL; int i = 0; - g_dbus_proxy_call_finish(proxy, res, &err); + reply = g_dbus_proxy_call_finish(proxy, res, &err); + if (reply) + g_variant_unref(reply); g_object_unref(proxy); @@ -1241,15 +1190,14 @@ static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res, g_dbus_error_strip_remote_error(err); BT_ERR("Error occured in Proxy call [%s]\n", err->message); - if (g_strrstr("Operation canceled", err->message)) { + if (g_strrstr("Operation canceled", err->message)) result = BLUETOOTH_ERROR_CANCEL_BY_USER; - } else if (g_strrstr("In Progress", err->message)) { + else if (g_strrstr("In Progress", err->message)) result = BLUETOOTH_ERROR_IN_PROGRESS; - } else if (g_strrstr("Host is down", err->message)) { + else if (g_strrstr("Host is down", err->message)) result = BLUETOOTH_ERROR_HOST_DOWN; - } else { + else result = BLUETOOTH_ERROR_CONNECTION_ERROR; - } if (result == BLUETOOTH_ERROR_HOST_DOWN || result == BLUETOOTH_ERROR_CONNECTION_ERROR) { @@ -1265,7 +1213,7 @@ static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res, } remote_dev_info = _bt_get_remote_device_info(searching_info->addr); - if(!remote_dev_info) + if (!remote_dev_info) goto dbus_return; event: @@ -1360,7 +1308,7 @@ int _bt_search_device(int request_id, _bt_convert_addr_type_to_string(searching_info->addr, device_address->addr); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1439,7 +1387,7 @@ int _bt_set_alias(bluetooth_device_address_t *device_address, adapter_proxy = _bt_get_adapter_proxy(); retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -1493,7 +1441,7 @@ int _bt_set_authorization(bluetooth_device_address_t *device_address, BT_CHECK_PARAMETER(device_address, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -1538,7 +1486,7 @@ int _bt_set_authorization(bluetooth_device_address_t *device_address, } result = g_dbus_proxy_call_sync(device_proxy, "Set", - g_variant_new("(ssv)", BT_DEVICE_INTERFACE, "Trusted", g_variant_new("b",authorize)), + g_variant_new("(ssv)", BT_DEVICE_INTERFACE, "Trusted", g_variant_new("b", authorize)), G_DBUS_CALL_FLAGS_NONE, -1, NULL, @@ -1566,14 +1514,13 @@ int _bt_is_gatt_connected(bluetooth_device_address_t *device_address, GDBusProxy *device_proxy; GError *error = NULL; GVariant *value; - GVariant *tmp_value; GDBusConnection *conn; GVariant *result = NULL; int ret = BLUETOOTH_ERROR_NONE; BT_CHECK_PARAMETER(device_address, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -1587,8 +1534,9 @@ int _bt_is_gatt_connected(bluetooth_device_address_t *device_address, g_free(object_path); retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - result = g_dbus_proxy_call_sync(device_proxy, "GetAll", - g_variant_new("(s)", BT_DEVICE_INTERFACE), + result = g_dbus_proxy_call_sync(device_proxy, "Get", + g_variant_new("(ss)", BT_DEVICE_INTERFACE, + "GattConnected"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, @@ -1602,21 +1550,12 @@ int _bt_is_gatt_connected(bluetooth_device_address_t *device_address, return BLUETOOTH_ERROR_INTERNAL; } - g_variant_get(result , "(@a{sv})", &value); + g_variant_get(result, "(v)", &value); + *is_connected = g_variant_get_boolean(value); g_variant_unref(result); - tmp_value = g_variant_lookup_value(value, "GattConnected", G_VARIANT_TYPE_BOOLEAN); - if (tmp_value == NULL) { - g_object_unref(device_proxy); - g_variant_unref(value); - return BLUETOOTH_ERROR_INTERNAL; - } - - *is_connected = g_variant_get_boolean(tmp_value); - BT_DBG("gatt is connected : %d", *is_connected); - g_variant_unref(tmp_value); g_variant_unref(value); g_object_unref(device_proxy); @@ -1628,6 +1567,7 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, { char *object_path = NULL; char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 }; GDBusProxy *device_proxy = NULL; GDBusProxy *adapter_proxy = NULL; GDBusConnection *conn; @@ -1640,18 +1580,24 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM); retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + _bt_convert_addr_type_to_string(address, device_address->addr); + _bt_convert_addr_string_to_secure_string(secure_address, address); + *is_connected = FALSE; - BT_DBG("connection_type: %d", connection_type); + BT_DBG("%s connection_type: 0x%02x", secure_address, connection_type); + if (connection_type == BLUETOOTH_RFCOMM_SERVICE) return _bt_rfcomm_is_device_connected(device_address, is_connected); else if (connection_type == BLUETOOTH_GATT_SERVICE) return _bt_is_gatt_connected(device_address, is_connected); + else if (connection_type == BLUETOOTH_PBAP_SERVICE) + return _bt_pbap_is_connected(device_address, is_connected); adapter_proxy = _bt_get_adapter_proxy(); retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -1680,8 +1626,9 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, BT_ERR("%s", error->message); g_error_free(error); } + *is_connected = FALSE; g_object_unref(device_proxy); - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ERROR_NONE; } g_variant_get(result , "(@a{sv})", &value); g_variant_unref(result); @@ -1702,11 +1649,10 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, } else { uuid = _bt_get_profile_uuid128(connection_type); if (uuid == NULL) { - BT_ERR("uuid is NULL"); + BT_ERR("connection_type: %d, uuid is NULL", connection_type); return BLUETOOTH_ERROR_INTERNAL; } - - BT_DBG("uuid: %s", uuid); + BT_DBG("uuid %s [%s]", uuid, _bt_convert_uuid_to_string(uuid)); object_path = _bt_get_device_object_path(address); retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED); @@ -1729,16 +1675,17 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, &error); if (result == NULL) { - int ret = BLUETOOTH_ERROR_INTERNAL; BT_ERR("[IsConnectedProfile] Error occured in Proxy call"); if (error) { BT_ERR("%s", error->message); if (g_strrstr(error->message, "Not Connected")) - ret = BLUETOOTH_ERROR_NOT_CONNECTED; + BT_DBG("Not connected"); g_error_free(error); } + *is_connected = FALSE; g_object_unref(device_proxy); - return ret; + g_free(uuid); + return BLUETOOTH_ERROR_NONE; } g_variant_get(result, "(b)", is_connected); g_free(uuid); @@ -1758,13 +1705,12 @@ int _bt_get_connected_link(bluetooth_device_address_t *device_address, GDBusProxy *device_proxy; GError *error = NULL; GDBusConnection *conn; - GVariant *tmp_value = NULL; GVariant *value = NULL; GVariant *result = NULL; BT_CHECK_PARAMETER(device_address, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -1781,33 +1727,24 @@ int _bt_get_connected_link(bluetooth_device_address_t *device_address, return BLUETOOTH_ERROR_NONE; } - result = g_dbus_proxy_call_sync(device_proxy, "GetAll", - g_variant_new("(s)", BT_DEVICE_INTERFACE), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); + result = g_dbus_proxy_call_sync(device_proxy, "Get", + g_variant_new("(ss)", BT_DEVICE_INTERFACE, "Connected"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error != NULL) { BT_ERR("Error occured in Proxy call [%s]\n", error->message); g_error_free(error); g_object_unref(device_proxy); return BLUETOOTH_ERROR_INTERNAL; + } else { + g_variant_get(result, "(v)", &value); + *connected = g_variant_get_byte(value); + g_variant_unref(value); + g_variant_unref(result); } - g_variant_get(result , "(@a{sv})", &value); - g_variant_unref(result); - - tmp_value = g_variant_lookup_value(value, "Connected", G_VARIANT_TYPE_BYTE); - if (tmp_value != NULL) { - *connected = g_variant_get_byte(tmp_value); - g_variant_unref(tmp_value); - g_object_unref(device_proxy); - return BLUETOOTH_ERROR_NONE; - } else { - BT_ERR("g_variant value is NULL"); - return BLUETOOTH_ERROR_INTERNAL; - } + g_object_unref(device_proxy); + return BLUETOOTH_ERROR_NONE; } static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res, @@ -1871,10 +1808,11 @@ done: } } -int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr, - gboolean auto_connect) +static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_address_t *bd_addr, + gboolean auto_connect) { char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 }; gchar *device_path = NULL; GDBusProxy *device_proxy = NULL; GDBusConnection *conn; @@ -1883,7 +1821,7 @@ int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr, BT_CHECK_PARAMETER(bd_addr, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(device_address, @@ -1909,12 +1847,10 @@ int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr, goto fail; } - func_data->req_id = req_id; + _bt_convert_addr_string_to_secure_string(secure_address, device_address); + BT_INFO("Connect LE [%s]", secure_address); - ret = _bt_hold_current_advertising(); - if (ret != BLUETOOTH_ERROR_NONE) { - BT_ERR("Unable to hold advertising"); - } + func_data->req_id = req_id; g_dbus_proxy_call(device_proxy, "ConnectLE", g_variant_new("(b)", auto_connect), @@ -1928,17 +1864,69 @@ int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr, fail: if (device_proxy) g_object_unref(device_proxy); - if (func_data) { - g_free(func_data->address); - g_free(func_data); - } + + g_free(func_data->address); + g_free(func_data); + return ret; } +static gboolean __bt_connect_le_timer_cb(gpointer user_data) +{ + BT_INFO("Try to initiate pending LE connection"); + + pending_le_conn_timer_id = 0; + + __bt_connect_le_device_internal(pending_le_conn_info->req_id, + &pending_le_conn_info->bd_addr, + pending_le_conn_info->auto_connect); + + g_free(pending_le_conn_info); + pending_le_conn_info = NULL; + + return FALSE; +} + +void _bt_pending_connect_le_device(void) +{ + if (pending_le_conn_timer_id > 0) { + g_source_remove(pending_le_conn_timer_id); + __bt_connect_le_timer_cb(NULL); + } +} + +int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr, + gboolean auto_connect) +{ + int ret = BLUETOOTH_ERROR_NONE; + + BT_CHECK_PARAMETER(bd_addr, return); + + ret = _bt_hold_current_advertising(); + if (ret == BLUETOOTH_ERROR_NONE) { + BT_INFO("Current advertising is held"); + pending_le_conn_info = g_malloc0(sizeof(bt_pending_le_conn_info_s)); + pending_le_conn_info->req_id = req_id; + memcpy(pending_le_conn_info->bd_addr.addr, bd_addr->addr, + BLUETOOTH_ADDRESS_LENGTH); + pending_le_conn_info->auto_connect = auto_connect; + + pending_le_conn_timer_id = + g_timeout_add(1000, __bt_connect_le_timer_cb, NULL); + + return BLUETOOTH_ERROR_NONE; + } else if (ret != BLUETOOTH_ERROR_NOT_IN_OPERATION) { + BT_ERR("Unable to hold advertising"); + } + + return __bt_connect_le_device_internal(req_id, bd_addr, auto_connect); +} + int _bt_disconnect_le_device(int req_id, const bluetooth_device_address_t *bd_addr) { char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 }; gchar *device_path; GDBusProxy *device_proxy; GDBusConnection *conn; @@ -1947,7 +1935,7 @@ int _bt_disconnect_le_device(int req_id, BT_CHECK_PARAMETER(bd_addr, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(device_address, @@ -1975,6 +1963,9 @@ int _bt_disconnect_le_device(int req_id, goto fail; } + _bt_convert_addr_string_to_secure_string(secure_address, device_address); + BT_INFO("Disconnect LE [%s]", secure_address); + func_data->req_id = req_id; g_dbus_proxy_call(device_proxy, "DisconnectLE", @@ -1988,10 +1979,10 @@ int _bt_disconnect_le_device(int req_id, fail: if (device_proxy) g_object_unref(device_proxy); - if (func_data) { - g_free(func_data->address); - g_free(func_data); - } + + g_free(func_data->address); + g_free(func_data); + return ret; } @@ -2010,7 +2001,7 @@ int _bt_connect_le_ipsp_device(const bluetooth_device_address_t *bd_addr) _bt_convert_addr_type_to_string(device_address, (unsigned char *)bd_addr->addr); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); adapter_proxy = _bt_get_adapter_proxy(); @@ -2064,7 +2055,7 @@ int _bt_disconnect_le_ipsp_device(const bluetooth_device_address_t *bd_addr) _bt_convert_addr_type_to_string(device_address, (unsigned char *)bd_addr->addr); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); adapter_proxy = _bt_get_adapter_proxy(); @@ -2113,7 +2104,7 @@ int _bt_connect_profile(char *address, char *uuid, GVariant *result = NULL; GError *error = NULL; - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); object_path = _bt_get_device_object_path(address); @@ -2158,30 +2149,71 @@ int _bt_connect_profile(char *address, char *uuid, return BLUETOOTH_ERROR_NONE; } -int _bt_disconnect_profile(char *address, char *uuid, - void *cb, gpointer func_data) +int _bt_disconnect_all(char *address) { + int ret = BLUETOOTH_ERROR_NONE; char *object_path; GDBusProxy *proxy; GDBusConnection *conn; + GVariant *result = NULL; + GError *err = NULL; - conn = _bt_get_system_gconn(); + BT_DBG(""); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); object_path = _bt_get_device_object_path(address); retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL); proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, - NULL, BT_BLUEZ_NAME, - object_path, BT_DEVICE_INTERFACE, NULL, NULL); + NULL, BT_BLUEZ_NAME, + object_path, BT_DEVICE_INTERFACE, NULL, NULL); g_free(object_path); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - g_dbus_proxy_call(proxy, "DisconnectProfile", - g_variant_new("(s)", uuid), - G_DBUS_CALL_FLAGS_NONE, - BT_MAX_DBUS_TIMEOUT, - NULL, + result = g_dbus_proxy_call_sync(proxy, "Disconnect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, + &err); + + if (err != NULL) { + BT_ERR("Dbus Call Error:[%s]", err->message); + g_error_free(err); + ret = BLUETOOTH_ERROR_INTERNAL; + } + + g_object_unref(proxy); + if (result) + g_variant_unref(result); + + return ret; +} + +int _bt_disconnect_profile(char *address, char *uuid, + void *cb, gpointer func_data) +{ + char *object_path; + GDBusProxy *proxy; + GDBusConnection *conn; + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + object_path = _bt_get_device_object_path(address); + retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL); + + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, + object_path, BT_DEVICE_INTERFACE, NULL, NULL); + g_free(object_path); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + g_dbus_proxy_call(proxy, "DisconnectProfile", + g_variant_new("(s)", uuid), + G_DBUS_CALL_FLAGS_NONE, + BT_MAX_DBUS_TIMEOUT, + NULL, (GAsyncReadyCallback)cb, func_data); @@ -2269,59 +2301,24 @@ int _bt_get_rssi_strength(bluetooth_device_address_t *bd_addr, return ret; } -int _bt_le_conn_update(unsigned char *device_address, +static int __bt_le_set_conn_parameter(const char *address, float interval_min, float interval_max, guint16 latency, guint16 time_out) { - char address[BT_ADDRESS_STRING_SIZE] = { 0 }; gchar *device_path = NULL; GError *error = NULL; GDBusProxy *device_proxy = NULL; GDBusConnection *conn; GVariant *reply; guint32 min, max, to; - guint32 min_supervision_to; int ret = BLUETOOTH_ERROR_NONE; - BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_PARAMETER(address, return); BT_INFO("Min interval: %f, Max interval: %f, Latency: %u, Supervision timeout: %u", interval_min, interval_max, latency, time_out); - if (interval_min > interval_max || - interval_min < BT_LE_CONN_INTERVAL_MIN || - interval_max > BT_LE_CONN_INTERVAL_MAX) { - ret = BLUETOOTH_ERROR_INVALID_PARAM; - goto fail; - } - - if (time_out < BT_LE_CONN_SUPER_TO_MIN || - time_out > BT_LE_CONN_SUPER_TO_MAX) { - ret = BLUETOOTH_ERROR_INVALID_PARAM; - goto fail; - } - - if (latency > BT_LE_CONN_SLAVE_LATENCY_MAX) { - ret = BLUETOOTH_ERROR_INVALID_PARAM; - goto fail; - } - - /* - * The Supervision_Timeout in milliseconds shall be larger than - * (1 + Conn_Latency) * Conn_Interval_Max * 2, - * where Conn_Interval_Max is given in milliseconds. - */ - min_supervision_to = (1 + latency) * interval_max * 2; - if (time_out <= min_supervision_to) { - ret = BLUETOOTH_ERROR_INVALID_PARAM; - goto fail; - } - - _bt_convert_addr_type_to_string(address, device_address); - - BT_DBG("Remote device address: %s", address); - - device_path = _bt_get_device_object_path(address); + device_path = _bt_get_device_object_path((char *)address); if (device_path == NULL) { BT_ERR("device_path NULL"); @@ -2329,7 +2326,7 @@ int _bt_le_conn_update(unsigned char *device_address, goto fail; } - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); if (conn == NULL) { BT_ERR("conn NULL"); ret = BLUETOOTH_ERROR_INTERNAL; @@ -2372,6 +2369,306 @@ fail: return ret; } +static void __bt_le_conn_param_free(void *data) +{ + bt_le_conn_param_t *param = (bt_le_conn_param_t *)data; + + BT_DBG("%s", param->sender); + g_free(param->sender); + g_free(param); +} + +static gint __bt_compare_le_conn_param_key(gpointer *a, gpointer *b) +{ + bt_le_conn_param_t *parama = (bt_le_conn_param_t *)a; + bt_le_conn_param_t *paramb = (bt_le_conn_param_t *)b; + + return parama->key > paramb->key; +} + +static bt_connected_le_dev_t *__bt_get_le_connected_dev_info(const char *address) +{ + GSList *l = NULL; + bt_connected_le_dev_t *dev; + + if (!address) + return NULL; + + for (l = le_connected_dev_list; l; l = g_slist_next(l)) { + dev = l->data; + + if (g_strcmp0(dev->address, address) == 0) + return dev; + } + return NULL; +} + +static bt_le_conn_param_t *__bt_get_le_conn_param_info(bt_connected_le_dev_t *dev, const char *sender) +{ + GSList *l = NULL; + bt_le_conn_param_t *param = NULL; + + if (!dev || !sender) + return NULL; + + for (l = dev->senders; l; l = g_slist_next(l)) { + param = l->data; + if (g_strcmp0(param->sender, sender) == 0) + return param; + } + + return NULL; +} + +int _bt_add_le_conn_param_info(const char *address, const char *sender, + float interval_min, float interval_max, guint16 latency, guint16 time_out) +{ + bt_connected_le_dev_t *dev = NULL; + bt_le_conn_param_t *param = NULL; + bt_le_conn_param_t *data = NULL; + + if (!address || !sender) + return BLUETOOTH_ERROR_INVALID_PARAM; + + dev = __bt_get_le_connected_dev_info(address); + if (!dev) + return BLUETOOTH_ERROR_INTERNAL; + + param = __bt_get_le_conn_param_info(dev, sender); + + data = g_malloc0(sizeof(bt_le_conn_param_t)); + data->sender = g_strdup(sender); + data->interval_min = interval_min; + data->interval_max = interval_max; + data->latency = latency; + data->time_out = time_out; + data->key = interval_min + (interval_max - interval_min)/2; + + if (param == NULL) { + BT_DBG("Add param %s %s %f %f", address, sender, interval_min, interval_max); + dev->senders = g_slist_append(dev->senders, data); + } else { + BT_DBG("Update param %s %s %f %f", address, sender, interval_min, interval_max); + dev->senders = g_slist_remove(dev->senders, param); + g_free(param->sender); + g_free(param); + dev->senders = g_slist_append(dev->senders, data); + } + + /* Sorting. First element have the minimum interval */ + dev->senders = g_slist_sort(dev->senders, + (GCompareFunc)__bt_compare_le_conn_param_key); + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_remove_le_conn_param_info(const char *address, const char *sender, gboolean *is_removed) +{ + bt_connected_le_dev_t *dev = NULL; + bt_le_conn_param_t *param = NULL; + + if (!address || !sender) + return BLUETOOTH_ERROR_INVALID_PARAM; + + dev = __bt_get_le_connected_dev_info(address); + if (!dev) + return BLUETOOTH_ERROR_INTERNAL; + + param = __bt_get_le_conn_param_info(dev, sender); + if (param) { + BT_DBG("Remove param %s %s ", address, sender); + dev->senders = g_slist_remove(dev->senders, param); + g_free(param->sender); + g_free(param); + *is_removed = TRUE; + } else + *is_removed = FALSE; + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_remove_all_le_conn_param_info(const char *sender) +{ + GSList *l = NULL; + bt_connected_le_dev_t *dev = NULL; + bt_le_conn_param_t *param = NULL; + gboolean is_removed = FALSE; + char *sender_new = NULL; + unsigned char addr[BLUETOOTH_ADDRESS_LENGTH]; + int ret = BLUETOOTH_ERROR_NONE; + + if (!sender) + return BLUETOOTH_ERROR_INVALID_PARAM; + + for (l = le_connected_dev_list; l; l = g_slist_next(l)) { + dev = l->data; + _bt_remove_le_conn_param_info(dev->address, sender, &is_removed); + + if (is_removed) { + BT_INFO("Sender terminated. Update le conn interval [senders %d]", + g_slist_length(dev->senders)); + if (g_slist_length(dev->senders) > 0) { + param = dev->senders->data; + BT_DBG("dev %f %f, param %f %f", dev->interval_min, dev->interval_max, + param->interval_min, param->interval_max); + + if (dev->interval_min != param->interval_min || + dev->interval_max != param->interval_max) { + sender_new = g_strdup(param->sender); + + _bt_convert_addr_string_to_type(addr, dev->address); + ret = _bt_le_conn_update(sender_new, addr, + param->interval_min, param->interval_max, + param->latency, param->time_out); + g_free(sender_new); + + if (ret != BLUETOOTH_ERROR_NONE) + BT_ERR("Unable to set le connection parameter"); + } + } else { + BT_INFO("Set the default interval"); + + bluetooth_le_connection_param_t param = { 0 }; + _bt_get_le_connection_parameter( + BLUETOOTH_LE_CONNECTION_MODE_LOW_POWER, + ¶m); + + ret = __bt_le_set_conn_parameter(dev->address, + param.interval_min, param.interval_max, + param.latency, param.timeout); + if (ret == BLUETOOTH_ERROR_NONE) { + dev->interval_min = param.interval_min; + dev->interval_max = param.interval_max; + } + } + } + } + + return ret; +} + +void _bt_add_le_connected_dev_info(const char *address) +{ + bt_connected_le_dev_t *dev = NULL; + + if (!address) + return; + + dev = g_malloc0(sizeof(bt_connected_le_dev_t)); + dev->address = g_strdup(address); + + le_connected_dev_list = g_slist_append(le_connected_dev_list, dev); + + return; +} + +void _bt_remove_le_connected_dev_info(const char *address) +{ + bt_connected_le_dev_t *dev = NULL; + + if (!address) + return; + + dev = __bt_get_le_connected_dev_info(address); + if (!dev) + return; + + g_slist_free_full(dev->senders, __bt_le_conn_param_free); + le_connected_dev_list = g_slist_remove(le_connected_dev_list, dev); + g_free(dev->address); + g_free(dev); + + return; +} + +int _bt_le_conn_update(const char *sender, + unsigned char *device_address, + float interval_min, float interval_max, + guint16 latency, guint16 time_out) +{ + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + guint32 min_supervision_to; + bt_connected_le_dev_t *dev = NULL; + bt_le_conn_param_t *param = NULL; + gboolean is_removed = FALSE; + int ret = BLUETOOTH_ERROR_NONE; + + BT_CHECK_PARAMETER(device_address, return); + + BT_DBG("Sender %s, Min interval: %f, Max interval: %f, Latency: %u, Supervision timeout: %u", + sender, interval_min, interval_max, latency, time_out); + + if (interval_min > interval_max || + interval_min < BT_LE_CONN_INTERVAL_MIN || + interval_max > BT_LE_CONN_INTERVAL_MAX) { + ret = BLUETOOTH_ERROR_INVALID_PARAM; + goto fail; + } + + if (time_out < BT_LE_CONN_SUPER_TO_MIN || + time_out > BT_LE_CONN_SUPER_TO_MAX) { + ret = BLUETOOTH_ERROR_INVALID_PARAM; + goto fail; + } + + if (latency > BT_LE_CONN_SLAVE_LATENCY_MAX) { + ret = BLUETOOTH_ERROR_INVALID_PARAM; + goto fail; + } + + /* + * The Supervision_Timeout in milliseconds shall be larger than + * (1 + Conn_Latency) * Conn_Interval_Max * 2, + * where Conn_Interval_Max is given in milliseconds. + */ + min_supervision_to = (1 + latency) * interval_max * 2; + if (time_out <= min_supervision_to) { + ret = BLUETOOTH_ERROR_INVALID_PARAM; + goto fail; + } + + _bt_convert_addr_type_to_string(address, device_address); + BT_DBG("Remote device address: %s", address); + + _bt_add_le_conn_param_info(address, sender, interval_min, interval_max, 0, 2000); + + dev = __bt_get_le_connected_dev_info(address); + if (dev == NULL) { + ret = BLUETOOTH_ERROR_NOT_CONNECTED; + goto fail; + } + + if (g_slist_length(dev->senders) == 1) + goto update; + else { + param = dev->senders->data; + + BT_DBG("dev %f, param %f, input %f", dev->interval_min, param->interval_min, interval_min); + + if (dev->interval_min == param->interval_min && dev->interval_max == param->interval_max) { + BT_DBG("Skip due to same interval"); + return ret; + } + + interval_min = param->interval_min; + interval_max = param->interval_max; + } + +update: + ret = __bt_le_set_conn_parameter(address, interval_min, interval_max, latency, time_out); + + if (ret != BLUETOOTH_ERROR_NONE) { + _bt_remove_le_conn_param_info(address, sender, &is_removed); + return ret; + } + + dev->interval_min = interval_min; + dev->interval_max = interval_max; + +fail: + return ret; +} + int _bt_set_pin_code(bluetooth_device_address_t *device_address, bluetooth_device_pin_code_t *pin_code) { @@ -2536,6 +2833,29 @@ int _bt_get_trusted_profile_from_flag(bluetooth_trusted_profile_t profile, return BLUETOOTH_ERROR_NONE; } +int _bt_get_restricted_profile_from_flag(bluetooth_restricted_profile_t profile, + guint restricted_profile_flag, guint *restricted) +{ + int restrict_profile; + *restricted = FALSE; + + switch (profile) { + case RESTRICTED_PROFILE_HFP_HS: + restrict_profile = restricted_profile_flag & (1 << 0); + break; + case RESTRICTED_PROFILE_A2DP: + restrict_profile = restricted_profile_flag & (1 << 2); + break; + default: + return BLUETOOTH_ERROR_NOT_SUPPORT; + } + + if (restrict_profile) + *restricted = TRUE; + + return BLUETOOTH_ERROR_NONE; +} + char *_bt_get_trusted_profile_uuid(bluetooth_trusted_profile_t profile) { switch (profile) { @@ -2552,15 +2872,27 @@ char *_bt_get_trusted_profile_uuid(bluetooth_trusted_profile_t profile) return NULL; } +char *_bt_get_restricted_profile_uuid(bluetooth_restricted_profile_t profile) +{ + switch (profile) { + case RESTRICTED_PROFILE_HFP_HS: + return g_strdup("0000111e-0000-1000-8000-00805f9b34fb"); + case RESTRICTED_PROFILE_A2DP: + return g_strdup("0000110b-0000-1000-8000-00805f9b34fb"); + } + + return NULL; +} + bluetooth_trusted_profile_t _bt_get_trusted_profile_enum(const char *uuid) { - if (g_strcmp0("0000112f-0000-1000-8000-00805f9b34fb", uuid) == 0) { + if (g_strcmp0("0000112f-0000-1000-8000-00805f9b34fb", uuid) == 0) return TRUSTED_PROFILE_PBAP; - } else if (g_strcmp0("00001132-0000-1000-8000-00805f9b34fb", uuid) == 0) { + else if (g_strcmp0("00001132-0000-1000-8000-00805f9b34fb", uuid) == 0) return TRUSTED_PROFILE_MAP; - } else if (g_strcmp0("0000112D-0000-1000-8000-00805f9b34fb", uuid) == 0) { + else if (g_strcmp0("0000112D-0000-1000-8000-00805f9b34fb", uuid) == 0) return TRUSTED_PROFILE_SAP; - } + return 0; /* 0 - Unknown Profile */ } @@ -2583,7 +2915,7 @@ int _bt_set_trust_profile(bluetooth_device_address_t *bd_addr, bd_addr->addr[4], bd_addr->addr[5], profile, trust); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, bd_addr->addr); @@ -2645,7 +2977,7 @@ int _bt_get_trust_profile(bluetooth_device_address_t *bd_addr, bd_addr->addr[4], bd_addr->addr[5], profile, *trust); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, bd_addr->addr); @@ -2690,6 +3022,132 @@ int _bt_get_trust_profile(bluetooth_device_address_t *bd_addr, return ret; } +int _bt_set_restrict_profile(bluetooth_device_address_t *bd_addr, + bluetooth_restricted_profile_t profile, gboolean restricted) +{ + int ret = BLUETOOTH_ERROR_NONE; + GDBusConnection *conn; + GDBusProxy *proxy; + GError *error = NULL; + char *device_path = NULL; + char *uuid = NULL; + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + GVariant *reply; + + BT_CHECK_PARAMETER(bd_addr, return); + BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] profile[%d] restricted[%d]", + bd_addr->addr[0], bd_addr->addr[1], + bd_addr->addr[2], bd_addr->addr[3], + bd_addr->addr[4], bd_addr->addr[5], + profile, restricted); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + _bt_convert_addr_type_to_string(address, bd_addr->addr); + + device_path = _bt_get_device_object_path(address); + retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); + + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, device_path, + BT_DEVICE_INTERFACE, NULL, NULL); + + g_free(device_path); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + uuid = _bt_get_restricted_profile_uuid(profile); + if (uuid == NULL) { + g_object_unref(proxy); + return BLUETOOTH_ERROR_NOT_SUPPORT; + } + + reply = g_dbus_proxy_call_sync(proxy, "SetRestrictedProfile", + g_variant_new("(sb)", uuid, restricted), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref(proxy); + + if (reply == NULL) { + BT_ERR("Failed to Set Profile Restricted"); + ret = BLUETOOTH_ERROR_INTERNAL; + if (error) { + BT_ERR("Error %s[%s]", error->message, address); + g_error_free(error); + } + goto finish; + } + g_variant_unref(reply); + +finish: + g_free(uuid); + return ret; +} + +int _bt_get_restrict_profile(bluetooth_device_address_t *bd_addr, + bluetooth_restricted_profile_t profile, guint *restricted) +{ + int ret = BLUETOOTH_ERROR_NONE; + GDBusConnection *conn; + GDBusProxy *proxy; + GError *error = NULL; + char *device_path = NULL; + guint restricted_profile_flag; + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + GVariant *reply; + + BT_CHECK_PARAMETER(bd_addr, return); + BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] profile[%d] restricted[%d]", + bd_addr->addr[0], bd_addr->addr[1], + bd_addr->addr[2], bd_addr->addr[3], + bd_addr->addr[4], bd_addr->addr[5], + profile, *restricted); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + _bt_convert_addr_type_to_string(address, bd_addr->addr); + + device_path = _bt_get_device_object_path(address); + retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); + + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, device_path, + BT_PROPERTIES_INTERFACE, NULL, NULL); + + g_free(device_path); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + reply = g_dbus_proxy_call_sync(proxy, "Get", + g_variant_new("(ss)", BT_DEVICE_INTERFACE, "RestrictedProfiles"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref(proxy); + + if (reply == NULL) { + BT_ERR("Failed to Get Profile Restricted"); + ret = BLUETOOTH_ERROR_INTERNAL; + if (error) { + BT_ERR("Error %s[%s]", error->message, address); + g_error_free(error); + } + *restricted = 0; + } else { + GVariant *temp; + g_variant_get(reply, "(v)", &temp); + restricted_profile_flag = g_variant_get_uint32(temp); + BT_DBG("Restricted_FLAG %d", restricted_profile_flag); + + ret = _bt_get_restricted_profile_from_flag(profile, + restricted_profile_flag, restricted); + g_variant_unref(temp); + g_variant_unref(reply); + } + + BT_DBG("TRUST %d", *restricted); + return ret; +} + static void __bt_request_att_mtu_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) { @@ -2739,8 +3197,8 @@ static void __bt_request_att_mtu_device_cb(GDBusProxy *proxy, GAsyncResult *res, goto dbus_return; if (val) { - g_variant_get (val, "(qy)", &mtu, &status); - g_variant_unref (val); + g_variant_get(val, "(qy)", &mtu, &status); + g_variant_unref(val); } BT_DBG("MTU %d, Status %d, %s", mtu, status, att_mtu_req_info->addr); @@ -2797,7 +3255,7 @@ int _bt_request_att_mtu(int request_id, bluetooth_device_address_t *device_addre return BLUETOOTH_ERROR_DEVICE_BUSY; } - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); adapter_proxy = _bt_get_adapter_proxy(); @@ -2817,12 +3275,6 @@ int _bt_request_att_mtu(int request_id, bluetooth_device_address_t *device_addre g_free(device_path); retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - if (device_path == NULL) { - BT_DBG("device_path NULL"); - ret = BLUETOOTH_ERROR_INTERNAL; - goto fail; - } - att_mtu_req_info = g_malloc0(sizeof(bt_funcion_data_t)); att_mtu_req_info->addr = (char *)g_strdup(address); att_mtu_req_info->req_id = request_id; @@ -2835,7 +3287,7 @@ int _bt_request_att_mtu(int request_id, bluetooth_device_address_t *device_addre NULL, (GAsyncReadyCallback)__bt_request_att_mtu_device_cb, NULL); -fail: + return ret; } @@ -2848,14 +3300,12 @@ int _bt_get_att_mtu(bluetooth_device_address_t *device_address, GDBusProxy *device_proxy; GError *error = NULL; GVariant *value; - GVariant *tmp_value; GDBusConnection *conn; GVariant *result = NULL; - int ret = BLUETOOTH_ERROR_NONE; BT_CHECK_PARAMETER(device_address, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -2869,40 +3319,29 @@ int _bt_get_att_mtu(bluetooth_device_address_t *device_address, g_free(object_path); retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - result = g_dbus_proxy_call_sync(device_proxy, "GetAll", - g_variant_new("(s)", BT_DEVICE_INTERFACE), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (result == NULL) { - if (error != NULL) { - BT_ERR("Error occured in Proxy call [%s]\n", error->message); - g_error_free(error); - } + result = g_dbus_proxy_call_sync(device_proxy, "Get", + g_variant_new("(ss)", BT_DEVICE_INTERFACE, "AttMtu"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("DBus Error : %s", error->message); + g_clear_error(&error); g_object_unref(device_proxy); return BLUETOOTH_ERROR_INTERNAL; - } - - g_variant_get(result , "(@a{sv})", &value); - g_variant_unref(result); - - tmp_value = g_variant_lookup_value(value, "AttMtu", G_VARIANT_TYPE_UINT16); - if (tmp_value == NULL) { - g_object_unref(device_proxy); + } else { + g_variant_get(result, "(v)", &value); + *mtu = g_variant_get_uint16(value); + BT_DBG("ATT MTU : %d", *mtu); g_variant_unref(value); - return BLUETOOTH_ERROR_INTERNAL; - } - - *mtu = g_variant_get_uint16(tmp_value); + g_variant_unref(result); - BT_DBG("ATT MTU : %d", *mtu); + if (*mtu == 0) { + g_object_unref(device_proxy); + return BLUETOOTH_ERROR_NOT_CONNECTED; + } + } - g_variant_unref(tmp_value); - g_variant_unref(value); g_object_unref(device_proxy); - - return ret; + return BLUETOOTH_ERROR_NONE; } int _bt_get_device_ida(bluetooth_device_address_t *device_address, @@ -2919,7 +3358,7 @@ int _bt_get_device_ida(bluetooth_device_address_t *device_address, BT_CHECK_PARAMETER(device_address, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); _bt_convert_addr_type_to_string(address, device_address->addr); @@ -2928,48 +3367,37 @@ int _bt_get_device_ida(bluetooth_device_address_t *device_address, retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED); device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, - NULL, BT_BLUEZ_NAME, - device_path, BT_DEVICE_INTERFACE, NULL, NULL); + NULL, BT_BLUEZ_NAME, + device_path, BT_DEVICE_INTERFACE, NULL, NULL); g_free(device_path); if (!device_proxy) { BT_ERR("Unable to get proxy"); return BLUETOOTH_ERROR_INTERNAL; } - result = g_dbus_proxy_call_sync(device_proxy, "GetIDAddress", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - + result = g_dbus_proxy_call_sync(device_proxy, "GetIDAddress", NULL, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (result == NULL) { BT_ERR("Failed to get device ID address"); + + ret = BLUETOOTH_ERROR_INTERNAL; if (error != NULL) { - BT_ERR("Error occured in Proxy call [%s]\n", error->message); + g_dbus_error_strip_remote_error(error); + BT_ERR("Error occured in Proxy call [%s]", error->message); + if (g_strcmp0(error->message, "Does Not Exist") == 0) + ret = BLUETOOTH_ERROR_NOT_PAIRED; g_error_free(error); } g_object_unref(device_proxy); - return BLUETOOTH_ERROR_INTERNAL; - } - - g_variant_get(result , "(s)", &idaddress); - g_variant_unref(result); - - if (idaddress == NULL) { - BT_ERR("No paired device"); - g_object_unref(device_proxy); - return BLUETOOTH_ERROR_NOT_PAIRED; + return ret; } - BT_DBG("ID Address:%s", idaddress); + g_variant_get(result , "(&s)", &idaddress); - if (idaddress) { - _bt_convert_addr_string_to_type(id_address->addr, idaddress); - } else { - ret = BLUETOOTH_ERROR_INTERNAL; - } + DBG_SECURE("ID Address : %s", idaddress); + _bt_convert_addr_string_to_type(id_address->addr, idaddress); + g_variant_unref(result); g_object_unref(device_proxy); return ret;