xref: /openbmc/linux/net/bluetooth/iso.c (revision 04566971)
1ccf74f23SLuiz Augusto von Dentz // SPDX-License-Identifier: GPL-2.0
2ccf74f23SLuiz Augusto von Dentz /*
3ccf74f23SLuiz Augusto von Dentz  * BlueZ - Bluetooth protocol stack for Linux
4ccf74f23SLuiz Augusto von Dentz  *
5ccf74f23SLuiz Augusto von Dentz  * Copyright (C) 2022 Intel Corporation
60fe8c8d0SIulia Tanasescu  * Copyright 2023 NXP
7ccf74f23SLuiz Augusto von Dentz  */
8ccf74f23SLuiz Augusto von Dentz 
9ccf74f23SLuiz Augusto von Dentz #include <linux/module.h>
10ccf74f23SLuiz Augusto von Dentz #include <linux/debugfs.h>
11ccf74f23SLuiz Augusto von Dentz #include <linux/seq_file.h>
12ccf74f23SLuiz Augusto von Dentz #include <linux/sched/signal.h>
13ccf74f23SLuiz Augusto von Dentz 
14ccf74f23SLuiz Augusto von Dentz #include <net/bluetooth/bluetooth.h>
15ccf74f23SLuiz Augusto von Dentz #include <net/bluetooth/hci_core.h>
16ccf74f23SLuiz Augusto von Dentz #include <net/bluetooth/iso.h>
17ccf74f23SLuiz Augusto von Dentz 
18ccf74f23SLuiz Augusto von Dentz static const struct proto_ops iso_sock_ops;
19ccf74f23SLuiz Augusto von Dentz 
20ccf74f23SLuiz Augusto von Dentz static struct bt_sock_list iso_sk_list = {
21ccf74f23SLuiz Augusto von Dentz 	.lock = __RW_LOCK_UNLOCKED(iso_sk_list.lock)
22ccf74f23SLuiz Augusto von Dentz };
23ccf74f23SLuiz Augusto von Dentz 
24ccf74f23SLuiz Augusto von Dentz /* ---- ISO connections ---- */
25ccf74f23SLuiz Augusto von Dentz struct iso_conn {
26ccf74f23SLuiz Augusto von Dentz 	struct hci_conn	*hcon;
27ccf74f23SLuiz Augusto von Dentz 
28ccf74f23SLuiz Augusto von Dentz 	/* @lock: spinlock protecting changes to iso_conn fields */
29ccf74f23SLuiz Augusto von Dentz 	spinlock_t	lock;
30ccf74f23SLuiz Augusto von Dentz 	struct sock	*sk;
31ccf74f23SLuiz Augusto von Dentz 
32ccf74f23SLuiz Augusto von Dentz 	struct delayed_work	timeout_work;
33ccf74f23SLuiz Augusto von Dentz 
34ccf74f23SLuiz Augusto von Dentz 	struct sk_buff	*rx_skb;
35ccf74f23SLuiz Augusto von Dentz 	__u32		rx_len;
36ccf74f23SLuiz Augusto von Dentz 	__u16		tx_sn;
37ccf74f23SLuiz Augusto von Dentz };
38ccf74f23SLuiz Augusto von Dentz 
39ccf74f23SLuiz Augusto von Dentz #define iso_conn_lock(c)	spin_lock(&(c)->lock)
40ccf74f23SLuiz Augusto von Dentz #define iso_conn_unlock(c)	spin_unlock(&(c)->lock)
41ccf74f23SLuiz Augusto von Dentz 
42ccf74f23SLuiz Augusto von Dentz static void iso_sock_close(struct sock *sk);
43ccf74f23SLuiz Augusto von Dentz static void iso_sock_kill(struct sock *sk);
44ccf74f23SLuiz Augusto von Dentz 
45ccf74f23SLuiz Augusto von Dentz /* ----- ISO socket info ----- */
46ccf74f23SLuiz Augusto von Dentz #define iso_pi(sk) ((struct iso_pinfo *)sk)
47ccf74f23SLuiz Augusto von Dentz 
48b4443423SLuiz Augusto von Dentz #define EIR_SERVICE_DATA_LENGTH 4
49b4443423SLuiz Augusto von Dentz #define BASE_MAX_LENGTH (HCI_MAX_PER_AD_LENGTH - EIR_SERVICE_DATA_LENGTH)
50b4443423SLuiz Augusto von Dentz 
51f777d882SIulia Tanasescu /* iso_pinfo flags values */
52f777d882SIulia Tanasescu enum {
53f777d882SIulia Tanasescu 	BT_SK_BIG_SYNC,
54fbdc4bc4SIulia Tanasescu 	BT_SK_PA_SYNC,
5514410544SIulia Tanasescu 	BT_SK_PA_SYNC_TERM,
56f777d882SIulia Tanasescu };
57f777d882SIulia Tanasescu 
58ccf74f23SLuiz Augusto von Dentz struct iso_pinfo {
59ccf74f23SLuiz Augusto von Dentz 	struct bt_sock		bt;
60ccf74f23SLuiz Augusto von Dentz 	bdaddr_t		src;
61ccf74f23SLuiz Augusto von Dentz 	__u8			src_type;
62ccf74f23SLuiz Augusto von Dentz 	bdaddr_t		dst;
63ccf74f23SLuiz Augusto von Dentz 	__u8			dst_type;
64f764a6c2SLuiz Augusto von Dentz 	__u8			bc_sid;
65f764a6c2SLuiz Augusto von Dentz 	__u8			bc_num_bis;
66f764a6c2SLuiz Augusto von Dentz 	__u8			bc_bis[ISO_MAX_NUM_BIS];
67f764a6c2SLuiz Augusto von Dentz 	__u16			sync_handle;
68f777d882SIulia Tanasescu 	unsigned long		flags;
69ccf74f23SLuiz Augusto von Dentz 	struct bt_iso_qos	qos;
700fe8c8d0SIulia Tanasescu 	bool			qos_user_set;
71f764a6c2SLuiz Augusto von Dentz 	__u8			base_len;
72b4443423SLuiz Augusto von Dentz 	__u8			base[BASE_MAX_LENGTH];
73ccf74f23SLuiz Augusto von Dentz 	struct iso_conn		*conn;
74ccf74f23SLuiz Augusto von Dentz };
75ccf74f23SLuiz Augusto von Dentz 
760fe8c8d0SIulia Tanasescu static struct bt_iso_qos default_qos;
770fe8c8d0SIulia Tanasescu 
780fe8c8d0SIulia Tanasescu static bool check_ucast_qos(struct bt_iso_qos *qos);
790fe8c8d0SIulia Tanasescu static bool check_bcast_qos(struct bt_iso_qos *qos);
80fbdc4bc4SIulia Tanasescu static bool iso_match_sid(struct sock *sk, void *data);
8123417475SIulia Tanasescu static bool iso_match_sync_handle(struct sock *sk, void *data);
82fbdc4bc4SIulia Tanasescu static void iso_sock_disconn(struct sock *sk);
830fe8c8d0SIulia Tanasescu 
8414410544SIulia Tanasescu typedef bool (*iso_sock_match_t)(struct sock *sk, void *data);
8514410544SIulia Tanasescu 
8614410544SIulia Tanasescu static struct sock *iso_get_sock_listen(bdaddr_t *src, bdaddr_t *dst,
8714410544SIulia Tanasescu 					iso_sock_match_t match, void *data);
8814410544SIulia Tanasescu 
89ccf74f23SLuiz Augusto von Dentz /* ---- ISO timers ---- */
90ccf74f23SLuiz Augusto von Dentz #define ISO_CONN_TIMEOUT	(HZ * 40)
91ccf74f23SLuiz Augusto von Dentz #define ISO_DISCONN_TIMEOUT	(HZ * 2)
92ccf74f23SLuiz Augusto von Dentz 
iso_sock_timeout(struct work_struct * work)93ccf74f23SLuiz Augusto von Dentz static void iso_sock_timeout(struct work_struct *work)
94ccf74f23SLuiz Augusto von Dentz {
95ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = container_of(work, struct iso_conn,
96ccf74f23SLuiz Augusto von Dentz 					     timeout_work.work);
97ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
98ccf74f23SLuiz Augusto von Dentz 
99ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
100ccf74f23SLuiz Augusto von Dentz 	sk = conn->sk;
101ccf74f23SLuiz Augusto von Dentz 	if (sk)
102ccf74f23SLuiz Augusto von Dentz 		sock_hold(sk);
103ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
104ccf74f23SLuiz Augusto von Dentz 
105ccf74f23SLuiz Augusto von Dentz 	if (!sk)
106ccf74f23SLuiz Augusto von Dentz 		return;
107ccf74f23SLuiz Augusto von Dentz 
108ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p state %d", sk, sk->sk_state);
109ccf74f23SLuiz Augusto von Dentz 
110ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
111ccf74f23SLuiz Augusto von Dentz 	sk->sk_err = ETIMEDOUT;
112ccf74f23SLuiz Augusto von Dentz 	sk->sk_state_change(sk);
113ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
114ccf74f23SLuiz Augusto von Dentz 	sock_put(sk);
115ccf74f23SLuiz Augusto von Dentz }
116ccf74f23SLuiz Augusto von Dentz 
iso_sock_set_timer(struct sock * sk,long timeout)117ccf74f23SLuiz Augusto von Dentz static void iso_sock_set_timer(struct sock *sk, long timeout)
118ccf74f23SLuiz Augusto von Dentz {
119ccf74f23SLuiz Augusto von Dentz 	if (!iso_pi(sk)->conn)
120ccf74f23SLuiz Augusto von Dentz 		return;
121ccf74f23SLuiz Augusto von Dentz 
122ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
123ccf74f23SLuiz Augusto von Dentz 	cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
124ccf74f23SLuiz Augusto von Dentz 	schedule_delayed_work(&iso_pi(sk)->conn->timeout_work, timeout);
125ccf74f23SLuiz Augusto von Dentz }
126ccf74f23SLuiz Augusto von Dentz 
iso_sock_clear_timer(struct sock * sk)127ccf74f23SLuiz Augusto von Dentz static void iso_sock_clear_timer(struct sock *sk)
128ccf74f23SLuiz Augusto von Dentz {
129ccf74f23SLuiz Augusto von Dentz 	if (!iso_pi(sk)->conn)
130ccf74f23SLuiz Augusto von Dentz 		return;
131ccf74f23SLuiz Augusto von Dentz 
132ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p state %d", sk, sk->sk_state);
133ccf74f23SLuiz Augusto von Dentz 	cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
134ccf74f23SLuiz Augusto von Dentz }
135ccf74f23SLuiz Augusto von Dentz 
136ccf74f23SLuiz Augusto von Dentz /* ---- ISO connections ---- */
iso_conn_add(struct hci_conn * hcon)137ccf74f23SLuiz Augusto von Dentz static struct iso_conn *iso_conn_add(struct hci_conn *hcon)
138ccf74f23SLuiz Augusto von Dentz {
139ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = hcon->iso_data;
140ccf74f23SLuiz Augusto von Dentz 
141d40ae85eSPauli Virtanen 	if (conn) {
142d40ae85eSPauli Virtanen 		if (!conn->hcon)
143d40ae85eSPauli Virtanen 			conn->hcon = hcon;
144ccf74f23SLuiz Augusto von Dentz 		return conn;
145d40ae85eSPauli Virtanen 	}
146ccf74f23SLuiz Augusto von Dentz 
147ccf74f23SLuiz Augusto von Dentz 	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
148ccf74f23SLuiz Augusto von Dentz 	if (!conn)
149ccf74f23SLuiz Augusto von Dentz 		return NULL;
150ccf74f23SLuiz Augusto von Dentz 
151ccf74f23SLuiz Augusto von Dentz 	spin_lock_init(&conn->lock);
152ccf74f23SLuiz Augusto von Dentz 	INIT_DELAYED_WORK(&conn->timeout_work, iso_sock_timeout);
153ccf74f23SLuiz Augusto von Dentz 
154ccf74f23SLuiz Augusto von Dentz 	hcon->iso_data = conn;
155ccf74f23SLuiz Augusto von Dentz 	conn->hcon = hcon;
156ccf74f23SLuiz Augusto von Dentz 	conn->tx_sn = 0;
157ccf74f23SLuiz Augusto von Dentz 
158ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p conn %p", hcon, conn);
159ccf74f23SLuiz Augusto von Dentz 
160ccf74f23SLuiz Augusto von Dentz 	return conn;
161ccf74f23SLuiz Augusto von Dentz }
162ccf74f23SLuiz Augusto von Dentz 
163ccf74f23SLuiz Augusto von Dentz /* Delete channel. Must be called on the locked socket. */
iso_chan_del(struct sock * sk,int err)164ccf74f23SLuiz Augusto von Dentz static void iso_chan_del(struct sock *sk, int err)
165ccf74f23SLuiz Augusto von Dentz {
166ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn;
167f764a6c2SLuiz Augusto von Dentz 	struct sock *parent;
168ccf74f23SLuiz Augusto von Dentz 
169ccf74f23SLuiz Augusto von Dentz 	conn = iso_pi(sk)->conn;
170ccf74f23SLuiz Augusto von Dentz 
171ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
172ccf74f23SLuiz Augusto von Dentz 
173ccf74f23SLuiz Augusto von Dentz 	if (conn) {
174ccf74f23SLuiz Augusto von Dentz 		iso_conn_lock(conn);
175ccf74f23SLuiz Augusto von Dentz 		conn->sk = NULL;
176ccf74f23SLuiz Augusto von Dentz 		iso_pi(sk)->conn = NULL;
177ccf74f23SLuiz Augusto von Dentz 		iso_conn_unlock(conn);
178ccf74f23SLuiz Augusto von Dentz 
179ccf74f23SLuiz Augusto von Dentz 		if (conn->hcon)
180ccf74f23SLuiz Augusto von Dentz 			hci_conn_drop(conn->hcon);
181ccf74f23SLuiz Augusto von Dentz 	}
182ccf74f23SLuiz Augusto von Dentz 
183ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_CLOSED;
184ccf74f23SLuiz Augusto von Dentz 	sk->sk_err   = err;
185f764a6c2SLuiz Augusto von Dentz 
186f764a6c2SLuiz Augusto von Dentz 	parent = bt_sk(sk)->parent;
187f764a6c2SLuiz Augusto von Dentz 	if (parent) {
188f764a6c2SLuiz Augusto von Dentz 		bt_accept_unlink(sk);
189f764a6c2SLuiz Augusto von Dentz 		parent->sk_data_ready(parent);
190f764a6c2SLuiz Augusto von Dentz 	} else {
191ccf74f23SLuiz Augusto von Dentz 		sk->sk_state_change(sk);
192f764a6c2SLuiz Augusto von Dentz 	}
193ccf74f23SLuiz Augusto von Dentz 
194ccf74f23SLuiz Augusto von Dentz 	sock_set_flag(sk, SOCK_ZAPPED);
195ccf74f23SLuiz Augusto von Dentz }
196ccf74f23SLuiz Augusto von Dentz 
iso_match_conn_sync_handle(struct sock * sk,void * data)19714410544SIulia Tanasescu static bool iso_match_conn_sync_handle(struct sock *sk, void *data)
19814410544SIulia Tanasescu {
19914410544SIulia Tanasescu 	struct hci_conn *hcon = data;
20014410544SIulia Tanasescu 
20114410544SIulia Tanasescu 	if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags))
20214410544SIulia Tanasescu 		return false;
20314410544SIulia Tanasescu 
20414410544SIulia Tanasescu 	return hcon->sync_handle == iso_pi(sk)->sync_handle;
20514410544SIulia Tanasescu }
20614410544SIulia Tanasescu 
iso_conn_del(struct hci_conn * hcon,int err)207ccf74f23SLuiz Augusto von Dentz static void iso_conn_del(struct hci_conn *hcon, int err)
208ccf74f23SLuiz Augusto von Dentz {
209ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = hcon->iso_data;
210ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
21114410544SIulia Tanasescu 	struct sock *parent;
212ccf74f23SLuiz Augusto von Dentz 
213ccf74f23SLuiz Augusto von Dentz 	if (!conn)
214ccf74f23SLuiz Augusto von Dentz 		return;
215ccf74f23SLuiz Augusto von Dentz 
216ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
217ccf74f23SLuiz Augusto von Dentz 
218ccf74f23SLuiz Augusto von Dentz 	/* Kill socket */
219ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
220ccf74f23SLuiz Augusto von Dentz 	sk = conn->sk;
221ccf74f23SLuiz Augusto von Dentz 	if (sk)
222ccf74f23SLuiz Augusto von Dentz 		sock_hold(sk);
223ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
224ccf74f23SLuiz Augusto von Dentz 
225ccf74f23SLuiz Augusto von Dentz 	if (sk) {
226ccf74f23SLuiz Augusto von Dentz 		lock_sock(sk);
22714410544SIulia Tanasescu 
22814410544SIulia Tanasescu 		/* While a PA sync hcon is in the process of closing,
22914410544SIulia Tanasescu 		 * mark parent socket with a flag, so that any residual
23014410544SIulia Tanasescu 		 * BIGInfo adv reports that arrive before PA sync is
23114410544SIulia Tanasescu 		 * terminated are not processed anymore.
23214410544SIulia Tanasescu 		 */
23314410544SIulia Tanasescu 		if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
23414410544SIulia Tanasescu 			parent = iso_get_sock_listen(&hcon->src,
23514410544SIulia Tanasescu 						     &hcon->dst,
23614410544SIulia Tanasescu 						     iso_match_conn_sync_handle,
23714410544SIulia Tanasescu 						     hcon);
23814410544SIulia Tanasescu 
23914410544SIulia Tanasescu 			if (parent) {
24014410544SIulia Tanasescu 				set_bit(BT_SK_PA_SYNC_TERM,
24114410544SIulia Tanasescu 					&iso_pi(parent)->flags);
24214410544SIulia Tanasescu 				sock_put(parent);
24314410544SIulia Tanasescu 			}
24414410544SIulia Tanasescu 		}
24514410544SIulia Tanasescu 
246ccf74f23SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
247ccf74f23SLuiz Augusto von Dentz 		iso_chan_del(sk, err);
248ccf74f23SLuiz Augusto von Dentz 		release_sock(sk);
249ccf74f23SLuiz Augusto von Dentz 		sock_put(sk);
250ccf74f23SLuiz Augusto von Dentz 	}
251ccf74f23SLuiz Augusto von Dentz 
252ccf74f23SLuiz Augusto von Dentz 	/* Ensure no more work items will run before freeing conn. */
253ccf74f23SLuiz Augusto von Dentz 	cancel_delayed_work_sync(&conn->timeout_work);
254ccf74f23SLuiz Augusto von Dentz 
255ccf74f23SLuiz Augusto von Dentz 	hcon->iso_data = NULL;
256ccf74f23SLuiz Augusto von Dentz 	kfree(conn);
257ccf74f23SLuiz Augusto von Dentz }
258ccf74f23SLuiz Augusto von Dentz 
__iso_chan_add(struct iso_conn * conn,struct sock * sk,struct sock * parent)259ccf74f23SLuiz Augusto von Dentz static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
260ccf74f23SLuiz Augusto von Dentz 			  struct sock *parent)
261ccf74f23SLuiz Augusto von Dentz {
262ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p", conn);
263ccf74f23SLuiz Augusto von Dentz 
264ccf74f23SLuiz Augusto von Dentz 	if (iso_pi(sk)->conn == conn && conn->sk == sk)
265ccf74f23SLuiz Augusto von Dentz 		return 0;
266ccf74f23SLuiz Augusto von Dentz 
267ccf74f23SLuiz Augusto von Dentz 	if (conn->sk) {
268ccf74f23SLuiz Augusto von Dentz 		BT_ERR("conn->sk already set");
269ccf74f23SLuiz Augusto von Dentz 		return -EBUSY;
270ccf74f23SLuiz Augusto von Dentz 	}
271ccf74f23SLuiz Augusto von Dentz 
272ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->conn = conn;
273ccf74f23SLuiz Augusto von Dentz 	conn->sk = sk;
274ccf74f23SLuiz Augusto von Dentz 
275ccf74f23SLuiz Augusto von Dentz 	if (parent)
276ccf74f23SLuiz Augusto von Dentz 		bt_accept_enqueue(parent, sk, true);
277ccf74f23SLuiz Augusto von Dentz 
278ccf74f23SLuiz Augusto von Dentz 	return 0;
279ccf74f23SLuiz Augusto von Dentz }
280ccf74f23SLuiz Augusto von Dentz 
iso_chan_add(struct iso_conn * conn,struct sock * sk,struct sock * parent)281ccf74f23SLuiz Augusto von Dentz static int iso_chan_add(struct iso_conn *conn, struct sock *sk,
282ccf74f23SLuiz Augusto von Dentz 			struct sock *parent)
283ccf74f23SLuiz Augusto von Dentz {
284ccf74f23SLuiz Augusto von Dentz 	int err;
285ccf74f23SLuiz Augusto von Dentz 
286ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
287ccf74f23SLuiz Augusto von Dentz 	err = __iso_chan_add(conn, sk, parent);
288ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
289ccf74f23SLuiz Augusto von Dentz 
290ccf74f23SLuiz Augusto von Dentz 	return err;
291ccf74f23SLuiz Augusto von Dentz }
292ccf74f23SLuiz Augusto von Dentz 
le_addr_type(u8 bdaddr_type)293b36a234dSPauli Virtanen static inline u8 le_addr_type(u8 bdaddr_type)
294b36a234dSPauli Virtanen {
295b36a234dSPauli Virtanen 	if (bdaddr_type == BDADDR_LE_PUBLIC)
296b36a234dSPauli Virtanen 		return ADDR_LE_DEV_PUBLIC;
297b36a234dSPauli Virtanen 	else
298b36a234dSPauli Virtanen 		return ADDR_LE_DEV_RANDOM;
299b36a234dSPauli Virtanen }
300b36a234dSPauli Virtanen 
iso_connect_bis(struct sock * sk)301f764a6c2SLuiz Augusto von Dentz static int iso_connect_bis(struct sock *sk)
302f764a6c2SLuiz Augusto von Dentz {
303f764a6c2SLuiz Augusto von Dentz 	struct iso_conn *conn;
304f764a6c2SLuiz Augusto von Dentz 	struct hci_conn *hcon;
305f764a6c2SLuiz Augusto von Dentz 	struct hci_dev  *hdev;
306f764a6c2SLuiz Augusto von Dentz 	int err;
307f764a6c2SLuiz Augusto von Dentz 
308f764a6c2SLuiz Augusto von Dentz 	BT_DBG("%pMR", &iso_pi(sk)->src);
309f764a6c2SLuiz Augusto von Dentz 
310f764a6c2SLuiz Augusto von Dentz 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
311f764a6c2SLuiz Augusto von Dentz 			     iso_pi(sk)->src_type);
312f764a6c2SLuiz Augusto von Dentz 	if (!hdev)
313f764a6c2SLuiz Augusto von Dentz 		return -EHOSTUNREACH;
314f764a6c2SLuiz Augusto von Dentz 
315f764a6c2SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
316f764a6c2SLuiz Augusto von Dentz 
317f764a6c2SLuiz Augusto von Dentz 	if (!bis_capable(hdev)) {
318f764a6c2SLuiz Augusto von Dentz 		err = -EOPNOTSUPP;
319241f5193SLuiz Augusto von Dentz 		goto unlock;
320f764a6c2SLuiz Augusto von Dentz 	}
321f764a6c2SLuiz Augusto von Dentz 
3220fe8c8d0SIulia Tanasescu 	/* Fail if user set invalid QoS */
3230fe8c8d0SIulia Tanasescu 	if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
3240fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos = default_qos;
3250fe8c8d0SIulia Tanasescu 		err = -EINVAL;
3260fe8c8d0SIulia Tanasescu 		goto unlock;
3270fe8c8d0SIulia Tanasescu 	}
3280fe8c8d0SIulia Tanasescu 
329f764a6c2SLuiz Augusto von Dentz 	/* Fail if out PHYs are marked as disabled */
3300fe8c8d0SIulia Tanasescu 	if (!iso_pi(sk)->qos.bcast.out.phy) {
331f764a6c2SLuiz Augusto von Dentz 		err = -EINVAL;
332241f5193SLuiz Augusto von Dentz 		goto unlock;
333f764a6c2SLuiz Augusto von Dentz 	}
334f764a6c2SLuiz Augusto von Dentz 
335a0bfde16SIulia Tanasescu 	/* Just bind if DEFER_SETUP has been set */
336a0bfde16SIulia Tanasescu 	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
337a0bfde16SIulia Tanasescu 		hcon = hci_bind_bis(hdev, &iso_pi(sk)->dst,
338a0bfde16SIulia Tanasescu 				    &iso_pi(sk)->qos, iso_pi(sk)->base_len,
339a0bfde16SIulia Tanasescu 				    iso_pi(sk)->base);
340a0bfde16SIulia Tanasescu 		if (IS_ERR(hcon)) {
341a0bfde16SIulia Tanasescu 			err = PTR_ERR(hcon);
342a0bfde16SIulia Tanasescu 			goto unlock;
343a0bfde16SIulia Tanasescu 		}
344a0bfde16SIulia Tanasescu 	} else {
345d11ab690SPauli Virtanen 		hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
346d11ab690SPauli Virtanen 				       le_addr_type(iso_pi(sk)->dst_type),
347f764a6c2SLuiz Augusto von Dentz 				       &iso_pi(sk)->qos, iso_pi(sk)->base_len,
348f764a6c2SLuiz Augusto von Dentz 				       iso_pi(sk)->base);
349f764a6c2SLuiz Augusto von Dentz 		if (IS_ERR(hcon)) {
350f764a6c2SLuiz Augusto von Dentz 			err = PTR_ERR(hcon);
351241f5193SLuiz Augusto von Dentz 			goto unlock;
352f764a6c2SLuiz Augusto von Dentz 		}
353a0bfde16SIulia Tanasescu 	}
354f764a6c2SLuiz Augusto von Dentz 
355f764a6c2SLuiz Augusto von Dentz 	conn = iso_conn_add(hcon);
356f764a6c2SLuiz Augusto von Dentz 	if (!conn) {
357f764a6c2SLuiz Augusto von Dentz 		hci_conn_drop(hcon);
358f764a6c2SLuiz Augusto von Dentz 		err = -ENOMEM;
359241f5193SLuiz Augusto von Dentz 		goto unlock;
360f764a6c2SLuiz Augusto von Dentz 	}
361f764a6c2SLuiz Augusto von Dentz 
362d40ae85eSPauli Virtanen 	lock_sock(sk);
363241f5193SLuiz Augusto von Dentz 
3646a5ad251SLuiz Augusto von Dentz 	err = iso_chan_add(conn, sk, NULL);
365d40ae85eSPauli Virtanen 	if (err) {
366d40ae85eSPauli Virtanen 		release_sock(sk);
367d40ae85eSPauli Virtanen 		goto unlock;
368d40ae85eSPauli Virtanen 	}
369241f5193SLuiz Augusto von Dentz 
370f764a6c2SLuiz Augusto von Dentz 	/* Update source addr of the socket */
371f764a6c2SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->src, &hcon->src);
372f764a6c2SLuiz Augusto von Dentz 
373f764a6c2SLuiz Augusto von Dentz 	if (hcon->state == BT_CONNECTED) {
374f764a6c2SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
375f764a6c2SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECTED;
376a0bfde16SIulia Tanasescu 	} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
377a0bfde16SIulia Tanasescu 		iso_sock_clear_timer(sk);
378a0bfde16SIulia Tanasescu 		sk->sk_state = BT_CONNECT;
379f764a6c2SLuiz Augusto von Dentz 	} else {
380f764a6c2SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECT;
381f764a6c2SLuiz Augusto von Dentz 		iso_sock_set_timer(sk, sk->sk_sndtimeo);
382f764a6c2SLuiz Augusto von Dentz 	}
383f764a6c2SLuiz Augusto von Dentz 
384241f5193SLuiz Augusto von Dentz 	release_sock(sk);
385241f5193SLuiz Augusto von Dentz 
386241f5193SLuiz Augusto von Dentz unlock:
387f764a6c2SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
388f764a6c2SLuiz Augusto von Dentz 	hci_dev_put(hdev);
389f764a6c2SLuiz Augusto von Dentz 	return err;
390f764a6c2SLuiz Augusto von Dentz }
391f764a6c2SLuiz Augusto von Dentz 
iso_connect_cis(struct sock * sk)392f764a6c2SLuiz Augusto von Dentz static int iso_connect_cis(struct sock *sk)
393ccf74f23SLuiz Augusto von Dentz {
394ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn;
395ccf74f23SLuiz Augusto von Dentz 	struct hci_conn *hcon;
396ccf74f23SLuiz Augusto von Dentz 	struct hci_dev  *hdev;
397ccf74f23SLuiz Augusto von Dentz 	int err;
398ccf74f23SLuiz Augusto von Dentz 
399ccf74f23SLuiz Augusto von Dentz 	BT_DBG("%pMR -> %pMR", &iso_pi(sk)->src, &iso_pi(sk)->dst);
400ccf74f23SLuiz Augusto von Dentz 
401ccf74f23SLuiz Augusto von Dentz 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
402ccf74f23SLuiz Augusto von Dentz 			     iso_pi(sk)->src_type);
403ccf74f23SLuiz Augusto von Dentz 	if (!hdev)
404ccf74f23SLuiz Augusto von Dentz 		return -EHOSTUNREACH;
405ccf74f23SLuiz Augusto von Dentz 
406ccf74f23SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
407ccf74f23SLuiz Augusto von Dentz 
408ccf74f23SLuiz Augusto von Dentz 	if (!cis_central_capable(hdev)) {
409ccf74f23SLuiz Augusto von Dentz 		err = -EOPNOTSUPP;
410241f5193SLuiz Augusto von Dentz 		goto unlock;
411ccf74f23SLuiz Augusto von Dentz 	}
412ccf74f23SLuiz Augusto von Dentz 
4130fe8c8d0SIulia Tanasescu 	/* Fail if user set invalid QoS */
4140fe8c8d0SIulia Tanasescu 	if (iso_pi(sk)->qos_user_set && !check_ucast_qos(&iso_pi(sk)->qos)) {
4150fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos = default_qos;
4160fe8c8d0SIulia Tanasescu 		err = -EINVAL;
4170fe8c8d0SIulia Tanasescu 		goto unlock;
4180fe8c8d0SIulia Tanasescu 	}
4190fe8c8d0SIulia Tanasescu 
420ccf74f23SLuiz Augusto von Dentz 	/* Fail if either PHYs are marked as disabled */
4210fe8c8d0SIulia Tanasescu 	if (!iso_pi(sk)->qos.ucast.in.phy && !iso_pi(sk)->qos.ucast.out.phy) {
422ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
423241f5193SLuiz Augusto von Dentz 		goto unlock;
424ccf74f23SLuiz Augusto von Dentz 	}
425ccf74f23SLuiz Augusto von Dentz 
426ccf74f23SLuiz Augusto von Dentz 	/* Just bind if DEFER_SETUP has been set */
427ccf74f23SLuiz Augusto von Dentz 	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
428ccf74f23SLuiz Augusto von Dentz 		hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,
429b36a234dSPauli Virtanen 				    le_addr_type(iso_pi(sk)->dst_type),
430b36a234dSPauli Virtanen 				    &iso_pi(sk)->qos);
431ccf74f23SLuiz Augusto von Dentz 		if (IS_ERR(hcon)) {
432ccf74f23SLuiz Augusto von Dentz 			err = PTR_ERR(hcon);
433241f5193SLuiz Augusto von Dentz 			goto unlock;
434ccf74f23SLuiz Augusto von Dentz 		}
435ccf74f23SLuiz Augusto von Dentz 	} else {
436ccf74f23SLuiz Augusto von Dentz 		hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
437b36a234dSPauli Virtanen 				       le_addr_type(iso_pi(sk)->dst_type),
438b36a234dSPauli Virtanen 				       &iso_pi(sk)->qos);
439ccf74f23SLuiz Augusto von Dentz 		if (IS_ERR(hcon)) {
440ccf74f23SLuiz Augusto von Dentz 			err = PTR_ERR(hcon);
441241f5193SLuiz Augusto von Dentz 			goto unlock;
442ccf74f23SLuiz Augusto von Dentz 		}
443ccf74f23SLuiz Augusto von Dentz 	}
444ccf74f23SLuiz Augusto von Dentz 
445ccf74f23SLuiz Augusto von Dentz 	conn = iso_conn_add(hcon);
446ccf74f23SLuiz Augusto von Dentz 	if (!conn) {
447ccf74f23SLuiz Augusto von Dentz 		hci_conn_drop(hcon);
448ccf74f23SLuiz Augusto von Dentz 		err = -ENOMEM;
449241f5193SLuiz Augusto von Dentz 		goto unlock;
450ccf74f23SLuiz Augusto von Dentz 	}
451ccf74f23SLuiz Augusto von Dentz 
452d40ae85eSPauli Virtanen 	lock_sock(sk);
453241f5193SLuiz Augusto von Dentz 
4546a5ad251SLuiz Augusto von Dentz 	err = iso_chan_add(conn, sk, NULL);
455d40ae85eSPauli Virtanen 	if (err) {
456d40ae85eSPauli Virtanen 		release_sock(sk);
457d40ae85eSPauli Virtanen 		goto unlock;
458d40ae85eSPauli Virtanen 	}
459241f5193SLuiz Augusto von Dentz 
460ccf74f23SLuiz Augusto von Dentz 	/* Update source addr of the socket */
461ccf74f23SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->src, &hcon->src);
462ccf74f23SLuiz Augusto von Dentz 
463ccf74f23SLuiz Augusto von Dentz 	if (hcon->state == BT_CONNECTED) {
464ccf74f23SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
465ccf74f23SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECTED;
466ccf74f23SLuiz Augusto von Dentz 	} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
467ccf74f23SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
468ccf74f23SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECT;
469ccf74f23SLuiz Augusto von Dentz 	} else {
470ccf74f23SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECT;
471ccf74f23SLuiz Augusto von Dentz 		iso_sock_set_timer(sk, sk->sk_sndtimeo);
472ccf74f23SLuiz Augusto von Dentz 	}
473ccf74f23SLuiz Augusto von Dentz 
474241f5193SLuiz Augusto von Dentz 	release_sock(sk);
475241f5193SLuiz Augusto von Dentz 
476241f5193SLuiz Augusto von Dentz unlock:
477ccf74f23SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
478ccf74f23SLuiz Augusto von Dentz 	hci_dev_put(hdev);
479ccf74f23SLuiz Augusto von Dentz 	return err;
480ccf74f23SLuiz Augusto von Dentz }
481ccf74f23SLuiz Augusto von Dentz 
iso_sock_get_qos(struct sock * sk)4821d1ab5d3SLuiz Augusto von Dentz static struct bt_iso_qos *iso_sock_get_qos(struct sock *sk)
4831d1ab5d3SLuiz Augusto von Dentz {
4841d1ab5d3SLuiz Augusto von Dentz 	if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONNECT2)
4851d1ab5d3SLuiz Augusto von Dentz 		return &iso_pi(sk)->conn->hcon->iso_qos;
4861d1ab5d3SLuiz Augusto von Dentz 
4871d1ab5d3SLuiz Augusto von Dentz 	return &iso_pi(sk)->qos;
4881d1ab5d3SLuiz Augusto von Dentz }
4891d1ab5d3SLuiz Augusto von Dentz 
iso_send_frame(struct sock * sk,struct sk_buff * skb)490ccf74f23SLuiz Augusto von Dentz static int iso_send_frame(struct sock *sk, struct sk_buff *skb)
491ccf74f23SLuiz Augusto von Dentz {
492ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = iso_pi(sk)->conn;
4931d1ab5d3SLuiz Augusto von Dentz 	struct bt_iso_qos *qos = iso_sock_get_qos(sk);
494ccf74f23SLuiz Augusto von Dentz 	struct hci_iso_data_hdr *hdr;
495ccf74f23SLuiz Augusto von Dentz 	int len = 0;
496ccf74f23SLuiz Augusto von Dentz 
497ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p len %d", sk, skb->len);
498ccf74f23SLuiz Augusto von Dentz 
4990fe8c8d0SIulia Tanasescu 	if (skb->len > qos->ucast.out.sdu)
500ccf74f23SLuiz Augusto von Dentz 		return -EMSGSIZE;
501ccf74f23SLuiz Augusto von Dentz 
502ccf74f23SLuiz Augusto von Dentz 	len = skb->len;
503ccf74f23SLuiz Augusto von Dentz 
504ccf74f23SLuiz Augusto von Dentz 	/* Push ISO data header */
505ccf74f23SLuiz Augusto von Dentz 	hdr = skb_push(skb, HCI_ISO_DATA_HDR_SIZE);
506ccf74f23SLuiz Augusto von Dentz 	hdr->sn = cpu_to_le16(conn->tx_sn++);
507ccf74f23SLuiz Augusto von Dentz 	hdr->slen = cpu_to_le16(hci_iso_data_len_pack(len,
508ccf74f23SLuiz Augusto von Dentz 						      HCI_ISO_STATUS_VALID));
509ccf74f23SLuiz Augusto von Dentz 
510ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state == BT_CONNECTED)
511ccf74f23SLuiz Augusto von Dentz 		hci_send_iso(conn->hcon, skb);
512ccf74f23SLuiz Augusto von Dentz 	else
513ccf74f23SLuiz Augusto von Dentz 		len = -ENOTCONN;
514ccf74f23SLuiz Augusto von Dentz 
515ccf74f23SLuiz Augusto von Dentz 	return len;
516ccf74f23SLuiz Augusto von Dentz }
517ccf74f23SLuiz Augusto von Dentz 
iso_recv_frame(struct iso_conn * conn,struct sk_buff * skb)518ccf74f23SLuiz Augusto von Dentz static void iso_recv_frame(struct iso_conn *conn, struct sk_buff *skb)
519ccf74f23SLuiz Augusto von Dentz {
520ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
521ccf74f23SLuiz Augusto von Dentz 
522ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
523ccf74f23SLuiz Augusto von Dentz 	sk = conn->sk;
524ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
525ccf74f23SLuiz Augusto von Dentz 
526ccf74f23SLuiz Augusto von Dentz 	if (!sk)
527ccf74f23SLuiz Augusto von Dentz 		goto drop;
528ccf74f23SLuiz Augusto von Dentz 
529ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p len %d", sk, skb->len);
530ccf74f23SLuiz Augusto von Dentz 
531ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_CONNECTED)
532ccf74f23SLuiz Augusto von Dentz 		goto drop;
533ccf74f23SLuiz Augusto von Dentz 
534ccf74f23SLuiz Augusto von Dentz 	if (!sock_queue_rcv_skb(sk, skb))
535ccf74f23SLuiz Augusto von Dentz 		return;
536ccf74f23SLuiz Augusto von Dentz 
537ccf74f23SLuiz Augusto von Dentz drop:
538ccf74f23SLuiz Augusto von Dentz 	kfree_skb(skb);
539ccf74f23SLuiz Augusto von Dentz }
540ccf74f23SLuiz Augusto von Dentz 
541ccf74f23SLuiz Augusto von Dentz /* -------- Socket interface ---------- */
__iso_get_sock_listen_by_addr(bdaddr_t * src,bdaddr_t * dst)542e0275ea5SLuiz Augusto von Dentz static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst)
543ccf74f23SLuiz Augusto von Dentz {
544ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
545ccf74f23SLuiz Augusto von Dentz 
546ccf74f23SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
547ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN)
548ccf74f23SLuiz Augusto von Dentz 			continue;
549ccf74f23SLuiz Augusto von Dentz 
550e0275ea5SLuiz Augusto von Dentz 		if (bacmp(&iso_pi(sk)->dst, dst))
551e0275ea5SLuiz Augusto von Dentz 			continue;
552e0275ea5SLuiz Augusto von Dentz 
553e0275ea5SLuiz Augusto von Dentz 		if (!bacmp(&iso_pi(sk)->src, src))
554ccf74f23SLuiz Augusto von Dentz 			return sk;
555ccf74f23SLuiz Augusto von Dentz 	}
556ccf74f23SLuiz Augusto von Dentz 
557ccf74f23SLuiz Augusto von Dentz 	return NULL;
558ccf74f23SLuiz Augusto von Dentz }
559ccf74f23SLuiz Augusto von Dentz 
__iso_get_sock_listen_by_sid(bdaddr_t * ba,bdaddr_t * bc,__u8 sid)560f764a6c2SLuiz Augusto von Dentz static struct sock *__iso_get_sock_listen_by_sid(bdaddr_t *ba, bdaddr_t *bc,
561f764a6c2SLuiz Augusto von Dentz 						 __u8 sid)
562f764a6c2SLuiz Augusto von Dentz {
563f764a6c2SLuiz Augusto von Dentz 	struct sock *sk;
564f764a6c2SLuiz Augusto von Dentz 
565f764a6c2SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
566f764a6c2SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN)
567f764a6c2SLuiz Augusto von Dentz 			continue;
568f764a6c2SLuiz Augusto von Dentz 
569f764a6c2SLuiz Augusto von Dentz 		if (bacmp(&iso_pi(sk)->src, ba))
570f764a6c2SLuiz Augusto von Dentz 			continue;
571f764a6c2SLuiz Augusto von Dentz 
572f764a6c2SLuiz Augusto von Dentz 		if (bacmp(&iso_pi(sk)->dst, bc))
573f764a6c2SLuiz Augusto von Dentz 			continue;
574f764a6c2SLuiz Augusto von Dentz 
575f764a6c2SLuiz Augusto von Dentz 		if (iso_pi(sk)->bc_sid == sid)
576f764a6c2SLuiz Augusto von Dentz 			return sk;
577f764a6c2SLuiz Augusto von Dentz 	}
578f764a6c2SLuiz Augusto von Dentz 
579f764a6c2SLuiz Augusto von Dentz 	return NULL;
580f764a6c2SLuiz Augusto von Dentz }
581f764a6c2SLuiz Augusto von Dentz 
582f764a6c2SLuiz Augusto von Dentz /* Find socket listening:
583f764a6c2SLuiz Augusto von Dentz  * source bdaddr (Unicast)
584f764a6c2SLuiz Augusto von Dentz  * destination bdaddr (Broadcast only)
585f764a6c2SLuiz Augusto von Dentz  * match func - pass NULL to ignore
586f764a6c2SLuiz Augusto von Dentz  * match func data - pass -1 to ignore
587ccf74f23SLuiz Augusto von Dentz  * Returns closest match.
588ccf74f23SLuiz Augusto von Dentz  */
iso_get_sock_listen(bdaddr_t * src,bdaddr_t * dst,iso_sock_match_t match,void * data)589f764a6c2SLuiz Augusto von Dentz static struct sock *iso_get_sock_listen(bdaddr_t *src, bdaddr_t *dst,
590f764a6c2SLuiz Augusto von Dentz 					iso_sock_match_t match, void *data)
591ccf74f23SLuiz Augusto von Dentz {
592ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = NULL, *sk1 = NULL;
593ccf74f23SLuiz Augusto von Dentz 
594ccf74f23SLuiz Augusto von Dentz 	read_lock(&iso_sk_list.lock);
595ccf74f23SLuiz Augusto von Dentz 
596ccf74f23SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
597ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN)
598ccf74f23SLuiz Augusto von Dentz 			continue;
599ccf74f23SLuiz Augusto von Dentz 
600f764a6c2SLuiz Augusto von Dentz 		/* Match Broadcast destination */
601f764a6c2SLuiz Augusto von Dentz 		if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst))
602f764a6c2SLuiz Augusto von Dentz 			continue;
603f764a6c2SLuiz Augusto von Dentz 
604f764a6c2SLuiz Augusto von Dentz 		/* Use Match function if provided */
605f764a6c2SLuiz Augusto von Dentz 		if (match && !match(sk, data))
606f764a6c2SLuiz Augusto von Dentz 			continue;
607f764a6c2SLuiz Augusto von Dentz 
608ccf74f23SLuiz Augusto von Dentz 		/* Exact match. */
609ccf74f23SLuiz Augusto von Dentz 		if (!bacmp(&iso_pi(sk)->src, src))
610ccf74f23SLuiz Augusto von Dentz 			break;
611ccf74f23SLuiz Augusto von Dentz 
612ccf74f23SLuiz Augusto von Dentz 		/* Closest match */
613ccf74f23SLuiz Augusto von Dentz 		if (!bacmp(&iso_pi(sk)->src, BDADDR_ANY))
614ccf74f23SLuiz Augusto von Dentz 			sk1 = sk;
615ccf74f23SLuiz Augusto von Dentz 	}
616ccf74f23SLuiz Augusto von Dentz 
617ccf74f23SLuiz Augusto von Dentz 	read_unlock(&iso_sk_list.lock);
618ccf74f23SLuiz Augusto von Dentz 
619ccf74f23SLuiz Augusto von Dentz 	return sk ? sk : sk1;
620ccf74f23SLuiz Augusto von Dentz }
621ccf74f23SLuiz Augusto von Dentz 
iso_sock_destruct(struct sock * sk)622ccf74f23SLuiz Augusto von Dentz static void iso_sock_destruct(struct sock *sk)
623ccf74f23SLuiz Augusto von Dentz {
624ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
625ccf74f23SLuiz Augusto von Dentz 
626ccf74f23SLuiz Augusto von Dentz 	skb_queue_purge(&sk->sk_receive_queue);
627ccf74f23SLuiz Augusto von Dentz 	skb_queue_purge(&sk->sk_write_queue);
628ccf74f23SLuiz Augusto von Dentz }
629ccf74f23SLuiz Augusto von Dentz 
iso_sock_cleanup_listen(struct sock * parent)630ccf74f23SLuiz Augusto von Dentz static void iso_sock_cleanup_listen(struct sock *parent)
631ccf74f23SLuiz Augusto von Dentz {
632ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
633ccf74f23SLuiz Augusto von Dentz 
634ccf74f23SLuiz Augusto von Dentz 	BT_DBG("parent %p", parent);
635ccf74f23SLuiz Augusto von Dentz 
636ccf74f23SLuiz Augusto von Dentz 	/* Close not yet accepted channels */
637ccf74f23SLuiz Augusto von Dentz 	while ((sk = bt_accept_dequeue(parent, NULL))) {
638ccf74f23SLuiz Augusto von Dentz 		iso_sock_close(sk);
639ccf74f23SLuiz Augusto von Dentz 		iso_sock_kill(sk);
640ccf74f23SLuiz Augusto von Dentz 	}
641ccf74f23SLuiz Augusto von Dentz 
642fbdc4bc4SIulia Tanasescu 	/* If listening socket stands for a PA sync connection,
643fbdc4bc4SIulia Tanasescu 	 * properly disconnect the hcon and socket.
644fbdc4bc4SIulia Tanasescu 	 */
645fbdc4bc4SIulia Tanasescu 	if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon &&
646fbdc4bc4SIulia Tanasescu 	    test_bit(HCI_CONN_PA_SYNC, &iso_pi(parent)->conn->hcon->flags)) {
647fbdc4bc4SIulia Tanasescu 		iso_sock_disconn(parent);
648fbdc4bc4SIulia Tanasescu 		return;
649fbdc4bc4SIulia Tanasescu 	}
650fbdc4bc4SIulia Tanasescu 
651ccf74f23SLuiz Augusto von Dentz 	parent->sk_state  = BT_CLOSED;
652ccf74f23SLuiz Augusto von Dentz 	sock_set_flag(parent, SOCK_ZAPPED);
653ccf74f23SLuiz Augusto von Dentz }
654ccf74f23SLuiz Augusto von Dentz 
655ccf74f23SLuiz Augusto von Dentz /* Kill socket (only if zapped and orphan)
656ccf74f23SLuiz Augusto von Dentz  * Must be called on unlocked socket.
657ccf74f23SLuiz Augusto von Dentz  */
iso_sock_kill(struct sock * sk)658ccf74f23SLuiz Augusto von Dentz static void iso_sock_kill(struct sock *sk)
659ccf74f23SLuiz Augusto von Dentz {
660ccf74f23SLuiz Augusto von Dentz 	if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket ||
661ccf74f23SLuiz Augusto von Dentz 	    sock_flag(sk, SOCK_DEAD))
662ccf74f23SLuiz Augusto von Dentz 		return;
663ccf74f23SLuiz Augusto von Dentz 
664ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p state %d", sk, sk->sk_state);
665ccf74f23SLuiz Augusto von Dentz 
666ccf74f23SLuiz Augusto von Dentz 	/* Kill poor orphan */
667ccf74f23SLuiz Augusto von Dentz 	bt_sock_unlink(&iso_sk_list, sk);
668ccf74f23SLuiz Augusto von Dentz 	sock_set_flag(sk, SOCK_DEAD);
669ccf74f23SLuiz Augusto von Dentz 	sock_put(sk);
670ccf74f23SLuiz Augusto von Dentz }
671ccf74f23SLuiz Augusto von Dentz 
iso_sock_disconn(struct sock * sk)672fbdc4bc4SIulia Tanasescu static void iso_sock_disconn(struct sock *sk)
673fbdc4bc4SIulia Tanasescu {
674fbdc4bc4SIulia Tanasescu 	sk->sk_state = BT_DISCONN;
675fbdc4bc4SIulia Tanasescu 	iso_sock_set_timer(sk, ISO_DISCONN_TIMEOUT);
676fbdc4bc4SIulia Tanasescu 	iso_conn_lock(iso_pi(sk)->conn);
677fbdc4bc4SIulia Tanasescu 	hci_conn_drop(iso_pi(sk)->conn->hcon);
678fbdc4bc4SIulia Tanasescu 	iso_pi(sk)->conn->hcon = NULL;
679fbdc4bc4SIulia Tanasescu 	iso_conn_unlock(iso_pi(sk)->conn);
680fbdc4bc4SIulia Tanasescu }
681fbdc4bc4SIulia Tanasescu 
__iso_sock_close(struct sock * sk)682ccf74f23SLuiz Augusto von Dentz static void __iso_sock_close(struct sock *sk)
683ccf74f23SLuiz Augusto von Dentz {
684ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
685ccf74f23SLuiz Augusto von Dentz 
686ccf74f23SLuiz Augusto von Dentz 	switch (sk->sk_state) {
687ccf74f23SLuiz Augusto von Dentz 	case BT_LISTEN:
688ccf74f23SLuiz Augusto von Dentz 		iso_sock_cleanup_listen(sk);
689ccf74f23SLuiz Augusto von Dentz 		break;
690ccf74f23SLuiz Augusto von Dentz 
69169997d50SPauli Virtanen 	case BT_CONNECT:
692ccf74f23SLuiz Augusto von Dentz 	case BT_CONNECTED:
693ccf74f23SLuiz Augusto von Dentz 	case BT_CONFIG:
694fbdc4bc4SIulia Tanasescu 		if (iso_pi(sk)->conn->hcon)
695fbdc4bc4SIulia Tanasescu 			iso_sock_disconn(sk);
696fbdc4bc4SIulia Tanasescu 		else
697ccf74f23SLuiz Augusto von Dentz 			iso_chan_del(sk, ECONNRESET);
698ccf74f23SLuiz Augusto von Dentz 		break;
699ccf74f23SLuiz Augusto von Dentz 
700ccf74f23SLuiz Augusto von Dentz 	case BT_CONNECT2:
701fbdc4bc4SIulia Tanasescu 		if (iso_pi(sk)->conn->hcon &&
702fbdc4bc4SIulia Tanasescu 		    (test_bit(HCI_CONN_PA_SYNC, &iso_pi(sk)->conn->hcon->flags) ||
703fbdc4bc4SIulia Tanasescu 		    test_bit(HCI_CONN_PA_SYNC_FAILED, &iso_pi(sk)->conn->hcon->flags)))
704fbdc4bc4SIulia Tanasescu 			iso_sock_disconn(sk);
705fbdc4bc4SIulia Tanasescu 		else
706ccf74f23SLuiz Augusto von Dentz 			iso_chan_del(sk, ECONNRESET);
707ccf74f23SLuiz Augusto von Dentz 		break;
708ccf74f23SLuiz Augusto von Dentz 	case BT_DISCONN:
709ccf74f23SLuiz Augusto von Dentz 		iso_chan_del(sk, ECONNRESET);
710ccf74f23SLuiz Augusto von Dentz 		break;
711ccf74f23SLuiz Augusto von Dentz 
712ccf74f23SLuiz Augusto von Dentz 	default:
713ccf74f23SLuiz Augusto von Dentz 		sock_set_flag(sk, SOCK_ZAPPED);
714ccf74f23SLuiz Augusto von Dentz 		break;
715ccf74f23SLuiz Augusto von Dentz 	}
716ccf74f23SLuiz Augusto von Dentz }
717ccf74f23SLuiz Augusto von Dentz 
718ccf74f23SLuiz Augusto von Dentz /* Must be called on unlocked socket. */
iso_sock_close(struct sock * sk)719ccf74f23SLuiz Augusto von Dentz static void iso_sock_close(struct sock *sk)
720ccf74f23SLuiz Augusto von Dentz {
721ccf74f23SLuiz Augusto von Dentz 	iso_sock_clear_timer(sk);
722ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
723ccf74f23SLuiz Augusto von Dentz 	__iso_sock_close(sk);
724ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
725ccf74f23SLuiz Augusto von Dentz 	iso_sock_kill(sk);
726ccf74f23SLuiz Augusto von Dentz }
727ccf74f23SLuiz Augusto von Dentz 
iso_sock_init(struct sock * sk,struct sock * parent)728ccf74f23SLuiz Augusto von Dentz static void iso_sock_init(struct sock *sk, struct sock *parent)
729ccf74f23SLuiz Augusto von Dentz {
730ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
731ccf74f23SLuiz Augusto von Dentz 
732ccf74f23SLuiz Augusto von Dentz 	if (parent) {
733ccf74f23SLuiz Augusto von Dentz 		sk->sk_type = parent->sk_type;
734ccf74f23SLuiz Augusto von Dentz 		bt_sk(sk)->flags = bt_sk(parent)->flags;
735ccf74f23SLuiz Augusto von Dentz 		security_sk_clone(parent, sk);
736ccf74f23SLuiz Augusto von Dentz 	}
737ccf74f23SLuiz Augusto von Dentz }
738ccf74f23SLuiz Augusto von Dentz 
739ccf74f23SLuiz Augusto von Dentz static struct proto iso_proto = {
740ccf74f23SLuiz Augusto von Dentz 	.name		= "ISO",
741ccf74f23SLuiz Augusto von Dentz 	.owner		= THIS_MODULE,
742ccf74f23SLuiz Augusto von Dentz 	.obj_size	= sizeof(struct iso_pinfo)
743ccf74f23SLuiz Augusto von Dentz };
744ccf74f23SLuiz Augusto von Dentz 
745ccf74f23SLuiz Augusto von Dentz #define DEFAULT_IO_QOS \
746ccf74f23SLuiz Augusto von Dentz { \
747ccf74f23SLuiz Augusto von Dentz 	.interval	= 10000u, \
748ccf74f23SLuiz Augusto von Dentz 	.latency	= 10u, \
749ccf74f23SLuiz Augusto von Dentz 	.sdu		= 40u, \
750ccf74f23SLuiz Augusto von Dentz 	.phy		= BT_ISO_PHY_2M, \
751ccf74f23SLuiz Augusto von Dentz 	.rtn		= 2u, \
752ccf74f23SLuiz Augusto von Dentz }
753ccf74f23SLuiz Augusto von Dentz 
754ccf74f23SLuiz Augusto von Dentz static struct bt_iso_qos default_qos = {
7550fe8c8d0SIulia Tanasescu 	.bcast = {
7560fe8c8d0SIulia Tanasescu 		.big			= BT_ISO_QOS_BIG_UNSET,
7570fe8c8d0SIulia Tanasescu 		.bis			= BT_ISO_QOS_BIS_UNSET,
75814f0dcecSLuiz Augusto von Dentz 		.sync_factor		= 0x01,
759ccf74f23SLuiz Augusto von Dentz 		.packing		= 0x00,
760ccf74f23SLuiz Augusto von Dentz 		.framing		= 0x00,
761ccf74f23SLuiz Augusto von Dentz 		.in			= DEFAULT_IO_QOS,
762ccf74f23SLuiz Augusto von Dentz 		.out			= DEFAULT_IO_QOS,
7630fe8c8d0SIulia Tanasescu 		.encryption		= 0x00,
7640fe8c8d0SIulia Tanasescu 		.bcode			= {0x00},
7650fe8c8d0SIulia Tanasescu 		.options		= 0x00,
7660fe8c8d0SIulia Tanasescu 		.skip			= 0x0000,
767c8321645SLuiz Augusto von Dentz 		.sync_timeout		= BT_ISO_SYNC_TIMEOUT,
7680fe8c8d0SIulia Tanasescu 		.sync_cte_type		= 0x00,
7690fe8c8d0SIulia Tanasescu 		.mse			= 0x00,
770c8321645SLuiz Augusto von Dentz 		.timeout		= BT_ISO_SYNC_TIMEOUT,
7710fe8c8d0SIulia Tanasescu 	},
772ccf74f23SLuiz Augusto von Dentz };
773ccf74f23SLuiz Augusto von Dentz 
iso_sock_alloc(struct net * net,struct socket * sock,int proto,gfp_t prio,int kern)774ccf74f23SLuiz Augusto von Dentz static struct sock *iso_sock_alloc(struct net *net, struct socket *sock,
775ccf74f23SLuiz Augusto von Dentz 				   int proto, gfp_t prio, int kern)
776ccf74f23SLuiz Augusto von Dentz {
777ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
778ccf74f23SLuiz Augusto von Dentz 
7796bfa273eSLuiz Augusto von Dentz 	sk = bt_sock_alloc(net, sock, &iso_proto, proto, prio, kern);
780ccf74f23SLuiz Augusto von Dentz 	if (!sk)
781ccf74f23SLuiz Augusto von Dentz 		return NULL;
782ccf74f23SLuiz Augusto von Dentz 
783ccf74f23SLuiz Augusto von Dentz 	sk->sk_destruct = iso_sock_destruct;
784ccf74f23SLuiz Augusto von Dentz 	sk->sk_sndtimeo = ISO_CONN_TIMEOUT;
785ccf74f23SLuiz Augusto von Dentz 
786ccf74f23SLuiz Augusto von Dentz 	/* Set address type as public as default src address is BDADDR_ANY */
787ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
788ccf74f23SLuiz Augusto von Dentz 
789ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->qos = default_qos;
790ccf74f23SLuiz Augusto von Dentz 
791ccf74f23SLuiz Augusto von Dentz 	bt_sock_link(&iso_sk_list, sk);
792ccf74f23SLuiz Augusto von Dentz 	return sk;
793ccf74f23SLuiz Augusto von Dentz }
794ccf74f23SLuiz Augusto von Dentz 
iso_sock_create(struct net * net,struct socket * sock,int protocol,int kern)795ccf74f23SLuiz Augusto von Dentz static int iso_sock_create(struct net *net, struct socket *sock, int protocol,
796ccf74f23SLuiz Augusto von Dentz 			   int kern)
797ccf74f23SLuiz Augusto von Dentz {
798ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
799ccf74f23SLuiz Augusto von Dentz 
800ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p", sock);
801ccf74f23SLuiz Augusto von Dentz 
802ccf74f23SLuiz Augusto von Dentz 	sock->state = SS_UNCONNECTED;
803ccf74f23SLuiz Augusto von Dentz 
804ccf74f23SLuiz Augusto von Dentz 	if (sock->type != SOCK_SEQPACKET)
805ccf74f23SLuiz Augusto von Dentz 		return -ESOCKTNOSUPPORT;
806ccf74f23SLuiz Augusto von Dentz 
807ccf74f23SLuiz Augusto von Dentz 	sock->ops = &iso_sock_ops;
808ccf74f23SLuiz Augusto von Dentz 
809ccf74f23SLuiz Augusto von Dentz 	sk = iso_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
810ccf74f23SLuiz Augusto von Dentz 	if (!sk)
811ccf74f23SLuiz Augusto von Dentz 		return -ENOMEM;
812ccf74f23SLuiz Augusto von Dentz 
813ccf74f23SLuiz Augusto von Dentz 	iso_sock_init(sk, NULL);
814ccf74f23SLuiz Augusto von Dentz 	return 0;
815ccf74f23SLuiz Augusto von Dentz }
816ccf74f23SLuiz Augusto von Dentz 
iso_sock_bind_bc(struct socket * sock,struct sockaddr * addr,int addr_len)817f764a6c2SLuiz Augusto von Dentz static int iso_sock_bind_bc(struct socket *sock, struct sockaddr *addr,
818f764a6c2SLuiz Augusto von Dentz 			    int addr_len)
819f764a6c2SLuiz Augusto von Dentz {
820f764a6c2SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
821f764a6c2SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
822f764a6c2SLuiz Augusto von Dentz 	int i;
823f764a6c2SLuiz Augusto von Dentz 
824f764a6c2SLuiz Augusto von Dentz 	BT_DBG("sk %p bc_sid %u bc_num_bis %u", sk, sa->iso_bc->bc_sid,
825f764a6c2SLuiz Augusto von Dentz 	       sa->iso_bc->bc_num_bis);
826f764a6c2SLuiz Augusto von Dentz 
827f764a6c2SLuiz Augusto von Dentz 	if (addr_len > sizeof(*sa) + sizeof(*sa->iso_bc) ||
828f764a6c2SLuiz Augusto von Dentz 	    sa->iso_bc->bc_num_bis < 0x01 || sa->iso_bc->bc_num_bis > 0x1f)
829f764a6c2SLuiz Augusto von Dentz 		return -EINVAL;
830f764a6c2SLuiz Augusto von Dentz 
831f764a6c2SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->dst, &sa->iso_bc->bc_bdaddr);
832f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->dst_type = sa->iso_bc->bc_bdaddr_type;
833f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->sync_handle = -1;
834f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->bc_sid = sa->iso_bc->bc_sid;
835f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->bc_num_bis = sa->iso_bc->bc_num_bis;
836f764a6c2SLuiz Augusto von Dentz 
837f764a6c2SLuiz Augusto von Dentz 	for (i = 0; i < iso_pi(sk)->bc_num_bis; i++) {
838f764a6c2SLuiz Augusto von Dentz 		if (sa->iso_bc->bc_bis[i] < 0x01 ||
839f764a6c2SLuiz Augusto von Dentz 		    sa->iso_bc->bc_bis[i] > 0x1f)
840f764a6c2SLuiz Augusto von Dentz 			return -EINVAL;
841f764a6c2SLuiz Augusto von Dentz 
842f764a6c2SLuiz Augusto von Dentz 		memcpy(iso_pi(sk)->bc_bis, sa->iso_bc->bc_bis,
843f764a6c2SLuiz Augusto von Dentz 		       iso_pi(sk)->bc_num_bis);
844f764a6c2SLuiz Augusto von Dentz 	}
845f764a6c2SLuiz Augusto von Dentz 
846f764a6c2SLuiz Augusto von Dentz 	return 0;
847f764a6c2SLuiz Augusto von Dentz }
848f764a6c2SLuiz Augusto von Dentz 
iso_sock_bind(struct socket * sock,struct sockaddr * addr,int addr_len)849ccf74f23SLuiz Augusto von Dentz static int iso_sock_bind(struct socket *sock, struct sockaddr *addr,
850ccf74f23SLuiz Augusto von Dentz 			 int addr_len)
851ccf74f23SLuiz Augusto von Dentz {
852ccf74f23SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
853ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
854ccf74f23SLuiz Augusto von Dentz 	int err = 0;
855ccf74f23SLuiz Augusto von Dentz 
856ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p %pMR type %u", sk, &sa->iso_bdaddr, sa->iso_bdaddr_type);
857ccf74f23SLuiz Augusto von Dentz 
858ccf74f23SLuiz Augusto von Dentz 	if (!addr || addr_len < sizeof(struct sockaddr_iso) ||
859ccf74f23SLuiz Augusto von Dentz 	    addr->sa_family != AF_BLUETOOTH)
860ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
861ccf74f23SLuiz Augusto von Dentz 
862ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
863ccf74f23SLuiz Augusto von Dentz 
864ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_OPEN) {
865ccf74f23SLuiz Augusto von Dentz 		err = -EBADFD;
866ccf74f23SLuiz Augusto von Dentz 		goto done;
867ccf74f23SLuiz Augusto von Dentz 	}
868ccf74f23SLuiz Augusto von Dentz 
869ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_type != SOCK_SEQPACKET) {
870ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
871ccf74f23SLuiz Augusto von Dentz 		goto done;
872ccf74f23SLuiz Augusto von Dentz 	}
873ccf74f23SLuiz Augusto von Dentz 
874ccf74f23SLuiz Augusto von Dentz 	/* Check if the address type is of LE type */
875ccf74f23SLuiz Augusto von Dentz 	if (!bdaddr_type_is_le(sa->iso_bdaddr_type)) {
876ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
877ccf74f23SLuiz Augusto von Dentz 		goto done;
878ccf74f23SLuiz Augusto von Dentz 	}
879ccf74f23SLuiz Augusto von Dentz 
880ccf74f23SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->src, &sa->iso_bdaddr);
881ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->src_type = sa->iso_bdaddr_type;
882ccf74f23SLuiz Augusto von Dentz 
883f764a6c2SLuiz Augusto von Dentz 	/* Check for Broadcast address */
884f764a6c2SLuiz Augusto von Dentz 	if (addr_len > sizeof(*sa)) {
885f764a6c2SLuiz Augusto von Dentz 		err = iso_sock_bind_bc(sock, addr, addr_len);
886f764a6c2SLuiz Augusto von Dentz 		if (err)
887f764a6c2SLuiz Augusto von Dentz 			goto done;
888f764a6c2SLuiz Augusto von Dentz 	}
889f764a6c2SLuiz Augusto von Dentz 
890ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_BOUND;
891ccf74f23SLuiz Augusto von Dentz 
892ccf74f23SLuiz Augusto von Dentz done:
893ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
894ccf74f23SLuiz Augusto von Dentz 	return err;
895ccf74f23SLuiz Augusto von Dentz }
896ccf74f23SLuiz Augusto von Dentz 
iso_sock_connect(struct socket * sock,struct sockaddr * addr,int alen,int flags)897ccf74f23SLuiz Augusto von Dentz static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
898ccf74f23SLuiz Augusto von Dentz 			    int alen, int flags)
899ccf74f23SLuiz Augusto von Dentz {
900ccf74f23SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
901ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
902ccf74f23SLuiz Augusto von Dentz 	int err;
903ccf74f23SLuiz Augusto von Dentz 
904ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
905ccf74f23SLuiz Augusto von Dentz 
906ccf74f23SLuiz Augusto von Dentz 	if (alen < sizeof(struct sockaddr_iso) ||
907ccf74f23SLuiz Augusto von Dentz 	    addr->sa_family != AF_BLUETOOTH)
908ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
909ccf74f23SLuiz Augusto von Dentz 
910ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
911ccf74f23SLuiz Augusto von Dentz 		return -EBADFD;
912ccf74f23SLuiz Augusto von Dentz 
913ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_type != SOCK_SEQPACKET)
914ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
915ccf74f23SLuiz Augusto von Dentz 
916ccf74f23SLuiz Augusto von Dentz 	/* Check if the address type is of LE type */
917ccf74f23SLuiz Augusto von Dentz 	if (!bdaddr_type_is_le(sa->iso_bdaddr_type))
918ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
919ccf74f23SLuiz Augusto von Dentz 
920ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
921ccf74f23SLuiz Augusto von Dentz 
922ccf74f23SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
923ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
924ccf74f23SLuiz Augusto von Dentz 
925241f5193SLuiz Augusto von Dentz 	release_sock(sk);
926241f5193SLuiz Augusto von Dentz 
927f764a6c2SLuiz Augusto von Dentz 	if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
928f764a6c2SLuiz Augusto von Dentz 		err = iso_connect_cis(sk);
929f764a6c2SLuiz Augusto von Dentz 	else
930f764a6c2SLuiz Augusto von Dentz 		err = iso_connect_bis(sk);
931f764a6c2SLuiz Augusto von Dentz 
932ccf74f23SLuiz Augusto von Dentz 	if (err)
933241f5193SLuiz Augusto von Dentz 		return err;
934241f5193SLuiz Augusto von Dentz 
935241f5193SLuiz Augusto von Dentz 	lock_sock(sk);
936ccf74f23SLuiz Augusto von Dentz 
937ccf74f23SLuiz Augusto von Dentz 	if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
938ccf74f23SLuiz Augusto von Dentz 		err = bt_sock_wait_state(sk, BT_CONNECTED,
939ccf74f23SLuiz Augusto von Dentz 					 sock_sndtimeo(sk, flags & O_NONBLOCK));
940ccf74f23SLuiz Augusto von Dentz 	}
941ccf74f23SLuiz Augusto von Dentz 
942ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
943ccf74f23SLuiz Augusto von Dentz 	return err;
944ccf74f23SLuiz Augusto von Dentz }
945ccf74f23SLuiz Augusto von Dentz 
iso_listen_bis(struct sock * sk)946f764a6c2SLuiz Augusto von Dentz static int iso_listen_bis(struct sock *sk)
947f764a6c2SLuiz Augusto von Dentz {
948f764a6c2SLuiz Augusto von Dentz 	struct hci_dev *hdev;
949f764a6c2SLuiz Augusto von Dentz 	int err = 0;
950f764a6c2SLuiz Augusto von Dentz 
951f764a6c2SLuiz Augusto von Dentz 	BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
952f764a6c2SLuiz Augusto von Dentz 	       &iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
953f764a6c2SLuiz Augusto von Dentz 
954f764a6c2SLuiz Augusto von Dentz 	write_lock(&iso_sk_list.lock);
955f764a6c2SLuiz Augusto von Dentz 
956f764a6c2SLuiz Augusto von Dentz 	if (__iso_get_sock_listen_by_sid(&iso_pi(sk)->src, &iso_pi(sk)->dst,
957f764a6c2SLuiz Augusto von Dentz 					 iso_pi(sk)->bc_sid))
958f764a6c2SLuiz Augusto von Dentz 		err = -EADDRINUSE;
959f764a6c2SLuiz Augusto von Dentz 
960f764a6c2SLuiz Augusto von Dentz 	write_unlock(&iso_sk_list.lock);
961f764a6c2SLuiz Augusto von Dentz 
962f764a6c2SLuiz Augusto von Dentz 	if (err)
963f764a6c2SLuiz Augusto von Dentz 		return err;
964f764a6c2SLuiz Augusto von Dentz 
965f764a6c2SLuiz Augusto von Dentz 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
966f764a6c2SLuiz Augusto von Dentz 			     iso_pi(sk)->src_type);
967f764a6c2SLuiz Augusto von Dentz 	if (!hdev)
968f764a6c2SLuiz Augusto von Dentz 		return -EHOSTUNREACH;
969f764a6c2SLuiz Augusto von Dentz 
9700fe8c8d0SIulia Tanasescu 	/* Fail if user set invalid QoS */
9710fe8c8d0SIulia Tanasescu 	if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
9720fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos = default_qos;
9730fe8c8d0SIulia Tanasescu 		return -EINVAL;
9740fe8c8d0SIulia Tanasescu 	}
9750fe8c8d0SIulia Tanasescu 
976d11ab690SPauli Virtanen 	err = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
977d11ab690SPauli Virtanen 				 le_addr_type(iso_pi(sk)->dst_type),
9780fe8c8d0SIulia Tanasescu 				 iso_pi(sk)->bc_sid, &iso_pi(sk)->qos);
979f764a6c2SLuiz Augusto von Dentz 
9807e7df2c1SWang ShaoBo 	hci_dev_put(hdev);
981f764a6c2SLuiz Augusto von Dentz 
982f764a6c2SLuiz Augusto von Dentz 	return err;
983f764a6c2SLuiz Augusto von Dentz }
984f764a6c2SLuiz Augusto von Dentz 
iso_listen_cis(struct sock * sk)985f764a6c2SLuiz Augusto von Dentz static int iso_listen_cis(struct sock *sk)
986f764a6c2SLuiz Augusto von Dentz {
987f764a6c2SLuiz Augusto von Dentz 	int err = 0;
988f764a6c2SLuiz Augusto von Dentz 
989f764a6c2SLuiz Augusto von Dentz 	BT_DBG("%pMR", &iso_pi(sk)->src);
990f764a6c2SLuiz Augusto von Dentz 
991f764a6c2SLuiz Augusto von Dentz 	write_lock(&iso_sk_list.lock);
992f764a6c2SLuiz Augusto von Dentz 
993e0275ea5SLuiz Augusto von Dentz 	if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst))
994f764a6c2SLuiz Augusto von Dentz 		err = -EADDRINUSE;
995f764a6c2SLuiz Augusto von Dentz 
996f764a6c2SLuiz Augusto von Dentz 	write_unlock(&iso_sk_list.lock);
997f764a6c2SLuiz Augusto von Dentz 
998f764a6c2SLuiz Augusto von Dentz 	return err;
999f764a6c2SLuiz Augusto von Dentz }
1000f764a6c2SLuiz Augusto von Dentz 
iso_sock_listen(struct socket * sock,int backlog)1001ccf74f23SLuiz Augusto von Dentz static int iso_sock_listen(struct socket *sock, int backlog)
1002ccf74f23SLuiz Augusto von Dentz {
1003ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1004ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1005ccf74f23SLuiz Augusto von Dentz 
1006ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p backlog %d", sk, backlog);
1007ccf74f23SLuiz Augusto von Dentz 
1008ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1009ccf74f23SLuiz Augusto von Dentz 
1010ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_BOUND) {
1011ccf74f23SLuiz Augusto von Dentz 		err = -EBADFD;
1012ccf74f23SLuiz Augusto von Dentz 		goto done;
1013ccf74f23SLuiz Augusto von Dentz 	}
1014ccf74f23SLuiz Augusto von Dentz 
1015ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_type != SOCK_SEQPACKET) {
1016ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
1017ccf74f23SLuiz Augusto von Dentz 		goto done;
1018ccf74f23SLuiz Augusto von Dentz 	}
1019ccf74f23SLuiz Augusto von Dentz 
1020f764a6c2SLuiz Augusto von Dentz 	if (!bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
1021f764a6c2SLuiz Augusto von Dentz 		err = iso_listen_cis(sk);
1022f764a6c2SLuiz Augusto von Dentz 	else
1023f764a6c2SLuiz Augusto von Dentz 		err = iso_listen_bis(sk);
1024ccf74f23SLuiz Augusto von Dentz 
1025f764a6c2SLuiz Augusto von Dentz 	if (err)
1026f764a6c2SLuiz Augusto von Dentz 		goto done;
1027ccf74f23SLuiz Augusto von Dentz 
1028ccf74f23SLuiz Augusto von Dentz 	sk->sk_max_ack_backlog = backlog;
1029ccf74f23SLuiz Augusto von Dentz 	sk->sk_ack_backlog = 0;
1030ccf74f23SLuiz Augusto von Dentz 
1031ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_LISTEN;
1032ccf74f23SLuiz Augusto von Dentz 
1033ccf74f23SLuiz Augusto von Dentz done:
1034ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1035ccf74f23SLuiz Augusto von Dentz 	return err;
1036ccf74f23SLuiz Augusto von Dentz }
1037ccf74f23SLuiz Augusto von Dentz 
iso_sock_accept(struct socket * sock,struct socket * newsock,int flags,bool kern)1038ccf74f23SLuiz Augusto von Dentz static int iso_sock_accept(struct socket *sock, struct socket *newsock,
1039ccf74f23SLuiz Augusto von Dentz 			   int flags, bool kern)
1040ccf74f23SLuiz Augusto von Dentz {
1041ccf74f23SLuiz Augusto von Dentz 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
1042ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk, *ch;
1043ccf74f23SLuiz Augusto von Dentz 	long timeo;
1044ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1045ccf74f23SLuiz Augusto von Dentz 
1046ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1047ccf74f23SLuiz Augusto von Dentz 
1048ccf74f23SLuiz Augusto von Dentz 	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1049ccf74f23SLuiz Augusto von Dentz 
1050ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p timeo %ld", sk, timeo);
1051ccf74f23SLuiz Augusto von Dentz 
1052ccf74f23SLuiz Augusto von Dentz 	/* Wait for an incoming connection. (wake-one). */
1053ccf74f23SLuiz Augusto von Dentz 	add_wait_queue_exclusive(sk_sleep(sk), &wait);
1054ccf74f23SLuiz Augusto von Dentz 	while (1) {
1055ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN) {
1056ccf74f23SLuiz Augusto von Dentz 			err = -EBADFD;
1057ccf74f23SLuiz Augusto von Dentz 			break;
1058ccf74f23SLuiz Augusto von Dentz 		}
1059ccf74f23SLuiz Augusto von Dentz 
1060ccf74f23SLuiz Augusto von Dentz 		ch = bt_accept_dequeue(sk, newsock);
1061ccf74f23SLuiz Augusto von Dentz 		if (ch)
1062ccf74f23SLuiz Augusto von Dentz 			break;
1063ccf74f23SLuiz Augusto von Dentz 
1064ccf74f23SLuiz Augusto von Dentz 		if (!timeo) {
1065ccf74f23SLuiz Augusto von Dentz 			err = -EAGAIN;
1066ccf74f23SLuiz Augusto von Dentz 			break;
1067ccf74f23SLuiz Augusto von Dentz 		}
1068ccf74f23SLuiz Augusto von Dentz 
1069ccf74f23SLuiz Augusto von Dentz 		if (signal_pending(current)) {
1070ccf74f23SLuiz Augusto von Dentz 			err = sock_intr_errno(timeo);
1071ccf74f23SLuiz Augusto von Dentz 			break;
1072ccf74f23SLuiz Augusto von Dentz 		}
1073ccf74f23SLuiz Augusto von Dentz 
1074ccf74f23SLuiz Augusto von Dentz 		release_sock(sk);
1075ccf74f23SLuiz Augusto von Dentz 
1076ccf74f23SLuiz Augusto von Dentz 		timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
1077ccf74f23SLuiz Augusto von Dentz 		lock_sock(sk);
1078ccf74f23SLuiz Augusto von Dentz 	}
1079ccf74f23SLuiz Augusto von Dentz 	remove_wait_queue(sk_sleep(sk), &wait);
1080ccf74f23SLuiz Augusto von Dentz 
1081ccf74f23SLuiz Augusto von Dentz 	if (err)
1082ccf74f23SLuiz Augusto von Dentz 		goto done;
1083ccf74f23SLuiz Augusto von Dentz 
1084ccf74f23SLuiz Augusto von Dentz 	newsock->state = SS_CONNECTED;
1085ccf74f23SLuiz Augusto von Dentz 
1086ccf74f23SLuiz Augusto von Dentz 	BT_DBG("new socket %p", ch);
1087ccf74f23SLuiz Augusto von Dentz 
1088ccf74f23SLuiz Augusto von Dentz done:
1089ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1090ccf74f23SLuiz Augusto von Dentz 	return err;
1091ccf74f23SLuiz Augusto von Dentz }
1092ccf74f23SLuiz Augusto von Dentz 
iso_sock_getname(struct socket * sock,struct sockaddr * addr,int peer)1093ccf74f23SLuiz Augusto von Dentz static int iso_sock_getname(struct socket *sock, struct sockaddr *addr,
1094ccf74f23SLuiz Augusto von Dentz 			    int peer)
1095ccf74f23SLuiz Augusto von Dentz {
1096ccf74f23SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
1097ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1098ccf74f23SLuiz Augusto von Dentz 
1099ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p", sock, sk);
1100ccf74f23SLuiz Augusto von Dentz 
1101ccf74f23SLuiz Augusto von Dentz 	addr->sa_family = AF_BLUETOOTH;
1102ccf74f23SLuiz Augusto von Dentz 
1103ccf74f23SLuiz Augusto von Dentz 	if (peer) {
1104ccf74f23SLuiz Augusto von Dentz 		bacpy(&sa->iso_bdaddr, &iso_pi(sk)->dst);
1105ccf74f23SLuiz Augusto von Dentz 		sa->iso_bdaddr_type = iso_pi(sk)->dst_type;
1106ccf74f23SLuiz Augusto von Dentz 	} else {
1107ccf74f23SLuiz Augusto von Dentz 		bacpy(&sa->iso_bdaddr, &iso_pi(sk)->src);
1108ccf74f23SLuiz Augusto von Dentz 		sa->iso_bdaddr_type = iso_pi(sk)->src_type;
1109ccf74f23SLuiz Augusto von Dentz 	}
1110ccf74f23SLuiz Augusto von Dentz 
1111ccf74f23SLuiz Augusto von Dentz 	return sizeof(struct sockaddr_iso);
1112ccf74f23SLuiz Augusto von Dentz }
1113ccf74f23SLuiz Augusto von Dentz 
iso_sock_sendmsg(struct socket * sock,struct msghdr * msg,size_t len)1114ccf74f23SLuiz Augusto von Dentz static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg,
1115ccf74f23SLuiz Augusto von Dentz 			    size_t len)
1116ccf74f23SLuiz Augusto von Dentz {
1117ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1118ccf74f23SLuiz Augusto von Dentz 	struct sk_buff *skb, **frag;
1119d40ae85eSPauli Virtanen 	size_t mtu;
1120ccf74f23SLuiz Augusto von Dentz 	int err;
1121ccf74f23SLuiz Augusto von Dentz 
1122ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p", sock, sk);
1123ccf74f23SLuiz Augusto von Dentz 
1124ccf74f23SLuiz Augusto von Dentz 	err = sock_error(sk);
1125ccf74f23SLuiz Augusto von Dentz 	if (err)
1126ccf74f23SLuiz Augusto von Dentz 		return err;
1127ccf74f23SLuiz Augusto von Dentz 
1128ccf74f23SLuiz Augusto von Dentz 	if (msg->msg_flags & MSG_OOB)
1129ccf74f23SLuiz Augusto von Dentz 		return -EOPNOTSUPP;
1130ccf74f23SLuiz Augusto von Dentz 
1131d40ae85eSPauli Virtanen 	lock_sock(sk);
1132ccf74f23SLuiz Augusto von Dentz 
1133d40ae85eSPauli Virtanen 	if (sk->sk_state != BT_CONNECTED) {
1134d40ae85eSPauli Virtanen 		release_sock(sk);
1135d40ae85eSPauli Virtanen 		return -ENOTCONN;
1136d40ae85eSPauli Virtanen 	}
1137d40ae85eSPauli Virtanen 
1138ad3f7986SSungwoo Kim 	mtu = iso_pi(sk)->conn->hcon->mtu;
1139d40ae85eSPauli Virtanen 
1140d40ae85eSPauli Virtanen 	release_sock(sk);
1141d40ae85eSPauli Virtanen 
1142d40ae85eSPauli Virtanen 	skb = bt_skb_sendmsg(sk, msg, len, mtu, HCI_ISO_DATA_HDR_SIZE, 0);
1143ccf74f23SLuiz Augusto von Dentz 	if (IS_ERR(skb))
1144ccf74f23SLuiz Augusto von Dentz 		return PTR_ERR(skb);
1145ccf74f23SLuiz Augusto von Dentz 
1146ccf74f23SLuiz Augusto von Dentz 	len -= skb->len;
1147ccf74f23SLuiz Augusto von Dentz 
1148ccf74f23SLuiz Augusto von Dentz 	BT_DBG("skb %p len %d", sk, skb->len);
1149ccf74f23SLuiz Augusto von Dentz 
1150ccf74f23SLuiz Augusto von Dentz 	/* Continuation fragments */
1151ccf74f23SLuiz Augusto von Dentz 	frag = &skb_shinfo(skb)->frag_list;
1152ccf74f23SLuiz Augusto von Dentz 	while (len) {
1153ccf74f23SLuiz Augusto von Dentz 		struct sk_buff *tmp;
1154ccf74f23SLuiz Augusto von Dentz 
1155d40ae85eSPauli Virtanen 		tmp = bt_skb_sendmsg(sk, msg, len, mtu, 0, 0);
1156ccf74f23SLuiz Augusto von Dentz 		if (IS_ERR(tmp)) {
1157ccf74f23SLuiz Augusto von Dentz 			kfree_skb(skb);
1158ccf74f23SLuiz Augusto von Dentz 			return PTR_ERR(tmp);
1159ccf74f23SLuiz Augusto von Dentz 		}
1160ccf74f23SLuiz Augusto von Dentz 
1161ccf74f23SLuiz Augusto von Dentz 		*frag = tmp;
1162ccf74f23SLuiz Augusto von Dentz 
1163ccf74f23SLuiz Augusto von Dentz 		len  -= tmp->len;
1164ccf74f23SLuiz Augusto von Dentz 
1165ccf74f23SLuiz Augusto von Dentz 		skb->len += tmp->len;
1166ccf74f23SLuiz Augusto von Dentz 		skb->data_len += tmp->len;
1167ccf74f23SLuiz Augusto von Dentz 
1168ccf74f23SLuiz Augusto von Dentz 		BT_DBG("frag %p len %d", *frag, tmp->len);
1169ccf74f23SLuiz Augusto von Dentz 
1170ccf74f23SLuiz Augusto von Dentz 		frag = &(*frag)->next;
1171ccf74f23SLuiz Augusto von Dentz 	}
1172ccf74f23SLuiz Augusto von Dentz 
1173ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1174ccf74f23SLuiz Augusto von Dentz 
1175ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state == BT_CONNECTED)
1176ccf74f23SLuiz Augusto von Dentz 		err = iso_send_frame(sk, skb);
1177ccf74f23SLuiz Augusto von Dentz 	else
1178ccf74f23SLuiz Augusto von Dentz 		err = -ENOTCONN;
1179ccf74f23SLuiz Augusto von Dentz 
1180ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1181ccf74f23SLuiz Augusto von Dentz 
1182ccf74f23SLuiz Augusto von Dentz 	if (err < 0)
1183ccf74f23SLuiz Augusto von Dentz 		kfree_skb(skb);
1184ccf74f23SLuiz Augusto von Dentz 	return err;
1185ccf74f23SLuiz Augusto von Dentz }
1186ccf74f23SLuiz Augusto von Dentz 
iso_conn_defer_accept(struct hci_conn * conn)1187ccf74f23SLuiz Augusto von Dentz static void iso_conn_defer_accept(struct hci_conn *conn)
1188ccf74f23SLuiz Augusto von Dentz {
1189ccf74f23SLuiz Augusto von Dentz 	struct hci_cp_le_accept_cis cp;
1190ccf74f23SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
1191ccf74f23SLuiz Augusto von Dentz 
1192ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p", conn);
1193ccf74f23SLuiz Augusto von Dentz 
1194ccf74f23SLuiz Augusto von Dentz 	conn->state = BT_CONFIG;
1195ccf74f23SLuiz Augusto von Dentz 
1196ccf74f23SLuiz Augusto von Dentz 	cp.handle = cpu_to_le16(conn->handle);
1197ccf74f23SLuiz Augusto von Dentz 
1198ccf74f23SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
1199ccf74f23SLuiz Augusto von Dentz }
1200ccf74f23SLuiz Augusto von Dentz 
iso_conn_big_sync(struct sock * sk)1201fbdc4bc4SIulia Tanasescu static void iso_conn_big_sync(struct sock *sk)
1202fbdc4bc4SIulia Tanasescu {
1203fbdc4bc4SIulia Tanasescu 	int err;
1204fbdc4bc4SIulia Tanasescu 	struct hci_dev *hdev;
1205fbdc4bc4SIulia Tanasescu 
1206fbdc4bc4SIulia Tanasescu 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
1207fbdc4bc4SIulia Tanasescu 			     iso_pi(sk)->src_type);
1208fbdc4bc4SIulia Tanasescu 
1209fbdc4bc4SIulia Tanasescu 	if (!hdev)
1210fbdc4bc4SIulia Tanasescu 		return;
1211fbdc4bc4SIulia Tanasescu 
1212fbdc4bc4SIulia Tanasescu 	if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
1213fbdc4bc4SIulia Tanasescu 		err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
1214fbdc4bc4SIulia Tanasescu 					     &iso_pi(sk)->qos,
1215fbdc4bc4SIulia Tanasescu 					     iso_pi(sk)->sync_handle,
1216fbdc4bc4SIulia Tanasescu 					     iso_pi(sk)->bc_num_bis,
1217fbdc4bc4SIulia Tanasescu 					     iso_pi(sk)->bc_bis);
1218fbdc4bc4SIulia Tanasescu 		if (err)
1219fbdc4bc4SIulia Tanasescu 			bt_dev_err(hdev, "hci_le_big_create_sync: %d",
1220fbdc4bc4SIulia Tanasescu 				   err);
1221fbdc4bc4SIulia Tanasescu 	}
1222fbdc4bc4SIulia Tanasescu }
1223fbdc4bc4SIulia Tanasescu 
iso_sock_recvmsg(struct socket * sock,struct msghdr * msg,size_t len,int flags)1224ccf74f23SLuiz Augusto von Dentz static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
1225ccf74f23SLuiz Augusto von Dentz 			    size_t len, int flags)
1226ccf74f23SLuiz Augusto von Dentz {
1227ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1228ccf74f23SLuiz Augusto von Dentz 	struct iso_pinfo *pi = iso_pi(sk);
1229ccf74f23SLuiz Augusto von Dentz 
1230ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1231ccf74f23SLuiz Augusto von Dentz 
1232ccf74f23SLuiz Augusto von Dentz 	if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
1233d40ae85eSPauli Virtanen 		lock_sock(sk);
1234ccf74f23SLuiz Augusto von Dentz 		switch (sk->sk_state) {
1235ccf74f23SLuiz Augusto von Dentz 		case BT_CONNECT2:
1236*04566971SIulia Tanasescu 			if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
1237fbdc4bc4SIulia Tanasescu 				iso_conn_big_sync(sk);
1238fbdc4bc4SIulia Tanasescu 				sk->sk_state = BT_LISTEN;
1239fbdc4bc4SIulia Tanasescu 			} else {
1240ccf74f23SLuiz Augusto von Dentz 				iso_conn_defer_accept(pi->conn->hcon);
1241ccf74f23SLuiz Augusto von Dentz 				sk->sk_state = BT_CONFIG;
1242fbdc4bc4SIulia Tanasescu 			}
1243ccf74f23SLuiz Augusto von Dentz 			release_sock(sk);
1244ccf74f23SLuiz Augusto von Dentz 			return 0;
1245ccf74f23SLuiz Augusto von Dentz 		case BT_CONNECT:
1246d40ae85eSPauli Virtanen 			release_sock(sk);
1247241f5193SLuiz Augusto von Dentz 			return iso_connect_cis(sk);
1248d40ae85eSPauli Virtanen 		default:
1249d40ae85eSPauli Virtanen 			release_sock(sk);
1250d40ae85eSPauli Virtanen 			break;
1251ccf74f23SLuiz Augusto von Dentz 		}
1252ccf74f23SLuiz Augusto von Dentz 	}
1253ccf74f23SLuiz Augusto von Dentz 
1254ccf74f23SLuiz Augusto von Dentz 	return bt_sock_recvmsg(sock, msg, len, flags);
1255ccf74f23SLuiz Augusto von Dentz }
1256ccf74f23SLuiz Augusto von Dentz 
check_io_qos(struct bt_iso_io_qos * qos)1257ccf74f23SLuiz Augusto von Dentz static bool check_io_qos(struct bt_iso_io_qos *qos)
1258ccf74f23SLuiz Augusto von Dentz {
1259ccf74f23SLuiz Augusto von Dentz 	/* If no PHY is enable SDU must be 0 */
1260ccf74f23SLuiz Augusto von Dentz 	if (!qos->phy && qos->sdu)
1261ccf74f23SLuiz Augusto von Dentz 		return false;
1262ccf74f23SLuiz Augusto von Dentz 
1263ccf74f23SLuiz Augusto von Dentz 	if (qos->interval && (qos->interval < 0xff || qos->interval > 0xfffff))
1264ccf74f23SLuiz Augusto von Dentz 		return false;
1265ccf74f23SLuiz Augusto von Dentz 
1266ccf74f23SLuiz Augusto von Dentz 	if (qos->latency && (qos->latency < 0x05 || qos->latency > 0xfa0))
1267ccf74f23SLuiz Augusto von Dentz 		return false;
1268ccf74f23SLuiz Augusto von Dentz 
1269ccf74f23SLuiz Augusto von Dentz 	if (qos->phy > BT_ISO_PHY_ANY)
1270ccf74f23SLuiz Augusto von Dentz 		return false;
1271ccf74f23SLuiz Augusto von Dentz 
1272ccf74f23SLuiz Augusto von Dentz 	return true;
1273ccf74f23SLuiz Augusto von Dentz }
1274ccf74f23SLuiz Augusto von Dentz 
check_ucast_qos(struct bt_iso_qos * qos)12750fe8c8d0SIulia Tanasescu static bool check_ucast_qos(struct bt_iso_qos *qos)
1276ccf74f23SLuiz Augusto von Dentz {
1277b7f923b1SLuiz Augusto von Dentz 	if (qos->ucast.cig > 0xef && qos->ucast.cig != BT_ISO_QOS_CIG_UNSET)
1278b7f923b1SLuiz Augusto von Dentz 		return false;
1279b7f923b1SLuiz Augusto von Dentz 
1280b7f923b1SLuiz Augusto von Dentz 	if (qos->ucast.cis > 0xef && qos->ucast.cis != BT_ISO_QOS_CIS_UNSET)
1281b7f923b1SLuiz Augusto von Dentz 		return false;
1282b7f923b1SLuiz Augusto von Dentz 
12830fe8c8d0SIulia Tanasescu 	if (qos->ucast.sca > 0x07)
1284ccf74f23SLuiz Augusto von Dentz 		return false;
1285ccf74f23SLuiz Augusto von Dentz 
12860fe8c8d0SIulia Tanasescu 	if (qos->ucast.packing > 0x01)
1287ccf74f23SLuiz Augusto von Dentz 		return false;
1288ccf74f23SLuiz Augusto von Dentz 
12890fe8c8d0SIulia Tanasescu 	if (qos->ucast.framing > 0x01)
1290ccf74f23SLuiz Augusto von Dentz 		return false;
1291ccf74f23SLuiz Augusto von Dentz 
12920fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->ucast.in))
1293ccf74f23SLuiz Augusto von Dentz 		return false;
1294ccf74f23SLuiz Augusto von Dentz 
12950fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->ucast.out))
12960fe8c8d0SIulia Tanasescu 		return false;
12970fe8c8d0SIulia Tanasescu 
12980fe8c8d0SIulia Tanasescu 	return true;
12990fe8c8d0SIulia Tanasescu }
13000fe8c8d0SIulia Tanasescu 
check_bcast_qos(struct bt_iso_qos * qos)13010fe8c8d0SIulia Tanasescu static bool check_bcast_qos(struct bt_iso_qos *qos)
13020fe8c8d0SIulia Tanasescu {
1303a39cc8d0SLuiz Augusto von Dentz 	if (!qos->bcast.sync_factor)
1304a39cc8d0SLuiz Augusto von Dentz 		qos->bcast.sync_factor = 0x01;
13050fe8c8d0SIulia Tanasescu 
13060fe8c8d0SIulia Tanasescu 	if (qos->bcast.packing > 0x01)
13070fe8c8d0SIulia Tanasescu 		return false;
13080fe8c8d0SIulia Tanasescu 
13090fe8c8d0SIulia Tanasescu 	if (qos->bcast.framing > 0x01)
13100fe8c8d0SIulia Tanasescu 		return false;
13110fe8c8d0SIulia Tanasescu 
13120fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->bcast.in))
13130fe8c8d0SIulia Tanasescu 		return false;
13140fe8c8d0SIulia Tanasescu 
13150fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->bcast.out))
13160fe8c8d0SIulia Tanasescu 		return false;
13170fe8c8d0SIulia Tanasescu 
13180fe8c8d0SIulia Tanasescu 	if (qos->bcast.encryption > 0x01)
13190fe8c8d0SIulia Tanasescu 		return false;
13200fe8c8d0SIulia Tanasescu 
13210fe8c8d0SIulia Tanasescu 	if (qos->bcast.options > 0x07)
13220fe8c8d0SIulia Tanasescu 		return false;
13230fe8c8d0SIulia Tanasescu 
13240fe8c8d0SIulia Tanasescu 	if (qos->bcast.skip > 0x01f3)
13250fe8c8d0SIulia Tanasescu 		return false;
13260fe8c8d0SIulia Tanasescu 
1327a39cc8d0SLuiz Augusto von Dentz 	if (!qos->bcast.sync_timeout)
1328a39cc8d0SLuiz Augusto von Dentz 		qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
1329a39cc8d0SLuiz Augusto von Dentz 
13300fe8c8d0SIulia Tanasescu 	if (qos->bcast.sync_timeout < 0x000a || qos->bcast.sync_timeout > 0x4000)
13310fe8c8d0SIulia Tanasescu 		return false;
13320fe8c8d0SIulia Tanasescu 
13330fe8c8d0SIulia Tanasescu 	if (qos->bcast.sync_cte_type > 0x1f)
13340fe8c8d0SIulia Tanasescu 		return false;
13350fe8c8d0SIulia Tanasescu 
13360fe8c8d0SIulia Tanasescu 	if (qos->bcast.mse > 0x1f)
13370fe8c8d0SIulia Tanasescu 		return false;
13380fe8c8d0SIulia Tanasescu 
1339a39cc8d0SLuiz Augusto von Dentz 	if (!qos->bcast.timeout)
1340a39cc8d0SLuiz Augusto von Dentz 		qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
1341a39cc8d0SLuiz Augusto von Dentz 
13420fe8c8d0SIulia Tanasescu 	if (qos->bcast.timeout < 0x000a || qos->bcast.timeout > 0x4000)
1343ccf74f23SLuiz Augusto von Dentz 		return false;
1344ccf74f23SLuiz Augusto von Dentz 
1345ccf74f23SLuiz Augusto von Dentz 	return true;
1346ccf74f23SLuiz Augusto von Dentz }
1347ccf74f23SLuiz Augusto von Dentz 
iso_sock_setsockopt(struct socket * sock,int level,int optname,sockptr_t optval,unsigned int optlen)1348ccf74f23SLuiz Augusto von Dentz static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
1349ccf74f23SLuiz Augusto von Dentz 			       sockptr_t optval, unsigned int optlen)
1350ccf74f23SLuiz Augusto von Dentz {
1351ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1352ccf74f23SLuiz Augusto von Dentz 	int len, err = 0;
13530fe8c8d0SIulia Tanasescu 	struct bt_iso_qos qos = default_qos;
1354ccf74f23SLuiz Augusto von Dentz 	u32 opt;
1355ccf74f23SLuiz Augusto von Dentz 
1356ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1357ccf74f23SLuiz Augusto von Dentz 
1358ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1359ccf74f23SLuiz Augusto von Dentz 
1360ccf74f23SLuiz Augusto von Dentz 	switch (optname) {
1361ccf74f23SLuiz Augusto von Dentz 	case BT_DEFER_SETUP:
1362ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1363ccf74f23SLuiz Augusto von Dentz 			err = -EINVAL;
1364ccf74f23SLuiz Augusto von Dentz 			break;
1365ccf74f23SLuiz Augusto von Dentz 		}
1366ccf74f23SLuiz Augusto von Dentz 
1367ccf74f23SLuiz Augusto von Dentz 		if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
1368ccf74f23SLuiz Augusto von Dentz 			err = -EFAULT;
1369ccf74f23SLuiz Augusto von Dentz 			break;
1370ccf74f23SLuiz Augusto von Dentz 		}
1371ccf74f23SLuiz Augusto von Dentz 
1372ccf74f23SLuiz Augusto von Dentz 		if (opt)
1373ccf74f23SLuiz Augusto von Dentz 			set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
1374ccf74f23SLuiz Augusto von Dentz 		else
1375ccf74f23SLuiz Augusto von Dentz 			clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
1376ccf74f23SLuiz Augusto von Dentz 		break;
1377ccf74f23SLuiz Augusto von Dentz 
13780731c5abSLuiz Augusto von Dentz 	case BT_PKT_STATUS:
13790731c5abSLuiz Augusto von Dentz 		if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
13800731c5abSLuiz Augusto von Dentz 			err = -EFAULT;
13810731c5abSLuiz Augusto von Dentz 			break;
13820731c5abSLuiz Augusto von Dentz 		}
13830731c5abSLuiz Augusto von Dentz 
13840731c5abSLuiz Augusto von Dentz 		if (opt)
13850731c5abSLuiz Augusto von Dentz 			set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
13860731c5abSLuiz Augusto von Dentz 		else
13870731c5abSLuiz Augusto von Dentz 			clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
13880731c5abSLuiz Augusto von Dentz 		break;
13890731c5abSLuiz Augusto von Dentz 
1390ccf74f23SLuiz Augusto von Dentz 	case BT_ISO_QOS:
1391ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
1392ccf74f23SLuiz Augusto von Dentz 		    sk->sk_state != BT_CONNECT2) {
1393ccf74f23SLuiz Augusto von Dentz 			err = -EINVAL;
1394ccf74f23SLuiz Augusto von Dentz 			break;
1395ccf74f23SLuiz Augusto von Dentz 		}
1396ccf74f23SLuiz Augusto von Dentz 
1397ccf74f23SLuiz Augusto von Dentz 		len = min_t(unsigned int, sizeof(qos), optlen);
1398ccf74f23SLuiz Augusto von Dentz 
1399ccf74f23SLuiz Augusto von Dentz 		if (copy_from_sockptr(&qos, optval, len)) {
1400ccf74f23SLuiz Augusto von Dentz 			err = -EFAULT;
1401ccf74f23SLuiz Augusto von Dentz 			break;
1402ccf74f23SLuiz Augusto von Dentz 		}
1403ccf74f23SLuiz Augusto von Dentz 
14040fe8c8d0SIulia Tanasescu 		if (len == sizeof(qos.ucast) && !check_ucast_qos(&qos)) {
1405ccf74f23SLuiz Augusto von Dentz 			err = -EINVAL;
1406ccf74f23SLuiz Augusto von Dentz 			break;
1407ccf74f23SLuiz Augusto von Dentz 		}
1408ccf74f23SLuiz Augusto von Dentz 
1409ccf74f23SLuiz Augusto von Dentz 		iso_pi(sk)->qos = qos;
14100fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos_user_set = true;
1411ccf74f23SLuiz Augusto von Dentz 
1412ccf74f23SLuiz Augusto von Dentz 		break;
1413ccf74f23SLuiz Augusto von Dentz 
1414f764a6c2SLuiz Augusto von Dentz 	case BT_ISO_BASE:
1415f764a6c2SLuiz Augusto von Dentz 		if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
1416f764a6c2SLuiz Augusto von Dentz 		    sk->sk_state != BT_CONNECT2) {
1417f764a6c2SLuiz Augusto von Dentz 			err = -EINVAL;
1418f764a6c2SLuiz Augusto von Dentz 			break;
1419f764a6c2SLuiz Augusto von Dentz 		}
1420f764a6c2SLuiz Augusto von Dentz 
1421f764a6c2SLuiz Augusto von Dentz 		if (optlen > sizeof(iso_pi(sk)->base)) {
1422f764a6c2SLuiz Augusto von Dentz 			err = -EOVERFLOW;
1423f764a6c2SLuiz Augusto von Dentz 			break;
1424f764a6c2SLuiz Augusto von Dentz 		}
1425f764a6c2SLuiz Augusto von Dentz 
1426f764a6c2SLuiz Augusto von Dentz 		len = min_t(unsigned int, sizeof(iso_pi(sk)->base), optlen);
1427f764a6c2SLuiz Augusto von Dentz 
1428f764a6c2SLuiz Augusto von Dentz 		if (copy_from_sockptr(iso_pi(sk)->base, optval, len)) {
1429f764a6c2SLuiz Augusto von Dentz 			err = -EFAULT;
1430f764a6c2SLuiz Augusto von Dentz 			break;
1431f764a6c2SLuiz Augusto von Dentz 		}
1432f764a6c2SLuiz Augusto von Dentz 
1433f764a6c2SLuiz Augusto von Dentz 		iso_pi(sk)->base_len = len;
1434f764a6c2SLuiz Augusto von Dentz 
1435f764a6c2SLuiz Augusto von Dentz 		break;
1436f764a6c2SLuiz Augusto von Dentz 
1437ccf74f23SLuiz Augusto von Dentz 	default:
1438ccf74f23SLuiz Augusto von Dentz 		err = -ENOPROTOOPT;
1439ccf74f23SLuiz Augusto von Dentz 		break;
1440ccf74f23SLuiz Augusto von Dentz 	}
1441ccf74f23SLuiz Augusto von Dentz 
1442ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1443ccf74f23SLuiz Augusto von Dentz 	return err;
1444ccf74f23SLuiz Augusto von Dentz }
1445ccf74f23SLuiz Augusto von Dentz 
iso_sock_getsockopt(struct socket * sock,int level,int optname,char __user * optval,int __user * optlen)1446ccf74f23SLuiz Augusto von Dentz static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
1447ccf74f23SLuiz Augusto von Dentz 			       char __user *optval, int __user *optlen)
1448ccf74f23SLuiz Augusto von Dentz {
1449ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1450ccf74f23SLuiz Augusto von Dentz 	int len, err = 0;
14510eee4995SLuiz Augusto von Dentz 	struct bt_iso_qos *qos;
1452f764a6c2SLuiz Augusto von Dentz 	u8 base_len;
1453f764a6c2SLuiz Augusto von Dentz 	u8 *base;
1454ccf74f23SLuiz Augusto von Dentz 
1455ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1456ccf74f23SLuiz Augusto von Dentz 
1457ccf74f23SLuiz Augusto von Dentz 	if (get_user(len, optlen))
1458ccf74f23SLuiz Augusto von Dentz 		return -EFAULT;
1459ccf74f23SLuiz Augusto von Dentz 
1460ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1461ccf74f23SLuiz Augusto von Dentz 
1462ccf74f23SLuiz Augusto von Dentz 	switch (optname) {
1463ccf74f23SLuiz Augusto von Dentz 	case BT_DEFER_SETUP:
14649dfe1727SLuiz Augusto von Dentz 		if (sk->sk_state == BT_CONNECTED) {
1465ccf74f23SLuiz Augusto von Dentz 			err = -EINVAL;
1466ccf74f23SLuiz Augusto von Dentz 			break;
1467ccf74f23SLuiz Augusto von Dentz 		}
1468ccf74f23SLuiz Augusto von Dentz 
1469ccf74f23SLuiz Augusto von Dentz 		if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
1470ccf74f23SLuiz Augusto von Dentz 			     (u32 __user *)optval))
1471ccf74f23SLuiz Augusto von Dentz 			err = -EFAULT;
1472ccf74f23SLuiz Augusto von Dentz 
1473ccf74f23SLuiz Augusto von Dentz 		break;
1474ccf74f23SLuiz Augusto von Dentz 
14750731c5abSLuiz Augusto von Dentz 	case BT_PKT_STATUS:
14760731c5abSLuiz Augusto von Dentz 		if (put_user(test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags),
14770731c5abSLuiz Augusto von Dentz 			     (int __user *)optval))
14780731c5abSLuiz Augusto von Dentz 			err = -EFAULT;
14790731c5abSLuiz Augusto von Dentz 		break;
14800731c5abSLuiz Augusto von Dentz 
1481ccf74f23SLuiz Augusto von Dentz 	case BT_ISO_QOS:
14821d1ab5d3SLuiz Augusto von Dentz 		qos = iso_sock_get_qos(sk);
1483ccf74f23SLuiz Augusto von Dentz 
14840eee4995SLuiz Augusto von Dentz 		len = min_t(unsigned int, len, sizeof(*qos));
14850eee4995SLuiz Augusto von Dentz 		if (copy_to_user(optval, qos, len))
1486ccf74f23SLuiz Augusto von Dentz 			err = -EFAULT;
1487ccf74f23SLuiz Augusto von Dentz 
1488ccf74f23SLuiz Augusto von Dentz 		break;
1489ccf74f23SLuiz Augusto von Dentz 
1490f764a6c2SLuiz Augusto von Dentz 	case BT_ISO_BASE:
14919c082631SClaudia Draghicescu 		if (sk->sk_state == BT_CONNECTED &&
14929c082631SClaudia Draghicescu 		    !bacmp(&iso_pi(sk)->dst, BDADDR_ANY)) {
1493f764a6c2SLuiz Augusto von Dentz 			base_len = iso_pi(sk)->conn->hcon->le_per_adv_data_len;
1494f764a6c2SLuiz Augusto von Dentz 			base = iso_pi(sk)->conn->hcon->le_per_adv_data;
1495f764a6c2SLuiz Augusto von Dentz 		} else {
1496f764a6c2SLuiz Augusto von Dentz 			base_len = iso_pi(sk)->base_len;
1497f764a6c2SLuiz Augusto von Dentz 			base = iso_pi(sk)->base;
1498f764a6c2SLuiz Augusto von Dentz 		}
1499f764a6c2SLuiz Augusto von Dentz 
1500f764a6c2SLuiz Augusto von Dentz 		len = min_t(unsigned int, len, base_len);
1501f764a6c2SLuiz Augusto von Dentz 		if (copy_to_user(optval, base, len))
1502f764a6c2SLuiz Augusto von Dentz 			err = -EFAULT;
1503f764a6c2SLuiz Augusto von Dentz 
1504f764a6c2SLuiz Augusto von Dentz 		break;
1505f764a6c2SLuiz Augusto von Dentz 
1506ccf74f23SLuiz Augusto von Dentz 	default:
1507ccf74f23SLuiz Augusto von Dentz 		err = -ENOPROTOOPT;
1508ccf74f23SLuiz Augusto von Dentz 		break;
1509ccf74f23SLuiz Augusto von Dentz 	}
1510ccf74f23SLuiz Augusto von Dentz 
1511ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1512ccf74f23SLuiz Augusto von Dentz 	return err;
1513ccf74f23SLuiz Augusto von Dentz }
1514ccf74f23SLuiz Augusto von Dentz 
iso_sock_shutdown(struct socket * sock,int how)1515ccf74f23SLuiz Augusto von Dentz static int iso_sock_shutdown(struct socket *sock, int how)
1516ccf74f23SLuiz Augusto von Dentz {
1517ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1518ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1519ccf74f23SLuiz Augusto von Dentz 
1520c5729093SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p, how %d", sock, sk, how);
1521ccf74f23SLuiz Augusto von Dentz 
1522ccf74f23SLuiz Augusto von Dentz 	if (!sk)
1523ccf74f23SLuiz Augusto von Dentz 		return 0;
1524ccf74f23SLuiz Augusto von Dentz 
1525ccf74f23SLuiz Augusto von Dentz 	sock_hold(sk);
1526ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1527ccf74f23SLuiz Augusto von Dentz 
1528c5729093SLuiz Augusto von Dentz 	switch (how) {
1529c5729093SLuiz Augusto von Dentz 	case SHUT_RD:
1530c5729093SLuiz Augusto von Dentz 		if (sk->sk_shutdown & RCV_SHUTDOWN)
1531c5729093SLuiz Augusto von Dentz 			goto unlock;
1532c5729093SLuiz Augusto von Dentz 		sk->sk_shutdown |= RCV_SHUTDOWN;
1533c5729093SLuiz Augusto von Dentz 		break;
1534c5729093SLuiz Augusto von Dentz 	case SHUT_WR:
1535c5729093SLuiz Augusto von Dentz 		if (sk->sk_shutdown & SEND_SHUTDOWN)
1536c5729093SLuiz Augusto von Dentz 			goto unlock;
1537c5729093SLuiz Augusto von Dentz 		sk->sk_shutdown |= SEND_SHUTDOWN;
1538c5729093SLuiz Augusto von Dentz 		break;
1539c5729093SLuiz Augusto von Dentz 	case SHUT_RDWR:
1540c5729093SLuiz Augusto von Dentz 		if (sk->sk_shutdown & SHUTDOWN_MASK)
1541c5729093SLuiz Augusto von Dentz 			goto unlock;
1542c5729093SLuiz Augusto von Dentz 		sk->sk_shutdown |= SHUTDOWN_MASK;
1543c5729093SLuiz Augusto von Dentz 		break;
1544c5729093SLuiz Augusto von Dentz 	}
1545c5729093SLuiz Augusto von Dentz 
1546ccf74f23SLuiz Augusto von Dentz 	iso_sock_clear_timer(sk);
1547ccf74f23SLuiz Augusto von Dentz 	__iso_sock_close(sk);
1548ccf74f23SLuiz Augusto von Dentz 
1549ccf74f23SLuiz Augusto von Dentz 	if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1550ccf74f23SLuiz Augusto von Dentz 	    !(current->flags & PF_EXITING))
1551c5729093SLuiz Augusto von Dentz 		err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
1552ccf74f23SLuiz Augusto von Dentz 
1553c5729093SLuiz Augusto von Dentz unlock:
1554ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1555ccf74f23SLuiz Augusto von Dentz 	sock_put(sk);
1556ccf74f23SLuiz Augusto von Dentz 
1557ccf74f23SLuiz Augusto von Dentz 	return err;
1558ccf74f23SLuiz Augusto von Dentz }
1559ccf74f23SLuiz Augusto von Dentz 
iso_sock_release(struct socket * sock)1560ccf74f23SLuiz Augusto von Dentz static int iso_sock_release(struct socket *sock)
1561ccf74f23SLuiz Augusto von Dentz {
1562ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1563ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1564ccf74f23SLuiz Augusto von Dentz 
1565ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p", sock, sk);
1566ccf74f23SLuiz Augusto von Dentz 
1567ccf74f23SLuiz Augusto von Dentz 	if (!sk)
1568ccf74f23SLuiz Augusto von Dentz 		return 0;
1569ccf74f23SLuiz Augusto von Dentz 
1570ccf74f23SLuiz Augusto von Dentz 	iso_sock_close(sk);
1571ccf74f23SLuiz Augusto von Dentz 
1572bc1fb82aSEric Dumazet 	if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) &&
1573ccf74f23SLuiz Augusto von Dentz 	    !(current->flags & PF_EXITING)) {
1574ccf74f23SLuiz Augusto von Dentz 		lock_sock(sk);
1575ccf74f23SLuiz Augusto von Dentz 		err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
1576ccf74f23SLuiz Augusto von Dentz 		release_sock(sk);
1577ccf74f23SLuiz Augusto von Dentz 	}
1578ccf74f23SLuiz Augusto von Dentz 
1579ccf74f23SLuiz Augusto von Dentz 	sock_orphan(sk);
1580ccf74f23SLuiz Augusto von Dentz 	iso_sock_kill(sk);
1581ccf74f23SLuiz Augusto von Dentz 	return err;
1582ccf74f23SLuiz Augusto von Dentz }
1583ccf74f23SLuiz Augusto von Dentz 
iso_sock_ready(struct sock * sk)1584ccf74f23SLuiz Augusto von Dentz static void iso_sock_ready(struct sock *sk)
1585ccf74f23SLuiz Augusto von Dentz {
1586ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1587ccf74f23SLuiz Augusto von Dentz 
1588ccf74f23SLuiz Augusto von Dentz 	if (!sk)
1589ccf74f23SLuiz Augusto von Dentz 		return;
1590ccf74f23SLuiz Augusto von Dentz 
1591ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1592ccf74f23SLuiz Augusto von Dentz 	iso_sock_clear_timer(sk);
1593ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_CONNECTED;
1594ccf74f23SLuiz Augusto von Dentz 	sk->sk_state_change(sk);
1595ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1596ccf74f23SLuiz Augusto von Dentz }
1597ccf74f23SLuiz Augusto von Dentz 
1598ccf74f23SLuiz Augusto von Dentz struct iso_list_data {
1599ccf74f23SLuiz Augusto von Dentz 	struct hci_conn *hcon;
1600ccf74f23SLuiz Augusto von Dentz 	int count;
1601ccf74f23SLuiz Augusto von Dentz };
1602ccf74f23SLuiz Augusto von Dentz 
iso_match_big(struct sock * sk,void * data)1603f764a6c2SLuiz Augusto von Dentz static bool iso_match_big(struct sock *sk, void *data)
1604f764a6c2SLuiz Augusto von Dentz {
1605f764a6c2SLuiz Augusto von Dentz 	struct hci_evt_le_big_sync_estabilished *ev = data;
1606f764a6c2SLuiz Augusto von Dentz 
16070fe8c8d0SIulia Tanasescu 	return ev->handle == iso_pi(sk)->qos.bcast.big;
1608f764a6c2SLuiz Augusto von Dentz }
1609f764a6c2SLuiz Augusto von Dentz 
iso_match_pa_sync_flag(struct sock * sk,void * data)1610fbdc4bc4SIulia Tanasescu static bool iso_match_pa_sync_flag(struct sock *sk, void *data)
1611fbdc4bc4SIulia Tanasescu {
1612fbdc4bc4SIulia Tanasescu 	return test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
1613fbdc4bc4SIulia Tanasescu }
1614fbdc4bc4SIulia Tanasescu 
iso_conn_ready(struct iso_conn * conn)1615ccf74f23SLuiz Augusto von Dentz static void iso_conn_ready(struct iso_conn *conn)
1616ccf74f23SLuiz Augusto von Dentz {
1617fbdc4bc4SIulia Tanasescu 	struct sock *parent = NULL;
1618ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = conn->sk;
1619fbdc4bc4SIulia Tanasescu 	struct hci_ev_le_big_sync_estabilished *ev = NULL;
1620fbdc4bc4SIulia Tanasescu 	struct hci_ev_le_pa_sync_established *ev2 = NULL;
162123417475SIulia Tanasescu 	struct hci_evt_le_big_info_adv_report *ev3 = NULL;
16226a5ad251SLuiz Augusto von Dentz 	struct hci_conn *hcon;
1623ccf74f23SLuiz Augusto von Dentz 
1624ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p", conn);
1625ccf74f23SLuiz Augusto von Dentz 
1626ccf74f23SLuiz Augusto von Dentz 	if (sk) {
1627ccf74f23SLuiz Augusto von Dentz 		iso_sock_ready(conn->sk);
1628ccf74f23SLuiz Augusto von Dentz 	} else {
16296a5ad251SLuiz Augusto von Dentz 		hcon = conn->hcon;
16306a5ad251SLuiz Augusto von Dentz 		if (!hcon)
1631ccf74f23SLuiz Augusto von Dentz 			return;
1632ccf74f23SLuiz Augusto von Dentz 
1633fbdc4bc4SIulia Tanasescu 		if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags) ||
1634fbdc4bc4SIulia Tanasescu 		    test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
16356a5ad251SLuiz Augusto von Dentz 			ev = hci_recv_event_data(hcon->hdev,
1636f764a6c2SLuiz Augusto von Dentz 						 HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
1637fbdc4bc4SIulia Tanasescu 
1638fbdc4bc4SIulia Tanasescu 			/* Get reference to PA sync parent socket, if it exists */
1639fbdc4bc4SIulia Tanasescu 			parent = iso_get_sock_listen(&hcon->src,
1640fbdc4bc4SIulia Tanasescu 						     &hcon->dst,
1641fbdc4bc4SIulia Tanasescu 						     iso_match_pa_sync_flag, NULL);
1642fbdc4bc4SIulia Tanasescu 			if (!parent && ev)
16436a5ad251SLuiz Augusto von Dentz 				parent = iso_get_sock_listen(&hcon->src,
16446a5ad251SLuiz Augusto von Dentz 							     &hcon->dst,
1645f764a6c2SLuiz Augusto von Dentz 							     iso_match_big, ev);
164623417475SIulia Tanasescu 		} else if (test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
1647fbdc4bc4SIulia Tanasescu 			ev2 = hci_recv_event_data(hcon->hdev,
1648fbdc4bc4SIulia Tanasescu 						  HCI_EV_LE_PA_SYNC_ESTABLISHED);
1649fbdc4bc4SIulia Tanasescu 			if (ev2)
1650fbdc4bc4SIulia Tanasescu 				parent = iso_get_sock_listen(&hcon->src,
1651fbdc4bc4SIulia Tanasescu 							     &hcon->dst,
1652fbdc4bc4SIulia Tanasescu 							     iso_match_sid, ev2);
165323417475SIulia Tanasescu 		} else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
165423417475SIulia Tanasescu 			ev3 = hci_recv_event_data(hcon->hdev,
165523417475SIulia Tanasescu 						  HCI_EVT_LE_BIG_INFO_ADV_REPORT);
165623417475SIulia Tanasescu 			if (ev3)
165723417475SIulia Tanasescu 				parent = iso_get_sock_listen(&hcon->src,
165823417475SIulia Tanasescu 							     &hcon->dst,
165923417475SIulia Tanasescu 							     iso_match_sync_handle, ev3);
1660fbdc4bc4SIulia Tanasescu 		}
1661fbdc4bc4SIulia Tanasescu 
1662fbdc4bc4SIulia Tanasescu 		if (!parent)
16636a5ad251SLuiz Augusto von Dentz 			parent = iso_get_sock_listen(&hcon->src,
1664f764a6c2SLuiz Augusto von Dentz 							BDADDR_ANY, NULL, NULL);
1665f764a6c2SLuiz Augusto von Dentz 
16666a5ad251SLuiz Augusto von Dentz 		if (!parent)
1667ccf74f23SLuiz Augusto von Dentz 			return;
1668ccf74f23SLuiz Augusto von Dentz 
1669ccf74f23SLuiz Augusto von Dentz 		lock_sock(parent);
1670ccf74f23SLuiz Augusto von Dentz 
1671ccf74f23SLuiz Augusto von Dentz 		sk = iso_sock_alloc(sock_net(parent), NULL,
1672ccf74f23SLuiz Augusto von Dentz 				    BTPROTO_ISO, GFP_ATOMIC, 0);
1673ccf74f23SLuiz Augusto von Dentz 		if (!sk) {
1674ccf74f23SLuiz Augusto von Dentz 			release_sock(parent);
1675ccf74f23SLuiz Augusto von Dentz 			return;
1676ccf74f23SLuiz Augusto von Dentz 		}
1677ccf74f23SLuiz Augusto von Dentz 
1678ccf74f23SLuiz Augusto von Dentz 		iso_sock_init(sk, parent);
1679ccf74f23SLuiz Augusto von Dentz 
16806a5ad251SLuiz Augusto von Dentz 		bacpy(&iso_pi(sk)->src, &hcon->src);
1681fbdc4bc4SIulia Tanasescu 
1682fbdc4bc4SIulia Tanasescu 		/* Convert from HCI to three-value type */
1683fbdc4bc4SIulia Tanasescu 		if (hcon->src_type == ADDR_LE_DEV_PUBLIC)
1684fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
1685fbdc4bc4SIulia Tanasescu 		else
1686fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->src_type = BDADDR_LE_RANDOM;
1687f764a6c2SLuiz Augusto von Dentz 
1688f764a6c2SLuiz Augusto von Dentz 		/* If hcon has no destination address (BDADDR_ANY) it means it
1689fbdc4bc4SIulia Tanasescu 		 * was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED or
1690fbdc4bc4SIulia Tanasescu 		 * HCI_EV_LE_PA_SYNC_ESTABLISHED so we need to initialize using
1691fbdc4bc4SIulia Tanasescu 		 * the parent socket destination address.
1692f764a6c2SLuiz Augusto von Dentz 		 */
16936a5ad251SLuiz Augusto von Dentz 		if (!bacmp(&hcon->dst, BDADDR_ANY)) {
16946a5ad251SLuiz Augusto von Dentz 			bacpy(&hcon->dst, &iso_pi(parent)->dst);
16956a5ad251SLuiz Augusto von Dentz 			hcon->dst_type = iso_pi(parent)->dst_type;
16966a5ad251SLuiz Augusto von Dentz 			hcon->sync_handle = iso_pi(parent)->sync_handle;
1697f764a6c2SLuiz Augusto von Dentz 		}
1698f764a6c2SLuiz Augusto von Dentz 
169923417475SIulia Tanasescu 		if (ev3) {
1700fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->qos = iso_pi(parent)->qos;
170123417475SIulia Tanasescu 			iso_pi(sk)->qos.bcast.encryption = ev3->encryption;
170223417475SIulia Tanasescu 			hcon->iso_qos = iso_pi(sk)->qos;
1703fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->bc_num_bis = iso_pi(parent)->bc_num_bis;
1704fbdc4bc4SIulia Tanasescu 			memcpy(iso_pi(sk)->bc_bis, iso_pi(parent)->bc_bis, ISO_MAX_NUM_BIS);
170523417475SIulia Tanasescu 			set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
1706fbdc4bc4SIulia Tanasescu 		}
1707fbdc4bc4SIulia Tanasescu 
17086a5ad251SLuiz Augusto von Dentz 		bacpy(&iso_pi(sk)->dst, &hcon->dst);
17096a5ad251SLuiz Augusto von Dentz 		iso_pi(sk)->dst_type = hcon->dst_type;
17109c082631SClaudia Draghicescu 		iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
17119c082631SClaudia Draghicescu 		memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
17129c082631SClaudia Draghicescu 		iso_pi(sk)->base_len = iso_pi(parent)->base_len;
1713ccf74f23SLuiz Augusto von Dentz 
17146a5ad251SLuiz Augusto von Dentz 		hci_conn_hold(hcon);
17156a5ad251SLuiz Augusto von Dentz 		iso_chan_add(conn, sk, parent);
1716ccf74f23SLuiz Augusto von Dentz 
1717fbdc4bc4SIulia Tanasescu 		if ((ev && ((struct hci_evt_le_big_sync_estabilished *)ev)->status) ||
1718fbdc4bc4SIulia Tanasescu 		    (ev2 && ev2->status)) {
1719f777d882SIulia Tanasescu 			/* Trigger error signal on child socket */
1720f777d882SIulia Tanasescu 			sk->sk_err = ECONNREFUSED;
1721f777d882SIulia Tanasescu 			sk->sk_error_report(sk);
1722f777d882SIulia Tanasescu 		}
1723f777d882SIulia Tanasescu 
1724ccf74f23SLuiz Augusto von Dentz 		if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
1725ccf74f23SLuiz Augusto von Dentz 			sk->sk_state = BT_CONNECT2;
1726ccf74f23SLuiz Augusto von Dentz 		else
1727ccf74f23SLuiz Augusto von Dentz 			sk->sk_state = BT_CONNECTED;
1728ccf74f23SLuiz Augusto von Dentz 
1729ccf74f23SLuiz Augusto von Dentz 		/* Wake up parent */
1730ccf74f23SLuiz Augusto von Dentz 		parent->sk_data_ready(parent);
1731ccf74f23SLuiz Augusto von Dentz 
1732ccf74f23SLuiz Augusto von Dentz 		release_sock(parent);
1733ccf74f23SLuiz Augusto von Dentz 	}
1734ccf74f23SLuiz Augusto von Dentz }
1735ccf74f23SLuiz Augusto von Dentz 
iso_match_sid(struct sock * sk,void * data)1736f764a6c2SLuiz Augusto von Dentz static bool iso_match_sid(struct sock *sk, void *data)
1737f764a6c2SLuiz Augusto von Dentz {
1738f764a6c2SLuiz Augusto von Dentz 	struct hci_ev_le_pa_sync_established *ev = data;
1739f764a6c2SLuiz Augusto von Dentz 
1740f764a6c2SLuiz Augusto von Dentz 	return ev->sid == iso_pi(sk)->bc_sid;
1741f764a6c2SLuiz Augusto von Dentz }
1742f764a6c2SLuiz Augusto von Dentz 
iso_match_sync_handle(struct sock * sk,void * data)1743f764a6c2SLuiz Augusto von Dentz static bool iso_match_sync_handle(struct sock *sk, void *data)
1744f764a6c2SLuiz Augusto von Dentz {
1745f764a6c2SLuiz Augusto von Dentz 	struct hci_evt_le_big_info_adv_report *ev = data;
1746f764a6c2SLuiz Augusto von Dentz 
1747f764a6c2SLuiz Augusto von Dentz 	return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
1748f764a6c2SLuiz Augusto von Dentz }
1749f764a6c2SLuiz Augusto von Dentz 
iso_match_sync_handle_pa_report(struct sock * sk,void * data)17509c082631SClaudia Draghicescu static bool iso_match_sync_handle_pa_report(struct sock *sk, void *data)
17519c082631SClaudia Draghicescu {
17529c082631SClaudia Draghicescu 	struct hci_ev_le_per_adv_report *ev = data;
17539c082631SClaudia Draghicescu 
17549c082631SClaudia Draghicescu 	return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
17559c082631SClaudia Draghicescu }
17569c082631SClaudia Draghicescu 
1757ccf74f23SLuiz Augusto von Dentz /* ----- ISO interface with lower layer (HCI) ----- */
1758f764a6c2SLuiz Augusto von Dentz 
iso_connect_ind(struct hci_dev * hdev,bdaddr_t * bdaddr,__u8 * flags)1759ccf74f23SLuiz Augusto von Dentz int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
1760ccf74f23SLuiz Augusto von Dentz {
1761f764a6c2SLuiz Augusto von Dentz 	struct hci_ev_le_pa_sync_established *ev1;
1762f764a6c2SLuiz Augusto von Dentz 	struct hci_evt_le_big_info_adv_report *ev2;
17639c082631SClaudia Draghicescu 	struct hci_ev_le_per_adv_report *ev3;
1764ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
1765ccf74f23SLuiz Augusto von Dentz 	int lm = 0;
1766ccf74f23SLuiz Augusto von Dentz 
1767f764a6c2SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR", bdaddr);
1768ccf74f23SLuiz Augusto von Dentz 
1769f764a6c2SLuiz Augusto von Dentz 	/* Broadcast receiver requires handling of some events before it can
1770f764a6c2SLuiz Augusto von Dentz 	 * proceed to establishing a BIG sync:
1771f764a6c2SLuiz Augusto von Dentz 	 *
1772f764a6c2SLuiz Augusto von Dentz 	 * 1. HCI_EV_LE_PA_SYNC_ESTABLISHED: The socket may specify a specific
1773f764a6c2SLuiz Augusto von Dentz 	 * SID to listen to and once sync is estabilished its handle needs to
1774f764a6c2SLuiz Augusto von Dentz 	 * be stored in iso_pi(sk)->sync_handle so it can be matched once
1775f764a6c2SLuiz Augusto von Dentz 	 * receiving the BIG Info.
1776f764a6c2SLuiz Augusto von Dentz 	 * 2. HCI_EVT_LE_BIG_INFO_ADV_REPORT: When connect_ind is triggered by a
1777f764a6c2SLuiz Augusto von Dentz 	 * a BIG Info it attempts to check if there any listening socket with
1778f764a6c2SLuiz Augusto von Dentz 	 * the same sync_handle and if it does then attempt to create a sync.
17799c082631SClaudia Draghicescu 	 * 3. HCI_EV_LE_PER_ADV_REPORT: When a PA report is received, it is stored
17809c082631SClaudia Draghicescu 	 * in iso_pi(sk)->base so it can be passed up to user, in the case of a
17819c082631SClaudia Draghicescu 	 * broadcast sink.
1782f764a6c2SLuiz Augusto von Dentz 	 */
1783f764a6c2SLuiz Augusto von Dentz 	ev1 = hci_recv_event_data(hdev, HCI_EV_LE_PA_SYNC_ESTABLISHED);
1784f764a6c2SLuiz Augusto von Dentz 	if (ev1) {
1785f764a6c2SLuiz Augusto von Dentz 		sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr, iso_match_sid,
1786f764a6c2SLuiz Augusto von Dentz 					 ev1);
1787fbdc4bc4SIulia Tanasescu 		if (sk && !ev1->status)
1788f764a6c2SLuiz Augusto von Dentz 			iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
1789ccf74f23SLuiz Augusto von Dentz 
1790f764a6c2SLuiz Augusto von Dentz 		goto done;
1791f764a6c2SLuiz Augusto von Dentz 	}
1792f764a6c2SLuiz Augusto von Dentz 
1793f764a6c2SLuiz Augusto von Dentz 	ev2 = hci_recv_event_data(hdev, HCI_EVT_LE_BIG_INFO_ADV_REPORT);
1794f764a6c2SLuiz Augusto von Dentz 	if (ev2) {
1795fbdc4bc4SIulia Tanasescu 		/* Try to get PA sync listening socket, if it exists */
1796fbdc4bc4SIulia Tanasescu 		sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr,
1797fbdc4bc4SIulia Tanasescu 						iso_match_pa_sync_flag, NULL);
179814410544SIulia Tanasescu 
179914410544SIulia Tanasescu 		if (!sk) {
1800f764a6c2SLuiz Augusto von Dentz 			sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr,
1801f764a6c2SLuiz Augusto von Dentz 						 iso_match_sync_handle, ev2);
180214410544SIulia Tanasescu 
180314410544SIulia Tanasescu 			/* If PA Sync is in process of terminating,
180414410544SIulia Tanasescu 			 * do not handle any more BIGInfo adv reports.
180514410544SIulia Tanasescu 			 */
180614410544SIulia Tanasescu 
180714410544SIulia Tanasescu 			if (sk && test_bit(BT_SK_PA_SYNC_TERM,
180814410544SIulia Tanasescu 					   &iso_pi(sk)->flags))
180914410544SIulia Tanasescu 				return lm;
181014410544SIulia Tanasescu 		}
181114410544SIulia Tanasescu 
1812f764a6c2SLuiz Augusto von Dentz 		if (sk) {
1813f764a6c2SLuiz Augusto von Dentz 			int err;
1814f764a6c2SLuiz Augusto von Dentz 
1815f764a6c2SLuiz Augusto von Dentz 			if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
1816f764a6c2SLuiz Augusto von Dentz 				iso_pi(sk)->bc_num_bis = ev2->num_bis;
1817f764a6c2SLuiz Augusto von Dentz 
1818fbdc4bc4SIulia Tanasescu 			if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
1819fbdc4bc4SIulia Tanasescu 			    !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
1820fbdc4bc4SIulia Tanasescu 				err = hci_le_big_create_sync(hdev, NULL,
1821f764a6c2SLuiz Augusto von Dentz 							     &iso_pi(sk)->qos,
1822f764a6c2SLuiz Augusto von Dentz 							     iso_pi(sk)->sync_handle,
1823f764a6c2SLuiz Augusto von Dentz 							     iso_pi(sk)->bc_num_bis,
1824f764a6c2SLuiz Augusto von Dentz 							     iso_pi(sk)->bc_bis);
1825f764a6c2SLuiz Augusto von Dentz 				if (err) {
1826f764a6c2SLuiz Augusto von Dentz 					bt_dev_err(hdev, "hci_le_big_create_sync: %d",
1827f764a6c2SLuiz Augusto von Dentz 						   err);
1828f764a6c2SLuiz Augusto von Dentz 					sk = NULL;
1829f764a6c2SLuiz Augusto von Dentz 				}
1830f764a6c2SLuiz Augusto von Dentz 			}
1831f777d882SIulia Tanasescu 		}
18329c082631SClaudia Draghicescu 	}
18339c082631SClaudia Draghicescu 
18349c082631SClaudia Draghicescu 	ev3 = hci_recv_event_data(hdev, HCI_EV_LE_PER_ADV_REPORT);
18359c082631SClaudia Draghicescu 	if (ev3) {
18369c082631SClaudia Draghicescu 		sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr,
18379c082631SClaudia Draghicescu 					 iso_match_sync_handle_pa_report, ev3);
18389c082631SClaudia Draghicescu 
18399c082631SClaudia Draghicescu 		if (sk) {
18409c082631SClaudia Draghicescu 			memcpy(iso_pi(sk)->base, ev3->data, ev3->length);
18419c082631SClaudia Draghicescu 			iso_pi(sk)->base_len = ev3->length;
18429c082631SClaudia Draghicescu 		}
1843f764a6c2SLuiz Augusto von Dentz 	} else {
1844f764a6c2SLuiz Augusto von Dentz 		sk = iso_get_sock_listen(&hdev->bdaddr, BDADDR_ANY, NULL, NULL);
1845f764a6c2SLuiz Augusto von Dentz 	}
1846f764a6c2SLuiz Augusto von Dentz 
1847f764a6c2SLuiz Augusto von Dentz done:
1848f764a6c2SLuiz Augusto von Dentz 	if (!sk)
1849f764a6c2SLuiz Augusto von Dentz 		return lm;
1850f764a6c2SLuiz Augusto von Dentz 
1851ccf74f23SLuiz Augusto von Dentz 	lm |= HCI_LM_ACCEPT;
1852ccf74f23SLuiz Augusto von Dentz 
1853ccf74f23SLuiz Augusto von Dentz 	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
1854ccf74f23SLuiz Augusto von Dentz 		*flags |= HCI_PROTO_DEFER;
1855ccf74f23SLuiz Augusto von Dentz 
1856ccf74f23SLuiz Augusto von Dentz 	return lm;
1857ccf74f23SLuiz Augusto von Dentz }
1858ccf74f23SLuiz Augusto von Dentz 
iso_connect_cfm(struct hci_conn * hcon,__u8 status)1859ccf74f23SLuiz Augusto von Dentz static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
1860ccf74f23SLuiz Augusto von Dentz {
1861ccf74f23SLuiz Augusto von Dentz 	if (hcon->type != ISO_LINK) {
1862ccf74f23SLuiz Augusto von Dentz 		if (hcon->type != LE_LINK)
1863ccf74f23SLuiz Augusto von Dentz 			return;
1864ccf74f23SLuiz Augusto von Dentz 
1865ccf74f23SLuiz Augusto von Dentz 		/* Check if LE link has failed */
1866ccf74f23SLuiz Augusto von Dentz 		if (status) {
186706149746SLuiz Augusto von Dentz 			struct hci_link *link, *t;
186806149746SLuiz Augusto von Dentz 
186906149746SLuiz Augusto von Dentz 			list_for_each_entry_safe(link, t, &hcon->link_list,
187006149746SLuiz Augusto von Dentz 						 list)
187106149746SLuiz Augusto von Dentz 				iso_conn_del(link->conn, bt_to_errno(status));
187206149746SLuiz Augusto von Dentz 
1873ccf74f23SLuiz Augusto von Dentz 			return;
1874ccf74f23SLuiz Augusto von Dentz 		}
1875ccf74f23SLuiz Augusto von Dentz 
1876ccf74f23SLuiz Augusto von Dentz 		/* Create CIS if pending */
18777f74563eSPauli Virtanen 		hci_le_create_cis_pending(hcon->hdev);
1878ccf74f23SLuiz Augusto von Dentz 		return;
1879ccf74f23SLuiz Augusto von Dentz 	}
1880ccf74f23SLuiz Augusto von Dentz 
1881ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
1882ccf74f23SLuiz Augusto von Dentz 
1883fbdc4bc4SIulia Tanasescu 	/* Similar to the success case, if HCI_CONN_BIG_SYNC_FAILED or
1884fbdc4bc4SIulia Tanasescu 	 * HCI_CONN_PA_SYNC_FAILED is set, queue the failed connection
1885fbdc4bc4SIulia Tanasescu 	 * into the accept queue of the listening socket and wake up
1886fbdc4bc4SIulia Tanasescu 	 * userspace, to inform the user about the event.
1887f777d882SIulia Tanasescu 	 */
1888fbdc4bc4SIulia Tanasescu 	if (!status || test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags) ||
1889fbdc4bc4SIulia Tanasescu 	    test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
1890ccf74f23SLuiz Augusto von Dentz 		struct iso_conn *conn;
1891ccf74f23SLuiz Augusto von Dentz 
1892ccf74f23SLuiz Augusto von Dentz 		conn = iso_conn_add(hcon);
1893ccf74f23SLuiz Augusto von Dentz 		if (conn)
1894ccf74f23SLuiz Augusto von Dentz 			iso_conn_ready(conn);
1895ccf74f23SLuiz Augusto von Dentz 	} else {
1896ccf74f23SLuiz Augusto von Dentz 		iso_conn_del(hcon, bt_to_errno(status));
1897ccf74f23SLuiz Augusto von Dentz 	}
1898ccf74f23SLuiz Augusto von Dentz }
1899ccf74f23SLuiz Augusto von Dentz 
iso_disconn_cfm(struct hci_conn * hcon,__u8 reason)1900ccf74f23SLuiz Augusto von Dentz static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
1901ccf74f23SLuiz Augusto von Dentz {
1902ccf74f23SLuiz Augusto von Dentz 	if (hcon->type != ISO_LINK)
1903ccf74f23SLuiz Augusto von Dentz 		return;
1904ccf74f23SLuiz Augusto von Dentz 
1905ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p reason %d", hcon, reason);
1906ccf74f23SLuiz Augusto von Dentz 
1907ccf74f23SLuiz Augusto von Dentz 	iso_conn_del(hcon, bt_to_errno(reason));
1908ccf74f23SLuiz Augusto von Dentz }
1909ccf74f23SLuiz Augusto von Dentz 
iso_recv(struct hci_conn * hcon,struct sk_buff * skb,u16 flags)1910ccf74f23SLuiz Augusto von Dentz void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
1911ccf74f23SLuiz Augusto von Dentz {
1912ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = hcon->iso_data;
1913ccf74f23SLuiz Augusto von Dentz 	__u16 pb, ts, len;
1914ccf74f23SLuiz Augusto von Dentz 
1915ccf74f23SLuiz Augusto von Dentz 	if (!conn)
1916ccf74f23SLuiz Augusto von Dentz 		goto drop;
1917ccf74f23SLuiz Augusto von Dentz 
1918ccf74f23SLuiz Augusto von Dentz 	pb     = hci_iso_flags_pb(flags);
1919ccf74f23SLuiz Augusto von Dentz 	ts     = hci_iso_flags_ts(flags);
1920ccf74f23SLuiz Augusto von Dentz 
1921ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p len %d pb 0x%x ts 0x%x", conn, skb->len, pb, ts);
1922ccf74f23SLuiz Augusto von Dentz 
1923ccf74f23SLuiz Augusto von Dentz 	switch (pb) {
1924ccf74f23SLuiz Augusto von Dentz 	case ISO_START:
1925ccf74f23SLuiz Augusto von Dentz 	case ISO_SINGLE:
1926ccf74f23SLuiz Augusto von Dentz 		if (conn->rx_len) {
1927ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Unexpected start frame (len %d)", skb->len);
1928ccf74f23SLuiz Augusto von Dentz 			kfree_skb(conn->rx_skb);
1929ccf74f23SLuiz Augusto von Dentz 			conn->rx_skb = NULL;
1930ccf74f23SLuiz Augusto von Dentz 			conn->rx_len = 0;
1931ccf74f23SLuiz Augusto von Dentz 		}
1932ccf74f23SLuiz Augusto von Dentz 
1933ccf74f23SLuiz Augusto von Dentz 		if (ts) {
19342f10e40aSPauli Virtanen 			struct hci_iso_ts_data_hdr *hdr;
19352f10e40aSPauli Virtanen 
1936ccf74f23SLuiz Augusto von Dentz 			/* TODO: add timestamp to the packet? */
1937ccf74f23SLuiz Augusto von Dentz 			hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE);
1938ccf74f23SLuiz Augusto von Dentz 			if (!hdr) {
1939ccf74f23SLuiz Augusto von Dentz 				BT_ERR("Frame is too short (len %d)", skb->len);
1940ccf74f23SLuiz Augusto von Dentz 				goto drop;
1941ccf74f23SLuiz Augusto von Dentz 			}
1942ccf74f23SLuiz Augusto von Dentz 
19432f10e40aSPauli Virtanen 			len = __le16_to_cpu(hdr->slen);
1944ccf74f23SLuiz Augusto von Dentz 		} else {
19452f10e40aSPauli Virtanen 			struct hci_iso_data_hdr *hdr;
19462f10e40aSPauli Virtanen 
1947ccf74f23SLuiz Augusto von Dentz 			hdr = skb_pull_data(skb, HCI_ISO_DATA_HDR_SIZE);
1948ccf74f23SLuiz Augusto von Dentz 			if (!hdr) {
1949ccf74f23SLuiz Augusto von Dentz 				BT_ERR("Frame is too short (len %d)", skb->len);
1950ccf74f23SLuiz Augusto von Dentz 				goto drop;
1951ccf74f23SLuiz Augusto von Dentz 			}
1952ccf74f23SLuiz Augusto von Dentz 
1953ccf74f23SLuiz Augusto von Dentz 			len = __le16_to_cpu(hdr->slen);
19542f10e40aSPauli Virtanen 		}
19552f10e40aSPauli Virtanen 
1956ccf74f23SLuiz Augusto von Dentz 		flags  = hci_iso_data_flags(len);
1957ccf74f23SLuiz Augusto von Dentz 		len    = hci_iso_data_len(len);
1958ccf74f23SLuiz Augusto von Dentz 
1959ccf74f23SLuiz Augusto von Dentz 		BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x", len,
1960ccf74f23SLuiz Augusto von Dentz 		       skb->len, flags);
1961ccf74f23SLuiz Augusto von Dentz 
1962ccf74f23SLuiz Augusto von Dentz 		if (len == skb->len) {
1963ccf74f23SLuiz Augusto von Dentz 			/* Complete frame received */
19640731c5abSLuiz Augusto von Dentz 			hci_skb_pkt_status(skb) = flags & 0x03;
1965ccf74f23SLuiz Augusto von Dentz 			iso_recv_frame(conn, skb);
1966ccf74f23SLuiz Augusto von Dentz 			return;
1967ccf74f23SLuiz Augusto von Dentz 		}
1968ccf74f23SLuiz Augusto von Dentz 
1969ccf74f23SLuiz Augusto von Dentz 		if (pb == ISO_SINGLE) {
1970ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Frame malformed (len %d, expected len %d)",
1971ccf74f23SLuiz Augusto von Dentz 			       skb->len, len);
1972ccf74f23SLuiz Augusto von Dentz 			goto drop;
1973ccf74f23SLuiz Augusto von Dentz 		}
1974ccf74f23SLuiz Augusto von Dentz 
1975ccf74f23SLuiz Augusto von Dentz 		if (skb->len > len) {
1976ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Frame is too long (len %d, expected len %d)",
1977ccf74f23SLuiz Augusto von Dentz 			       skb->len, len);
1978ccf74f23SLuiz Augusto von Dentz 			goto drop;
1979ccf74f23SLuiz Augusto von Dentz 		}
1980ccf74f23SLuiz Augusto von Dentz 
1981ccf74f23SLuiz Augusto von Dentz 		/* Allocate skb for the complete frame (with header) */
1982ccf74f23SLuiz Augusto von Dentz 		conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
1983ccf74f23SLuiz Augusto von Dentz 		if (!conn->rx_skb)
1984ccf74f23SLuiz Augusto von Dentz 			goto drop;
1985ccf74f23SLuiz Augusto von Dentz 
19860731c5abSLuiz Augusto von Dentz 		hci_skb_pkt_status(conn->rx_skb) = flags & 0x03;
1987ccf74f23SLuiz Augusto von Dentz 		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
1988ccf74f23SLuiz Augusto von Dentz 					  skb->len);
1989ccf74f23SLuiz Augusto von Dentz 		conn->rx_len = len - skb->len;
1990ccf74f23SLuiz Augusto von Dentz 		break;
1991ccf74f23SLuiz Augusto von Dentz 
1992ccf74f23SLuiz Augusto von Dentz 	case ISO_CONT:
1993ccf74f23SLuiz Augusto von Dentz 		BT_DBG("Cont: frag len %d (expecting %d)", skb->len,
1994ccf74f23SLuiz Augusto von Dentz 		       conn->rx_len);
1995ccf74f23SLuiz Augusto von Dentz 
1996ccf74f23SLuiz Augusto von Dentz 		if (!conn->rx_len) {
1997ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Unexpected continuation frame (len %d)",
1998ccf74f23SLuiz Augusto von Dentz 			       skb->len);
1999ccf74f23SLuiz Augusto von Dentz 			goto drop;
2000ccf74f23SLuiz Augusto von Dentz 		}
2001ccf74f23SLuiz Augusto von Dentz 
2002ccf74f23SLuiz Augusto von Dentz 		if (skb->len > conn->rx_len) {
2003ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Fragment is too long (len %d, expected %d)",
2004ccf74f23SLuiz Augusto von Dentz 			       skb->len, conn->rx_len);
2005ccf74f23SLuiz Augusto von Dentz 			kfree_skb(conn->rx_skb);
2006ccf74f23SLuiz Augusto von Dentz 			conn->rx_skb = NULL;
2007ccf74f23SLuiz Augusto von Dentz 			conn->rx_len = 0;
2008ccf74f23SLuiz Augusto von Dentz 			goto drop;
2009ccf74f23SLuiz Augusto von Dentz 		}
2010ccf74f23SLuiz Augusto von Dentz 
2011ccf74f23SLuiz Augusto von Dentz 		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
2012ccf74f23SLuiz Augusto von Dentz 					  skb->len);
2013ccf74f23SLuiz Augusto von Dentz 		conn->rx_len -= skb->len;
2014ccf74f23SLuiz Augusto von Dentz 		return;
2015ccf74f23SLuiz Augusto von Dentz 
2016ccf74f23SLuiz Augusto von Dentz 	case ISO_END:
2017ccf74f23SLuiz Augusto von Dentz 		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
2018ccf74f23SLuiz Augusto von Dentz 					  skb->len);
2019ccf74f23SLuiz Augusto von Dentz 		conn->rx_len -= skb->len;
2020ccf74f23SLuiz Augusto von Dentz 
2021ccf74f23SLuiz Augusto von Dentz 		if (!conn->rx_len) {
2022ccf74f23SLuiz Augusto von Dentz 			struct sk_buff *rx_skb = conn->rx_skb;
2023ccf74f23SLuiz Augusto von Dentz 
2024ccf74f23SLuiz Augusto von Dentz 			/* Complete frame received. iso_recv_frame
2025ccf74f23SLuiz Augusto von Dentz 			 * takes ownership of the skb so set the global
2026ccf74f23SLuiz Augusto von Dentz 			 * rx_skb pointer to NULL first.
2027ccf74f23SLuiz Augusto von Dentz 			 */
2028ccf74f23SLuiz Augusto von Dentz 			conn->rx_skb = NULL;
2029ccf74f23SLuiz Augusto von Dentz 			iso_recv_frame(conn, rx_skb);
2030ccf74f23SLuiz Augusto von Dentz 		}
2031ccf74f23SLuiz Augusto von Dentz 		break;
2032ccf74f23SLuiz Augusto von Dentz 	}
2033ccf74f23SLuiz Augusto von Dentz 
2034ccf74f23SLuiz Augusto von Dentz drop:
2035ccf74f23SLuiz Augusto von Dentz 	kfree_skb(skb);
2036ccf74f23SLuiz Augusto von Dentz }
2037ccf74f23SLuiz Augusto von Dentz 
2038ccf74f23SLuiz Augusto von Dentz static struct hci_cb iso_cb = {
2039ccf74f23SLuiz Augusto von Dentz 	.name		= "ISO",
2040ccf74f23SLuiz Augusto von Dentz 	.connect_cfm	= iso_connect_cfm,
2041ccf74f23SLuiz Augusto von Dentz 	.disconn_cfm	= iso_disconn_cfm,
2042ccf74f23SLuiz Augusto von Dentz };
2043ccf74f23SLuiz Augusto von Dentz 
iso_debugfs_show(struct seq_file * f,void * p)2044ccf74f23SLuiz Augusto von Dentz static int iso_debugfs_show(struct seq_file *f, void *p)
2045ccf74f23SLuiz Augusto von Dentz {
2046ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
2047ccf74f23SLuiz Augusto von Dentz 
2048ccf74f23SLuiz Augusto von Dentz 	read_lock(&iso_sk_list.lock);
2049ccf74f23SLuiz Augusto von Dentz 
2050ccf74f23SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
2051ccf74f23SLuiz Augusto von Dentz 		seq_printf(f, "%pMR %pMR %d\n", &iso_pi(sk)->src,
2052ccf74f23SLuiz Augusto von Dentz 			   &iso_pi(sk)->dst, sk->sk_state);
2053ccf74f23SLuiz Augusto von Dentz 	}
2054ccf74f23SLuiz Augusto von Dentz 
2055ccf74f23SLuiz Augusto von Dentz 	read_unlock(&iso_sk_list.lock);
2056ccf74f23SLuiz Augusto von Dentz 
2057ccf74f23SLuiz Augusto von Dentz 	return 0;
2058ccf74f23SLuiz Augusto von Dentz }
2059ccf74f23SLuiz Augusto von Dentz 
2060ccf74f23SLuiz Augusto von Dentz DEFINE_SHOW_ATTRIBUTE(iso_debugfs);
2061ccf74f23SLuiz Augusto von Dentz 
2062ccf74f23SLuiz Augusto von Dentz static struct dentry *iso_debugfs;
2063ccf74f23SLuiz Augusto von Dentz 
2064ccf74f23SLuiz Augusto von Dentz static const struct proto_ops iso_sock_ops = {
2065ccf74f23SLuiz Augusto von Dentz 	.family		= PF_BLUETOOTH,
2066ccf74f23SLuiz Augusto von Dentz 	.owner		= THIS_MODULE,
2067ccf74f23SLuiz Augusto von Dentz 	.release	= iso_sock_release,
2068ccf74f23SLuiz Augusto von Dentz 	.bind		= iso_sock_bind,
2069ccf74f23SLuiz Augusto von Dentz 	.connect	= iso_sock_connect,
2070ccf74f23SLuiz Augusto von Dentz 	.listen		= iso_sock_listen,
2071ccf74f23SLuiz Augusto von Dentz 	.accept		= iso_sock_accept,
2072ccf74f23SLuiz Augusto von Dentz 	.getname	= iso_sock_getname,
2073ccf74f23SLuiz Augusto von Dentz 	.sendmsg	= iso_sock_sendmsg,
2074ccf74f23SLuiz Augusto von Dentz 	.recvmsg	= iso_sock_recvmsg,
2075ccf74f23SLuiz Augusto von Dentz 	.poll		= bt_sock_poll,
2076ccf74f23SLuiz Augusto von Dentz 	.ioctl		= bt_sock_ioctl,
2077ccf74f23SLuiz Augusto von Dentz 	.mmap		= sock_no_mmap,
2078ccf74f23SLuiz Augusto von Dentz 	.socketpair	= sock_no_socketpair,
2079ccf74f23SLuiz Augusto von Dentz 	.shutdown	= iso_sock_shutdown,
2080ccf74f23SLuiz Augusto von Dentz 	.setsockopt	= iso_sock_setsockopt,
2081ccf74f23SLuiz Augusto von Dentz 	.getsockopt	= iso_sock_getsockopt
2082ccf74f23SLuiz Augusto von Dentz };
2083ccf74f23SLuiz Augusto von Dentz 
2084ccf74f23SLuiz Augusto von Dentz static const struct net_proto_family iso_sock_family_ops = {
2085ccf74f23SLuiz Augusto von Dentz 	.family	= PF_BLUETOOTH,
2086ccf74f23SLuiz Augusto von Dentz 	.owner	= THIS_MODULE,
2087ccf74f23SLuiz Augusto von Dentz 	.create	= iso_sock_create,
2088ccf74f23SLuiz Augusto von Dentz };
2089ccf74f23SLuiz Augusto von Dentz 
2090ccf74f23SLuiz Augusto von Dentz static bool iso_inited;
2091ccf74f23SLuiz Augusto von Dentz 
iso_enabled(void)2092ccf74f23SLuiz Augusto von Dentz bool iso_enabled(void)
2093ccf74f23SLuiz Augusto von Dentz {
2094ccf74f23SLuiz Augusto von Dentz 	return iso_inited;
2095ccf74f23SLuiz Augusto von Dentz }
2096ccf74f23SLuiz Augusto von Dentz 
iso_init(void)2097ccf74f23SLuiz Augusto von Dentz int iso_init(void)
2098ccf74f23SLuiz Augusto von Dentz {
2099ccf74f23SLuiz Augusto von Dentz 	int err;
2100ccf74f23SLuiz Augusto von Dentz 
2101ccf74f23SLuiz Augusto von Dentz 	BUILD_BUG_ON(sizeof(struct sockaddr_iso) > sizeof(struct sockaddr));
2102ccf74f23SLuiz Augusto von Dentz 
2103ccf74f23SLuiz Augusto von Dentz 	if (iso_inited)
2104ccf74f23SLuiz Augusto von Dentz 		return -EALREADY;
2105ccf74f23SLuiz Augusto von Dentz 
2106ccf74f23SLuiz Augusto von Dentz 	err = proto_register(&iso_proto, 0);
2107ccf74f23SLuiz Augusto von Dentz 	if (err < 0)
2108ccf74f23SLuiz Augusto von Dentz 		return err;
2109ccf74f23SLuiz Augusto von Dentz 
2110ccf74f23SLuiz Augusto von Dentz 	err = bt_sock_register(BTPROTO_ISO, &iso_sock_family_ops);
2111ccf74f23SLuiz Augusto von Dentz 	if (err < 0) {
2112ccf74f23SLuiz Augusto von Dentz 		BT_ERR("ISO socket registration failed");
2113ccf74f23SLuiz Augusto von Dentz 		goto error;
2114ccf74f23SLuiz Augusto von Dentz 	}
2115ccf74f23SLuiz Augusto von Dentz 
2116ccf74f23SLuiz Augusto von Dentz 	err = bt_procfs_init(&init_net, "iso", &iso_sk_list, NULL);
2117ccf74f23SLuiz Augusto von Dentz 	if (err < 0) {
2118ccf74f23SLuiz Augusto von Dentz 		BT_ERR("Failed to create ISO proc file");
2119ccf74f23SLuiz Augusto von Dentz 		bt_sock_unregister(BTPROTO_ISO);
2120ccf74f23SLuiz Augusto von Dentz 		goto error;
2121ccf74f23SLuiz Augusto von Dentz 	}
2122ccf74f23SLuiz Augusto von Dentz 
2123ccf74f23SLuiz Augusto von Dentz 	BT_INFO("ISO socket layer initialized");
2124ccf74f23SLuiz Augusto von Dentz 
2125ccf74f23SLuiz Augusto von Dentz 	hci_register_cb(&iso_cb);
2126ccf74f23SLuiz Augusto von Dentz 
2127ccf74f23SLuiz Augusto von Dentz 	if (IS_ERR_OR_NULL(bt_debugfs))
2128ccf74f23SLuiz Augusto von Dentz 		return 0;
2129ccf74f23SLuiz Augusto von Dentz 
2130ccf74f23SLuiz Augusto von Dentz 	if (!iso_debugfs) {
2131ccf74f23SLuiz Augusto von Dentz 		iso_debugfs = debugfs_create_file("iso", 0444, bt_debugfs,
2132ccf74f23SLuiz Augusto von Dentz 						  NULL, &iso_debugfs_fops);
2133ccf74f23SLuiz Augusto von Dentz 	}
2134ccf74f23SLuiz Augusto von Dentz 
2135ccf74f23SLuiz Augusto von Dentz 	iso_inited = true;
2136ccf74f23SLuiz Augusto von Dentz 
2137ccf74f23SLuiz Augusto von Dentz 	return 0;
2138ccf74f23SLuiz Augusto von Dentz 
2139ccf74f23SLuiz Augusto von Dentz error:
2140ccf74f23SLuiz Augusto von Dentz 	proto_unregister(&iso_proto);
2141ccf74f23SLuiz Augusto von Dentz 	return err;
2142ccf74f23SLuiz Augusto von Dentz }
2143ccf74f23SLuiz Augusto von Dentz 
iso_exit(void)2144ccf74f23SLuiz Augusto von Dentz int iso_exit(void)
2145ccf74f23SLuiz Augusto von Dentz {
2146ccf74f23SLuiz Augusto von Dentz 	if (!iso_inited)
2147ccf74f23SLuiz Augusto von Dentz 		return -EALREADY;
2148ccf74f23SLuiz Augusto von Dentz 
2149ccf74f23SLuiz Augusto von Dentz 	bt_procfs_cleanup(&init_net, "iso");
2150ccf74f23SLuiz Augusto von Dentz 
2151ccf74f23SLuiz Augusto von Dentz 	debugfs_remove(iso_debugfs);
2152ccf74f23SLuiz Augusto von Dentz 	iso_debugfs = NULL;
2153ccf74f23SLuiz Augusto von Dentz 
2154ccf74f23SLuiz Augusto von Dentz 	hci_unregister_cb(&iso_cb);
2155ccf74f23SLuiz Augusto von Dentz 
2156ccf74f23SLuiz Augusto von Dentz 	bt_sock_unregister(BTPROTO_ISO);
2157ccf74f23SLuiz Augusto von Dentz 
2158ccf74f23SLuiz Augusto von Dentz 	proto_unregister(&iso_proto);
2159ccf74f23SLuiz Augusto von Dentz 
2160ccf74f23SLuiz Augusto von Dentz 	iso_inited = false;
2161ccf74f23SLuiz Augusto von Dentz 
2162ccf74f23SLuiz Augusto von Dentz 	return 0;
2163ccf74f23SLuiz Augusto von Dentz }
2164