Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d0db0a3 authored by Marcel Holtmann's avatar Marcel Holtmann
Browse files

[Bluetooth] Use a more unique bus name for connections



When attaching Bluetooth low-level connections to the bus, the bus name
is constructed from the remote address since at that time the connection
handle is not assigned yet. This has worked so far, but also caused a
lot of troubles. It is better to postpone the creation of the sysfs
entry to the time when the connection actually has been established
and then use its connection handle as unique identifier.

This also fixes the case where two different adapters try to connect
to the same remote device.

Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 43cbeee9
Loading
Loading
Loading
Loading
+5 −3
Original line number Original line Diff line number Diff line
@@ -245,8 +245,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
	if (hdev->notify)
	if (hdev->notify)
		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);


	hci_conn_add_sysfs(conn);

	tasklet_enable(&hdev->tx_task);
	tasklet_enable(&hdev->tx_task);


	return conn;
	return conn;
@@ -278,12 +276,14 @@ int hci_conn_del(struct hci_conn *conn)
	}
	}


	tasklet_disable(&hdev->tx_task);
	tasklet_disable(&hdev->tx_task);

	hci_conn_hash_del(hdev, conn);
	hci_conn_hash_del(hdev, conn);
	if (hdev->notify)
	if (hdev->notify)
		hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
		hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);

	tasklet_enable(&hdev->tx_task);
	tasklet_enable(&hdev->tx_task);

	skb_queue_purge(&conn->data_q);
	skb_queue_purge(&conn->data_q);
	hci_conn_del_sysfs(conn);


	return 0;
	return 0;
}
}
@@ -532,6 +532,8 @@ void hci_conn_hash_flush(struct hci_dev *hdev)


		c->state = BT_CLOSED;
		c->state = BT_CLOSED;


		hci_conn_del_sysfs(c);

		hci_proto_disconn_ind(c, 0x16);
		hci_proto_disconn_ind(c, 0x16);
		hci_conn_del(c);
		hci_conn_del(c);
	}
	}
+7 −0
Original line number Original line Diff line number Diff line
@@ -874,6 +874,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
		} else
		} else
			conn->state = BT_CONNECTED;
			conn->state = BT_CONNECTED;


		hci_conn_add_sysfs(conn);

		if (test_bit(HCI_AUTH, &hdev->flags))
		if (test_bit(HCI_AUTH, &hdev->flags))
			conn->link_mode |= HCI_LM_AUTH;
			conn->link_mode |= HCI_LM_AUTH;


@@ -1011,6 +1013,9 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
	if (conn) {
	if (conn) {
		conn->state = BT_CLOSED;
		conn->state = BT_CLOSED;

		hci_conn_del_sysfs(conn);

		hci_proto_disconn_ind(conn, ev->reason);
		hci_proto_disconn_ind(conn, ev->reason);
		hci_conn_del(conn);
		hci_conn_del(conn);
	}
	}
@@ -1643,6 +1648,8 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
	if (!ev->status) {
	if (!ev->status) {
		conn->handle = __le16_to_cpu(ev->handle);
		conn->handle = __le16_to_cpu(ev->handle);
		conn->state  = BT_CONNECTED;
		conn->state  = BT_CONNECTED;

		hci_conn_add_sysfs(conn);
	} else
	} else
		conn->state = BT_CLOSED;
		conn->state = BT_CLOSED;


+2 −6
Original line number Original line Diff line number Diff line
@@ -311,7 +311,6 @@ static void add_conn(struct work_struct *work)
void hci_conn_add_sysfs(struct hci_conn *conn)
void hci_conn_add_sysfs(struct hci_conn *conn)
{
{
	struct hci_dev *hdev = conn->hdev;
	struct hci_dev *hdev = conn->hdev;
	bdaddr_t *ba = &conn->dst;


	BT_DBG("conn %p", conn);
	BT_DBG("conn %p", conn);


@@ -320,11 +319,8 @@ void hci_conn_add_sysfs(struct hci_conn *conn)


	conn->dev.release = bt_release;
	conn->dev.release = bt_release;


	snprintf(conn->dev.bus_id, BUS_ID_SIZE,
	snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
			"%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
					hdev->name, conn->handle);
			conn->type == ACL_LINK ? "acl" : "sco",
			ba->b[5], ba->b[4], ba->b[3],
			ba->b[2], ba->b[1], ba->b[0]);


	dev_set_drvdata(&conn->dev, conn);
	dev_set_drvdata(&conn->dev, conn);