xref: /openbmc/linux/net/bluetooth/iso.c (revision 36db6e8484ed455bbb320d89a119378897ae991c)
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_hold(struct iso_conn * conn)9314bcb721SLuiz Augusto von Dentz static struct sock *iso_sock_hold(struct iso_conn *conn)
9414bcb721SLuiz Augusto von Dentz {
9514bcb721SLuiz Augusto von Dentz 	if (!conn || !bt_sock_linked(&iso_sk_list, conn->sk))
9614bcb721SLuiz Augusto von Dentz 		return NULL;
9714bcb721SLuiz Augusto von Dentz 
9814bcb721SLuiz Augusto von Dentz 	sock_hold(conn->sk);
9914bcb721SLuiz Augusto von Dentz 
10014bcb721SLuiz Augusto von Dentz 	return conn->sk;
10114bcb721SLuiz Augusto von Dentz }
10214bcb721SLuiz Augusto von Dentz 
iso_sock_timeout(struct work_struct * work)103ccf74f23SLuiz Augusto von Dentz static void iso_sock_timeout(struct work_struct *work)
104ccf74f23SLuiz Augusto von Dentz {
105ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = container_of(work, struct iso_conn,
106ccf74f23SLuiz Augusto von Dentz 					     timeout_work.work);
107ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
108ccf74f23SLuiz Augusto von Dentz 
109ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
11014bcb721SLuiz Augusto von Dentz 	sk = iso_sock_hold(conn);
111ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
112ccf74f23SLuiz Augusto von Dentz 
113ccf74f23SLuiz Augusto von Dentz 	if (!sk)
114ccf74f23SLuiz Augusto von Dentz 		return;
115ccf74f23SLuiz Augusto von Dentz 
116ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p state %d", sk, sk->sk_state);
117ccf74f23SLuiz Augusto von Dentz 
118ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
119ccf74f23SLuiz Augusto von Dentz 	sk->sk_err = ETIMEDOUT;
120ccf74f23SLuiz Augusto von Dentz 	sk->sk_state_change(sk);
121ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
122ccf74f23SLuiz Augusto von Dentz 	sock_put(sk);
123ccf74f23SLuiz Augusto von Dentz }
124ccf74f23SLuiz Augusto von Dentz 
iso_sock_set_timer(struct sock * sk,long timeout)125ccf74f23SLuiz Augusto von Dentz static void iso_sock_set_timer(struct sock *sk, long timeout)
126ccf74f23SLuiz Augusto von Dentz {
127ccf74f23SLuiz Augusto von Dentz 	if (!iso_pi(sk)->conn)
128ccf74f23SLuiz Augusto von Dentz 		return;
129ccf74f23SLuiz Augusto von Dentz 
130ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
131ccf74f23SLuiz Augusto von Dentz 	cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
132ccf74f23SLuiz Augusto von Dentz 	schedule_delayed_work(&iso_pi(sk)->conn->timeout_work, timeout);
133ccf74f23SLuiz Augusto von Dentz }
134ccf74f23SLuiz Augusto von Dentz 
iso_sock_clear_timer(struct sock * sk)135ccf74f23SLuiz Augusto von Dentz static void iso_sock_clear_timer(struct sock *sk)
136ccf74f23SLuiz Augusto von Dentz {
137ccf74f23SLuiz Augusto von Dentz 	if (!iso_pi(sk)->conn)
138ccf74f23SLuiz Augusto von Dentz 		return;
139ccf74f23SLuiz Augusto von Dentz 
140ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p state %d", sk, sk->sk_state);
141ccf74f23SLuiz Augusto von Dentz 	cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
142ccf74f23SLuiz Augusto von Dentz }
143ccf74f23SLuiz Augusto von Dentz 
144ccf74f23SLuiz Augusto von Dentz /* ---- ISO connections ---- */
iso_conn_add(struct hci_conn * hcon)145ccf74f23SLuiz Augusto von Dentz static struct iso_conn *iso_conn_add(struct hci_conn *hcon)
146ccf74f23SLuiz Augusto von Dentz {
147ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = hcon->iso_data;
148ccf74f23SLuiz Augusto von Dentz 
149d40ae85eSPauli Virtanen 	if (conn) {
150d40ae85eSPauli Virtanen 		if (!conn->hcon)
151d40ae85eSPauli Virtanen 			conn->hcon = hcon;
152ccf74f23SLuiz Augusto von Dentz 		return conn;
153d40ae85eSPauli Virtanen 	}
154ccf74f23SLuiz Augusto von Dentz 
155ccf74f23SLuiz Augusto von Dentz 	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
156ccf74f23SLuiz Augusto von Dentz 	if (!conn)
157ccf74f23SLuiz Augusto von Dentz 		return NULL;
158ccf74f23SLuiz Augusto von Dentz 
159ccf74f23SLuiz Augusto von Dentz 	spin_lock_init(&conn->lock);
160ccf74f23SLuiz Augusto von Dentz 	INIT_DELAYED_WORK(&conn->timeout_work, iso_sock_timeout);
161ccf74f23SLuiz Augusto von Dentz 
162ccf74f23SLuiz Augusto von Dentz 	hcon->iso_data = conn;
163ccf74f23SLuiz Augusto von Dentz 	conn->hcon = hcon;
164ccf74f23SLuiz Augusto von Dentz 	conn->tx_sn = 0;
165ccf74f23SLuiz Augusto von Dentz 
166ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p conn %p", hcon, conn);
167ccf74f23SLuiz Augusto von Dentz 
168ccf74f23SLuiz Augusto von Dentz 	return conn;
169ccf74f23SLuiz Augusto von Dentz }
170ccf74f23SLuiz Augusto von Dentz 
171ccf74f23SLuiz Augusto von Dentz /* Delete channel. Must be called on the locked socket. */
iso_chan_del(struct sock * sk,int err)172ccf74f23SLuiz Augusto von Dentz static void iso_chan_del(struct sock *sk, int err)
173ccf74f23SLuiz Augusto von Dentz {
174ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn;
175f764a6c2SLuiz Augusto von Dentz 	struct sock *parent;
176ccf74f23SLuiz Augusto von Dentz 
177ccf74f23SLuiz Augusto von Dentz 	conn = iso_pi(sk)->conn;
178ccf74f23SLuiz Augusto von Dentz 
179ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
180ccf74f23SLuiz Augusto von Dentz 
181ccf74f23SLuiz Augusto von Dentz 	if (conn) {
182ccf74f23SLuiz Augusto von Dentz 		iso_conn_lock(conn);
183ccf74f23SLuiz Augusto von Dentz 		conn->sk = NULL;
184ccf74f23SLuiz Augusto von Dentz 		iso_pi(sk)->conn = NULL;
185ccf74f23SLuiz Augusto von Dentz 		iso_conn_unlock(conn);
186ccf74f23SLuiz Augusto von Dentz 
187ccf74f23SLuiz Augusto von Dentz 		if (conn->hcon)
188ccf74f23SLuiz Augusto von Dentz 			hci_conn_drop(conn->hcon);
189ccf74f23SLuiz Augusto von Dentz 	}
190ccf74f23SLuiz Augusto von Dentz 
191ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_CLOSED;
192ccf74f23SLuiz Augusto von Dentz 	sk->sk_err   = err;
193f764a6c2SLuiz Augusto von Dentz 
194f764a6c2SLuiz Augusto von Dentz 	parent = bt_sk(sk)->parent;
195f764a6c2SLuiz Augusto von Dentz 	if (parent) {
196f764a6c2SLuiz Augusto von Dentz 		bt_accept_unlink(sk);
197f764a6c2SLuiz Augusto von Dentz 		parent->sk_data_ready(parent);
198f764a6c2SLuiz Augusto von Dentz 	} else {
199ccf74f23SLuiz Augusto von Dentz 		sk->sk_state_change(sk);
200f764a6c2SLuiz Augusto von Dentz 	}
201ccf74f23SLuiz Augusto von Dentz 
202ccf74f23SLuiz Augusto von Dentz 	sock_set_flag(sk, SOCK_ZAPPED);
203ccf74f23SLuiz Augusto von Dentz }
204ccf74f23SLuiz Augusto von Dentz 
iso_match_conn_sync_handle(struct sock * sk,void * data)20514410544SIulia Tanasescu static bool iso_match_conn_sync_handle(struct sock *sk, void *data)
20614410544SIulia Tanasescu {
20714410544SIulia Tanasescu 	struct hci_conn *hcon = data;
20814410544SIulia Tanasescu 
20914410544SIulia Tanasescu 	if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags))
21014410544SIulia Tanasescu 		return false;
21114410544SIulia Tanasescu 
21214410544SIulia Tanasescu 	return hcon->sync_handle == iso_pi(sk)->sync_handle;
21314410544SIulia Tanasescu }
21414410544SIulia Tanasescu 
iso_conn_del(struct hci_conn * hcon,int err)215ccf74f23SLuiz Augusto von Dentz static void iso_conn_del(struct hci_conn *hcon, int err)
216ccf74f23SLuiz Augusto von Dentz {
217ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = hcon->iso_data;
218ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
21914410544SIulia Tanasescu 	struct sock *parent;
220ccf74f23SLuiz Augusto von Dentz 
221ccf74f23SLuiz Augusto von Dentz 	if (!conn)
222ccf74f23SLuiz Augusto von Dentz 		return;
223ccf74f23SLuiz Augusto von Dentz 
224ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
225ccf74f23SLuiz Augusto von Dentz 
226ccf74f23SLuiz Augusto von Dentz 	/* Kill socket */
227ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
22814bcb721SLuiz Augusto von Dentz 	sk = iso_sock_hold(conn);
229ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
230ccf74f23SLuiz Augusto von Dentz 
231ccf74f23SLuiz Augusto von Dentz 	if (sk) {
232ccf74f23SLuiz Augusto von Dentz 		lock_sock(sk);
23314410544SIulia Tanasescu 
23414410544SIulia Tanasescu 		/* While a PA sync hcon is in the process of closing,
23514410544SIulia Tanasescu 		 * mark parent socket with a flag, so that any residual
23614410544SIulia Tanasescu 		 * BIGInfo adv reports that arrive before PA sync is
23714410544SIulia Tanasescu 		 * terminated are not processed anymore.
23814410544SIulia Tanasescu 		 */
23914410544SIulia Tanasescu 		if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
24014410544SIulia Tanasescu 			parent = iso_get_sock_listen(&hcon->src,
24114410544SIulia Tanasescu 						     &hcon->dst,
24214410544SIulia Tanasescu 						     iso_match_conn_sync_handle,
24314410544SIulia Tanasescu 						     hcon);
24414410544SIulia Tanasescu 
24514410544SIulia Tanasescu 			if (parent) {
24614410544SIulia Tanasescu 				set_bit(BT_SK_PA_SYNC_TERM,
24714410544SIulia Tanasescu 					&iso_pi(parent)->flags);
24814410544SIulia Tanasescu 				sock_put(parent);
24914410544SIulia Tanasescu 			}
25014410544SIulia Tanasescu 		}
25114410544SIulia Tanasescu 
252ccf74f23SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
253ccf74f23SLuiz Augusto von Dentz 		iso_chan_del(sk, err);
254ccf74f23SLuiz Augusto von Dentz 		release_sock(sk);
255ccf74f23SLuiz Augusto von Dentz 		sock_put(sk);
256ccf74f23SLuiz Augusto von Dentz 	}
257ccf74f23SLuiz Augusto von Dentz 
258ccf74f23SLuiz Augusto von Dentz 	/* Ensure no more work items will run before freeing conn. */
259ccf74f23SLuiz Augusto von Dentz 	cancel_delayed_work_sync(&conn->timeout_work);
260ccf74f23SLuiz Augusto von Dentz 
261ccf74f23SLuiz Augusto von Dentz 	hcon->iso_data = NULL;
262ccf74f23SLuiz Augusto von Dentz 	kfree(conn);
263ccf74f23SLuiz Augusto von Dentz }
264ccf74f23SLuiz Augusto von Dentz 
__iso_chan_add(struct iso_conn * conn,struct sock * sk,struct sock * parent)265ccf74f23SLuiz Augusto von Dentz static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
266ccf74f23SLuiz Augusto von Dentz 			  struct sock *parent)
267ccf74f23SLuiz Augusto von Dentz {
268ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p", conn);
269ccf74f23SLuiz Augusto von Dentz 
270ccf74f23SLuiz Augusto von Dentz 	if (iso_pi(sk)->conn == conn && conn->sk == sk)
271ccf74f23SLuiz Augusto von Dentz 		return 0;
272ccf74f23SLuiz Augusto von Dentz 
273ccf74f23SLuiz Augusto von Dentz 	if (conn->sk) {
274ccf74f23SLuiz Augusto von Dentz 		BT_ERR("conn->sk already set");
275ccf74f23SLuiz Augusto von Dentz 		return -EBUSY;
276ccf74f23SLuiz Augusto von Dentz 	}
277ccf74f23SLuiz Augusto von Dentz 
278ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->conn = conn;
279ccf74f23SLuiz Augusto von Dentz 	conn->sk = sk;
280ccf74f23SLuiz Augusto von Dentz 
281ccf74f23SLuiz Augusto von Dentz 	if (parent)
282ccf74f23SLuiz Augusto von Dentz 		bt_accept_enqueue(parent, sk, true);
283ccf74f23SLuiz Augusto von Dentz 
284ccf74f23SLuiz Augusto von Dentz 	return 0;
285ccf74f23SLuiz Augusto von Dentz }
286ccf74f23SLuiz Augusto von Dentz 
iso_chan_add(struct iso_conn * conn,struct sock * sk,struct sock * parent)287ccf74f23SLuiz Augusto von Dentz static int iso_chan_add(struct iso_conn *conn, struct sock *sk,
288ccf74f23SLuiz Augusto von Dentz 			struct sock *parent)
289ccf74f23SLuiz Augusto von Dentz {
290ccf74f23SLuiz Augusto von Dentz 	int err;
291ccf74f23SLuiz Augusto von Dentz 
292ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
293ccf74f23SLuiz Augusto von Dentz 	err = __iso_chan_add(conn, sk, parent);
294ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
295ccf74f23SLuiz Augusto von Dentz 
296ccf74f23SLuiz Augusto von Dentz 	return err;
297ccf74f23SLuiz Augusto von Dentz }
298ccf74f23SLuiz Augusto von Dentz 
le_addr_type(u8 bdaddr_type)299b36a234dSPauli Virtanen static inline u8 le_addr_type(u8 bdaddr_type)
300b36a234dSPauli Virtanen {
301b36a234dSPauli Virtanen 	if (bdaddr_type == BDADDR_LE_PUBLIC)
302b36a234dSPauli Virtanen 		return ADDR_LE_DEV_PUBLIC;
303b36a234dSPauli Virtanen 	else
304b36a234dSPauli Virtanen 		return ADDR_LE_DEV_RANDOM;
305b36a234dSPauli Virtanen }
306b36a234dSPauli Virtanen 
iso_connect_bis(struct sock * sk)307f764a6c2SLuiz Augusto von Dentz static int iso_connect_bis(struct sock *sk)
308f764a6c2SLuiz Augusto von Dentz {
309f764a6c2SLuiz Augusto von Dentz 	struct iso_conn *conn;
310f764a6c2SLuiz Augusto von Dentz 	struct hci_conn *hcon;
311f764a6c2SLuiz Augusto von Dentz 	struct hci_dev  *hdev;
312f764a6c2SLuiz Augusto von Dentz 	int err;
313f764a6c2SLuiz Augusto von Dentz 
314f764a6c2SLuiz Augusto von Dentz 	BT_DBG("%pMR", &iso_pi(sk)->src);
315f764a6c2SLuiz Augusto von Dentz 
316f764a6c2SLuiz Augusto von Dentz 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
317f764a6c2SLuiz Augusto von Dentz 			     iso_pi(sk)->src_type);
318f764a6c2SLuiz Augusto von Dentz 	if (!hdev)
319f764a6c2SLuiz Augusto von Dentz 		return -EHOSTUNREACH;
320f764a6c2SLuiz Augusto von Dentz 
321f764a6c2SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
322f764a6c2SLuiz Augusto von Dentz 
323f764a6c2SLuiz Augusto von Dentz 	if (!bis_capable(hdev)) {
324f764a6c2SLuiz Augusto von Dentz 		err = -EOPNOTSUPP;
325241f5193SLuiz Augusto von Dentz 		goto unlock;
326f764a6c2SLuiz Augusto von Dentz 	}
327f764a6c2SLuiz Augusto von Dentz 
3280fe8c8d0SIulia Tanasescu 	/* Fail if user set invalid QoS */
3290fe8c8d0SIulia Tanasescu 	if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
3300fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos = default_qos;
3310fe8c8d0SIulia Tanasescu 		err = -EINVAL;
3320fe8c8d0SIulia Tanasescu 		goto unlock;
3330fe8c8d0SIulia Tanasescu 	}
3340fe8c8d0SIulia Tanasescu 
335f764a6c2SLuiz Augusto von Dentz 	/* Fail if out PHYs are marked as disabled */
3360fe8c8d0SIulia Tanasescu 	if (!iso_pi(sk)->qos.bcast.out.phy) {
337f764a6c2SLuiz Augusto von Dentz 		err = -EINVAL;
338241f5193SLuiz Augusto von Dentz 		goto unlock;
339f764a6c2SLuiz Augusto von Dentz 	}
340f764a6c2SLuiz Augusto von Dentz 
341a0bfde16SIulia Tanasescu 	/* Just bind if DEFER_SETUP has been set */
342a0bfde16SIulia Tanasescu 	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
343a0bfde16SIulia Tanasescu 		hcon = hci_bind_bis(hdev, &iso_pi(sk)->dst,
344a0bfde16SIulia Tanasescu 				    &iso_pi(sk)->qos, iso_pi(sk)->base_len,
345a0bfde16SIulia Tanasescu 				    iso_pi(sk)->base);
346a0bfde16SIulia Tanasescu 		if (IS_ERR(hcon)) {
347a0bfde16SIulia Tanasescu 			err = PTR_ERR(hcon);
348a0bfde16SIulia Tanasescu 			goto unlock;
349a0bfde16SIulia Tanasescu 		}
350a0bfde16SIulia Tanasescu 	} else {
351d11ab690SPauli Virtanen 		hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
352d11ab690SPauli Virtanen 				       le_addr_type(iso_pi(sk)->dst_type),
353f764a6c2SLuiz Augusto von Dentz 				       &iso_pi(sk)->qos, iso_pi(sk)->base_len,
354f764a6c2SLuiz Augusto von Dentz 				       iso_pi(sk)->base);
355f764a6c2SLuiz Augusto von Dentz 		if (IS_ERR(hcon)) {
356f764a6c2SLuiz Augusto von Dentz 			err = PTR_ERR(hcon);
357241f5193SLuiz Augusto von Dentz 			goto unlock;
358f764a6c2SLuiz Augusto von Dentz 		}
359a0bfde16SIulia Tanasescu 	}
360f764a6c2SLuiz Augusto von Dentz 
361f764a6c2SLuiz Augusto von Dentz 	conn = iso_conn_add(hcon);
362f764a6c2SLuiz Augusto von Dentz 	if (!conn) {
363f764a6c2SLuiz Augusto von Dentz 		hci_conn_drop(hcon);
364f764a6c2SLuiz Augusto von Dentz 		err = -ENOMEM;
365241f5193SLuiz Augusto von Dentz 		goto unlock;
366f764a6c2SLuiz Augusto von Dentz 	}
367f764a6c2SLuiz Augusto von Dentz 
368d40ae85eSPauli Virtanen 	lock_sock(sk);
369241f5193SLuiz Augusto von Dentz 
3706a5ad251SLuiz Augusto von Dentz 	err = iso_chan_add(conn, sk, NULL);
371d40ae85eSPauli Virtanen 	if (err) {
372d40ae85eSPauli Virtanen 		release_sock(sk);
373d40ae85eSPauli Virtanen 		goto unlock;
374d40ae85eSPauli Virtanen 	}
375241f5193SLuiz Augusto von Dentz 
376f764a6c2SLuiz Augusto von Dentz 	/* Update source addr of the socket */
377f764a6c2SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->src, &hcon->src);
378f764a6c2SLuiz Augusto von Dentz 
379f764a6c2SLuiz Augusto von Dentz 	if (hcon->state == BT_CONNECTED) {
380f764a6c2SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
381f764a6c2SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECTED;
382a0bfde16SIulia Tanasescu 	} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
383a0bfde16SIulia Tanasescu 		iso_sock_clear_timer(sk);
384a0bfde16SIulia Tanasescu 		sk->sk_state = BT_CONNECT;
385f764a6c2SLuiz Augusto von Dentz 	} else {
386f764a6c2SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECT;
387f764a6c2SLuiz Augusto von Dentz 		iso_sock_set_timer(sk, sk->sk_sndtimeo);
388f764a6c2SLuiz Augusto von Dentz 	}
389f764a6c2SLuiz Augusto von Dentz 
390241f5193SLuiz Augusto von Dentz 	release_sock(sk);
391241f5193SLuiz Augusto von Dentz 
392241f5193SLuiz Augusto von Dentz unlock:
393f764a6c2SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
394f764a6c2SLuiz Augusto von Dentz 	hci_dev_put(hdev);
395f764a6c2SLuiz Augusto von Dentz 	return err;
396f764a6c2SLuiz Augusto von Dentz }
397f764a6c2SLuiz Augusto von Dentz 
iso_connect_cis(struct sock * sk)398f764a6c2SLuiz Augusto von Dentz static int iso_connect_cis(struct sock *sk)
399ccf74f23SLuiz Augusto von Dentz {
400ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn;
401ccf74f23SLuiz Augusto von Dentz 	struct hci_conn *hcon;
402ccf74f23SLuiz Augusto von Dentz 	struct hci_dev  *hdev;
403ccf74f23SLuiz Augusto von Dentz 	int err;
404ccf74f23SLuiz Augusto von Dentz 
405ccf74f23SLuiz Augusto von Dentz 	BT_DBG("%pMR -> %pMR", &iso_pi(sk)->src, &iso_pi(sk)->dst);
406ccf74f23SLuiz Augusto von Dentz 
407ccf74f23SLuiz Augusto von Dentz 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
408ccf74f23SLuiz Augusto von Dentz 			     iso_pi(sk)->src_type);
409ccf74f23SLuiz Augusto von Dentz 	if (!hdev)
410ccf74f23SLuiz Augusto von Dentz 		return -EHOSTUNREACH;
411ccf74f23SLuiz Augusto von Dentz 
412ccf74f23SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
413ccf74f23SLuiz Augusto von Dentz 
414ccf74f23SLuiz Augusto von Dentz 	if (!cis_central_capable(hdev)) {
415ccf74f23SLuiz Augusto von Dentz 		err = -EOPNOTSUPP;
416241f5193SLuiz Augusto von Dentz 		goto unlock;
417ccf74f23SLuiz Augusto von Dentz 	}
418ccf74f23SLuiz Augusto von Dentz 
4190fe8c8d0SIulia Tanasescu 	/* Fail if user set invalid QoS */
4200fe8c8d0SIulia Tanasescu 	if (iso_pi(sk)->qos_user_set && !check_ucast_qos(&iso_pi(sk)->qos)) {
4210fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos = default_qos;
4220fe8c8d0SIulia Tanasescu 		err = -EINVAL;
4230fe8c8d0SIulia Tanasescu 		goto unlock;
4240fe8c8d0SIulia Tanasescu 	}
4250fe8c8d0SIulia Tanasescu 
426ccf74f23SLuiz Augusto von Dentz 	/* Fail if either PHYs are marked as disabled */
4270fe8c8d0SIulia Tanasescu 	if (!iso_pi(sk)->qos.ucast.in.phy && !iso_pi(sk)->qos.ucast.out.phy) {
428ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
429241f5193SLuiz Augusto von Dentz 		goto unlock;
430ccf74f23SLuiz Augusto von Dentz 	}
431ccf74f23SLuiz Augusto von Dentz 
432ccf74f23SLuiz Augusto von Dentz 	/* Just bind if DEFER_SETUP has been set */
433ccf74f23SLuiz Augusto von Dentz 	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
434ccf74f23SLuiz Augusto von Dentz 		hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,
435b36a234dSPauli Virtanen 				    le_addr_type(iso_pi(sk)->dst_type),
436b36a234dSPauli Virtanen 				    &iso_pi(sk)->qos);
437ccf74f23SLuiz Augusto von Dentz 		if (IS_ERR(hcon)) {
438ccf74f23SLuiz Augusto von Dentz 			err = PTR_ERR(hcon);
439241f5193SLuiz Augusto von Dentz 			goto unlock;
440ccf74f23SLuiz Augusto von Dentz 		}
441ccf74f23SLuiz Augusto von Dentz 	} else {
442ccf74f23SLuiz Augusto von Dentz 		hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
443b36a234dSPauli Virtanen 				       le_addr_type(iso_pi(sk)->dst_type),
444b36a234dSPauli Virtanen 				       &iso_pi(sk)->qos);
445ccf74f23SLuiz Augusto von Dentz 		if (IS_ERR(hcon)) {
446ccf74f23SLuiz Augusto von Dentz 			err = PTR_ERR(hcon);
447241f5193SLuiz Augusto von Dentz 			goto unlock;
448ccf74f23SLuiz Augusto von Dentz 		}
449ccf74f23SLuiz Augusto von Dentz 	}
450ccf74f23SLuiz Augusto von Dentz 
451ccf74f23SLuiz Augusto von Dentz 	conn = iso_conn_add(hcon);
452ccf74f23SLuiz Augusto von Dentz 	if (!conn) {
453ccf74f23SLuiz Augusto von Dentz 		hci_conn_drop(hcon);
454ccf74f23SLuiz Augusto von Dentz 		err = -ENOMEM;
455241f5193SLuiz Augusto von Dentz 		goto unlock;
456ccf74f23SLuiz Augusto von Dentz 	}
457ccf74f23SLuiz Augusto von Dentz 
458d40ae85eSPauli Virtanen 	lock_sock(sk);
459241f5193SLuiz Augusto von Dentz 
4606a5ad251SLuiz Augusto von Dentz 	err = iso_chan_add(conn, sk, NULL);
461d40ae85eSPauli Virtanen 	if (err) {
462d40ae85eSPauli Virtanen 		release_sock(sk);
463d40ae85eSPauli Virtanen 		goto unlock;
464d40ae85eSPauli Virtanen 	}
465241f5193SLuiz Augusto von Dentz 
466ccf74f23SLuiz Augusto von Dentz 	/* Update source addr of the socket */
467ccf74f23SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->src, &hcon->src);
468ccf74f23SLuiz Augusto von Dentz 
469ccf74f23SLuiz Augusto von Dentz 	if (hcon->state == BT_CONNECTED) {
470ccf74f23SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
471ccf74f23SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECTED;
472ccf74f23SLuiz Augusto von Dentz 	} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
473ccf74f23SLuiz Augusto von Dentz 		iso_sock_clear_timer(sk);
474ccf74f23SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECT;
475ccf74f23SLuiz Augusto von Dentz 	} else {
476ccf74f23SLuiz Augusto von Dentz 		sk->sk_state = BT_CONNECT;
477ccf74f23SLuiz Augusto von Dentz 		iso_sock_set_timer(sk, sk->sk_sndtimeo);
478ccf74f23SLuiz Augusto von Dentz 	}
479ccf74f23SLuiz Augusto von Dentz 
480241f5193SLuiz Augusto von Dentz 	release_sock(sk);
481241f5193SLuiz Augusto von Dentz 
482241f5193SLuiz Augusto von Dentz unlock:
483ccf74f23SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
484ccf74f23SLuiz Augusto von Dentz 	hci_dev_put(hdev);
485ccf74f23SLuiz Augusto von Dentz 	return err;
486ccf74f23SLuiz Augusto von Dentz }
487ccf74f23SLuiz Augusto von Dentz 
iso_sock_get_qos(struct sock * sk)4881d1ab5d3SLuiz Augusto von Dentz static struct bt_iso_qos *iso_sock_get_qos(struct sock *sk)
4891d1ab5d3SLuiz Augusto von Dentz {
4901d1ab5d3SLuiz Augusto von Dentz 	if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONNECT2)
4911d1ab5d3SLuiz Augusto von Dentz 		return &iso_pi(sk)->conn->hcon->iso_qos;
4921d1ab5d3SLuiz Augusto von Dentz 
4931d1ab5d3SLuiz Augusto von Dentz 	return &iso_pi(sk)->qos;
4941d1ab5d3SLuiz Augusto von Dentz }
4951d1ab5d3SLuiz Augusto von Dentz 
iso_send_frame(struct sock * sk,struct sk_buff * skb)496ccf74f23SLuiz Augusto von Dentz static int iso_send_frame(struct sock *sk, struct sk_buff *skb)
497ccf74f23SLuiz Augusto von Dentz {
498ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = iso_pi(sk)->conn;
4991d1ab5d3SLuiz Augusto von Dentz 	struct bt_iso_qos *qos = iso_sock_get_qos(sk);
500ccf74f23SLuiz Augusto von Dentz 	struct hci_iso_data_hdr *hdr;
501ccf74f23SLuiz Augusto von Dentz 	int len = 0;
502ccf74f23SLuiz Augusto von Dentz 
503ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p len %d", sk, skb->len);
504ccf74f23SLuiz Augusto von Dentz 
5050fe8c8d0SIulia Tanasescu 	if (skb->len > qos->ucast.out.sdu)
506ccf74f23SLuiz Augusto von Dentz 		return -EMSGSIZE;
507ccf74f23SLuiz Augusto von Dentz 
508ccf74f23SLuiz Augusto von Dentz 	len = skb->len;
509ccf74f23SLuiz Augusto von Dentz 
510ccf74f23SLuiz Augusto von Dentz 	/* Push ISO data header */
511ccf74f23SLuiz Augusto von Dentz 	hdr = skb_push(skb, HCI_ISO_DATA_HDR_SIZE);
512ccf74f23SLuiz Augusto von Dentz 	hdr->sn = cpu_to_le16(conn->tx_sn++);
513ccf74f23SLuiz Augusto von Dentz 	hdr->slen = cpu_to_le16(hci_iso_data_len_pack(len,
514ccf74f23SLuiz Augusto von Dentz 						      HCI_ISO_STATUS_VALID));
515ccf74f23SLuiz Augusto von Dentz 
516ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state == BT_CONNECTED)
517ccf74f23SLuiz Augusto von Dentz 		hci_send_iso(conn->hcon, skb);
518ccf74f23SLuiz Augusto von Dentz 	else
519ccf74f23SLuiz Augusto von Dentz 		len = -ENOTCONN;
520ccf74f23SLuiz Augusto von Dentz 
521ccf74f23SLuiz Augusto von Dentz 	return len;
522ccf74f23SLuiz Augusto von Dentz }
523ccf74f23SLuiz Augusto von Dentz 
iso_recv_frame(struct iso_conn * conn,struct sk_buff * skb)524ccf74f23SLuiz Augusto von Dentz static void iso_recv_frame(struct iso_conn *conn, struct sk_buff *skb)
525ccf74f23SLuiz Augusto von Dentz {
526ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
527ccf74f23SLuiz Augusto von Dentz 
528ccf74f23SLuiz Augusto von Dentz 	iso_conn_lock(conn);
529ccf74f23SLuiz Augusto von Dentz 	sk = conn->sk;
530ccf74f23SLuiz Augusto von Dentz 	iso_conn_unlock(conn);
531ccf74f23SLuiz Augusto von Dentz 
532ccf74f23SLuiz Augusto von Dentz 	if (!sk)
533ccf74f23SLuiz Augusto von Dentz 		goto drop;
534ccf74f23SLuiz Augusto von Dentz 
535ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p len %d", sk, skb->len);
536ccf74f23SLuiz Augusto von Dentz 
537ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_CONNECTED)
538ccf74f23SLuiz Augusto von Dentz 		goto drop;
539ccf74f23SLuiz Augusto von Dentz 
540ccf74f23SLuiz Augusto von Dentz 	if (!sock_queue_rcv_skb(sk, skb))
541ccf74f23SLuiz Augusto von Dentz 		return;
542ccf74f23SLuiz Augusto von Dentz 
543ccf74f23SLuiz Augusto von Dentz drop:
544ccf74f23SLuiz Augusto von Dentz 	kfree_skb(skb);
545ccf74f23SLuiz Augusto von Dentz }
546ccf74f23SLuiz Augusto von Dentz 
547ccf74f23SLuiz Augusto von Dentz /* -------- Socket interface ---------- */
__iso_get_sock_listen_by_addr(bdaddr_t * src,bdaddr_t * dst)548e0275ea5SLuiz Augusto von Dentz static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst)
549ccf74f23SLuiz Augusto von Dentz {
550ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
551ccf74f23SLuiz Augusto von Dentz 
552ccf74f23SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
553ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN)
554ccf74f23SLuiz Augusto von Dentz 			continue;
555ccf74f23SLuiz Augusto von Dentz 
556e0275ea5SLuiz Augusto von Dentz 		if (bacmp(&iso_pi(sk)->dst, dst))
557e0275ea5SLuiz Augusto von Dentz 			continue;
558e0275ea5SLuiz Augusto von Dentz 
559e0275ea5SLuiz Augusto von Dentz 		if (!bacmp(&iso_pi(sk)->src, src))
560ccf74f23SLuiz Augusto von Dentz 			return sk;
561ccf74f23SLuiz Augusto von Dentz 	}
562ccf74f23SLuiz Augusto von Dentz 
563ccf74f23SLuiz Augusto von Dentz 	return NULL;
564ccf74f23SLuiz Augusto von Dentz }
565ccf74f23SLuiz Augusto von Dentz 
__iso_get_sock_listen_by_sid(bdaddr_t * ba,bdaddr_t * bc,__u8 sid)566f764a6c2SLuiz Augusto von Dentz static struct sock *__iso_get_sock_listen_by_sid(bdaddr_t *ba, bdaddr_t *bc,
567f764a6c2SLuiz Augusto von Dentz 						 __u8 sid)
568f764a6c2SLuiz Augusto von Dentz {
569f764a6c2SLuiz Augusto von Dentz 	struct sock *sk;
570f764a6c2SLuiz Augusto von Dentz 
571f764a6c2SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
572f764a6c2SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN)
573f764a6c2SLuiz Augusto von Dentz 			continue;
574f764a6c2SLuiz Augusto von Dentz 
575f764a6c2SLuiz Augusto von Dentz 		if (bacmp(&iso_pi(sk)->src, ba))
576f764a6c2SLuiz Augusto von Dentz 			continue;
577f764a6c2SLuiz Augusto von Dentz 
578f764a6c2SLuiz Augusto von Dentz 		if (bacmp(&iso_pi(sk)->dst, bc))
579f764a6c2SLuiz Augusto von Dentz 			continue;
580f764a6c2SLuiz Augusto von Dentz 
581f764a6c2SLuiz Augusto von Dentz 		if (iso_pi(sk)->bc_sid == sid)
582f764a6c2SLuiz Augusto von Dentz 			return sk;
583f764a6c2SLuiz Augusto von Dentz 	}
584f764a6c2SLuiz Augusto von Dentz 
585f764a6c2SLuiz Augusto von Dentz 	return NULL;
586f764a6c2SLuiz Augusto von Dentz }
587f764a6c2SLuiz Augusto von Dentz 
588f764a6c2SLuiz Augusto von Dentz /* Find socket listening:
589f764a6c2SLuiz Augusto von Dentz  * source bdaddr (Unicast)
590f764a6c2SLuiz Augusto von Dentz  * destination bdaddr (Broadcast only)
591f764a6c2SLuiz Augusto von Dentz  * match func - pass NULL to ignore
592f764a6c2SLuiz Augusto von Dentz  * match func data - pass -1 to ignore
593ccf74f23SLuiz Augusto von Dentz  * Returns closest match.
594ccf74f23SLuiz Augusto von Dentz  */
iso_get_sock_listen(bdaddr_t * src,bdaddr_t * dst,iso_sock_match_t match,void * data)595f764a6c2SLuiz Augusto von Dentz static struct sock *iso_get_sock_listen(bdaddr_t *src, bdaddr_t *dst,
596f764a6c2SLuiz Augusto von Dentz 					iso_sock_match_t match, void *data)
597ccf74f23SLuiz Augusto von Dentz {
598ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = NULL, *sk1 = NULL;
599ccf74f23SLuiz Augusto von Dentz 
600ccf74f23SLuiz Augusto von Dentz 	read_lock(&iso_sk_list.lock);
601ccf74f23SLuiz Augusto von Dentz 
602ccf74f23SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
603ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN)
604ccf74f23SLuiz Augusto von Dentz 			continue;
605ccf74f23SLuiz Augusto von Dentz 
606f764a6c2SLuiz Augusto von Dentz 		/* Match Broadcast destination */
607f764a6c2SLuiz Augusto von Dentz 		if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst))
608f764a6c2SLuiz Augusto von Dentz 			continue;
609f764a6c2SLuiz Augusto von Dentz 
610f764a6c2SLuiz Augusto von Dentz 		/* Use Match function if provided */
611f764a6c2SLuiz Augusto von Dentz 		if (match && !match(sk, data))
612f764a6c2SLuiz Augusto von Dentz 			continue;
613f764a6c2SLuiz Augusto von Dentz 
614ccf74f23SLuiz Augusto von Dentz 		/* Exact match. */
61511dc486eSIulia Tanasescu 		if (!bacmp(&iso_pi(sk)->src, src)) {
61611dc486eSIulia Tanasescu 			sock_hold(sk);
617ccf74f23SLuiz Augusto von Dentz 			break;
61811dc486eSIulia Tanasescu 		}
619ccf74f23SLuiz Augusto von Dentz 
620ccf74f23SLuiz Augusto von Dentz 		/* Closest match */
62111dc486eSIulia Tanasescu 		if (!bacmp(&iso_pi(sk)->src, BDADDR_ANY)) {
62211dc486eSIulia Tanasescu 			if (sk1)
62311dc486eSIulia Tanasescu 				sock_put(sk1);
62411dc486eSIulia Tanasescu 
625ccf74f23SLuiz Augusto von Dentz 			sk1 = sk;
62611dc486eSIulia Tanasescu 			sock_hold(sk1);
627ccf74f23SLuiz Augusto von Dentz 		}
62811dc486eSIulia Tanasescu 	}
62911dc486eSIulia Tanasescu 
63011dc486eSIulia Tanasescu 	if (sk && sk1)
63111dc486eSIulia Tanasescu 		sock_put(sk1);
632ccf74f23SLuiz Augusto von Dentz 
633ccf74f23SLuiz Augusto von Dentz 	read_unlock(&iso_sk_list.lock);
634ccf74f23SLuiz Augusto von Dentz 
635ccf74f23SLuiz Augusto von Dentz 	return sk ? sk : sk1;
636ccf74f23SLuiz Augusto von Dentz }
637ccf74f23SLuiz Augusto von Dentz 
iso_get_sock_big(struct sock * match_sk,bdaddr_t * src,bdaddr_t * dst,uint8_t big)63811dc486eSIulia Tanasescu static struct sock *iso_get_sock_big(struct sock *match_sk, bdaddr_t *src,
63911dc486eSIulia Tanasescu 				     bdaddr_t *dst, uint8_t big)
64011dc486eSIulia Tanasescu {
64111dc486eSIulia Tanasescu 	struct sock *sk = NULL;
64211dc486eSIulia Tanasescu 
64311dc486eSIulia Tanasescu 	read_lock(&iso_sk_list.lock);
64411dc486eSIulia Tanasescu 
64511dc486eSIulia Tanasescu 	sk_for_each(sk, &iso_sk_list.head) {
64611dc486eSIulia Tanasescu 		if (match_sk == sk)
64711dc486eSIulia Tanasescu 			continue;
64811dc486eSIulia Tanasescu 
64911dc486eSIulia Tanasescu 		/* Look for sockets that have already been
65011dc486eSIulia Tanasescu 		 * connected to the BIG
65111dc486eSIulia Tanasescu 		 */
65211dc486eSIulia Tanasescu 		if (sk->sk_state != BT_CONNECTED &&
65311dc486eSIulia Tanasescu 		    sk->sk_state != BT_CONNECT)
65411dc486eSIulia Tanasescu 			continue;
65511dc486eSIulia Tanasescu 
65611dc486eSIulia Tanasescu 		/* Match Broadcast destination */
65711dc486eSIulia Tanasescu 		if (bacmp(&iso_pi(sk)->dst, dst))
65811dc486eSIulia Tanasescu 			continue;
65911dc486eSIulia Tanasescu 
66011dc486eSIulia Tanasescu 		/* Match BIG handle */
66111dc486eSIulia Tanasescu 		if (iso_pi(sk)->qos.bcast.big != big)
66211dc486eSIulia Tanasescu 			continue;
66311dc486eSIulia Tanasescu 
66411dc486eSIulia Tanasescu 		/* Match source address */
66511dc486eSIulia Tanasescu 		if (bacmp(&iso_pi(sk)->src, src))
66611dc486eSIulia Tanasescu 			continue;
66711dc486eSIulia Tanasescu 
66811dc486eSIulia Tanasescu 		sock_hold(sk);
66911dc486eSIulia Tanasescu 		break;
67011dc486eSIulia Tanasescu 	}
67111dc486eSIulia Tanasescu 
67211dc486eSIulia Tanasescu 	read_unlock(&iso_sk_list.lock);
67311dc486eSIulia Tanasescu 
67411dc486eSIulia Tanasescu 	return sk;
67511dc486eSIulia Tanasescu }
67611dc486eSIulia Tanasescu 
iso_sock_destruct(struct sock * sk)677ccf74f23SLuiz Augusto von Dentz static void iso_sock_destruct(struct sock *sk)
678ccf74f23SLuiz Augusto von Dentz {
679ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
680ccf74f23SLuiz Augusto von Dentz 
681ccf74f23SLuiz Augusto von Dentz 	skb_queue_purge(&sk->sk_receive_queue);
682ccf74f23SLuiz Augusto von Dentz 	skb_queue_purge(&sk->sk_write_queue);
683ccf74f23SLuiz Augusto von Dentz }
684ccf74f23SLuiz Augusto von Dentz 
iso_sock_cleanup_listen(struct sock * parent)685ccf74f23SLuiz Augusto von Dentz static void iso_sock_cleanup_listen(struct sock *parent)
686ccf74f23SLuiz Augusto von Dentz {
687ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
688ccf74f23SLuiz Augusto von Dentz 
689ccf74f23SLuiz Augusto von Dentz 	BT_DBG("parent %p", parent);
690ccf74f23SLuiz Augusto von Dentz 
691ccf74f23SLuiz Augusto von Dentz 	/* Close not yet accepted channels */
692ccf74f23SLuiz Augusto von Dentz 	while ((sk = bt_accept_dequeue(parent, NULL))) {
693ccf74f23SLuiz Augusto von Dentz 		iso_sock_close(sk);
694ccf74f23SLuiz Augusto von Dentz 		iso_sock_kill(sk);
695ccf74f23SLuiz Augusto von Dentz 	}
696ccf74f23SLuiz Augusto von Dentz 
697fbdc4bc4SIulia Tanasescu 	/* If listening socket stands for a PA sync connection,
698fbdc4bc4SIulia Tanasescu 	 * properly disconnect the hcon and socket.
699fbdc4bc4SIulia Tanasescu 	 */
700fbdc4bc4SIulia Tanasescu 	if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon &&
701fbdc4bc4SIulia Tanasescu 	    test_bit(HCI_CONN_PA_SYNC, &iso_pi(parent)->conn->hcon->flags)) {
702fbdc4bc4SIulia Tanasescu 		iso_sock_disconn(parent);
703fbdc4bc4SIulia Tanasescu 		return;
704fbdc4bc4SIulia Tanasescu 	}
705fbdc4bc4SIulia Tanasescu 
706ccf74f23SLuiz Augusto von Dentz 	parent->sk_state  = BT_CLOSED;
707ccf74f23SLuiz Augusto von Dentz 	sock_set_flag(parent, SOCK_ZAPPED);
708ccf74f23SLuiz Augusto von Dentz }
709ccf74f23SLuiz Augusto von Dentz 
710ccf74f23SLuiz Augusto von Dentz /* Kill socket (only if zapped and orphan)
711ccf74f23SLuiz Augusto von Dentz  * Must be called on unlocked socket.
712ccf74f23SLuiz Augusto von Dentz  */
iso_sock_kill(struct sock * sk)713ccf74f23SLuiz Augusto von Dentz static void iso_sock_kill(struct sock *sk)
714ccf74f23SLuiz Augusto von Dentz {
715ccf74f23SLuiz Augusto von Dentz 	if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket ||
716ccf74f23SLuiz Augusto von Dentz 	    sock_flag(sk, SOCK_DEAD))
717ccf74f23SLuiz Augusto von Dentz 		return;
718ccf74f23SLuiz Augusto von Dentz 
719ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p state %d", sk, sk->sk_state);
720ccf74f23SLuiz Augusto von Dentz 
721ccf74f23SLuiz Augusto von Dentz 	/* Kill poor orphan */
722ccf74f23SLuiz Augusto von Dentz 	bt_sock_unlink(&iso_sk_list, sk);
723ccf74f23SLuiz Augusto von Dentz 	sock_set_flag(sk, SOCK_DEAD);
724ccf74f23SLuiz Augusto von Dentz 	sock_put(sk);
725ccf74f23SLuiz Augusto von Dentz }
726ccf74f23SLuiz Augusto von Dentz 
iso_sock_disconn(struct sock * sk)727fbdc4bc4SIulia Tanasescu static void iso_sock_disconn(struct sock *sk)
728fbdc4bc4SIulia Tanasescu {
72911dc486eSIulia Tanasescu 	struct sock *bis_sk;
73011dc486eSIulia Tanasescu 	struct hci_conn *hcon = iso_pi(sk)->conn->hcon;
73111dc486eSIulia Tanasescu 
73211dc486eSIulia Tanasescu 	if (test_bit(HCI_CONN_BIG_CREATED, &hcon->flags)) {
73311dc486eSIulia Tanasescu 		bis_sk = iso_get_sock_big(sk, &iso_pi(sk)->src,
73411dc486eSIulia Tanasescu 					  &iso_pi(sk)->dst,
73511dc486eSIulia Tanasescu 					  iso_pi(sk)->qos.bcast.big);
73611dc486eSIulia Tanasescu 
73711dc486eSIulia Tanasescu 		/* If there are any other connected sockets for the
73811dc486eSIulia Tanasescu 		 * same BIG, just delete the sk and leave the bis
73911dc486eSIulia Tanasescu 		 * hcon active, in case later rebinding is needed.
74011dc486eSIulia Tanasescu 		 */
74111dc486eSIulia Tanasescu 		if (bis_sk) {
74211dc486eSIulia Tanasescu 			hcon->state = BT_OPEN;
74311dc486eSIulia Tanasescu 			iso_pi(sk)->conn->hcon = NULL;
74411dc486eSIulia Tanasescu 			iso_sock_clear_timer(sk);
74511dc486eSIulia Tanasescu 			iso_chan_del(sk, bt_to_errno(hcon->abort_reason));
74611dc486eSIulia Tanasescu 			sock_put(bis_sk);
74711dc486eSIulia Tanasescu 			return;
74811dc486eSIulia Tanasescu 		}
74911dc486eSIulia Tanasescu 	}
75011dc486eSIulia Tanasescu 
751fbdc4bc4SIulia Tanasescu 	sk->sk_state = BT_DISCONN;
752fbdc4bc4SIulia Tanasescu 	iso_sock_set_timer(sk, ISO_DISCONN_TIMEOUT);
753fbdc4bc4SIulia Tanasescu 	iso_conn_lock(iso_pi(sk)->conn);
754fbdc4bc4SIulia Tanasescu 	hci_conn_drop(iso_pi(sk)->conn->hcon);
755fbdc4bc4SIulia Tanasescu 	iso_pi(sk)->conn->hcon = NULL;
756fbdc4bc4SIulia Tanasescu 	iso_conn_unlock(iso_pi(sk)->conn);
757fbdc4bc4SIulia Tanasescu }
758fbdc4bc4SIulia Tanasescu 
__iso_sock_close(struct sock * sk)759ccf74f23SLuiz Augusto von Dentz static void __iso_sock_close(struct sock *sk)
760ccf74f23SLuiz Augusto von Dentz {
761ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
762ccf74f23SLuiz Augusto von Dentz 
763ccf74f23SLuiz Augusto von Dentz 	switch (sk->sk_state) {
764ccf74f23SLuiz Augusto von Dentz 	case BT_LISTEN:
765ccf74f23SLuiz Augusto von Dentz 		iso_sock_cleanup_listen(sk);
766ccf74f23SLuiz Augusto von Dentz 		break;
767ccf74f23SLuiz Augusto von Dentz 
76869997d50SPauli Virtanen 	case BT_CONNECT:
769ccf74f23SLuiz Augusto von Dentz 	case BT_CONNECTED:
770ccf74f23SLuiz Augusto von Dentz 	case BT_CONFIG:
771fbdc4bc4SIulia Tanasescu 		if (iso_pi(sk)->conn->hcon)
772fbdc4bc4SIulia Tanasescu 			iso_sock_disconn(sk);
773fbdc4bc4SIulia Tanasescu 		else
774ccf74f23SLuiz Augusto von Dentz 			iso_chan_del(sk, ECONNRESET);
775ccf74f23SLuiz Augusto von Dentz 		break;
776ccf74f23SLuiz Augusto von Dentz 
777ccf74f23SLuiz Augusto von Dentz 	case BT_CONNECT2:
778fbdc4bc4SIulia Tanasescu 		if (iso_pi(sk)->conn->hcon &&
779fbdc4bc4SIulia Tanasescu 		    (test_bit(HCI_CONN_PA_SYNC, &iso_pi(sk)->conn->hcon->flags) ||
780fbdc4bc4SIulia Tanasescu 		    test_bit(HCI_CONN_PA_SYNC_FAILED, &iso_pi(sk)->conn->hcon->flags)))
781fbdc4bc4SIulia Tanasescu 			iso_sock_disconn(sk);
782fbdc4bc4SIulia Tanasescu 		else
783ccf74f23SLuiz Augusto von Dentz 			iso_chan_del(sk, ECONNRESET);
784ccf74f23SLuiz Augusto von Dentz 		break;
785ccf74f23SLuiz Augusto von Dentz 	case BT_DISCONN:
786ccf74f23SLuiz Augusto von Dentz 		iso_chan_del(sk, ECONNRESET);
787ccf74f23SLuiz Augusto von Dentz 		break;
788ccf74f23SLuiz Augusto von Dentz 
789ccf74f23SLuiz Augusto von Dentz 	default:
790ccf74f23SLuiz Augusto von Dentz 		sock_set_flag(sk, SOCK_ZAPPED);
791ccf74f23SLuiz Augusto von Dentz 		break;
792ccf74f23SLuiz Augusto von Dentz 	}
793ccf74f23SLuiz Augusto von Dentz }
794ccf74f23SLuiz Augusto von Dentz 
795ccf74f23SLuiz Augusto von Dentz /* Must be called on unlocked socket. */
iso_sock_close(struct sock * sk)796ccf74f23SLuiz Augusto von Dentz static void iso_sock_close(struct sock *sk)
797ccf74f23SLuiz Augusto von Dentz {
798ccf74f23SLuiz Augusto von Dentz 	iso_sock_clear_timer(sk);
799ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
800ccf74f23SLuiz Augusto von Dentz 	__iso_sock_close(sk);
801ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
802ccf74f23SLuiz Augusto von Dentz 	iso_sock_kill(sk);
803ccf74f23SLuiz Augusto von Dentz }
804ccf74f23SLuiz Augusto von Dentz 
iso_sock_init(struct sock * sk,struct sock * parent)805ccf74f23SLuiz Augusto von Dentz static void iso_sock_init(struct sock *sk, struct sock *parent)
806ccf74f23SLuiz Augusto von Dentz {
807ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
808ccf74f23SLuiz Augusto von Dentz 
809ccf74f23SLuiz Augusto von Dentz 	if (parent) {
810ccf74f23SLuiz Augusto von Dentz 		sk->sk_type = parent->sk_type;
811ccf74f23SLuiz Augusto von Dentz 		bt_sk(sk)->flags = bt_sk(parent)->flags;
812ccf74f23SLuiz Augusto von Dentz 		security_sk_clone(parent, sk);
813ccf74f23SLuiz Augusto von Dentz 	}
814ccf74f23SLuiz Augusto von Dentz }
815ccf74f23SLuiz Augusto von Dentz 
816ccf74f23SLuiz Augusto von Dentz static struct proto iso_proto = {
817ccf74f23SLuiz Augusto von Dentz 	.name		= "ISO",
818ccf74f23SLuiz Augusto von Dentz 	.owner		= THIS_MODULE,
819ccf74f23SLuiz Augusto von Dentz 	.obj_size	= sizeof(struct iso_pinfo)
820ccf74f23SLuiz Augusto von Dentz };
821ccf74f23SLuiz Augusto von Dentz 
822ccf74f23SLuiz Augusto von Dentz #define DEFAULT_IO_QOS \
823ccf74f23SLuiz Augusto von Dentz { \
824ccf74f23SLuiz Augusto von Dentz 	.interval	= 10000u, \
825ccf74f23SLuiz Augusto von Dentz 	.latency	= 10u, \
826ccf74f23SLuiz Augusto von Dentz 	.sdu		= 40u, \
827ccf74f23SLuiz Augusto von Dentz 	.phy		= BT_ISO_PHY_2M, \
828ccf74f23SLuiz Augusto von Dentz 	.rtn		= 2u, \
829ccf74f23SLuiz Augusto von Dentz }
830ccf74f23SLuiz Augusto von Dentz 
831ccf74f23SLuiz Augusto von Dentz static struct bt_iso_qos default_qos = {
8320fe8c8d0SIulia Tanasescu 	.bcast = {
8330fe8c8d0SIulia Tanasescu 		.big			= BT_ISO_QOS_BIG_UNSET,
8340fe8c8d0SIulia Tanasescu 		.bis			= BT_ISO_QOS_BIS_UNSET,
83514f0dcecSLuiz Augusto von Dentz 		.sync_factor		= 0x01,
836ccf74f23SLuiz Augusto von Dentz 		.packing		= 0x00,
837ccf74f23SLuiz Augusto von Dentz 		.framing		= 0x00,
838ccf74f23SLuiz Augusto von Dentz 		.in			= DEFAULT_IO_QOS,
839ccf74f23SLuiz Augusto von Dentz 		.out			= DEFAULT_IO_QOS,
8400fe8c8d0SIulia Tanasescu 		.encryption		= 0x00,
8410fe8c8d0SIulia Tanasescu 		.bcode			= {0x00},
8420fe8c8d0SIulia Tanasescu 		.options		= 0x00,
8430fe8c8d0SIulia Tanasescu 		.skip			= 0x0000,
844c8321645SLuiz Augusto von Dentz 		.sync_timeout		= BT_ISO_SYNC_TIMEOUT,
8450fe8c8d0SIulia Tanasescu 		.sync_cte_type		= 0x00,
8460fe8c8d0SIulia Tanasescu 		.mse			= 0x00,
847c8321645SLuiz Augusto von Dentz 		.timeout		= BT_ISO_SYNC_TIMEOUT,
8480fe8c8d0SIulia Tanasescu 	},
849ccf74f23SLuiz Augusto von Dentz };
850ccf74f23SLuiz Augusto von Dentz 
iso_sock_alloc(struct net * net,struct socket * sock,int proto,gfp_t prio,int kern)851ccf74f23SLuiz Augusto von Dentz static struct sock *iso_sock_alloc(struct net *net, struct socket *sock,
852ccf74f23SLuiz Augusto von Dentz 				   int proto, gfp_t prio, int kern)
853ccf74f23SLuiz Augusto von Dentz {
854ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
855ccf74f23SLuiz Augusto von Dentz 
8566bfa273eSLuiz Augusto von Dentz 	sk = bt_sock_alloc(net, sock, &iso_proto, proto, prio, kern);
857ccf74f23SLuiz Augusto von Dentz 	if (!sk)
858ccf74f23SLuiz Augusto von Dentz 		return NULL;
859ccf74f23SLuiz Augusto von Dentz 
860ccf74f23SLuiz Augusto von Dentz 	sk->sk_destruct = iso_sock_destruct;
861ccf74f23SLuiz Augusto von Dentz 	sk->sk_sndtimeo = ISO_CONN_TIMEOUT;
862ccf74f23SLuiz Augusto von Dentz 
863ccf74f23SLuiz Augusto von Dentz 	/* Set address type as public as default src address is BDADDR_ANY */
864ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
865ccf74f23SLuiz Augusto von Dentz 
866ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->qos = default_qos;
867ccf74f23SLuiz Augusto von Dentz 
868ccf74f23SLuiz Augusto von Dentz 	bt_sock_link(&iso_sk_list, sk);
869ccf74f23SLuiz Augusto von Dentz 	return sk;
870ccf74f23SLuiz Augusto von Dentz }
871ccf74f23SLuiz Augusto von Dentz 
iso_sock_create(struct net * net,struct socket * sock,int protocol,int kern)872ccf74f23SLuiz Augusto von Dentz static int iso_sock_create(struct net *net, struct socket *sock, int protocol,
873ccf74f23SLuiz Augusto von Dentz 			   int kern)
874ccf74f23SLuiz Augusto von Dentz {
875ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
876ccf74f23SLuiz Augusto von Dentz 
877ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p", sock);
878ccf74f23SLuiz Augusto von Dentz 
879ccf74f23SLuiz Augusto von Dentz 	sock->state = SS_UNCONNECTED;
880ccf74f23SLuiz Augusto von Dentz 
881ccf74f23SLuiz Augusto von Dentz 	if (sock->type != SOCK_SEQPACKET)
882ccf74f23SLuiz Augusto von Dentz 		return -ESOCKTNOSUPPORT;
883ccf74f23SLuiz Augusto von Dentz 
884ccf74f23SLuiz Augusto von Dentz 	sock->ops = &iso_sock_ops;
885ccf74f23SLuiz Augusto von Dentz 
886ccf74f23SLuiz Augusto von Dentz 	sk = iso_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
887ccf74f23SLuiz Augusto von Dentz 	if (!sk)
888ccf74f23SLuiz Augusto von Dentz 		return -ENOMEM;
889ccf74f23SLuiz Augusto von Dentz 
890ccf74f23SLuiz Augusto von Dentz 	iso_sock_init(sk, NULL);
891ccf74f23SLuiz Augusto von Dentz 	return 0;
892ccf74f23SLuiz Augusto von Dentz }
893ccf74f23SLuiz Augusto von Dentz 
iso_sock_bind_bc(struct socket * sock,struct sockaddr * addr,int addr_len)894f764a6c2SLuiz Augusto von Dentz static int iso_sock_bind_bc(struct socket *sock, struct sockaddr *addr,
895f764a6c2SLuiz Augusto von Dentz 			    int addr_len)
896f764a6c2SLuiz Augusto von Dentz {
897f764a6c2SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
898f764a6c2SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
899f764a6c2SLuiz Augusto von Dentz 	int i;
900f764a6c2SLuiz Augusto von Dentz 
901f764a6c2SLuiz Augusto von Dentz 	BT_DBG("sk %p bc_sid %u bc_num_bis %u", sk, sa->iso_bc->bc_sid,
902f764a6c2SLuiz Augusto von Dentz 	       sa->iso_bc->bc_num_bis);
903f764a6c2SLuiz Augusto von Dentz 
904f764a6c2SLuiz Augusto von Dentz 	if (addr_len > sizeof(*sa) + sizeof(*sa->iso_bc) ||
905f764a6c2SLuiz Augusto von Dentz 	    sa->iso_bc->bc_num_bis < 0x01 || sa->iso_bc->bc_num_bis > 0x1f)
906f764a6c2SLuiz Augusto von Dentz 		return -EINVAL;
907f764a6c2SLuiz Augusto von Dentz 
908f764a6c2SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->dst, &sa->iso_bc->bc_bdaddr);
909f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->dst_type = sa->iso_bc->bc_bdaddr_type;
910f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->sync_handle = -1;
911f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->bc_sid = sa->iso_bc->bc_sid;
912f764a6c2SLuiz Augusto von Dentz 	iso_pi(sk)->bc_num_bis = sa->iso_bc->bc_num_bis;
913f764a6c2SLuiz Augusto von Dentz 
914f764a6c2SLuiz Augusto von Dentz 	for (i = 0; i < iso_pi(sk)->bc_num_bis; i++) {
915f764a6c2SLuiz Augusto von Dentz 		if (sa->iso_bc->bc_bis[i] < 0x01 ||
916f764a6c2SLuiz Augusto von Dentz 		    sa->iso_bc->bc_bis[i] > 0x1f)
917f764a6c2SLuiz Augusto von Dentz 			return -EINVAL;
918f764a6c2SLuiz Augusto von Dentz 
919f764a6c2SLuiz Augusto von Dentz 		memcpy(iso_pi(sk)->bc_bis, sa->iso_bc->bc_bis,
920f764a6c2SLuiz Augusto von Dentz 		       iso_pi(sk)->bc_num_bis);
921f764a6c2SLuiz Augusto von Dentz 	}
922f764a6c2SLuiz Augusto von Dentz 
923f764a6c2SLuiz Augusto von Dentz 	return 0;
924f764a6c2SLuiz Augusto von Dentz }
925f764a6c2SLuiz Augusto von Dentz 
iso_sock_bind(struct socket * sock,struct sockaddr * addr,int addr_len)926ccf74f23SLuiz Augusto von Dentz static int iso_sock_bind(struct socket *sock, struct sockaddr *addr,
927ccf74f23SLuiz Augusto von Dentz 			 int addr_len)
928ccf74f23SLuiz Augusto von Dentz {
929ccf74f23SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
930ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
931ccf74f23SLuiz Augusto von Dentz 	int err = 0;
932ccf74f23SLuiz Augusto von Dentz 
933ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p %pMR type %u", sk, &sa->iso_bdaddr, sa->iso_bdaddr_type);
934ccf74f23SLuiz Augusto von Dentz 
935ccf74f23SLuiz Augusto von Dentz 	if (!addr || addr_len < sizeof(struct sockaddr_iso) ||
936ccf74f23SLuiz Augusto von Dentz 	    addr->sa_family != AF_BLUETOOTH)
937ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
938ccf74f23SLuiz Augusto von Dentz 
939ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
940ccf74f23SLuiz Augusto von Dentz 
941ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_OPEN) {
942ccf74f23SLuiz Augusto von Dentz 		err = -EBADFD;
943ccf74f23SLuiz Augusto von Dentz 		goto done;
944ccf74f23SLuiz Augusto von Dentz 	}
945ccf74f23SLuiz Augusto von Dentz 
946ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_type != SOCK_SEQPACKET) {
947ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
948ccf74f23SLuiz Augusto von Dentz 		goto done;
949ccf74f23SLuiz Augusto von Dentz 	}
950ccf74f23SLuiz Augusto von Dentz 
951ccf74f23SLuiz Augusto von Dentz 	/* Check if the address type is of LE type */
952ccf74f23SLuiz Augusto von Dentz 	if (!bdaddr_type_is_le(sa->iso_bdaddr_type)) {
953ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
954ccf74f23SLuiz Augusto von Dentz 		goto done;
955ccf74f23SLuiz Augusto von Dentz 	}
956ccf74f23SLuiz Augusto von Dentz 
957ccf74f23SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->src, &sa->iso_bdaddr);
958ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->src_type = sa->iso_bdaddr_type;
959ccf74f23SLuiz Augusto von Dentz 
960f764a6c2SLuiz Augusto von Dentz 	/* Check for Broadcast address */
961f764a6c2SLuiz Augusto von Dentz 	if (addr_len > sizeof(*sa)) {
962f764a6c2SLuiz Augusto von Dentz 		err = iso_sock_bind_bc(sock, addr, addr_len);
963f764a6c2SLuiz Augusto von Dentz 		if (err)
964f764a6c2SLuiz Augusto von Dentz 			goto done;
965f764a6c2SLuiz Augusto von Dentz 	}
966f764a6c2SLuiz Augusto von Dentz 
967ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_BOUND;
968ccf74f23SLuiz Augusto von Dentz 
969ccf74f23SLuiz Augusto von Dentz done:
970ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
971ccf74f23SLuiz Augusto von Dentz 	return err;
972ccf74f23SLuiz Augusto von Dentz }
973ccf74f23SLuiz Augusto von Dentz 
iso_sock_connect(struct socket * sock,struct sockaddr * addr,int alen,int flags)974ccf74f23SLuiz Augusto von Dentz static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
975ccf74f23SLuiz Augusto von Dentz 			    int alen, int flags)
976ccf74f23SLuiz Augusto von Dentz {
977ccf74f23SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
978ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
979ccf74f23SLuiz Augusto von Dentz 	int err;
980ccf74f23SLuiz Augusto von Dentz 
981ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
982ccf74f23SLuiz Augusto von Dentz 
983ccf74f23SLuiz Augusto von Dentz 	if (alen < sizeof(struct sockaddr_iso) ||
984ccf74f23SLuiz Augusto von Dentz 	    addr->sa_family != AF_BLUETOOTH)
985ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
986ccf74f23SLuiz Augusto von Dentz 
987ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
988ccf74f23SLuiz Augusto von Dentz 		return -EBADFD;
989ccf74f23SLuiz Augusto von Dentz 
990ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_type != SOCK_SEQPACKET)
991ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
992ccf74f23SLuiz Augusto von Dentz 
993ccf74f23SLuiz Augusto von Dentz 	/* Check if the address type is of LE type */
994ccf74f23SLuiz Augusto von Dentz 	if (!bdaddr_type_is_le(sa->iso_bdaddr_type))
995ccf74f23SLuiz Augusto von Dentz 		return -EINVAL;
996ccf74f23SLuiz Augusto von Dentz 
997ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
998ccf74f23SLuiz Augusto von Dentz 
999ccf74f23SLuiz Augusto von Dentz 	bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
1000ccf74f23SLuiz Augusto von Dentz 	iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
1001ccf74f23SLuiz Augusto von Dentz 
1002241f5193SLuiz Augusto von Dentz 	release_sock(sk);
1003241f5193SLuiz Augusto von Dentz 
1004f764a6c2SLuiz Augusto von Dentz 	if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
1005f764a6c2SLuiz Augusto von Dentz 		err = iso_connect_cis(sk);
1006f764a6c2SLuiz Augusto von Dentz 	else
1007f764a6c2SLuiz Augusto von Dentz 		err = iso_connect_bis(sk);
1008f764a6c2SLuiz Augusto von Dentz 
1009ccf74f23SLuiz Augusto von Dentz 	if (err)
1010241f5193SLuiz Augusto von Dentz 		return err;
1011241f5193SLuiz Augusto von Dentz 
1012241f5193SLuiz Augusto von Dentz 	lock_sock(sk);
1013ccf74f23SLuiz Augusto von Dentz 
1014ccf74f23SLuiz Augusto von Dentz 	if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
1015ccf74f23SLuiz Augusto von Dentz 		err = bt_sock_wait_state(sk, BT_CONNECTED,
1016ccf74f23SLuiz Augusto von Dentz 					 sock_sndtimeo(sk, flags & O_NONBLOCK));
1017ccf74f23SLuiz Augusto von Dentz 	}
1018ccf74f23SLuiz Augusto von Dentz 
1019ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1020ccf74f23SLuiz Augusto von Dentz 	return err;
1021ccf74f23SLuiz Augusto von Dentz }
1022ccf74f23SLuiz Augusto von Dentz 
iso_listen_bis(struct sock * sk)1023f764a6c2SLuiz Augusto von Dentz static int iso_listen_bis(struct sock *sk)
1024f764a6c2SLuiz Augusto von Dentz {
1025f764a6c2SLuiz Augusto von Dentz 	struct hci_dev *hdev;
1026f764a6c2SLuiz Augusto von Dentz 	int err = 0;
1027f764a6c2SLuiz Augusto von Dentz 
1028f764a6c2SLuiz Augusto von Dentz 	BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
1029f764a6c2SLuiz Augusto von Dentz 	       &iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
1030f764a6c2SLuiz Augusto von Dentz 
1031f764a6c2SLuiz Augusto von Dentz 	write_lock(&iso_sk_list.lock);
1032f764a6c2SLuiz Augusto von Dentz 
1033f764a6c2SLuiz Augusto von Dentz 	if (__iso_get_sock_listen_by_sid(&iso_pi(sk)->src, &iso_pi(sk)->dst,
1034f764a6c2SLuiz Augusto von Dentz 					 iso_pi(sk)->bc_sid))
1035f764a6c2SLuiz Augusto von Dentz 		err = -EADDRINUSE;
1036f764a6c2SLuiz Augusto von Dentz 
1037f764a6c2SLuiz Augusto von Dentz 	write_unlock(&iso_sk_list.lock);
1038f764a6c2SLuiz Augusto von Dentz 
1039f764a6c2SLuiz Augusto von Dentz 	if (err)
1040f764a6c2SLuiz Augusto von Dentz 		return err;
1041f764a6c2SLuiz Augusto von Dentz 
1042f764a6c2SLuiz Augusto von Dentz 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
1043f764a6c2SLuiz Augusto von Dentz 			     iso_pi(sk)->src_type);
1044f764a6c2SLuiz Augusto von Dentz 	if (!hdev)
1045f764a6c2SLuiz Augusto von Dentz 		return -EHOSTUNREACH;
1046f764a6c2SLuiz Augusto von Dentz 
10470fe8c8d0SIulia Tanasescu 	/* Fail if user set invalid QoS */
10480fe8c8d0SIulia Tanasescu 	if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
10490fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos = default_qos;
10500fe8c8d0SIulia Tanasescu 		return -EINVAL;
10510fe8c8d0SIulia Tanasescu 	}
10520fe8c8d0SIulia Tanasescu 
1053d11ab690SPauli Virtanen 	err = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
1054d11ab690SPauli Virtanen 				 le_addr_type(iso_pi(sk)->dst_type),
10550fe8c8d0SIulia Tanasescu 				 iso_pi(sk)->bc_sid, &iso_pi(sk)->qos);
1056f764a6c2SLuiz Augusto von Dentz 
10577e7df2c1SWang ShaoBo 	hci_dev_put(hdev);
1058f764a6c2SLuiz Augusto von Dentz 
1059f764a6c2SLuiz Augusto von Dentz 	return err;
1060f764a6c2SLuiz Augusto von Dentz }
1061f764a6c2SLuiz Augusto von Dentz 
iso_listen_cis(struct sock * sk)1062f764a6c2SLuiz Augusto von Dentz static int iso_listen_cis(struct sock *sk)
1063f764a6c2SLuiz Augusto von Dentz {
1064f764a6c2SLuiz Augusto von Dentz 	int err = 0;
1065f764a6c2SLuiz Augusto von Dentz 
1066f764a6c2SLuiz Augusto von Dentz 	BT_DBG("%pMR", &iso_pi(sk)->src);
1067f764a6c2SLuiz Augusto von Dentz 
1068f764a6c2SLuiz Augusto von Dentz 	write_lock(&iso_sk_list.lock);
1069f764a6c2SLuiz Augusto von Dentz 
1070e0275ea5SLuiz Augusto von Dentz 	if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst))
1071f764a6c2SLuiz Augusto von Dentz 		err = -EADDRINUSE;
1072f764a6c2SLuiz Augusto von Dentz 
1073f764a6c2SLuiz Augusto von Dentz 	write_unlock(&iso_sk_list.lock);
1074f764a6c2SLuiz Augusto von Dentz 
1075f764a6c2SLuiz Augusto von Dentz 	return err;
1076f764a6c2SLuiz Augusto von Dentz }
1077f764a6c2SLuiz Augusto von Dentz 
iso_sock_listen(struct socket * sock,int backlog)1078ccf74f23SLuiz Augusto von Dentz static int iso_sock_listen(struct socket *sock, int backlog)
1079ccf74f23SLuiz Augusto von Dentz {
1080ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1081ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1082ccf74f23SLuiz Augusto von Dentz 
1083ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p backlog %d", sk, backlog);
1084ccf74f23SLuiz Augusto von Dentz 
1085ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1086ccf74f23SLuiz Augusto von Dentz 
1087ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state != BT_BOUND) {
1088ccf74f23SLuiz Augusto von Dentz 		err = -EBADFD;
1089ccf74f23SLuiz Augusto von Dentz 		goto done;
1090ccf74f23SLuiz Augusto von Dentz 	}
1091ccf74f23SLuiz Augusto von Dentz 
1092ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_type != SOCK_SEQPACKET) {
1093ccf74f23SLuiz Augusto von Dentz 		err = -EINVAL;
1094ccf74f23SLuiz Augusto von Dentz 		goto done;
1095ccf74f23SLuiz Augusto von Dentz 	}
1096ccf74f23SLuiz Augusto von Dentz 
1097f764a6c2SLuiz Augusto von Dentz 	if (!bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
1098f764a6c2SLuiz Augusto von Dentz 		err = iso_listen_cis(sk);
1099f764a6c2SLuiz Augusto von Dentz 	else
1100f764a6c2SLuiz Augusto von Dentz 		err = iso_listen_bis(sk);
1101ccf74f23SLuiz Augusto von Dentz 
1102f764a6c2SLuiz Augusto von Dentz 	if (err)
1103f764a6c2SLuiz Augusto von Dentz 		goto done;
1104ccf74f23SLuiz Augusto von Dentz 
1105ccf74f23SLuiz Augusto von Dentz 	sk->sk_max_ack_backlog = backlog;
1106ccf74f23SLuiz Augusto von Dentz 	sk->sk_ack_backlog = 0;
1107ccf74f23SLuiz Augusto von Dentz 
1108ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_LISTEN;
1109ccf74f23SLuiz Augusto von Dentz 
1110ccf74f23SLuiz Augusto von Dentz done:
1111ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1112ccf74f23SLuiz Augusto von Dentz 	return err;
1113ccf74f23SLuiz Augusto von Dentz }
1114ccf74f23SLuiz Augusto von Dentz 
iso_sock_accept(struct socket * sock,struct socket * newsock,int flags,bool kern)1115ccf74f23SLuiz Augusto von Dentz static int iso_sock_accept(struct socket *sock, struct socket *newsock,
1116ccf74f23SLuiz Augusto von Dentz 			   int flags, bool kern)
1117ccf74f23SLuiz Augusto von Dentz {
1118ccf74f23SLuiz Augusto von Dentz 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
1119ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk, *ch;
1120ccf74f23SLuiz Augusto von Dentz 	long timeo;
1121ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1122ccf74f23SLuiz Augusto von Dentz 
1123*263b390aSIulia Tanasescu 	/* Use explicit nested locking to avoid lockdep warnings generated
1124*263b390aSIulia Tanasescu 	 * because the parent socket and the child socket are locked on the
1125*263b390aSIulia Tanasescu 	 * same thread.
1126*263b390aSIulia Tanasescu 	 */
1127*263b390aSIulia Tanasescu 	lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
1128ccf74f23SLuiz Augusto von Dentz 
1129ccf74f23SLuiz Augusto von Dentz 	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1130ccf74f23SLuiz Augusto von Dentz 
1131ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p timeo %ld", sk, timeo);
1132ccf74f23SLuiz Augusto von Dentz 
1133ccf74f23SLuiz Augusto von Dentz 	/* Wait for an incoming connection. (wake-one). */
1134ccf74f23SLuiz Augusto von Dentz 	add_wait_queue_exclusive(sk_sleep(sk), &wait);
1135ccf74f23SLuiz Augusto von Dentz 	while (1) {
1136ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_LISTEN) {
1137ccf74f23SLuiz Augusto von Dentz 			err = -EBADFD;
1138ccf74f23SLuiz Augusto von Dentz 			break;
1139ccf74f23SLuiz Augusto von Dentz 		}
1140ccf74f23SLuiz Augusto von Dentz 
1141ccf74f23SLuiz Augusto von Dentz 		ch = bt_accept_dequeue(sk, newsock);
1142ccf74f23SLuiz Augusto von Dentz 		if (ch)
1143ccf74f23SLuiz Augusto von Dentz 			break;
1144ccf74f23SLuiz Augusto von Dentz 
1145ccf74f23SLuiz Augusto von Dentz 		if (!timeo) {
1146ccf74f23SLuiz Augusto von Dentz 			err = -EAGAIN;
1147ccf74f23SLuiz Augusto von Dentz 			break;
1148ccf74f23SLuiz Augusto von Dentz 		}
1149ccf74f23SLuiz Augusto von Dentz 
1150ccf74f23SLuiz Augusto von Dentz 		if (signal_pending(current)) {
1151ccf74f23SLuiz Augusto von Dentz 			err = sock_intr_errno(timeo);
1152ccf74f23SLuiz Augusto von Dentz 			break;
1153ccf74f23SLuiz Augusto von Dentz 		}
1154ccf74f23SLuiz Augusto von Dentz 
1155ccf74f23SLuiz Augusto von Dentz 		release_sock(sk);
1156ccf74f23SLuiz Augusto von Dentz 
1157ccf74f23SLuiz Augusto von Dentz 		timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
1158*263b390aSIulia Tanasescu 		lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
1159ccf74f23SLuiz Augusto von Dentz 	}
1160ccf74f23SLuiz Augusto von Dentz 	remove_wait_queue(sk_sleep(sk), &wait);
1161ccf74f23SLuiz Augusto von Dentz 
1162ccf74f23SLuiz Augusto von Dentz 	if (err)
1163ccf74f23SLuiz Augusto von Dentz 		goto done;
1164ccf74f23SLuiz Augusto von Dentz 
1165ccf74f23SLuiz Augusto von Dentz 	newsock->state = SS_CONNECTED;
1166ccf74f23SLuiz Augusto von Dentz 
1167ccf74f23SLuiz Augusto von Dentz 	BT_DBG("new socket %p", ch);
1168ccf74f23SLuiz Augusto von Dentz 
1169ccf74f23SLuiz Augusto von Dentz done:
1170ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1171ccf74f23SLuiz Augusto von Dentz 	return err;
1172ccf74f23SLuiz Augusto von Dentz }
1173ccf74f23SLuiz Augusto von Dentz 
iso_sock_getname(struct socket * sock,struct sockaddr * addr,int peer)1174ccf74f23SLuiz Augusto von Dentz static int iso_sock_getname(struct socket *sock, struct sockaddr *addr,
1175ccf74f23SLuiz Augusto von Dentz 			    int peer)
1176ccf74f23SLuiz Augusto von Dentz {
1177ccf74f23SLuiz Augusto von Dentz 	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
1178ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1179ccf74f23SLuiz Augusto von Dentz 
1180ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p", sock, sk);
1181ccf74f23SLuiz Augusto von Dentz 
1182ccf74f23SLuiz Augusto von Dentz 	addr->sa_family = AF_BLUETOOTH;
1183ccf74f23SLuiz Augusto von Dentz 
1184ccf74f23SLuiz Augusto von Dentz 	if (peer) {
1185ccf74f23SLuiz Augusto von Dentz 		bacpy(&sa->iso_bdaddr, &iso_pi(sk)->dst);
1186ccf74f23SLuiz Augusto von Dentz 		sa->iso_bdaddr_type = iso_pi(sk)->dst_type;
1187ccf74f23SLuiz Augusto von Dentz 	} else {
1188ccf74f23SLuiz Augusto von Dentz 		bacpy(&sa->iso_bdaddr, &iso_pi(sk)->src);
1189ccf74f23SLuiz Augusto von Dentz 		sa->iso_bdaddr_type = iso_pi(sk)->src_type;
1190ccf74f23SLuiz Augusto von Dentz 	}
1191ccf74f23SLuiz Augusto von Dentz 
1192ccf74f23SLuiz Augusto von Dentz 	return sizeof(struct sockaddr_iso);
1193ccf74f23SLuiz Augusto von Dentz }
1194ccf74f23SLuiz Augusto von Dentz 
iso_sock_sendmsg(struct socket * sock,struct msghdr * msg,size_t len)1195ccf74f23SLuiz Augusto von Dentz static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg,
1196ccf74f23SLuiz Augusto von Dentz 			    size_t len)
1197ccf74f23SLuiz Augusto von Dentz {
1198ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1199ccf74f23SLuiz Augusto von Dentz 	struct sk_buff *skb, **frag;
1200d40ae85eSPauli Virtanen 	size_t mtu;
1201ccf74f23SLuiz Augusto von Dentz 	int err;
1202ccf74f23SLuiz Augusto von Dentz 
1203ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p", sock, sk);
1204ccf74f23SLuiz Augusto von Dentz 
1205ccf74f23SLuiz Augusto von Dentz 	err = sock_error(sk);
1206ccf74f23SLuiz Augusto von Dentz 	if (err)
1207ccf74f23SLuiz Augusto von Dentz 		return err;
1208ccf74f23SLuiz Augusto von Dentz 
1209ccf74f23SLuiz Augusto von Dentz 	if (msg->msg_flags & MSG_OOB)
1210ccf74f23SLuiz Augusto von Dentz 		return -EOPNOTSUPP;
1211ccf74f23SLuiz Augusto von Dentz 
1212d40ae85eSPauli Virtanen 	lock_sock(sk);
1213ccf74f23SLuiz Augusto von Dentz 
1214d40ae85eSPauli Virtanen 	if (sk->sk_state != BT_CONNECTED) {
1215d40ae85eSPauli Virtanen 		release_sock(sk);
1216d40ae85eSPauli Virtanen 		return -ENOTCONN;
1217d40ae85eSPauli Virtanen 	}
1218d40ae85eSPauli Virtanen 
1219ad3f7986SSungwoo Kim 	mtu = iso_pi(sk)->conn->hcon->mtu;
1220d40ae85eSPauli Virtanen 
1221d40ae85eSPauli Virtanen 	release_sock(sk);
1222d40ae85eSPauli Virtanen 
1223d40ae85eSPauli Virtanen 	skb = bt_skb_sendmsg(sk, msg, len, mtu, HCI_ISO_DATA_HDR_SIZE, 0);
1224ccf74f23SLuiz Augusto von Dentz 	if (IS_ERR(skb))
1225ccf74f23SLuiz Augusto von Dentz 		return PTR_ERR(skb);
1226ccf74f23SLuiz Augusto von Dentz 
1227ccf74f23SLuiz Augusto von Dentz 	len -= skb->len;
1228ccf74f23SLuiz Augusto von Dentz 
1229ccf74f23SLuiz Augusto von Dentz 	BT_DBG("skb %p len %d", sk, skb->len);
1230ccf74f23SLuiz Augusto von Dentz 
1231ccf74f23SLuiz Augusto von Dentz 	/* Continuation fragments */
1232ccf74f23SLuiz Augusto von Dentz 	frag = &skb_shinfo(skb)->frag_list;
1233ccf74f23SLuiz Augusto von Dentz 	while (len) {
1234ccf74f23SLuiz Augusto von Dentz 		struct sk_buff *tmp;
1235ccf74f23SLuiz Augusto von Dentz 
1236d40ae85eSPauli Virtanen 		tmp = bt_skb_sendmsg(sk, msg, len, mtu, 0, 0);
1237ccf74f23SLuiz Augusto von Dentz 		if (IS_ERR(tmp)) {
1238ccf74f23SLuiz Augusto von Dentz 			kfree_skb(skb);
1239ccf74f23SLuiz Augusto von Dentz 			return PTR_ERR(tmp);
1240ccf74f23SLuiz Augusto von Dentz 		}
1241ccf74f23SLuiz Augusto von Dentz 
1242ccf74f23SLuiz Augusto von Dentz 		*frag = tmp;
1243ccf74f23SLuiz Augusto von Dentz 
1244ccf74f23SLuiz Augusto von Dentz 		len  -= tmp->len;
1245ccf74f23SLuiz Augusto von Dentz 
1246ccf74f23SLuiz Augusto von Dentz 		skb->len += tmp->len;
1247ccf74f23SLuiz Augusto von Dentz 		skb->data_len += tmp->len;
1248ccf74f23SLuiz Augusto von Dentz 
1249ccf74f23SLuiz Augusto von Dentz 		BT_DBG("frag %p len %d", *frag, tmp->len);
1250ccf74f23SLuiz Augusto von Dentz 
1251ccf74f23SLuiz Augusto von Dentz 		frag = &(*frag)->next;
1252ccf74f23SLuiz Augusto von Dentz 	}
1253ccf74f23SLuiz Augusto von Dentz 
1254ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1255ccf74f23SLuiz Augusto von Dentz 
1256ccf74f23SLuiz Augusto von Dentz 	if (sk->sk_state == BT_CONNECTED)
1257ccf74f23SLuiz Augusto von Dentz 		err = iso_send_frame(sk, skb);
1258ccf74f23SLuiz Augusto von Dentz 	else
1259ccf74f23SLuiz Augusto von Dentz 		err = -ENOTCONN;
1260ccf74f23SLuiz Augusto von Dentz 
1261ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1262ccf74f23SLuiz Augusto von Dentz 
1263ccf74f23SLuiz Augusto von Dentz 	if (err < 0)
1264ccf74f23SLuiz Augusto von Dentz 		kfree_skb(skb);
1265ccf74f23SLuiz Augusto von Dentz 	return err;
1266ccf74f23SLuiz Augusto von Dentz }
1267ccf74f23SLuiz Augusto von Dentz 
iso_conn_defer_accept(struct hci_conn * conn)1268ccf74f23SLuiz Augusto von Dentz static void iso_conn_defer_accept(struct hci_conn *conn)
1269ccf74f23SLuiz Augusto von Dentz {
1270ccf74f23SLuiz Augusto von Dentz 	struct hci_cp_le_accept_cis cp;
1271ccf74f23SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
1272ccf74f23SLuiz Augusto von Dentz 
1273ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p", conn);
1274ccf74f23SLuiz Augusto von Dentz 
1275ccf74f23SLuiz Augusto von Dentz 	conn->state = BT_CONFIG;
1276ccf74f23SLuiz Augusto von Dentz 
1277ccf74f23SLuiz Augusto von Dentz 	cp.handle = cpu_to_le16(conn->handle);
1278ccf74f23SLuiz Augusto von Dentz 
1279ccf74f23SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
1280ccf74f23SLuiz Augusto von Dentz }
1281ccf74f23SLuiz Augusto von Dentz 
iso_conn_big_sync(struct sock * sk)1282fbdc4bc4SIulia Tanasescu static void iso_conn_big_sync(struct sock *sk)
1283fbdc4bc4SIulia Tanasescu {
1284fbdc4bc4SIulia Tanasescu 	int err;
1285fbdc4bc4SIulia Tanasescu 	struct hci_dev *hdev;
1286fbdc4bc4SIulia Tanasescu 
1287fbdc4bc4SIulia Tanasescu 	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
1288fbdc4bc4SIulia Tanasescu 			     iso_pi(sk)->src_type);
1289fbdc4bc4SIulia Tanasescu 
1290fbdc4bc4SIulia Tanasescu 	if (!hdev)
1291fbdc4bc4SIulia Tanasescu 		return;
1292fbdc4bc4SIulia Tanasescu 
1293fbdc4bc4SIulia Tanasescu 	if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
1294fbdc4bc4SIulia Tanasescu 		err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
1295fbdc4bc4SIulia Tanasescu 					     &iso_pi(sk)->qos,
1296fbdc4bc4SIulia Tanasescu 					     iso_pi(sk)->sync_handle,
1297fbdc4bc4SIulia Tanasescu 					     iso_pi(sk)->bc_num_bis,
1298fbdc4bc4SIulia Tanasescu 					     iso_pi(sk)->bc_bis);
1299fbdc4bc4SIulia Tanasescu 		if (err)
1300fbdc4bc4SIulia Tanasescu 			bt_dev_err(hdev, "hci_le_big_create_sync: %d",
1301fbdc4bc4SIulia Tanasescu 				   err);
1302fbdc4bc4SIulia Tanasescu 	}
1303fbdc4bc4SIulia Tanasescu }
1304fbdc4bc4SIulia Tanasescu 
iso_sock_recvmsg(struct socket * sock,struct msghdr * msg,size_t len,int flags)1305ccf74f23SLuiz Augusto von Dentz static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
1306ccf74f23SLuiz Augusto von Dentz 			    size_t len, int flags)
1307ccf74f23SLuiz Augusto von Dentz {
1308ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1309ccf74f23SLuiz Augusto von Dentz 	struct iso_pinfo *pi = iso_pi(sk);
1310ccf74f23SLuiz Augusto von Dentz 
1311ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1312ccf74f23SLuiz Augusto von Dentz 
1313ccf74f23SLuiz Augusto von Dentz 	if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
1314d40ae85eSPauli Virtanen 		lock_sock(sk);
1315ccf74f23SLuiz Augusto von Dentz 		switch (sk->sk_state) {
1316ccf74f23SLuiz Augusto von Dentz 		case BT_CONNECT2:
131704566971SIulia Tanasescu 			if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
1318fbdc4bc4SIulia Tanasescu 				iso_conn_big_sync(sk);
1319fbdc4bc4SIulia Tanasescu 				sk->sk_state = BT_LISTEN;
1320fbdc4bc4SIulia Tanasescu 			} else {
1321ccf74f23SLuiz Augusto von Dentz 				iso_conn_defer_accept(pi->conn->hcon);
1322ccf74f23SLuiz Augusto von Dentz 				sk->sk_state = BT_CONFIG;
1323fbdc4bc4SIulia Tanasescu 			}
1324ccf74f23SLuiz Augusto von Dentz 			release_sock(sk);
1325ccf74f23SLuiz Augusto von Dentz 			return 0;
1326ccf74f23SLuiz Augusto von Dentz 		case BT_CONNECT:
1327d40ae85eSPauli Virtanen 			release_sock(sk);
1328241f5193SLuiz Augusto von Dentz 			return iso_connect_cis(sk);
1329d40ae85eSPauli Virtanen 		default:
1330d40ae85eSPauli Virtanen 			release_sock(sk);
1331d40ae85eSPauli Virtanen 			break;
1332ccf74f23SLuiz Augusto von Dentz 		}
1333ccf74f23SLuiz Augusto von Dentz 	}
1334ccf74f23SLuiz Augusto von Dentz 
1335ccf74f23SLuiz Augusto von Dentz 	return bt_sock_recvmsg(sock, msg, len, flags);
1336ccf74f23SLuiz Augusto von Dentz }
1337ccf74f23SLuiz Augusto von Dentz 
check_io_qos(struct bt_iso_io_qos * qos)1338ccf74f23SLuiz Augusto von Dentz static bool check_io_qos(struct bt_iso_io_qos *qos)
1339ccf74f23SLuiz Augusto von Dentz {
1340ccf74f23SLuiz Augusto von Dentz 	/* If no PHY is enable SDU must be 0 */
1341ccf74f23SLuiz Augusto von Dentz 	if (!qos->phy && qos->sdu)
1342ccf74f23SLuiz Augusto von Dentz 		return false;
1343ccf74f23SLuiz Augusto von Dentz 
1344ccf74f23SLuiz Augusto von Dentz 	if (qos->interval && (qos->interval < 0xff || qos->interval > 0xfffff))
1345ccf74f23SLuiz Augusto von Dentz 		return false;
1346ccf74f23SLuiz Augusto von Dentz 
1347ccf74f23SLuiz Augusto von Dentz 	if (qos->latency && (qos->latency < 0x05 || qos->latency > 0xfa0))
1348ccf74f23SLuiz Augusto von Dentz 		return false;
1349ccf74f23SLuiz Augusto von Dentz 
1350ccf74f23SLuiz Augusto von Dentz 	if (qos->phy > BT_ISO_PHY_ANY)
1351ccf74f23SLuiz Augusto von Dentz 		return false;
1352ccf74f23SLuiz Augusto von Dentz 
1353ccf74f23SLuiz Augusto von Dentz 	return true;
1354ccf74f23SLuiz Augusto von Dentz }
1355ccf74f23SLuiz Augusto von Dentz 
check_ucast_qos(struct bt_iso_qos * qos)13560fe8c8d0SIulia Tanasescu static bool check_ucast_qos(struct bt_iso_qos *qos)
1357ccf74f23SLuiz Augusto von Dentz {
1358b7f923b1SLuiz Augusto von Dentz 	if (qos->ucast.cig > 0xef && qos->ucast.cig != BT_ISO_QOS_CIG_UNSET)
1359b7f923b1SLuiz Augusto von Dentz 		return false;
1360b7f923b1SLuiz Augusto von Dentz 
1361b7f923b1SLuiz Augusto von Dentz 	if (qos->ucast.cis > 0xef && qos->ucast.cis != BT_ISO_QOS_CIS_UNSET)
1362b7f923b1SLuiz Augusto von Dentz 		return false;
1363b7f923b1SLuiz Augusto von Dentz 
13640fe8c8d0SIulia Tanasescu 	if (qos->ucast.sca > 0x07)
1365ccf74f23SLuiz Augusto von Dentz 		return false;
1366ccf74f23SLuiz Augusto von Dentz 
13670fe8c8d0SIulia Tanasescu 	if (qos->ucast.packing > 0x01)
1368ccf74f23SLuiz Augusto von Dentz 		return false;
1369ccf74f23SLuiz Augusto von Dentz 
13700fe8c8d0SIulia Tanasescu 	if (qos->ucast.framing > 0x01)
1371ccf74f23SLuiz Augusto von Dentz 		return false;
1372ccf74f23SLuiz Augusto von Dentz 
13730fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->ucast.in))
1374ccf74f23SLuiz Augusto von Dentz 		return false;
1375ccf74f23SLuiz Augusto von Dentz 
13760fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->ucast.out))
13770fe8c8d0SIulia Tanasescu 		return false;
13780fe8c8d0SIulia Tanasescu 
13790fe8c8d0SIulia Tanasescu 	return true;
13800fe8c8d0SIulia Tanasescu }
13810fe8c8d0SIulia Tanasescu 
check_bcast_qos(struct bt_iso_qos * qos)13820fe8c8d0SIulia Tanasescu static bool check_bcast_qos(struct bt_iso_qos *qos)
13830fe8c8d0SIulia Tanasescu {
1384a39cc8d0SLuiz Augusto von Dentz 	if (!qos->bcast.sync_factor)
1385a39cc8d0SLuiz Augusto von Dentz 		qos->bcast.sync_factor = 0x01;
13860fe8c8d0SIulia Tanasescu 
13870fe8c8d0SIulia Tanasescu 	if (qos->bcast.packing > 0x01)
13880fe8c8d0SIulia Tanasescu 		return false;
13890fe8c8d0SIulia Tanasescu 
13900fe8c8d0SIulia Tanasescu 	if (qos->bcast.framing > 0x01)
13910fe8c8d0SIulia Tanasescu 		return false;
13920fe8c8d0SIulia Tanasescu 
13930fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->bcast.in))
13940fe8c8d0SIulia Tanasescu 		return false;
13950fe8c8d0SIulia Tanasescu 
13960fe8c8d0SIulia Tanasescu 	if (!check_io_qos(&qos->bcast.out))
13970fe8c8d0SIulia Tanasescu 		return false;
13980fe8c8d0SIulia Tanasescu 
13990fe8c8d0SIulia Tanasescu 	if (qos->bcast.encryption > 0x01)
14000fe8c8d0SIulia Tanasescu 		return false;
14010fe8c8d0SIulia Tanasescu 
14020fe8c8d0SIulia Tanasescu 	if (qos->bcast.options > 0x07)
14030fe8c8d0SIulia Tanasescu 		return false;
14040fe8c8d0SIulia Tanasescu 
14050fe8c8d0SIulia Tanasescu 	if (qos->bcast.skip > 0x01f3)
14060fe8c8d0SIulia Tanasescu 		return false;
14070fe8c8d0SIulia Tanasescu 
1408a39cc8d0SLuiz Augusto von Dentz 	if (!qos->bcast.sync_timeout)
1409a39cc8d0SLuiz Augusto von Dentz 		qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
1410a39cc8d0SLuiz Augusto von Dentz 
14110fe8c8d0SIulia Tanasescu 	if (qos->bcast.sync_timeout < 0x000a || qos->bcast.sync_timeout > 0x4000)
14120fe8c8d0SIulia Tanasescu 		return false;
14130fe8c8d0SIulia Tanasescu 
14140fe8c8d0SIulia Tanasescu 	if (qos->bcast.sync_cte_type > 0x1f)
14150fe8c8d0SIulia Tanasescu 		return false;
14160fe8c8d0SIulia Tanasescu 
14170fe8c8d0SIulia Tanasescu 	if (qos->bcast.mse > 0x1f)
14180fe8c8d0SIulia Tanasescu 		return false;
14190fe8c8d0SIulia Tanasescu 
1420a39cc8d0SLuiz Augusto von Dentz 	if (!qos->bcast.timeout)
1421a39cc8d0SLuiz Augusto von Dentz 		qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
1422a39cc8d0SLuiz Augusto von Dentz 
14230fe8c8d0SIulia Tanasescu 	if (qos->bcast.timeout < 0x000a || qos->bcast.timeout > 0x4000)
1424ccf74f23SLuiz Augusto von Dentz 		return false;
1425ccf74f23SLuiz Augusto von Dentz 
1426ccf74f23SLuiz Augusto von Dentz 	return true;
1427ccf74f23SLuiz Augusto von Dentz }
1428ccf74f23SLuiz Augusto von Dentz 
iso_sock_setsockopt(struct socket * sock,int level,int optname,sockptr_t optval,unsigned int optlen)1429ccf74f23SLuiz Augusto von Dentz static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
1430ccf74f23SLuiz Augusto von Dentz 			       sockptr_t optval, unsigned int optlen)
1431ccf74f23SLuiz Augusto von Dentz {
1432ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
14336a6baa1eSLuiz Augusto von Dentz 	int err = 0;
14340fe8c8d0SIulia Tanasescu 	struct bt_iso_qos qos = default_qos;
1435ccf74f23SLuiz Augusto von Dentz 	u32 opt;
1436ccf74f23SLuiz Augusto von Dentz 
1437ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1438ccf74f23SLuiz Augusto von Dentz 
1439ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1440ccf74f23SLuiz Augusto von Dentz 
1441ccf74f23SLuiz Augusto von Dentz 	switch (optname) {
1442ccf74f23SLuiz Augusto von Dentz 	case BT_DEFER_SETUP:
1443ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1444ccf74f23SLuiz Augusto von Dentz 			err = -EINVAL;
1445ccf74f23SLuiz Augusto von Dentz 			break;
1446ccf74f23SLuiz Augusto von Dentz 		}
1447ccf74f23SLuiz Augusto von Dentz 
14486a6baa1eSLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
14496a6baa1eSLuiz Augusto von Dentz 		if (err)
1450ccf74f23SLuiz Augusto von Dentz 			break;
1451ccf74f23SLuiz Augusto von Dentz 
1452ccf74f23SLuiz Augusto von Dentz 		if (opt)
1453ccf74f23SLuiz Augusto von Dentz 			set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
1454ccf74f23SLuiz Augusto von Dentz 		else
1455ccf74f23SLuiz Augusto von Dentz 			clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
1456ccf74f23SLuiz Augusto von Dentz 		break;
1457ccf74f23SLuiz Augusto von Dentz 
14580731c5abSLuiz Augusto von Dentz 	case BT_PKT_STATUS:
14596a6baa1eSLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
14606a6baa1eSLuiz Augusto von Dentz 		if (err)
14610731c5abSLuiz Augusto von Dentz 			break;
14620731c5abSLuiz Augusto von Dentz 
14630731c5abSLuiz Augusto von Dentz 		if (opt)
14640731c5abSLuiz Augusto von Dentz 			set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
14650731c5abSLuiz Augusto von Dentz 		else
14660731c5abSLuiz Augusto von Dentz 			clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
14670731c5abSLuiz Augusto von Dentz 		break;
14680731c5abSLuiz Augusto von Dentz 
1469ccf74f23SLuiz Augusto von Dentz 	case BT_ISO_QOS:
1470ccf74f23SLuiz Augusto von Dentz 		if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
1471ccf74f23SLuiz Augusto von Dentz 		    sk->sk_state != BT_CONNECT2) {
1472ccf74f23SLuiz Augusto von Dentz 			err = -EINVAL;
1473ccf74f23SLuiz Augusto von Dentz 			break;
1474ccf74f23SLuiz Augusto von Dentz 		}
1475ccf74f23SLuiz Augusto von Dentz 
14766a6baa1eSLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&qos, sizeof(qos), optval, optlen);
14776a6baa1eSLuiz Augusto von Dentz 		if (err)
1478ccf74f23SLuiz Augusto von Dentz 			break;
1479ccf74f23SLuiz Augusto von Dentz 
1480ccf74f23SLuiz Augusto von Dentz 		iso_pi(sk)->qos = qos;
14810fe8c8d0SIulia Tanasescu 		iso_pi(sk)->qos_user_set = true;
1482ccf74f23SLuiz Augusto von Dentz 
1483ccf74f23SLuiz Augusto von Dentz 		break;
1484ccf74f23SLuiz Augusto von Dentz 
1485f764a6c2SLuiz Augusto von Dentz 	case BT_ISO_BASE:
1486f764a6c2SLuiz Augusto von Dentz 		if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
1487f764a6c2SLuiz Augusto von Dentz 		    sk->sk_state != BT_CONNECT2) {
1488f764a6c2SLuiz Augusto von Dentz 			err = -EINVAL;
1489f764a6c2SLuiz Augusto von Dentz 			break;
1490f764a6c2SLuiz Augusto von Dentz 		}
1491f764a6c2SLuiz Augusto von Dentz 
1492f764a6c2SLuiz Augusto von Dentz 		if (optlen > sizeof(iso_pi(sk)->base)) {
14936a6baa1eSLuiz Augusto von Dentz 			err = -EINVAL;
1494f764a6c2SLuiz Augusto von Dentz 			break;
1495f764a6c2SLuiz Augusto von Dentz 		}
1496f764a6c2SLuiz Augusto von Dentz 
14976a6baa1eSLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(iso_pi(sk)->base, optlen, optval,
14986a6baa1eSLuiz Augusto von Dentz 					   optlen);
14996a6baa1eSLuiz Augusto von Dentz 		if (err)
1500f764a6c2SLuiz Augusto von Dentz 			break;
1501f764a6c2SLuiz Augusto von Dentz 
15026a6baa1eSLuiz Augusto von Dentz 		iso_pi(sk)->base_len = optlen;
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_getsockopt(struct socket * sock,int level,int optname,char __user * optval,int __user * optlen)1515ccf74f23SLuiz Augusto von Dentz static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
1516ccf74f23SLuiz Augusto von Dentz 			       char __user *optval, int __user *optlen)
1517ccf74f23SLuiz Augusto von Dentz {
1518ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1519ccf74f23SLuiz Augusto von Dentz 	int len, err = 0;
15200eee4995SLuiz Augusto von Dentz 	struct bt_iso_qos *qos;
1521f764a6c2SLuiz Augusto von Dentz 	u8 base_len;
1522f764a6c2SLuiz Augusto von Dentz 	u8 *base;
1523ccf74f23SLuiz Augusto von Dentz 
1524ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1525ccf74f23SLuiz Augusto von Dentz 
1526ccf74f23SLuiz Augusto von Dentz 	if (get_user(len, optlen))
1527ccf74f23SLuiz Augusto von Dentz 		return -EFAULT;
1528ccf74f23SLuiz Augusto von Dentz 
1529ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1530ccf74f23SLuiz Augusto von Dentz 
1531ccf74f23SLuiz Augusto von Dentz 	switch (optname) {
1532ccf74f23SLuiz Augusto von Dentz 	case BT_DEFER_SETUP:
15339dfe1727SLuiz Augusto von Dentz 		if (sk->sk_state == BT_CONNECTED) {
1534ccf74f23SLuiz Augusto von Dentz 			err = -EINVAL;
1535ccf74f23SLuiz Augusto von Dentz 			break;
1536ccf74f23SLuiz Augusto von Dentz 		}
1537ccf74f23SLuiz Augusto von Dentz 
1538ccf74f23SLuiz Augusto von Dentz 		if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
1539ccf74f23SLuiz Augusto von Dentz 			     (u32 __user *)optval))
1540ccf74f23SLuiz Augusto von Dentz 			err = -EFAULT;
1541ccf74f23SLuiz Augusto von Dentz 
1542ccf74f23SLuiz Augusto von Dentz 		break;
1543ccf74f23SLuiz Augusto von Dentz 
15440731c5abSLuiz Augusto von Dentz 	case BT_PKT_STATUS:
15450731c5abSLuiz Augusto von Dentz 		if (put_user(test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags),
15460731c5abSLuiz Augusto von Dentz 			     (int __user *)optval))
15470731c5abSLuiz Augusto von Dentz 			err = -EFAULT;
15480731c5abSLuiz Augusto von Dentz 		break;
15490731c5abSLuiz Augusto von Dentz 
1550ccf74f23SLuiz Augusto von Dentz 	case BT_ISO_QOS:
15511d1ab5d3SLuiz Augusto von Dentz 		qos = iso_sock_get_qos(sk);
1552ccf74f23SLuiz Augusto von Dentz 
15530eee4995SLuiz Augusto von Dentz 		len = min_t(unsigned int, len, sizeof(*qos));
15540eee4995SLuiz Augusto von Dentz 		if (copy_to_user(optval, qos, len))
1555ccf74f23SLuiz Augusto von Dentz 			err = -EFAULT;
1556ccf74f23SLuiz Augusto von Dentz 
1557ccf74f23SLuiz Augusto von Dentz 		break;
1558ccf74f23SLuiz Augusto von Dentz 
1559f764a6c2SLuiz Augusto von Dentz 	case BT_ISO_BASE:
15609c082631SClaudia Draghicescu 		if (sk->sk_state == BT_CONNECTED &&
15619c082631SClaudia Draghicescu 		    !bacmp(&iso_pi(sk)->dst, BDADDR_ANY)) {
1562f764a6c2SLuiz Augusto von Dentz 			base_len = iso_pi(sk)->conn->hcon->le_per_adv_data_len;
1563f764a6c2SLuiz Augusto von Dentz 			base = iso_pi(sk)->conn->hcon->le_per_adv_data;
1564f764a6c2SLuiz Augusto von Dentz 		} else {
1565f764a6c2SLuiz Augusto von Dentz 			base_len = iso_pi(sk)->base_len;
1566f764a6c2SLuiz Augusto von Dentz 			base = iso_pi(sk)->base;
1567f764a6c2SLuiz Augusto von Dentz 		}
1568f764a6c2SLuiz Augusto von Dentz 
1569f764a6c2SLuiz Augusto von Dentz 		len = min_t(unsigned int, len, base_len);
1570f764a6c2SLuiz Augusto von Dentz 		if (copy_to_user(optval, base, len))
1571f764a6c2SLuiz Augusto von Dentz 			err = -EFAULT;
1572f764a6c2SLuiz Augusto von Dentz 
1573f764a6c2SLuiz Augusto von Dentz 		break;
1574f764a6c2SLuiz Augusto von Dentz 
1575ccf74f23SLuiz Augusto von Dentz 	default:
1576ccf74f23SLuiz Augusto von Dentz 		err = -ENOPROTOOPT;
1577ccf74f23SLuiz Augusto von Dentz 		break;
1578ccf74f23SLuiz Augusto von Dentz 	}
1579ccf74f23SLuiz Augusto von Dentz 
1580ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1581ccf74f23SLuiz Augusto von Dentz 	return err;
1582ccf74f23SLuiz Augusto von Dentz }
1583ccf74f23SLuiz Augusto von Dentz 
iso_sock_shutdown(struct socket * sock,int how)1584ccf74f23SLuiz Augusto von Dentz static int iso_sock_shutdown(struct socket *sock, int how)
1585ccf74f23SLuiz Augusto von Dentz {
1586ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1587ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1588ccf74f23SLuiz Augusto von Dentz 
1589c5729093SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p, how %d", sock, sk, how);
1590ccf74f23SLuiz Augusto von Dentz 
1591ccf74f23SLuiz Augusto von Dentz 	if (!sk)
1592ccf74f23SLuiz Augusto von Dentz 		return 0;
1593ccf74f23SLuiz Augusto von Dentz 
1594ccf74f23SLuiz Augusto von Dentz 	sock_hold(sk);
1595ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1596ccf74f23SLuiz Augusto von Dentz 
1597c5729093SLuiz Augusto von Dentz 	switch (how) {
1598c5729093SLuiz Augusto von Dentz 	case SHUT_RD:
1599c5729093SLuiz Augusto von Dentz 		if (sk->sk_shutdown & RCV_SHUTDOWN)
1600c5729093SLuiz Augusto von Dentz 			goto unlock;
1601c5729093SLuiz Augusto von Dentz 		sk->sk_shutdown |= RCV_SHUTDOWN;
1602c5729093SLuiz Augusto von Dentz 		break;
1603c5729093SLuiz Augusto von Dentz 	case SHUT_WR:
1604c5729093SLuiz Augusto von Dentz 		if (sk->sk_shutdown & SEND_SHUTDOWN)
1605c5729093SLuiz Augusto von Dentz 			goto unlock;
1606c5729093SLuiz Augusto von Dentz 		sk->sk_shutdown |= SEND_SHUTDOWN;
1607c5729093SLuiz Augusto von Dentz 		break;
1608c5729093SLuiz Augusto von Dentz 	case SHUT_RDWR:
1609c5729093SLuiz Augusto von Dentz 		if (sk->sk_shutdown & SHUTDOWN_MASK)
1610c5729093SLuiz Augusto von Dentz 			goto unlock;
1611c5729093SLuiz Augusto von Dentz 		sk->sk_shutdown |= SHUTDOWN_MASK;
1612c5729093SLuiz Augusto von Dentz 		break;
1613c5729093SLuiz Augusto von Dentz 	}
1614c5729093SLuiz Augusto von Dentz 
1615ccf74f23SLuiz Augusto von Dentz 	iso_sock_clear_timer(sk);
1616ccf74f23SLuiz Augusto von Dentz 	__iso_sock_close(sk);
1617ccf74f23SLuiz Augusto von Dentz 
1618ccf74f23SLuiz Augusto von Dentz 	if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1619ccf74f23SLuiz Augusto von Dentz 	    !(current->flags & PF_EXITING))
1620c5729093SLuiz Augusto von Dentz 		err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
1621ccf74f23SLuiz Augusto von Dentz 
1622c5729093SLuiz Augusto von Dentz unlock:
1623ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1624ccf74f23SLuiz Augusto von Dentz 	sock_put(sk);
1625ccf74f23SLuiz Augusto von Dentz 
1626ccf74f23SLuiz Augusto von Dentz 	return err;
1627ccf74f23SLuiz Augusto von Dentz }
1628ccf74f23SLuiz Augusto von Dentz 
iso_sock_release(struct socket * sock)1629ccf74f23SLuiz Augusto von Dentz static int iso_sock_release(struct socket *sock)
1630ccf74f23SLuiz Augusto von Dentz {
1631ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = sock->sk;
1632ccf74f23SLuiz Augusto von Dentz 	int err = 0;
1633ccf74f23SLuiz Augusto von Dentz 
1634ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sock %p, sk %p", sock, sk);
1635ccf74f23SLuiz Augusto von Dentz 
1636ccf74f23SLuiz Augusto von Dentz 	if (!sk)
1637ccf74f23SLuiz Augusto von Dentz 		return 0;
1638ccf74f23SLuiz Augusto von Dentz 
1639ccf74f23SLuiz Augusto von Dentz 	iso_sock_close(sk);
1640ccf74f23SLuiz Augusto von Dentz 
1641bc1fb82aSEric Dumazet 	if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) &&
1642ccf74f23SLuiz Augusto von Dentz 	    !(current->flags & PF_EXITING)) {
1643ccf74f23SLuiz Augusto von Dentz 		lock_sock(sk);
1644ccf74f23SLuiz Augusto von Dentz 		err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
1645ccf74f23SLuiz Augusto von Dentz 		release_sock(sk);
1646ccf74f23SLuiz Augusto von Dentz 	}
1647ccf74f23SLuiz Augusto von Dentz 
1648ccf74f23SLuiz Augusto von Dentz 	sock_orphan(sk);
1649ccf74f23SLuiz Augusto von Dentz 	iso_sock_kill(sk);
1650ccf74f23SLuiz Augusto von Dentz 	return err;
1651ccf74f23SLuiz Augusto von Dentz }
1652ccf74f23SLuiz Augusto von Dentz 
iso_sock_ready(struct sock * sk)1653ccf74f23SLuiz Augusto von Dentz static void iso_sock_ready(struct sock *sk)
1654ccf74f23SLuiz Augusto von Dentz {
1655ccf74f23SLuiz Augusto von Dentz 	BT_DBG("sk %p", sk);
1656ccf74f23SLuiz Augusto von Dentz 
1657ccf74f23SLuiz Augusto von Dentz 	if (!sk)
1658ccf74f23SLuiz Augusto von Dentz 		return;
1659ccf74f23SLuiz Augusto von Dentz 
1660ccf74f23SLuiz Augusto von Dentz 	lock_sock(sk);
1661ccf74f23SLuiz Augusto von Dentz 	iso_sock_clear_timer(sk);
1662ccf74f23SLuiz Augusto von Dentz 	sk->sk_state = BT_CONNECTED;
1663ccf74f23SLuiz Augusto von Dentz 	sk->sk_state_change(sk);
1664ccf74f23SLuiz Augusto von Dentz 	release_sock(sk);
1665ccf74f23SLuiz Augusto von Dentz }
1666ccf74f23SLuiz Augusto von Dentz 
1667ccf74f23SLuiz Augusto von Dentz struct iso_list_data {
1668ccf74f23SLuiz Augusto von Dentz 	struct hci_conn *hcon;
1669ccf74f23SLuiz Augusto von Dentz 	int count;
1670ccf74f23SLuiz Augusto von Dentz };
1671ccf74f23SLuiz Augusto von Dentz 
iso_match_big(struct sock * sk,void * data)1672f764a6c2SLuiz Augusto von Dentz static bool iso_match_big(struct sock *sk, void *data)
1673f764a6c2SLuiz Augusto von Dentz {
1674f764a6c2SLuiz Augusto von Dentz 	struct hci_evt_le_big_sync_estabilished *ev = data;
1675f764a6c2SLuiz Augusto von Dentz 
16760fe8c8d0SIulia Tanasescu 	return ev->handle == iso_pi(sk)->qos.bcast.big;
1677f764a6c2SLuiz Augusto von Dentz }
1678f764a6c2SLuiz Augusto von Dentz 
iso_match_pa_sync_flag(struct sock * sk,void * data)1679fbdc4bc4SIulia Tanasescu static bool iso_match_pa_sync_flag(struct sock *sk, void *data)
1680fbdc4bc4SIulia Tanasescu {
1681fbdc4bc4SIulia Tanasescu 	return test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
1682fbdc4bc4SIulia Tanasescu }
1683fbdc4bc4SIulia Tanasescu 
iso_conn_ready(struct iso_conn * conn)1684ccf74f23SLuiz Augusto von Dentz static void iso_conn_ready(struct iso_conn *conn)
1685ccf74f23SLuiz Augusto von Dentz {
1686fbdc4bc4SIulia Tanasescu 	struct sock *parent = NULL;
1687ccf74f23SLuiz Augusto von Dentz 	struct sock *sk = conn->sk;
1688fbdc4bc4SIulia Tanasescu 	struct hci_ev_le_big_sync_estabilished *ev = NULL;
1689fbdc4bc4SIulia Tanasescu 	struct hci_ev_le_pa_sync_established *ev2 = NULL;
169023417475SIulia Tanasescu 	struct hci_evt_le_big_info_adv_report *ev3 = NULL;
16916a5ad251SLuiz Augusto von Dentz 	struct hci_conn *hcon;
1692ccf74f23SLuiz Augusto von Dentz 
1693ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p", conn);
1694ccf74f23SLuiz Augusto von Dentz 
1695ccf74f23SLuiz Augusto von Dentz 	if (sk) {
1696ccf74f23SLuiz Augusto von Dentz 		iso_sock_ready(conn->sk);
1697ccf74f23SLuiz Augusto von Dentz 	} else {
16986a5ad251SLuiz Augusto von Dentz 		hcon = conn->hcon;
16996a5ad251SLuiz Augusto von Dentz 		if (!hcon)
1700ccf74f23SLuiz Augusto von Dentz 			return;
1701ccf74f23SLuiz Augusto von Dentz 
1702fbdc4bc4SIulia Tanasescu 		if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags) ||
1703fbdc4bc4SIulia Tanasescu 		    test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
17046a5ad251SLuiz Augusto von Dentz 			ev = hci_recv_event_data(hcon->hdev,
1705f764a6c2SLuiz Augusto von Dentz 						 HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
1706fbdc4bc4SIulia Tanasescu 
1707fbdc4bc4SIulia Tanasescu 			/* Get reference to PA sync parent socket, if it exists */
1708fbdc4bc4SIulia Tanasescu 			parent = iso_get_sock_listen(&hcon->src,
1709fbdc4bc4SIulia Tanasescu 						     &hcon->dst,
1710fbdc4bc4SIulia Tanasescu 						     iso_match_pa_sync_flag, NULL);
1711fbdc4bc4SIulia Tanasescu 			if (!parent && ev)
17126a5ad251SLuiz Augusto von Dentz 				parent = iso_get_sock_listen(&hcon->src,
17136a5ad251SLuiz Augusto von Dentz 							     &hcon->dst,
1714f764a6c2SLuiz Augusto von Dentz 							     iso_match_big, ev);
171523417475SIulia Tanasescu 		} else if (test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
1716fbdc4bc4SIulia Tanasescu 			ev2 = hci_recv_event_data(hcon->hdev,
1717fbdc4bc4SIulia Tanasescu 						  HCI_EV_LE_PA_SYNC_ESTABLISHED);
1718fbdc4bc4SIulia Tanasescu 			if (ev2)
1719fbdc4bc4SIulia Tanasescu 				parent = iso_get_sock_listen(&hcon->src,
1720fbdc4bc4SIulia Tanasescu 							     &hcon->dst,
1721fbdc4bc4SIulia Tanasescu 							     iso_match_sid, ev2);
172223417475SIulia Tanasescu 		} else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
172323417475SIulia Tanasescu 			ev3 = hci_recv_event_data(hcon->hdev,
172423417475SIulia Tanasescu 						  HCI_EVT_LE_BIG_INFO_ADV_REPORT);
172523417475SIulia Tanasescu 			if (ev3)
172623417475SIulia Tanasescu 				parent = iso_get_sock_listen(&hcon->src,
172723417475SIulia Tanasescu 							     &hcon->dst,
172823417475SIulia Tanasescu 							     iso_match_sync_handle, ev3);
1729fbdc4bc4SIulia Tanasescu 		}
1730fbdc4bc4SIulia Tanasescu 
1731fbdc4bc4SIulia Tanasescu 		if (!parent)
17326a5ad251SLuiz Augusto von Dentz 			parent = iso_get_sock_listen(&hcon->src,
1733f764a6c2SLuiz Augusto von Dentz 							BDADDR_ANY, NULL, NULL);
1734f764a6c2SLuiz Augusto von Dentz 
17356a5ad251SLuiz Augusto von Dentz 		if (!parent)
1736ccf74f23SLuiz Augusto von Dentz 			return;
1737ccf74f23SLuiz Augusto von Dentz 
1738ccf74f23SLuiz Augusto von Dentz 		lock_sock(parent);
1739ccf74f23SLuiz Augusto von Dentz 
1740ccf74f23SLuiz Augusto von Dentz 		sk = iso_sock_alloc(sock_net(parent), NULL,
1741ccf74f23SLuiz Augusto von Dentz 				    BTPROTO_ISO, GFP_ATOMIC, 0);
1742ccf74f23SLuiz Augusto von Dentz 		if (!sk) {
1743ccf74f23SLuiz Augusto von Dentz 			release_sock(parent);
1744ccf74f23SLuiz Augusto von Dentz 			return;
1745ccf74f23SLuiz Augusto von Dentz 		}
1746ccf74f23SLuiz Augusto von Dentz 
1747ccf74f23SLuiz Augusto von Dentz 		iso_sock_init(sk, parent);
1748ccf74f23SLuiz Augusto von Dentz 
17496a5ad251SLuiz Augusto von Dentz 		bacpy(&iso_pi(sk)->src, &hcon->src);
1750fbdc4bc4SIulia Tanasescu 
1751fbdc4bc4SIulia Tanasescu 		/* Convert from HCI to three-value type */
1752fbdc4bc4SIulia Tanasescu 		if (hcon->src_type == ADDR_LE_DEV_PUBLIC)
1753fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
1754fbdc4bc4SIulia Tanasescu 		else
1755fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->src_type = BDADDR_LE_RANDOM;
1756f764a6c2SLuiz Augusto von Dentz 
1757f764a6c2SLuiz Augusto von Dentz 		/* If hcon has no destination address (BDADDR_ANY) it means it
1758fbdc4bc4SIulia Tanasescu 		 * was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED or
1759fbdc4bc4SIulia Tanasescu 		 * HCI_EV_LE_PA_SYNC_ESTABLISHED so we need to initialize using
1760fbdc4bc4SIulia Tanasescu 		 * the parent socket destination address.
1761f764a6c2SLuiz Augusto von Dentz 		 */
17626a5ad251SLuiz Augusto von Dentz 		if (!bacmp(&hcon->dst, BDADDR_ANY)) {
17636a5ad251SLuiz Augusto von Dentz 			bacpy(&hcon->dst, &iso_pi(parent)->dst);
17646a5ad251SLuiz Augusto von Dentz 			hcon->dst_type = iso_pi(parent)->dst_type;
17656a5ad251SLuiz Augusto von Dentz 			hcon->sync_handle = iso_pi(parent)->sync_handle;
1766f764a6c2SLuiz Augusto von Dentz 		}
1767f764a6c2SLuiz Augusto von Dentz 
176823417475SIulia Tanasescu 		if (ev3) {
1769fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->qos = iso_pi(parent)->qos;
177023417475SIulia Tanasescu 			iso_pi(sk)->qos.bcast.encryption = ev3->encryption;
177123417475SIulia Tanasescu 			hcon->iso_qos = iso_pi(sk)->qos;
1772fbdc4bc4SIulia Tanasescu 			iso_pi(sk)->bc_num_bis = iso_pi(parent)->bc_num_bis;
1773fbdc4bc4SIulia Tanasescu 			memcpy(iso_pi(sk)->bc_bis, iso_pi(parent)->bc_bis, ISO_MAX_NUM_BIS);
177423417475SIulia Tanasescu 			set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
1775fbdc4bc4SIulia Tanasescu 		}
1776fbdc4bc4SIulia Tanasescu 
17776a5ad251SLuiz Augusto von Dentz 		bacpy(&iso_pi(sk)->dst, &hcon->dst);
17786a5ad251SLuiz Augusto von Dentz 		iso_pi(sk)->dst_type = hcon->dst_type;
17799c082631SClaudia Draghicescu 		iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
17809c082631SClaudia Draghicescu 		memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
17819c082631SClaudia Draghicescu 		iso_pi(sk)->base_len = iso_pi(parent)->base_len;
1782ccf74f23SLuiz Augusto von Dentz 
17836a5ad251SLuiz Augusto von Dentz 		hci_conn_hold(hcon);
17846a5ad251SLuiz Augusto von Dentz 		iso_chan_add(conn, sk, parent);
1785ccf74f23SLuiz Augusto von Dentz 
1786fbdc4bc4SIulia Tanasescu 		if ((ev && ((struct hci_evt_le_big_sync_estabilished *)ev)->status) ||
1787fbdc4bc4SIulia Tanasescu 		    (ev2 && ev2->status)) {
1788f777d882SIulia Tanasescu 			/* Trigger error signal on child socket */
1789f777d882SIulia Tanasescu 			sk->sk_err = ECONNREFUSED;
1790f777d882SIulia Tanasescu 			sk->sk_error_report(sk);
1791f777d882SIulia Tanasescu 		}
1792f777d882SIulia Tanasescu 
1793ccf74f23SLuiz Augusto von Dentz 		if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
1794ccf74f23SLuiz Augusto von Dentz 			sk->sk_state = BT_CONNECT2;
1795ccf74f23SLuiz Augusto von Dentz 		else
1796ccf74f23SLuiz Augusto von Dentz 			sk->sk_state = BT_CONNECTED;
1797ccf74f23SLuiz Augusto von Dentz 
1798ccf74f23SLuiz Augusto von Dentz 		/* Wake up parent */
1799ccf74f23SLuiz Augusto von Dentz 		parent->sk_data_ready(parent);
1800ccf74f23SLuiz Augusto von Dentz 
1801ccf74f23SLuiz Augusto von Dentz 		release_sock(parent);
180211dc486eSIulia Tanasescu 		sock_put(parent);
1803ccf74f23SLuiz Augusto von Dentz 	}
1804ccf74f23SLuiz Augusto von Dentz }
1805ccf74f23SLuiz Augusto von Dentz 
iso_match_sid(struct sock * sk,void * data)1806f764a6c2SLuiz Augusto von Dentz static bool iso_match_sid(struct sock *sk, void *data)
1807f764a6c2SLuiz Augusto von Dentz {
1808f764a6c2SLuiz Augusto von Dentz 	struct hci_ev_le_pa_sync_established *ev = data;
1809f764a6c2SLuiz Augusto von Dentz 
1810f764a6c2SLuiz Augusto von Dentz 	return ev->sid == iso_pi(sk)->bc_sid;
1811f764a6c2SLuiz Augusto von Dentz }
1812f764a6c2SLuiz Augusto von Dentz 
iso_match_sync_handle(struct sock * sk,void * data)1813f764a6c2SLuiz Augusto von Dentz static bool iso_match_sync_handle(struct sock *sk, void *data)
1814f764a6c2SLuiz Augusto von Dentz {
1815f764a6c2SLuiz Augusto von Dentz 	struct hci_evt_le_big_info_adv_report *ev = data;
1816f764a6c2SLuiz Augusto von Dentz 
1817f764a6c2SLuiz Augusto von Dentz 	return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
1818f764a6c2SLuiz Augusto von Dentz }
1819f764a6c2SLuiz Augusto von Dentz 
iso_match_sync_handle_pa_report(struct sock * sk,void * data)18209c082631SClaudia Draghicescu static bool iso_match_sync_handle_pa_report(struct sock *sk, void *data)
18219c082631SClaudia Draghicescu {
18229c082631SClaudia Draghicescu 	struct hci_ev_le_per_adv_report *ev = data;
18239c082631SClaudia Draghicescu 
18249c082631SClaudia Draghicescu 	return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
18259c082631SClaudia Draghicescu }
18269c082631SClaudia Draghicescu 
1827ccf74f23SLuiz Augusto von Dentz /* ----- ISO interface with lower layer (HCI) ----- */
1828f764a6c2SLuiz Augusto von Dentz 
iso_connect_ind(struct hci_dev * hdev,bdaddr_t * bdaddr,__u8 * flags)1829ccf74f23SLuiz Augusto von Dentz int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
1830ccf74f23SLuiz Augusto von Dentz {
1831f764a6c2SLuiz Augusto von Dentz 	struct hci_ev_le_pa_sync_established *ev1;
1832f764a6c2SLuiz Augusto von Dentz 	struct hci_evt_le_big_info_adv_report *ev2;
18339c082631SClaudia Draghicescu 	struct hci_ev_le_per_adv_report *ev3;
1834ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
1835ccf74f23SLuiz Augusto von Dentz 	int lm = 0;
1836ccf74f23SLuiz Augusto von Dentz 
1837f764a6c2SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR", bdaddr);
1838ccf74f23SLuiz Augusto von Dentz 
1839f764a6c2SLuiz Augusto von Dentz 	/* Broadcast receiver requires handling of some events before it can
1840f764a6c2SLuiz Augusto von Dentz 	 * proceed to establishing a BIG sync:
1841f764a6c2SLuiz Augusto von Dentz 	 *
1842f764a6c2SLuiz Augusto von Dentz 	 * 1. HCI_EV_LE_PA_SYNC_ESTABLISHED: The socket may specify a specific
1843f764a6c2SLuiz Augusto von Dentz 	 * SID to listen to and once sync is estabilished its handle needs to
1844f764a6c2SLuiz Augusto von Dentz 	 * be stored in iso_pi(sk)->sync_handle so it can be matched once
1845f764a6c2SLuiz Augusto von Dentz 	 * receiving the BIG Info.
1846f764a6c2SLuiz Augusto von Dentz 	 * 2. HCI_EVT_LE_BIG_INFO_ADV_REPORT: When connect_ind is triggered by a
1847f764a6c2SLuiz Augusto von Dentz 	 * a BIG Info it attempts to check if there any listening socket with
1848f764a6c2SLuiz Augusto von Dentz 	 * the same sync_handle and if it does then attempt to create a sync.
18499c082631SClaudia Draghicescu 	 * 3. HCI_EV_LE_PER_ADV_REPORT: When a PA report is received, it is stored
18509c082631SClaudia Draghicescu 	 * in iso_pi(sk)->base so it can be passed up to user, in the case of a
18519c082631SClaudia Draghicescu 	 * broadcast sink.
1852f764a6c2SLuiz Augusto von Dentz 	 */
1853f764a6c2SLuiz Augusto von Dentz 	ev1 = hci_recv_event_data(hdev, HCI_EV_LE_PA_SYNC_ESTABLISHED);
1854f764a6c2SLuiz Augusto von Dentz 	if (ev1) {
1855f764a6c2SLuiz Augusto von Dentz 		sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr, iso_match_sid,
1856f764a6c2SLuiz Augusto von Dentz 					 ev1);
1857fbdc4bc4SIulia Tanasescu 		if (sk && !ev1->status)
1858f764a6c2SLuiz Augusto von Dentz 			iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
1859ccf74f23SLuiz Augusto von Dentz 
1860f764a6c2SLuiz Augusto von Dentz 		goto done;
1861f764a6c2SLuiz Augusto von Dentz 	}
1862f764a6c2SLuiz Augusto von Dentz 
1863f764a6c2SLuiz Augusto von Dentz 	ev2 = hci_recv_event_data(hdev, HCI_EVT_LE_BIG_INFO_ADV_REPORT);
1864f764a6c2SLuiz Augusto von Dentz 	if (ev2) {
1865fbdc4bc4SIulia Tanasescu 		/* Try to get PA sync listening socket, if it exists */
1866fbdc4bc4SIulia Tanasescu 		sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr,
1867fbdc4bc4SIulia Tanasescu 						iso_match_pa_sync_flag, NULL);
186814410544SIulia Tanasescu 
186914410544SIulia Tanasescu 		if (!sk) {
1870f764a6c2SLuiz Augusto von Dentz 			sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr,
1871f764a6c2SLuiz Augusto von Dentz 						 iso_match_sync_handle, ev2);
187214410544SIulia Tanasescu 
187314410544SIulia Tanasescu 			/* If PA Sync is in process of terminating,
187414410544SIulia Tanasescu 			 * do not handle any more BIGInfo adv reports.
187514410544SIulia Tanasescu 			 */
187614410544SIulia Tanasescu 
187714410544SIulia Tanasescu 			if (sk && test_bit(BT_SK_PA_SYNC_TERM,
187814410544SIulia Tanasescu 					   &iso_pi(sk)->flags))
187914410544SIulia Tanasescu 				return lm;
188014410544SIulia Tanasescu 		}
188114410544SIulia Tanasescu 
1882f764a6c2SLuiz Augusto von Dentz 		if (sk) {
1883f764a6c2SLuiz Augusto von Dentz 			int err;
1884f764a6c2SLuiz Augusto von Dentz 
1885f764a6c2SLuiz Augusto von Dentz 			if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
1886f764a6c2SLuiz Augusto von Dentz 				iso_pi(sk)->bc_num_bis = ev2->num_bis;
1887f764a6c2SLuiz Augusto von Dentz 
1888fbdc4bc4SIulia Tanasescu 			if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
1889fbdc4bc4SIulia Tanasescu 			    !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
1890fbdc4bc4SIulia Tanasescu 				err = hci_le_big_create_sync(hdev, NULL,
1891f764a6c2SLuiz Augusto von Dentz 							     &iso_pi(sk)->qos,
1892f764a6c2SLuiz Augusto von Dentz 							     iso_pi(sk)->sync_handle,
1893f764a6c2SLuiz Augusto von Dentz 							     iso_pi(sk)->bc_num_bis,
1894f764a6c2SLuiz Augusto von Dentz 							     iso_pi(sk)->bc_bis);
1895f764a6c2SLuiz Augusto von Dentz 				if (err) {
1896f764a6c2SLuiz Augusto von Dentz 					bt_dev_err(hdev, "hci_le_big_create_sync: %d",
1897f764a6c2SLuiz Augusto von Dentz 						   err);
189811dc486eSIulia Tanasescu 					sock_put(sk);
1899f764a6c2SLuiz Augusto von Dentz 					sk = NULL;
1900f764a6c2SLuiz Augusto von Dentz 				}
1901f764a6c2SLuiz Augusto von Dentz 			}
1902f777d882SIulia Tanasescu 		}
19039c082631SClaudia Draghicescu 	}
19049c082631SClaudia Draghicescu 
19059c082631SClaudia Draghicescu 	ev3 = hci_recv_event_data(hdev, HCI_EV_LE_PER_ADV_REPORT);
19069c082631SClaudia Draghicescu 	if (ev3) {
19079c082631SClaudia Draghicescu 		sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr,
19089c082631SClaudia Draghicescu 					 iso_match_sync_handle_pa_report, ev3);
19099c082631SClaudia Draghicescu 
19109c082631SClaudia Draghicescu 		if (sk) {
19119c082631SClaudia Draghicescu 			memcpy(iso_pi(sk)->base, ev3->data, ev3->length);
19129c082631SClaudia Draghicescu 			iso_pi(sk)->base_len = ev3->length;
19139c082631SClaudia Draghicescu 		}
1914f764a6c2SLuiz Augusto von Dentz 	} else {
1915f764a6c2SLuiz Augusto von Dentz 		sk = iso_get_sock_listen(&hdev->bdaddr, BDADDR_ANY, NULL, NULL);
1916f764a6c2SLuiz Augusto von Dentz 	}
1917f764a6c2SLuiz Augusto von Dentz 
1918f764a6c2SLuiz Augusto von Dentz done:
1919f764a6c2SLuiz Augusto von Dentz 	if (!sk)
1920f764a6c2SLuiz Augusto von Dentz 		return lm;
1921f764a6c2SLuiz Augusto von Dentz 
1922ccf74f23SLuiz Augusto von Dentz 	lm |= HCI_LM_ACCEPT;
1923ccf74f23SLuiz Augusto von Dentz 
1924ccf74f23SLuiz Augusto von Dentz 	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
1925ccf74f23SLuiz Augusto von Dentz 		*flags |= HCI_PROTO_DEFER;
1926ccf74f23SLuiz Augusto von Dentz 
192711dc486eSIulia Tanasescu 	sock_put(sk);
192811dc486eSIulia Tanasescu 
1929ccf74f23SLuiz Augusto von Dentz 	return lm;
1930ccf74f23SLuiz Augusto von Dentz }
1931ccf74f23SLuiz Augusto von Dentz 
iso_match(struct hci_conn * hcon)1932ccf74f23SLuiz Augusto von Dentz static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
1933ccf74f23SLuiz Augusto von Dentz {
1934ccf74f23SLuiz Augusto von Dentz 	if (hcon->type != ISO_LINK) {
1935ccf74f23SLuiz Augusto von Dentz 		if (hcon->type != LE_LINK)
1936ccf74f23SLuiz Augusto von Dentz 			return;
1937ccf74f23SLuiz Augusto von Dentz 
1938ccf74f23SLuiz Augusto von Dentz 		/* Check if LE link has failed */
1939ccf74f23SLuiz Augusto von Dentz 		if (status) {
194006149746SLuiz Augusto von Dentz 			struct hci_link *link, *t;
194106149746SLuiz Augusto von Dentz 
194206149746SLuiz Augusto von Dentz 			list_for_each_entry_safe(link, t, &hcon->link_list,
194306149746SLuiz Augusto von Dentz 						 list)
194406149746SLuiz Augusto von Dentz 				iso_conn_del(link->conn, bt_to_errno(status));
194506149746SLuiz Augusto von Dentz 
1946ccf74f23SLuiz Augusto von Dentz 			return;
1947ccf74f23SLuiz Augusto von Dentz 		}
1948ccf74f23SLuiz Augusto von Dentz 
1949ccf74f23SLuiz Augusto von Dentz 		/* Create CIS if pending */
19507f74563eSPauli Virtanen 		hci_le_create_cis_pending(hcon->hdev);
1951ccf74f23SLuiz Augusto von Dentz 		return;
1952ccf74f23SLuiz Augusto von Dentz 	}
1953ccf74f23SLuiz Augusto von Dentz 
1954ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
1955ccf74f23SLuiz Augusto von Dentz 
1956fbdc4bc4SIulia Tanasescu 	/* Similar to the success case, if HCI_CONN_BIG_SYNC_FAILED or
1957fbdc4bc4SIulia Tanasescu 	 * HCI_CONN_PA_SYNC_FAILED is set, queue the failed connection
1958fbdc4bc4SIulia Tanasescu 	 * into the accept queue of the listening socket and wake up
1959fbdc4bc4SIulia Tanasescu 	 * userspace, to inform the user about the event.
1960f777d882SIulia Tanasescu 	 */
1961fbdc4bc4SIulia Tanasescu 	if (!status || test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags) ||
1962fbdc4bc4SIulia Tanasescu 	    test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
1963ccf74f23SLuiz Augusto von Dentz 		struct iso_conn *conn;
1964ccf74f23SLuiz Augusto von Dentz 
1965ccf74f23SLuiz Augusto von Dentz 		conn = iso_conn_add(hcon);
1966ccf74f23SLuiz Augusto von Dentz 		if (conn)
1967ccf74f23SLuiz Augusto von Dentz 			iso_conn_ready(conn);
1968ccf74f23SLuiz Augusto von Dentz 	} else {
1969ccf74f23SLuiz Augusto von Dentz 		iso_conn_del(hcon, bt_to_errno(status));
1970ccf74f23SLuiz Augusto von Dentz 	}
1971ccf74f23SLuiz Augusto von Dentz }
1972ccf74f23SLuiz Augusto von Dentz 
1973ccf74f23SLuiz Augusto von Dentz static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
1974ccf74f23SLuiz Augusto von Dentz {
1975ccf74f23SLuiz Augusto von Dentz 	if (hcon->type != ISO_LINK)
1976ccf74f23SLuiz Augusto von Dentz 		return;
1977ccf74f23SLuiz Augusto von Dentz 
iso_disconn_cfm(struct hci_conn * hcon,__u8 reason)1978ccf74f23SLuiz Augusto von Dentz 	BT_DBG("hcon %p reason %d", hcon, reason);
1979ccf74f23SLuiz Augusto von Dentz 
1980ccf74f23SLuiz Augusto von Dentz 	iso_conn_del(hcon, bt_to_errno(reason));
1981ccf74f23SLuiz Augusto von Dentz }
1982ccf74f23SLuiz Augusto von Dentz 
1983ccf74f23SLuiz Augusto von Dentz void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
1984ccf74f23SLuiz Augusto von Dentz {
1985ccf74f23SLuiz Augusto von Dentz 	struct iso_conn *conn = hcon->iso_data;
1986ccf74f23SLuiz Augusto von Dentz 	__u16 pb, ts, len;
1987ccf74f23SLuiz Augusto von Dentz 
iso_recv(struct hci_conn * hcon,struct sk_buff * skb,u16 flags)1988ccf74f23SLuiz Augusto von Dentz 	if (!conn)
1989ccf74f23SLuiz Augusto von Dentz 		goto drop;
1990ccf74f23SLuiz Augusto von Dentz 
1991ccf74f23SLuiz Augusto von Dentz 	pb     = hci_iso_flags_pb(flags);
1992ccf74f23SLuiz Augusto von Dentz 	ts     = hci_iso_flags_ts(flags);
1993ccf74f23SLuiz Augusto von Dentz 
1994ccf74f23SLuiz Augusto von Dentz 	BT_DBG("conn %p len %d pb 0x%x ts 0x%x", conn, skb->len, pb, ts);
1995ccf74f23SLuiz Augusto von Dentz 
1996ccf74f23SLuiz Augusto von Dentz 	switch (pb) {
1997ccf74f23SLuiz Augusto von Dentz 	case ISO_START:
1998ccf74f23SLuiz Augusto von Dentz 	case ISO_SINGLE:
1999ccf74f23SLuiz Augusto von Dentz 		if (conn->rx_len) {
2000ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Unexpected start frame (len %d)", skb->len);
2001ccf74f23SLuiz Augusto von Dentz 			kfree_skb(conn->rx_skb);
2002ccf74f23SLuiz Augusto von Dentz 			conn->rx_skb = NULL;
2003ccf74f23SLuiz Augusto von Dentz 			conn->rx_len = 0;
2004ccf74f23SLuiz Augusto von Dentz 		}
2005ccf74f23SLuiz Augusto von Dentz 
2006ccf74f23SLuiz Augusto von Dentz 		if (ts) {
20072f10e40aSPauli Virtanen 			struct hci_iso_ts_data_hdr *hdr;
20082f10e40aSPauli Virtanen 
2009ccf74f23SLuiz Augusto von Dentz 			/* TODO: add timestamp to the packet? */
2010ccf74f23SLuiz Augusto von Dentz 			hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE);
2011ccf74f23SLuiz Augusto von Dentz 			if (!hdr) {
2012ccf74f23SLuiz Augusto von Dentz 				BT_ERR("Frame is too short (len %d)", skb->len);
2013ccf74f23SLuiz Augusto von Dentz 				goto drop;
2014ccf74f23SLuiz Augusto von Dentz 			}
2015ccf74f23SLuiz Augusto von Dentz 
20162f10e40aSPauli Virtanen 			len = __le16_to_cpu(hdr->slen);
2017ccf74f23SLuiz Augusto von Dentz 		} else {
20182f10e40aSPauli Virtanen 			struct hci_iso_data_hdr *hdr;
20192f10e40aSPauli Virtanen 
2020ccf74f23SLuiz Augusto von Dentz 			hdr = skb_pull_data(skb, HCI_ISO_DATA_HDR_SIZE);
2021ccf74f23SLuiz Augusto von Dentz 			if (!hdr) {
2022ccf74f23SLuiz Augusto von Dentz 				BT_ERR("Frame is too short (len %d)", skb->len);
2023ccf74f23SLuiz Augusto von Dentz 				goto drop;
2024ccf74f23SLuiz Augusto von Dentz 			}
2025ccf74f23SLuiz Augusto von Dentz 
2026ccf74f23SLuiz Augusto von Dentz 			len = __le16_to_cpu(hdr->slen);
20272f10e40aSPauli Virtanen 		}
20282f10e40aSPauli Virtanen 
2029ccf74f23SLuiz Augusto von Dentz 		flags  = hci_iso_data_flags(len);
2030ccf74f23SLuiz Augusto von Dentz 		len    = hci_iso_data_len(len);
2031ccf74f23SLuiz Augusto von Dentz 
2032ccf74f23SLuiz Augusto von Dentz 		BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x", len,
2033ccf74f23SLuiz Augusto von Dentz 		       skb->len, flags);
2034ccf74f23SLuiz Augusto von Dentz 
2035ccf74f23SLuiz Augusto von Dentz 		if (len == skb->len) {
2036ccf74f23SLuiz Augusto von Dentz 			/* Complete frame received */
20370731c5abSLuiz Augusto von Dentz 			hci_skb_pkt_status(skb) = flags & 0x03;
2038ccf74f23SLuiz Augusto von Dentz 			iso_recv_frame(conn, skb);
2039ccf74f23SLuiz Augusto von Dentz 			return;
2040ccf74f23SLuiz Augusto von Dentz 		}
2041ccf74f23SLuiz Augusto von Dentz 
2042ccf74f23SLuiz Augusto von Dentz 		if (pb == ISO_SINGLE) {
2043ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Frame malformed (len %d, expected len %d)",
2044ccf74f23SLuiz Augusto von Dentz 			       skb->len, len);
2045ccf74f23SLuiz Augusto von Dentz 			goto drop;
2046ccf74f23SLuiz Augusto von Dentz 		}
2047ccf74f23SLuiz Augusto von Dentz 
2048ccf74f23SLuiz Augusto von Dentz 		if (skb->len > len) {
2049ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Frame is too long (len %d, expected len %d)",
2050ccf74f23SLuiz Augusto von Dentz 			       skb->len, len);
2051ccf74f23SLuiz Augusto von Dentz 			goto drop;
2052ccf74f23SLuiz Augusto von Dentz 		}
2053ccf74f23SLuiz Augusto von Dentz 
2054ccf74f23SLuiz Augusto von Dentz 		/* Allocate skb for the complete frame (with header) */
2055ccf74f23SLuiz Augusto von Dentz 		conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
2056ccf74f23SLuiz Augusto von Dentz 		if (!conn->rx_skb)
2057ccf74f23SLuiz Augusto von Dentz 			goto drop;
2058ccf74f23SLuiz Augusto von Dentz 
20590731c5abSLuiz Augusto von Dentz 		hci_skb_pkt_status(conn->rx_skb) = flags & 0x03;
2060ccf74f23SLuiz Augusto von Dentz 		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
2061ccf74f23SLuiz Augusto von Dentz 					  skb->len);
2062ccf74f23SLuiz Augusto von Dentz 		conn->rx_len = len - skb->len;
2063ccf74f23SLuiz Augusto von Dentz 		break;
2064ccf74f23SLuiz Augusto von Dentz 
2065ccf74f23SLuiz Augusto von Dentz 	case ISO_CONT:
2066ccf74f23SLuiz Augusto von Dentz 		BT_DBG("Cont: frag len %d (expecting %d)", skb->len,
2067ccf74f23SLuiz Augusto von Dentz 		       conn->rx_len);
2068ccf74f23SLuiz Augusto von Dentz 
2069ccf74f23SLuiz Augusto von Dentz 		if (!conn->rx_len) {
2070ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Unexpected continuation frame (len %d)",
2071ccf74f23SLuiz Augusto von Dentz 			       skb->len);
2072ccf74f23SLuiz Augusto von Dentz 			goto drop;
2073ccf74f23SLuiz Augusto von Dentz 		}
2074ccf74f23SLuiz Augusto von Dentz 
2075ccf74f23SLuiz Augusto von Dentz 		if (skb->len > conn->rx_len) {
2076ccf74f23SLuiz Augusto von Dentz 			BT_ERR("Fragment is too long (len %d, expected %d)",
2077ccf74f23SLuiz Augusto von Dentz 			       skb->len, conn->rx_len);
2078ccf74f23SLuiz Augusto von Dentz 			kfree_skb(conn->rx_skb);
2079ccf74f23SLuiz Augusto von Dentz 			conn->rx_skb = NULL;
2080ccf74f23SLuiz Augusto von Dentz 			conn->rx_len = 0;
2081ccf74f23SLuiz Augusto von Dentz 			goto drop;
2082ccf74f23SLuiz Augusto von Dentz 		}
2083ccf74f23SLuiz Augusto von Dentz 
2084ccf74f23SLuiz Augusto von Dentz 		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
2085ccf74f23SLuiz Augusto von Dentz 					  skb->len);
2086ccf74f23SLuiz Augusto von Dentz 		conn->rx_len -= skb->len;
2087ccf74f23SLuiz Augusto von Dentz 		return;
2088ccf74f23SLuiz Augusto von Dentz 
2089ccf74f23SLuiz Augusto von Dentz 	case ISO_END:
2090ccf74f23SLuiz Augusto von Dentz 		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
2091ccf74f23SLuiz Augusto von Dentz 					  skb->len);
2092ccf74f23SLuiz Augusto von Dentz 		conn->rx_len -= skb->len;
2093ccf74f23SLuiz Augusto von Dentz 
2094ccf74f23SLuiz Augusto von Dentz 		if (!conn->rx_len) {
2095ccf74f23SLuiz Augusto von Dentz 			struct sk_buff *rx_skb = conn->rx_skb;
2096ccf74f23SLuiz Augusto von Dentz 
2097ccf74f23SLuiz Augusto von Dentz 			/* Complete frame received. iso_recv_frame
2098ccf74f23SLuiz Augusto von Dentz 			 * takes ownership of the skb so set the global
2099ccf74f23SLuiz Augusto von Dentz 			 * rx_skb pointer to NULL first.
2100ccf74f23SLuiz Augusto von Dentz 			 */
2101ccf74f23SLuiz Augusto von Dentz 			conn->rx_skb = NULL;
2102ccf74f23SLuiz Augusto von Dentz 			iso_recv_frame(conn, rx_skb);
2103ccf74f23SLuiz Augusto von Dentz 		}
2104ccf74f23SLuiz Augusto von Dentz 		break;
2105ccf74f23SLuiz Augusto von Dentz 	}
2106ccf74f23SLuiz Augusto von Dentz 
2107ccf74f23SLuiz Augusto von Dentz drop:
2108ccf74f23SLuiz Augusto von Dentz 	kfree_skb(skb);
2109ccf74f23SLuiz Augusto von Dentz }
2110ccf74f23SLuiz Augusto von Dentz 
2111ccf74f23SLuiz Augusto von Dentz static struct hci_cb iso_cb = {
2112ccf74f23SLuiz Augusto von Dentz 	.name		= "ISO",
2113ccf74f23SLuiz Augusto von Dentz 	.connect_cfm	= iso_connect_cfm,
2114ccf74f23SLuiz Augusto von Dentz 	.disconn_cfm	= iso_disconn_cfm,
2115ccf74f23SLuiz Augusto von Dentz };
2116ccf74f23SLuiz Augusto von Dentz 
2117ccf74f23SLuiz Augusto von Dentz static int iso_debugfs_show(struct seq_file *f, void *p)
2118ccf74f23SLuiz Augusto von Dentz {
2119ccf74f23SLuiz Augusto von Dentz 	struct sock *sk;
2120ccf74f23SLuiz Augusto von Dentz 
2121ccf74f23SLuiz Augusto von Dentz 	read_lock(&iso_sk_list.lock);
2122ccf74f23SLuiz Augusto von Dentz 
iso_debugfs_show(struct seq_file * f,void * p)2123ccf74f23SLuiz Augusto von Dentz 	sk_for_each(sk, &iso_sk_list.head) {
2124ccf74f23SLuiz Augusto von Dentz 		seq_printf(f, "%pMR %pMR %d\n", &iso_pi(sk)->src,
2125ccf74f23SLuiz Augusto von Dentz 			   &iso_pi(sk)->dst, sk->sk_state);
2126ccf74f23SLuiz Augusto von Dentz 	}
2127ccf74f23SLuiz Augusto von Dentz 
2128ccf74f23SLuiz Augusto von Dentz 	read_unlock(&iso_sk_list.lock);
2129ccf74f23SLuiz Augusto von Dentz 
2130ccf74f23SLuiz Augusto von Dentz 	return 0;
2131ccf74f23SLuiz Augusto von Dentz }
2132ccf74f23SLuiz Augusto von Dentz 
2133ccf74f23SLuiz Augusto von Dentz DEFINE_SHOW_ATTRIBUTE(iso_debugfs);
2134ccf74f23SLuiz Augusto von Dentz 
2135ccf74f23SLuiz Augusto von Dentz static struct dentry *iso_debugfs;
2136ccf74f23SLuiz Augusto von Dentz 
2137ccf74f23SLuiz Augusto von Dentz static const struct proto_ops iso_sock_ops = {
2138ccf74f23SLuiz Augusto von Dentz 	.family		= PF_BLUETOOTH,
2139ccf74f23SLuiz Augusto von Dentz 	.owner		= THIS_MODULE,
2140ccf74f23SLuiz Augusto von Dentz 	.release	= iso_sock_release,
2141ccf74f23SLuiz Augusto von Dentz 	.bind		= iso_sock_bind,
2142ccf74f23SLuiz Augusto von Dentz 	.connect	= iso_sock_connect,
2143ccf74f23SLuiz Augusto von Dentz 	.listen		= iso_sock_listen,
2144ccf74f23SLuiz Augusto von Dentz 	.accept		= iso_sock_accept,
2145ccf74f23SLuiz Augusto von Dentz 	.getname	= iso_sock_getname,
2146ccf74f23SLuiz Augusto von Dentz 	.sendmsg	= iso_sock_sendmsg,
2147ccf74f23SLuiz Augusto von Dentz 	.recvmsg	= iso_sock_recvmsg,
2148ccf74f23SLuiz Augusto von Dentz 	.poll		= bt_sock_poll,
2149ccf74f23SLuiz Augusto von Dentz 	.ioctl		= bt_sock_ioctl,
2150ccf74f23SLuiz Augusto von Dentz 	.mmap		= sock_no_mmap,
2151ccf74f23SLuiz Augusto von Dentz 	.socketpair	= sock_no_socketpair,
2152ccf74f23SLuiz Augusto von Dentz 	.shutdown	= iso_sock_shutdown,
2153ccf74f23SLuiz Augusto von Dentz 	.setsockopt	= iso_sock_setsockopt,
2154ccf74f23SLuiz Augusto von Dentz 	.getsockopt	= iso_sock_getsockopt
2155ccf74f23SLuiz Augusto von Dentz };
2156ccf74f23SLuiz Augusto von Dentz 
2157ccf74f23SLuiz Augusto von Dentz static const struct net_proto_family iso_sock_family_ops = {
2158ccf74f23SLuiz Augusto von Dentz 	.family	= PF_BLUETOOTH,
2159ccf74f23SLuiz Augusto von Dentz 	.owner	= THIS_MODULE,
2160ccf74f23SLuiz Augusto von Dentz 	.create	= iso_sock_create,
2161ccf74f23SLuiz Augusto von Dentz };
2162ccf74f23SLuiz Augusto von Dentz 
2163ccf74f23SLuiz Augusto von Dentz static bool iso_inited;
2164ccf74f23SLuiz Augusto von Dentz 
2165ccf74f23SLuiz Augusto von Dentz bool iso_enabled(void)
2166ccf74f23SLuiz Augusto von Dentz {
2167ccf74f23SLuiz Augusto von Dentz 	return iso_inited;
2168ccf74f23SLuiz Augusto von Dentz }
2169ccf74f23SLuiz Augusto von Dentz 
2170ccf74f23SLuiz Augusto von Dentz int iso_init(void)
iso_enabled(void)2171ccf74f23SLuiz Augusto von Dentz {
2172ccf74f23SLuiz Augusto von Dentz 	int err;
2173ccf74f23SLuiz Augusto von Dentz 
2174ccf74f23SLuiz Augusto von Dentz 	BUILD_BUG_ON(sizeof(struct sockaddr_iso) > sizeof(struct sockaddr));
2175ccf74f23SLuiz Augusto von Dentz 
2176ccf74f23SLuiz Augusto von Dentz 	if (iso_inited)
2177ccf74f23SLuiz Augusto von Dentz 		return -EALREADY;
2178ccf74f23SLuiz Augusto von Dentz 
2179ccf74f23SLuiz Augusto von Dentz 	err = proto_register(&iso_proto, 0);
2180ccf74f23SLuiz Augusto von Dentz 	if (err < 0)
2181ccf74f23SLuiz Augusto von Dentz 		return err;
2182ccf74f23SLuiz Augusto von Dentz 
2183ccf74f23SLuiz Augusto von Dentz 	err = bt_sock_register(BTPROTO_ISO, &iso_sock_family_ops);
2184ccf74f23SLuiz Augusto von Dentz 	if (err < 0) {
2185ccf74f23SLuiz Augusto von Dentz 		BT_ERR("ISO socket registration failed");
2186ccf74f23SLuiz Augusto von Dentz 		goto error;
2187ccf74f23SLuiz Augusto von Dentz 	}
2188ccf74f23SLuiz Augusto von Dentz 
2189ccf74f23SLuiz Augusto von Dentz 	err = bt_procfs_init(&init_net, "iso", &iso_sk_list, NULL);
2190ccf74f23SLuiz Augusto von Dentz 	if (err < 0) {
2191ccf74f23SLuiz Augusto von Dentz 		BT_ERR("Failed to create ISO proc file");
2192ccf74f23SLuiz Augusto von Dentz 		bt_sock_unregister(BTPROTO_ISO);
2193ccf74f23SLuiz Augusto von Dentz 		goto error;
2194ccf74f23SLuiz Augusto von Dentz 	}
2195ccf74f23SLuiz Augusto von Dentz 
2196ccf74f23SLuiz Augusto von Dentz 	BT_INFO("ISO socket layer initialized");
2197ccf74f23SLuiz Augusto von Dentz 
2198ccf74f23SLuiz Augusto von Dentz 	hci_register_cb(&iso_cb);
2199ccf74f23SLuiz Augusto von Dentz 
22008fb8e912SAaron Thompson 	if (!IS_ERR_OR_NULL(bt_debugfs))
2201ccf74f23SLuiz Augusto von Dentz 		iso_debugfs = debugfs_create_file("iso", 0444, bt_debugfs,
2202ccf74f23SLuiz Augusto von Dentz 						  NULL, &iso_debugfs_fops);
2203ccf74f23SLuiz Augusto von Dentz 
2204ccf74f23SLuiz Augusto von Dentz 	iso_inited = true;
2205ccf74f23SLuiz Augusto von Dentz 
2206ccf74f23SLuiz Augusto von Dentz 	return 0;
2207ccf74f23SLuiz Augusto von Dentz 
2208ccf74f23SLuiz Augusto von Dentz error:
2209ccf74f23SLuiz Augusto von Dentz 	proto_unregister(&iso_proto);
2210ccf74f23SLuiz Augusto von Dentz 	return err;
2211ccf74f23SLuiz Augusto von Dentz }
2212ccf74f23SLuiz Augusto von Dentz 
2213ccf74f23SLuiz Augusto von Dentz int iso_exit(void)
2214ccf74f23SLuiz Augusto von Dentz {
2215ccf74f23SLuiz Augusto von Dentz 	if (!iso_inited)
2216ccf74f23SLuiz Augusto von Dentz 		return -EALREADY;
2217ccf74f23SLuiz Augusto von Dentz 
2218ccf74f23SLuiz Augusto von Dentz 	bt_procfs_cleanup(&init_net, "iso");
iso_exit(void)2219ccf74f23SLuiz Augusto von Dentz 
2220ccf74f23SLuiz Augusto von Dentz 	debugfs_remove(iso_debugfs);
2221ccf74f23SLuiz Augusto von Dentz 	iso_debugfs = NULL;
2222ccf74f23SLuiz Augusto von Dentz 
2223ccf74f23SLuiz Augusto von Dentz 	hci_unregister_cb(&iso_cb);
2224ccf74f23SLuiz Augusto von Dentz 
2225ccf74f23SLuiz Augusto von Dentz 	bt_sock_unregister(BTPROTO_ISO);
2226ccf74f23SLuiz Augusto von Dentz 
2227ccf74f23SLuiz Augusto von Dentz 	proto_unregister(&iso_proto);
2228ccf74f23SLuiz Augusto von Dentz 
2229ccf74f23SLuiz Augusto von Dentz 	iso_inited = false;
2230ccf74f23SLuiz Augusto von Dentz 
2231ccf74f23SLuiz Augusto von Dentz 	return 0;
2232ccf74f23SLuiz Augusto von Dentz }
2233