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