forked from mirrors/linux
		
	Bluetooth: hci_event: Fix not indicating new connection for BIG Sync
BIG Sync (aka. Broadcast sink) requires to inform that the device is
connected when a data path is active otherwise userspace could attempt
to free resources allocated to the device object while scanning.
Fixes: 1d11d70d1f ("Bluetooth: ISO: Pass BIG encryption info through QoS")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
			
			
This commit is contained in:
		
							parent
							
								
									e7b02296fb
								
							
						
					
					
						commit
						eeda1bf97b
					
				
					 2 changed files with 18 additions and 7 deletions
				
			
		| 
						 | 
					@ -2524,9 +2524,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
 | 
				
			||||||
	 * Only those in BT_CONFIG or BT_CONNECTED states can be
 | 
						 * Only those in BT_CONFIG or BT_CONNECTED states can be
 | 
				
			||||||
	 * considered connected.
 | 
						 * considered connected.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (conn &&
 | 
						if (conn && (conn->state == BT_CONFIG || conn->state == BT_CONNECTED))
 | 
				
			||||||
	    (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) &&
 | 
					 | 
				
			||||||
	    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
					 | 
				
			||||||
		mgmt_device_connected(hdev, conn, name, name_len);
 | 
							mgmt_device_connected(hdev, conn, name, name_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (discov->state == DISCOVERY_STOPPED)
 | 
						if (discov->state == DISCOVERY_STOPPED)
 | 
				
			||||||
| 
						 | 
					@ -3758,8 +3756,9 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
 | 
				
			||||||
		bacpy(&cp.bdaddr, &conn->dst);
 | 
							bacpy(&cp.bdaddr, &conn->dst);
 | 
				
			||||||
		cp.pscan_rep_mode = 0x02;
 | 
							cp.pscan_rep_mode = 0x02;
 | 
				
			||||||
		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
							hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
				
			||||||
	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
						} else {
 | 
				
			||||||
		mgmt_device_connected(hdev, conn, NULL, 0);
 | 
							mgmt_device_connected(hdev, conn, NULL, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
						if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
				
			||||||
		conn->state = BT_CONNECTED;
 | 
							conn->state = BT_CONNECTED;
 | 
				
			||||||
| 
						 | 
					@ -3932,6 +3931,11 @@ static u8 hci_cc_le_setup_iso_path(struct hci_dev *hdev, void *data,
 | 
				
			||||||
		 * last.
 | 
							 * last.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		hci_connect_cfm(conn, rp->status);
 | 
							hci_connect_cfm(conn, rp->status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Notify device connected in case it is a BIG Sync */
 | 
				
			||||||
 | 
							if (!rp->status && test_bit(HCI_CONN_BIG_SYNC, &conn->flags))
 | 
				
			||||||
 | 
								mgmt_device_connected(hdev, conn, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5006,8 +5010,9 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
 | 
				
			||||||
		bacpy(&cp.bdaddr, &conn->dst);
 | 
							bacpy(&cp.bdaddr, &conn->dst);
 | 
				
			||||||
		cp.pscan_rep_mode = 0x02;
 | 
							cp.pscan_rep_mode = 0x02;
 | 
				
			||||||
		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
							hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
 | 
				
			||||||
	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
						} else {
 | 
				
			||||||
		mgmt_device_connected(hdev, conn, NULL, 0);
 | 
							mgmt_device_connected(hdev, conn, NULL, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
						if (!hci_outgoing_auth_needed(hdev, conn)) {
 | 
				
			||||||
		conn->state = BT_CONNECTED;
 | 
							conn->state = BT_CONNECTED;
 | 
				
			||||||
| 
						 | 
					@ -5980,8 +5985,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
 | 
				
			||||||
		goto unlock;
 | 
							goto unlock;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
						mgmt_device_connected(hdev, conn, NULL, 0);
 | 
				
			||||||
		mgmt_device_connected(hdev, conn, NULL, 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	conn->sec_level = BT_SECURITY_LOW;
 | 
						conn->sec_level = BT_SECURITY_LOW;
 | 
				
			||||||
	conn->state = BT_CONFIG;
 | 
						conn->state = BT_CONFIG;
 | 
				
			||||||
| 
						 | 
					@ -7210,6 +7214,9 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
 | 
				
			||||||
	/* Notify iso layer */
 | 
						/* Notify iso layer */
 | 
				
			||||||
	hci_connect_cfm(pa_sync, 0x00);
 | 
						hci_connect_cfm(pa_sync, 0x00);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Notify MGMT layer */
 | 
				
			||||||
 | 
						mgmt_device_connected(hdev, pa_sync, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unlock:
 | 
					unlock:
 | 
				
			||||||
	hci_dev_unlock(hdev);
 | 
						hci_dev_unlock(hdev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3126,6 +3126,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
 | 
				
			||||||
static u8 link_to_bdaddr(u8 link_type, u8 addr_type)
 | 
					static u8 link_to_bdaddr(u8 link_type, u8 addr_type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch (link_type) {
 | 
						switch (link_type) {
 | 
				
			||||||
 | 
						case ISO_LINK:
 | 
				
			||||||
	case LE_LINK:
 | 
						case LE_LINK:
 | 
				
			||||||
		switch (addr_type) {
 | 
							switch (addr_type) {
 | 
				
			||||||
		case ADDR_LE_DEV_PUBLIC:
 | 
							case ADDR_LE_DEV_PUBLIC:
 | 
				
			||||||
| 
						 | 
					@ -9618,6 +9619,9 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
 | 
				
			||||||
	u16 eir_len = 0;
 | 
						u16 eir_len = 0;
 | 
				
			||||||
	u32 flags = 0;
 | 
						u32 flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* allocate buff for LE or BR/EDR adv */
 | 
						/* allocate buff for LE or BR/EDR adv */
 | 
				
			||||||
	if (conn->le_adv_data_len > 0)
 | 
						if (conn->le_adv_data_len > 0)
 | 
				
			||||||
		skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED,
 | 
							skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue