X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-service%2Fbt-service-device.c;h=4709e9d4437e5242f7bbef441e4768370ea3db51;hb=8be593a40f32cf0245157f62c313ea02658204a7;hp=206af0887f5c49b0d687eb88e6d6a0e5ef0e5e78;hpb=7bbbb922f719a9f3056c974a2d714152f9baa7fe;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-service/bt-service-device.c b/bt-service/bt-service-device.c index 206af08..4709e9d 100644 --- a/bt-service/bt-service-device.c +++ b/bt-service/bt-service-device.c @@ -90,11 +90,28 @@ typedef struct { 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; @@ -105,9 +122,6 @@ static guint pending_le_conn_timer_id = 0; 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; @@ -455,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) { @@ -466,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)) { @@ -490,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"); @@ -503,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); - _bt_get_bonded_device_info(&device_address, &dev_info); + 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); + } - return g_strdup(dev_info.device_name.name); + 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); + } + } + + g_object_unref(device_proxy); + return dev_name; } static gboolean __ignore_auto_pairing_request(const char *address) @@ -558,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) { @@ -631,79 +688,6 @@ 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) { @@ -713,9 +697,6 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, 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(); @@ -745,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"); @@ -757,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) { @@ -856,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; @@ -1141,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; @@ -1582,7 +1514,6 @@ 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; @@ -1603,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, @@ -1618,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); @@ -1644,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; @@ -1656,8 +1580,12 @@ 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); @@ -1721,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); @@ -1778,7 +1705,6 @@ 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; @@ -1801,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, @@ -1895,6 +1812,7 @@ static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_ad 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; @@ -1922,12 +1840,6 @@ static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_ad retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); func_data = g_malloc0(sizeof(bt_function_data_t)); - if (func_data == NULL) { - BT_ERR("Unable to allocate memory for address"); - ret = BLUETOOTH_ERROR_MEMORY_ALLOCATION; - goto fail; - } - func_data->address = g_strdup(device_address); if (func_data->address == NULL) { BT_ERR("Unable to allocate memory for address"); @@ -1935,6 +1847,9 @@ static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_ad goto fail; } + _bt_convert_addr_string_to_secure_string(secure_address, device_address); + BT_INFO("Connect LE [%s]", secure_address); + func_data->req_id = req_id; g_dbus_proxy_call(device_proxy, "ConnectLE", @@ -1949,10 +1864,10 @@ static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_ad 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; } @@ -2000,10 +1915,10 @@ int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr, 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"); } - BT_ERR("Unable to hold advertising"); - return __bt_connect_le_device_internal(req_id, bd_addr, auto_connect); } @@ -2011,6 +1926,7 @@ 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; @@ -2040,12 +1956,6 @@ int _bt_disconnect_le_device(int req_id, retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); func_data = g_malloc0(sizeof(bt_function_data_t)); - if (func_data == NULL) { - BT_ERR("Unable to allocate memory for address"); - ret = BLUETOOTH_ERROR_MEMORY_ALLOCATION; - goto fail; - } - func_data->address = g_strdup(device_address); if (func_data->address == NULL) { BT_ERR("Unable to allocate memory for address"); @@ -2053,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", @@ -2066,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; } @@ -2388,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"); @@ -2491,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) { @@ -3097,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; @@ -3115,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; } @@ -3128,10 +3300,8 @@ 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); @@ -3149,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, @@ -3208,47 +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;