Commit 7087c4f6 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz Committed by Marcel Holtmann
Browse files

Bluetooth: Store advertising handle so it can be re-enabled



This stores the advertising handle/instance into hci_conn so it is
accessible when re-enabling the advertising once disconnected.

Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent cafae4cd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -629,6 +629,7 @@ struct hci_conn {
	__u8		init_addr_type;
	bdaddr_t	resp_addr;
	__u8		resp_addr_type;
	__u8		adv_instance;
	__u16		handle;
	__u16		state;
	__u8		mode;
+29 −16
Original line number Diff line number Diff line
@@ -2348,19 +2348,20 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)

	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
	if (conn) {
		u8 type = conn->type;

		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
				       conn->dst_type, status);

		if (conn->type == LE_LINK) {
			hdev->cur_adv_instance = conn->adv_instance;
			hci_req_reenable_advertising(hdev);
		}

		/* If the disconnection failed for any reason, the upper layer
		 * does not retry to disconnect in current implementation.
		 * Hence, we need to do some basic cleanup here and re-enable
		 * advertising if necessary.
		 */
		hci_conn_del(conn);
		if (type == LE_LINK)
			hci_req_reenable_advertising(hdev);
	}

	hci_dev_unlock(hdev);
@@ -2886,7 +2887,6 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
	struct hci_conn_params *params;
	struct hci_conn *conn;
	bool mgmt_connected;
	u8 type;

	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);

@@ -2941,10 +2941,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
		}
	}

	type = conn->type;

	hci_disconn_cfm(conn, ev->reason);
	hci_conn_del(conn);

	/* The suspend notifier is waiting for all devices to disconnect so
	 * clear the bit from pending tasks and inform the wait queue.
@@ -2964,8 +2961,12 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
	 * or until a connection is created or until the Advertising
	 * is timed out due to Directed Advertising."
	 */
	if (type == LE_LINK)
	if (conn->type == LE_LINK) {
		hdev->cur_adv_instance = conn->adv_instance;
		hci_req_reenable_advertising(hdev);
	}

	hci_conn_del(conn);

unlock:
	hci_dev_unlock(hdev);
@@ -5323,6 +5324,13 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
	conn->handle = handle;
	conn->state = BT_CONFIG;

	/* Store current advertising instance as connection advertising instance
	 * when sotfware rotation is in use so it can be re-enabled when
	 * disconnected.
	 */
	if (!ext_adv_capable(hdev))
		conn->adv_instance = hdev->cur_adv_instance;

	conn->le_conn_interval = interval;
	conn->le_conn_latency = latency;
	conn->le_supv_timeout = supervision_timeout;
@@ -5406,13 +5414,13 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_evt_le_ext_adv_set_term *ev = (void *) skb->data;
	struct hci_conn *conn;
	struct adv_info *adv;

	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);

	if (ev->status) {
		struct adv_info *adv;

	adv = hci_find_adv_instance(hdev, ev->handle);

	if (ev->status) {
		if (!adv)
			return;

@@ -5423,9 +5431,15 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
		return;
	}

	if (adv)
		adv->enabled = false;

	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
	if (conn) {
		struct adv_info *adv_instance;
		/* Store handle in the connection so the correct advertising
		 * instance can be re-enabled when disconnected.
		 */
		conn->adv_instance = ev->handle;

		if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
		    bacmp(&conn->resp_addr, BDADDR_ANY))
@@ -5436,9 +5450,8 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
			return;
		}

		adv_instance = hci_find_adv_instance(hdev, ev->handle);
		if (adv_instance)
			bacpy(&conn->resp_addr, &adv_instance->random_addr);
		if (adv)
			bacpy(&conn->resp_addr, &adv->random_addr);
	}
}