// SPDX-License-Identifier: GPL-2.0
/*
 * BlueZ - Bluetooth protocol stack for Linux
 *
 * Copyright (C) 2022 Intel Corporation
 * Copyright 2023-2024 NXP
 */

#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/sched/signal.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/iso.h>
#include "eir.h"

static const struct proto_ops iso_sock_ops;

static struct bt_sock_list iso_sk_list = {
	.lock = __RW_LOCK_UNLOCKED(iso_sk_list.lock)
};

/* ---- ISO connections ---- */
struct iso_conn {
	struct hci_conn	*hcon;

	/* @lock: spinlock protecting changes to iso_conn fields */
	spinlock_t	lock;
	struct sock	*sk;

	struct delayed_work	timeout_work;

	struct sk_buff	*rx_skb;
	__u32		rx_len;
	__u16		tx_sn;
	struct kref	ref;
};

#define iso_conn_lock(c)	spin_lock(&(c)->lock)
#define iso_conn_unlock(c)	spin_unlock(&(c)->lock)

static void iso_sock_close(struct sock *sk);
static void iso_sock_kill(struct sock *sk);

/* ----- ISO socket info ----- */
#define iso_pi(sk) ((struct iso_pinfo *)sk)

#define EIR_SERVICE_DATA_LENGTH 4
#define BASE_MAX_LENGTH (HCI_MAX_PER_AD_LENGTH - EIR_SERVICE_DATA_LENGTH)
#define EIR_BAA_SERVICE_UUID	0x1851

/* iso_pinfo flags values */
enum {
	BT_SK_BIG_SYNC,
	BT_SK_PA_SYNC,
};

struct iso_pinfo {
	struct bt_sock		bt;
	bdaddr_t		src;
	__u8			src_type;
	bdaddr_t		dst;
	__u8			dst_type;
	__u8			bc_sid;
	__u8			bc_num_bis;
	__u8			bc_bis[ISO_MAX_NUM_BIS];
	__u16			sync_handle;
	unsigned long		flags;
	struct bt_iso_qos	qos;
	bool			qos_user_set;
	__u8			base_len;
	__u8			base[BASE_MAX_LENGTH];
	struct iso_conn		*conn;
};

static struct bt_iso_qos default_qos;

static bool check_ucast_qos(struct bt_iso_qos *qos);
static bool check_bcast_qos(struct bt_iso_qos *qos);
static bool iso_match_sid(struct sock *sk, void *data);
static bool iso_match_sync_handle(struct sock *sk, void *data);
static bool iso_match_sync_handle_pa_report(struct sock *sk, void *data);
static void iso_sock_disconn(struct sock *sk);

typedef bool (*iso_sock_match_t)(struct sock *sk, void *data);

static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
				 enum bt_sock_state state,
				 iso_sock_match_t match, void *data);

/* ---- ISO timers ---- */
#define ISO_CONN_TIMEOUT	secs_to_jiffies(20)
#define ISO_DISCONN_TIMEOUT	secs_to_jiffies(2)

static void iso_conn_free(struct kref *ref)
{
	struct iso_conn *conn = container_of(ref, struct iso_conn, ref);

	BT_DBG("conn %p", conn);

	if (conn->sk)
		iso_pi(conn->sk)->conn = NULL;

	if (conn->hcon) {
		conn->hcon->iso_data = NULL;
		hci_conn_drop(conn->hcon);
	}

	/* Ensure no more work items will run since hci_conn has been dropped */
	disable_delayed_work_sync(&conn->timeout_work);

	kfree_skb(conn->rx_skb);

	kfree(conn);
}

static void iso_conn_put(struct iso_conn *conn)
{
	if (!conn)
		return;

	BT_DBG("conn %p refcnt %d", conn, kref_read(&conn->ref));

	kref_put(&conn->ref, iso_conn_free);
}

static struct iso_conn *iso_conn_hold_unless_zero(struct iso_conn *conn)
{
	if (!conn)
		return NULL;

	BT_DBG("conn %p refcnt %u", conn, kref_read(&conn->ref));

	if (!kref_get_unless_zero(&conn->ref))
		return NULL;

	return conn;
}

static struct sock *iso_sock_hold(struct iso_conn *conn)
{
	if (!conn || !bt_sock_linked(&iso_sk_list, conn->sk))
		return NULL;

	sock_hold(conn->sk);

	return conn->sk;
}

static void iso_sock_timeout(struct work_struct *work)
{
	struct iso_conn *conn = container_of(work, struct iso_conn,
					     timeout_work.work);
	struct sock *sk;

	conn = iso_conn_hold_unless_zero(conn);
	if (!conn)
		return;

	iso_conn_lock(conn);
	sk = iso_sock_hold(conn);
	iso_conn_unlock(conn);
	iso_conn_put(conn);

	if (!sk)
		return;

	BT_DBG("sock %p state %d", sk, sk->sk_state);

	lock_sock(sk);
	sk->sk_err = ETIMEDOUT;
	sk->sk_state_change(sk);
	release_sock(sk);
	sock_put(sk);
}

static void iso_sock_set_timer(struct sock *sk, long timeout)
{
	if (!iso_pi(sk)->conn)
		return;

	BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
	cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
	schedule_delayed_work(&iso_pi(sk)->conn->timeout_work, timeout);
}

static void iso_sock_clear_timer(struct sock *sk)
{
	if (!iso_pi(sk)->conn)
		return;

	BT_DBG("sock %p state %d", sk, sk->sk_state);
	cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
}

/* ---- ISO connections ---- */
static struct iso_conn *iso_conn_add(struct hci_conn *hcon)
{
	struct iso_conn *conn = hcon->iso_data;

	conn = iso_conn_hold_unless_zero(conn);
	if (conn) {
		if (!conn->hcon) {
			iso_conn_lock(conn);
			conn->hcon = hcon;
			iso_conn_unlock(conn);
		}
		iso_conn_put(conn);
		return conn;
	}

	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
	if (!conn)
		return NULL;

	kref_init(&conn->ref);
	spin_lock_init(&conn->lock);
	INIT_DELAYED_WORK(&conn->timeout_work, iso_sock_timeout);

	hcon->iso_data = conn;
	conn->hcon = hcon;
	conn->tx_sn = 0;

	BT_DBG("hcon %p conn %p", hcon, conn);

	return conn;
}

/* Delete channel. Must be called on the locked socket. */
static void iso_chan_del(struct sock *sk, int err)
{
	struct iso_conn *conn;
	struct sock *parent;

	conn = iso_pi(sk)->conn;
	iso_pi(sk)->conn = NULL;

	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);

	if (conn) {
		iso_conn_lock(conn);
		conn->sk = NULL;
		iso_conn_unlock(conn);
		iso_conn_put(conn);
	}

	sk->sk_state = BT_CLOSED;
	sk->sk_err   = err;

	parent = bt_sk(sk)->parent;
	if (parent) {
		bt_accept_unlink(sk);
		parent->sk_data_ready(parent);
	} else {
		sk->sk_state_change(sk);
	}

	sock_set_flag(sk, SOCK_ZAPPED);
}

static void iso_conn_del(struct hci_conn *hcon, int err)
{
	struct iso_conn *conn = hcon->iso_data;
	struct sock *sk;

	conn = iso_conn_hold_unless_zero(conn);
	if (!conn)
		return;

	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);

	/* Kill socket */
	iso_conn_lock(conn);
	sk = iso_sock_hold(conn);
	iso_conn_unlock(conn);
	iso_conn_put(conn);

	if (!sk) {
		iso_conn_put(conn);
		return;
	}

	lock_sock(sk);
	iso_sock_clear_timer(sk);
	iso_chan_del(sk, err);
	release_sock(sk);
	sock_put(sk);
}

static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
			  struct sock *parent)
{
	BT_DBG("conn %p", conn);

	if (iso_pi(sk)->conn == conn && conn->sk == sk)
		return 0;

	if (conn->sk) {
		BT_ERR("conn->sk already set");
		return -EBUSY;
	}

	iso_pi(sk)->conn = conn;
	conn->sk = sk;

	if (parent)
		bt_accept_enqueue(parent, sk, true);

	return 0;
}

static int iso_chan_add(struct iso_conn *conn, struct sock *sk,
			struct sock *parent)
{
	int err;

	iso_conn_lock(conn);
	err = __iso_chan_add(conn, sk, parent);
	iso_conn_unlock(conn);

	return err;
}

static inline u8 le_addr_type(u8 bdaddr_type)
{
	if (bdaddr_type == BDADDR_LE_PUBLIC)
		return ADDR_LE_DEV_PUBLIC;
	else
		return ADDR_LE_DEV_RANDOM;
}

static int iso_connect_bis(struct sock *sk)
{
	struct iso_conn *conn;
	struct hci_conn *hcon;
	struct hci_dev  *hdev;
	int err;

	BT_DBG("%pMR (SID 0x%2.2x)", &iso_pi(sk)->src, iso_pi(sk)->bc_sid);

	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
			     iso_pi(sk)->src_type);
	if (!hdev)
		return -EHOSTUNREACH;

	hci_dev_lock(hdev);

	if (!bis_capable(hdev)) {
		err = -EOPNOTSUPP;
		goto unlock;
	}

	/* Fail if user set invalid QoS */
	if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
		iso_pi(sk)->qos = default_qos;
		err = -EINVAL;
		goto unlock;
	}

	/* Fail if out PHYs are marked as disabled */
	if (!iso_pi(sk)->qos.bcast.out.phy) {
		err = -EINVAL;
		goto unlock;
	}

	/* Just bind if DEFER_SETUP has been set */
	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
		hcon = hci_bind_bis(hdev, &iso_pi(sk)->dst, iso_pi(sk)->bc_sid,
				    &iso_pi(sk)->qos, iso_pi(sk)->base_len,
				    iso_pi(sk)->base,
				    READ_ONCE(sk->sk_sndtimeo));
		if (IS_ERR(hcon)) {
			err = PTR_ERR(hcon);
			goto unlock;
		}
	} else {
		hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
				       le_addr_type(iso_pi(sk)->dst_type),
				       iso_pi(sk)->bc_sid, &iso_pi(sk)->qos,
				       iso_pi(sk)->base_len, iso_pi(sk)->base,
				       READ_ONCE(sk->sk_sndtimeo));
		if (IS_ERR(hcon)) {
			err = PTR_ERR(hcon);
			goto unlock;
		}

		/* Update SID if it was not set */
		if (iso_pi(sk)->bc_sid == HCI_SID_INVALID)
			iso_pi(sk)->bc_sid = hcon->sid;
	}

	conn = iso_conn_add(hcon);
	if (!conn) {
		hci_conn_drop(hcon);
		err = -ENOMEM;
		goto unlock;
	}

	lock_sock(sk);

	err = iso_chan_add(conn, sk, NULL);
	if (err) {
		release_sock(sk);
		goto unlock;
	}

	/* Update source addr of the socket */
	bacpy(&iso_pi(sk)->src, &hcon->src);

	if (hcon->state == BT_CONNECTED) {
		iso_sock_clear_timer(sk);
		sk->sk_state = BT_CONNECTED;
	} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
		iso_sock_clear_timer(sk);
		sk->sk_state = BT_CONNECT;
	} else {
		sk->sk_state = BT_CONNECT;
		iso_sock_set_timer(sk, READ_ONCE(sk->sk_sndtimeo));
	}

	release_sock(sk);

unlock:
	hci_dev_unlock(hdev);
	hci_dev_put(hdev);
	return err;
}

static int iso_connect_cis(struct sock *sk)
{
	struct iso_conn *conn;
	struct hci_conn *hcon;
	struct hci_dev  *hdev;
	int err;

	BT_DBG("%pMR -> %pMR", &iso_pi(sk)->src, &iso_pi(sk)->dst);

	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
			     iso_pi(sk)->src_type);
	if (!hdev)
		return -EHOSTUNREACH;

	hci_dev_lock(hdev);

	if (!cis_central_capable(hdev)) {
		err = -EOPNOTSUPP;
		goto unlock;
	}

	/* Fail if user set invalid QoS */
	if (iso_pi(sk)->qos_user_set && !check_ucast_qos(&iso_pi(sk)->qos)) {
		iso_pi(sk)->qos = default_qos;
		err = -EINVAL;
		goto unlock;
	}

	/* Fail if either PHYs are marked as disabled */
	if (!iso_pi(sk)->qos.ucast.in.phy && !iso_pi(sk)->qos.ucast.out.phy) {
		err = -EINVAL;
		goto unlock;
	}

	/* Check if there are available buffers for output/TX. */
	if (iso_pi(sk)->qos.ucast.out.sdu && !hci_iso_count(hdev) &&
	    (hdev->iso_pkts && !hdev->iso_cnt)) {
		err = -ENOBUFS;
		goto unlock;
	}

	/* Just bind if DEFER_SETUP has been set */
	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
		hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,
				    le_addr_type(iso_pi(sk)->dst_type),
				    &iso_pi(sk)->qos,
				    READ_ONCE(sk->sk_sndtimeo));
		if (IS_ERR(hcon)) {
			err = PTR_ERR(hcon);
			goto unlock;
		}
	} else {
		hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
				       le_addr_type(iso_pi(sk)->dst_type),
				       &iso_pi(sk)->qos,
				       READ_ONCE(sk->sk_sndtimeo));
		if (IS_ERR(hcon)) {
			err = PTR_ERR(hcon);
			goto unlock;
		}
	}

	conn = iso_conn_add(hcon);
	if (!conn) {
		hci_conn_drop(hcon);
		err = -ENOMEM;
		goto unlock;
	}

	lock_sock(sk);

	err = iso_chan_add(conn, sk, NULL);
	if (err) {
		release_sock(sk);
		goto unlock;
	}

	/* Update source addr of the socket */
	bacpy(&iso_pi(sk)->src, &hcon->src);

	if (hcon->state == BT_CONNECTED) {
		iso_sock_clear_timer(sk);
		sk->sk_state = BT_CONNECTED;
	} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
		iso_sock_clear_timer(sk);
		sk->sk_state = BT_CONNECT;
	} else {
		sk->sk_state = BT_CONNECT;
		iso_sock_set_timer(sk, READ_ONCE(sk->sk_sndtimeo));
	}

	release_sock(sk);

unlock:
	hci_dev_unlock(hdev);
	hci_dev_put(hdev);
	return err;
}

static struct bt_iso_qos *iso_sock_get_qos(struct sock *sk)
{
	if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONNECT2)
		return &iso_pi(sk)->conn->hcon->iso_qos;

	return &iso_pi(sk)->qos;
}

static int iso_send_frame(struct sock *sk, struct sk_buff *skb,
			  const struct sockcm_cookie *sockc)
{
	struct iso_conn *conn = iso_pi(sk)->conn;
	struct bt_iso_qos *qos = iso_sock_get_qos(sk);
	struct hci_iso_data_hdr *hdr;
	int len = 0;

	BT_DBG("sk %p len %d", sk, skb->len);

	if (skb->len > qos->ucast.out.sdu)
		return -EMSGSIZE;

	len = skb->len;

	/* Push ISO data header */
	hdr = skb_push(skb, HCI_ISO_DATA_HDR_SIZE);
	hdr->sn = cpu_to_le16(conn->tx_sn++);
	hdr->slen = cpu_to_le16(hci_iso_data_len_pack(len,
						      HCI_ISO_STATUS_VALID));

	if (sk->sk_state == BT_CONNECTED) {
		hci_setup_tx_timestamp(skb, 1, sockc);
		hci_send_iso(conn->hcon, skb);
	} else {
		len = -ENOTCONN;
	}

	return len;
}

static void iso_recv_frame(struct iso_conn *conn, struct sk_buff *skb)
{
	struct sock *sk;

	iso_conn_lock(conn);
	sk = conn->sk;
	iso_conn_unlock(conn);

	if (!sk)
		goto drop;

	BT_DBG("sk %p len %d", sk, skb->len);

	if (sk->sk_state != BT_CONNECTED)
		goto drop;

	if (!sock_queue_rcv_skb(sk, skb))
		return;

drop:
	kfree_skb(skb);
}

/* -------- Socket interface ---------- */
static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst)
{
	struct sock *sk;

	sk_for_each(sk, &iso_sk_list.head) {
		if (sk->sk_state != BT_LISTEN)
			continue;

		if (bacmp(&iso_pi(sk)->dst, dst))
			continue;

		if (!bacmp(&iso_pi(sk)->src, src))
			return sk;
	}

	return NULL;
}

static struct sock *__iso_get_sock_listen_by_sid(bdaddr_t *ba, bdaddr_t *bc,
						 __u8 sid)
{
	struct sock *sk;

	sk_for_each(sk, &iso_sk_list.head) {
		if (sk->sk_state != BT_LISTEN)
			continue;

		if (bacmp(&iso_pi(sk)->src, ba))
			continue;

		if (bacmp(&iso_pi(sk)->dst, bc))
			continue;

		if (iso_pi(sk)->bc_sid == sid)
			return sk;
	}

	return NULL;
}

/* Find socket in given state:
 * source bdaddr (Unicast)
 * destination bdaddr (Broadcast only)
 * match func - pass NULL to ignore
 * match func data - pass -1 to ignore
 * Returns closest match.
 */
static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
				 enum bt_sock_state state,
				 iso_sock_match_t match, void *data)
{
	struct sock *sk = NULL, *sk1 = NULL;

	read_lock(&iso_sk_list.lock);

	sk_for_each(sk, &iso_sk_list.head) {
		if (sk->sk_state != state)
			continue;

		/* Match Broadcast destination */
		if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst))
			continue;

		/* Use Match function if provided */
		if (match && !match(sk, data))
			continue;

		/* Exact match. */
		if (!bacmp(&iso_pi(sk)->src, src)) {
			sock_hold(sk);
			break;
		}

		/* Closest match */
		if (!bacmp(&iso_pi(sk)->src, BDADDR_ANY)) {
			if (sk1)
				sock_put(sk1);

			sk1 = sk;
			sock_hold(sk1);
		}
	}

	if (sk && sk1)
		sock_put(sk1);

	read_unlock(&iso_sk_list.lock);

	return sk ? sk : sk1;
}

static struct sock *iso_get_sock_big(struct sock *match_sk, bdaddr_t *src,
				     bdaddr_t *dst, uint8_t big)
{
	struct sock *sk = NULL;

	read_lock(&iso_sk_list.lock);

	sk_for_each(sk, &iso_sk_list.head) {
		if (match_sk == sk)
			continue;

		/* Look for sockets that have already been
		 * connected to the BIG
		 */
		if (sk->sk_state != BT_CONNECTED &&
		    sk->sk_state != BT_CONNECT)
			continue;

		/* Match Broadcast destination */
		if (bacmp(&iso_pi(sk)->dst, dst))
			continue;

		/* Match BIG handle */
		if (iso_pi(sk)->qos.bcast.big != big)
			continue;

		/* Match source address */
		if (bacmp(&iso_pi(sk)->src, src))
			continue;

		sock_hold(sk);
		break;
	}

	read_unlock(&iso_sk_list.lock);

	return sk;
}

static void iso_sock_destruct(struct sock *sk)
{
	BT_DBG("sk %p", sk);

	iso_conn_put(iso_pi(sk)->conn);

	skb_queue_purge(&sk->sk_receive_queue);
	skb_queue_purge(&sk->sk_write_queue);
	skb_queue_purge(&sk->sk_error_queue);
}

static void iso_sock_cleanup_listen(struct sock *parent)
{
	struct sock *sk;

	BT_DBG("parent %p", parent);

	/* Close not yet accepted channels */
	while ((sk = bt_accept_dequeue(parent, NULL))) {
		iso_sock_close(sk);
		iso_sock_kill(sk);
		/* Drop the reference handed back by bt_accept_dequeue(). */
		sock_put(sk);
	}

	/* If listening socket has a hcon, properly disconnect it */
	if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon) {
		iso_sock_disconn(parent);
		return;
	}

	parent->sk_state  = BT_CLOSED;
	sock_set_flag(parent, SOCK_ZAPPED);
}

/* Kill socket (only if zapped and orphan)
 * Must be called on unlocked socket.
 */
static void iso_sock_kill(struct sock *sk)
{
	if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket ||
	    sock_flag(sk, SOCK_DEAD))
		return;

	BT_DBG("sk %p state %d", sk, sk->sk_state);

	/* Sock is dead, so set conn->sk to NULL to avoid possible UAF */
	if (iso_pi(sk)->conn) {
		iso_conn_lock(iso_pi(sk)->conn);
		iso_pi(sk)->conn->sk = NULL;
		iso_conn_unlock(iso_pi(sk)->conn);
	}

	/* Kill poor orphan */
	bt_sock_unlink(&iso_sk_list, sk);
	sock_set_flag(sk, SOCK_DEAD);
	sock_put(sk);
}

static void iso_sock_disconn(struct sock *sk)
{
	struct sock *bis_sk;
	struct hci_conn *hcon = iso_pi(sk)->conn->hcon;

	if (test_bit(HCI_CONN_BIG_CREATED, &hcon->flags)) {
		bis_sk = iso_get_sock_big(sk, &iso_pi(sk)->src,
					  &iso_pi(sk)->dst,
					  iso_pi(sk)->qos.bcast.big);

		/* If there are any other connected sockets for the
		 * same BIG, just delete the sk and leave the bis
		 * hcon active, in case later rebinding is needed.
		 */
		if (bis_sk) {
			hcon->state = BT_OPEN;
			hcon->iso_data = NULL;
			iso_pi(sk)->conn->hcon = NULL;
			iso_sock_clear_timer(sk);
			iso_chan_del(sk, bt_to_errno(hcon->abort_reason));
			sock_put(bis_sk);
			return;
		}
	}

	sk->sk_state = BT_DISCONN;
	iso_conn_lock(iso_pi(sk)->conn);
	hci_conn_drop(iso_pi(sk)->conn->hcon);
	iso_pi(sk)->conn->hcon = NULL;
	iso_conn_unlock(iso_pi(sk)->conn);
}

static void __iso_sock_close(struct sock *sk)
{
	BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);

	switch (sk->sk_state) {
	case BT_LISTEN:
		iso_sock_cleanup_listen(sk);
		break;

	case BT_CONNECT:
	case BT_CONNECTED:
	case BT_CONFIG:
		if (iso_pi(sk)->conn->hcon)
			iso_sock_disconn(sk);
		else
			iso_chan_del(sk, ECONNRESET);
		break;

	case BT_CONNECT2:
		if (iso_pi(sk)->conn->hcon &&
		    (test_bit(HCI_CONN_PA_SYNC, &iso_pi(sk)->conn->hcon->flags) ||
		    test_bit(HCI_CONN_PA_SYNC_FAILED, &iso_pi(sk)->conn->hcon->flags)))
			iso_sock_disconn(sk);
		else
			iso_chan_del(sk, ECONNRESET);
		break;
	case BT_DISCONN:
		iso_chan_del(sk, ECONNRESET);
		break;

	default:
		sock_set_flag(sk, SOCK_ZAPPED);
		break;
	}
}

/* Must be called on unlocked socket. */
static void iso_sock_close(struct sock *sk)
{
	iso_sock_clear_timer(sk);
	lock_sock(sk);
	__iso_sock_close(sk);
	release_sock(sk);
	iso_sock_kill(sk);
}

static void iso_sock_init(struct sock *sk, struct sock *parent)
{
	BT_DBG("sk %p", sk);

	if (parent) {
		sk->sk_type = parent->sk_type;
		bt_sk(sk)->flags = bt_sk(parent)->flags;
		security_sk_clone(parent, sk);
	}
}

static struct proto iso_proto = {
	.name		= "ISO",
	.owner		= THIS_MODULE,
	.obj_size	= sizeof(struct iso_pinfo)
};

#define DEFAULT_IO_QOS \
{ \
	.interval	= 10000u, \
	.latency	= 10u, \
	.sdu		= 40u, \
	.phy		= BT_ISO_PHY_2M, \
	.rtn		= 2u, \
}

static struct bt_iso_qos default_qos = {
	.bcast = {
		.big			= BT_ISO_QOS_BIG_UNSET,
		.bis			= BT_ISO_QOS_BIS_UNSET,
		.sync_factor		= 0x01,
		.packing		= 0x00,
		.framing		= 0x00,
		.in			= DEFAULT_IO_QOS,
		.out			= DEFAULT_IO_QOS,
		.encryption		= 0x00,
		.bcode			= {0x00},
		.options		= 0x00,
		.skip			= 0x0000,
		.sync_timeout		= BT_ISO_SYNC_TIMEOUT,
		.sync_cte_type		= 0x00,
		.mse			= 0x00,
		.timeout		= BT_ISO_SYNC_TIMEOUT,
	},
};

static struct sock *iso_sock_alloc(struct net *net, struct socket *sock,
				   int proto, gfp_t prio, int kern)
{
	struct sock *sk;

	sk = bt_sock_alloc(net, sock, &iso_proto, proto, prio, kern);
	if (!sk)
		return NULL;

	sk->sk_destruct = iso_sock_destruct;
	sk->sk_sndtimeo = ISO_CONN_TIMEOUT;

	/* Set address type as public as default src address is BDADDR_ANY */
	iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;

	iso_pi(sk)->qos = default_qos;
	iso_pi(sk)->sync_handle = -1;

	bt_sock_link(&iso_sk_list, sk);
	return sk;
}

static int iso_sock_create(struct net *net, struct socket *sock, int protocol,
			   int kern)
{
	struct sock *sk;

	BT_DBG("sock %p", sock);

	sock->state = SS_UNCONNECTED;

	if (sock->type != SOCK_SEQPACKET)
		return -ESOCKTNOSUPPORT;

	sock->ops = &iso_sock_ops;

	sk = iso_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
	if (!sk)
		return -ENOMEM;

	iso_sock_init(sk, NULL);
	return 0;
}

static int iso_sock_bind_bc(struct socket *sock, struct sockaddr *addr,
			    int addr_len)
{
	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
	struct sock *sk = sock->sk;
	int i;

	BT_DBG("sk %p bc_sid %u bc_num_bis %u", sk, sa->iso_bc->bc_sid,
	       sa->iso_bc->bc_num_bis);

	if (addr_len != sizeof(*sa) + sizeof(*sa->iso_bc))
		return -EINVAL;

	bacpy(&iso_pi(sk)->dst, &sa->iso_bc->bc_bdaddr);

	/* Check if the address type is of LE type */
	if (!bdaddr_type_is_le(sa->iso_bc->bc_bdaddr_type))
		return -EINVAL;

	iso_pi(sk)->dst_type = sa->iso_bc->bc_bdaddr_type;

	if (sa->iso_bc->bc_sid > 0x0f && sa->iso_bc->bc_sid != HCI_SID_INVALID)
		return -EINVAL;

	iso_pi(sk)->bc_sid = sa->iso_bc->bc_sid;

	if (sa->iso_bc->bc_num_bis > ISO_MAX_NUM_BIS)
		return -EINVAL;

	iso_pi(sk)->bc_num_bis = sa->iso_bc->bc_num_bis;

	for (i = 0; i < iso_pi(sk)->bc_num_bis; i++)
		if (sa->iso_bc->bc_bis[i] < 0x01 ||
		    sa->iso_bc->bc_bis[i] > 0x1f)
			return -EINVAL;

	memcpy(iso_pi(sk)->bc_bis, sa->iso_bc->bc_bis,
	       iso_pi(sk)->bc_num_bis);

	return 0;
}

static int iso_sock_bind_pa_sk(struct sock *sk, struct sockaddr_iso *sa,
			       int addr_len)
{
	int err = 0;

	if (sk->sk_type != SOCK_SEQPACKET) {
		err = -EINVAL;
		goto done;
	}

	if (addr_len != sizeof(*sa) + sizeof(*sa->iso_bc)) {
		err = -EINVAL;
		goto done;
	}

	if (sa->iso_bc->bc_num_bis > ISO_MAX_NUM_BIS) {
		err = -EINVAL;
		goto done;
	}

	iso_pi(sk)->bc_num_bis = sa->iso_bc->bc_num_bis;

	for (int i = 0; i < iso_pi(sk)->bc_num_bis; i++)
		if (sa->iso_bc->bc_bis[i] < 0x01 ||
		    sa->iso_bc->bc_bis[i] > 0x1f) {
			err = -EINVAL;
			goto done;
		}

	memcpy(iso_pi(sk)->bc_bis, sa->iso_bc->bc_bis,
	       iso_pi(sk)->bc_num_bis);

done:
	return err;
}

static int iso_sock_bind(struct socket *sock, struct sockaddr *addr,
			 int addr_len)
{
	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
	struct sock *sk = sock->sk;
	int err = 0;

	BT_DBG("sk %p %pMR type %u", sk, &sa->iso_bdaddr, sa->iso_bdaddr_type);

	if (!addr || addr_len < sizeof(struct sockaddr_iso) ||
	    addr->sa_family != AF_BLUETOOTH)
		return -EINVAL;

	lock_sock(sk);

	/* Allow the user to bind a PA sync socket to a number
	 * of BISes to sync to.
	 */
	if ((sk->sk_state == BT_CONNECT2 ||
	     sk->sk_state == BT_CONNECTED) &&
	    test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
		err = iso_sock_bind_pa_sk(sk, sa, addr_len);
		goto done;
	}

	if (sk->sk_state != BT_OPEN) {
		err = -EBADFD;
		goto done;
	}

	if (sk->sk_type != SOCK_SEQPACKET) {
		err = -EINVAL;
		goto done;
	}

	/* Check if the address type is of LE type */
	if (!bdaddr_type_is_le(sa->iso_bdaddr_type)) {
		err = -EINVAL;
		goto done;
	}

	bacpy(&iso_pi(sk)->src, &sa->iso_bdaddr);
	iso_pi(sk)->src_type = sa->iso_bdaddr_type;

	/* Check for Broadcast address */
	if (addr_len > sizeof(*sa)) {
		err = iso_sock_bind_bc(sock, addr, addr_len);
		if (err)
			goto done;
	}

	sk->sk_state = BT_BOUND;

done:
	release_sock(sk);
	return err;
}

static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
			    int alen, int flags)
{
	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
	struct sock *sk = sock->sk;
	int err;

	BT_DBG("sk %p", sk);

	if (alen < sizeof(struct sockaddr_iso) ||
	    addr->sa_family != AF_BLUETOOTH)
		return -EINVAL;

	if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
		return -EBADFD;

	if (sk->sk_type != SOCK_SEQPACKET)
		return -EINVAL;

	/* Check if the address type is of LE type */
	if (!bdaddr_type_is_le(sa->iso_bdaddr_type))
		return -EINVAL;

	lock_sock(sk);

	bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
	iso_pi(sk)->dst_type = sa->iso_bdaddr_type;

	release_sock(sk);

	if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
		err = iso_connect_cis(sk);
	else
		err = iso_connect_bis(sk);

	if (err)
		return err;

	lock_sock(sk);

	if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
		err = bt_sock_wait_state(sk, BT_CONNECTED,
					 sock_sndtimeo(sk, flags & O_NONBLOCK));
	}

	release_sock(sk);
	return err;
}

static int iso_listen_bis(struct sock *sk)
{
	struct hci_dev *hdev;
	int err = 0;
	struct iso_conn *conn;
	struct hci_conn *hcon;

	BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
	       &iso_pi(sk)->dst, iso_pi(sk)->bc_sid);

	write_lock(&iso_sk_list.lock);

	if (__iso_get_sock_listen_by_sid(&iso_pi(sk)->src, &iso_pi(sk)->dst,
					 iso_pi(sk)->bc_sid))
		err = -EADDRINUSE;

	write_unlock(&iso_sk_list.lock);

	if (err)
		return err;

	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
			     iso_pi(sk)->src_type);
	if (!hdev)
		return -EHOSTUNREACH;

	hci_dev_lock(hdev);
	lock_sock(sk);

	/* Fail if user set invalid QoS */
	if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
		iso_pi(sk)->qos = default_qos;
		err = -EINVAL;
		goto unlock;
	}

	hcon = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
				  le_addr_type(iso_pi(sk)->dst_type),
				  iso_pi(sk)->bc_sid, &iso_pi(sk)->qos);
	if (IS_ERR(hcon)) {
		err = PTR_ERR(hcon);
		goto unlock;
	}

	conn = iso_conn_add(hcon);
	if (!conn) {
		hci_conn_drop(hcon);
		err = -ENOMEM;
		goto unlock;
	}

	err = iso_chan_add(conn, sk, NULL);
	if (err) {
		hci_conn_drop(hcon);
		goto unlock;
	}

unlock:
	release_sock(sk);
	hci_dev_unlock(hdev);
	hci_dev_put(hdev);
	return err;
}

static int iso_listen_cis(struct sock *sk)
{
	int err = 0;

	BT_DBG("%pMR", &iso_pi(sk)->src);

	write_lock(&iso_sk_list.lock);

	if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst))
		err = -EADDRINUSE;

	write_unlock(&iso_sk_list.lock);

	return err;
}

static int iso_sock_listen(struct socket *sock, int backlog)
{
	struct sock *sk = sock->sk;
	int err = 0;

	BT_DBG("sk %p backlog %d", sk, backlog);

	sock_hold(sk);
	lock_sock(sk);

	if (sk->sk_state != BT_BOUND) {
		err = -EBADFD;
		goto done;
	}

	if (sk->sk_type != SOCK_SEQPACKET) {
		err = -EINVAL;
		goto done;
	}

	if (!bacmp(&iso_pi(sk)->dst, BDADDR_ANY)) {
		err = iso_listen_cis(sk);
	} else {
		/* Drop sock lock to avoid potential
		 * deadlock with the hdev lock.
		 */
		release_sock(sk);
		err = iso_listen_bis(sk);
		lock_sock(sk);
	}

	if (err)
		goto done;

	sk->sk_max_ack_backlog = backlog;
	sk->sk_ack_backlog = 0;

	sk->sk_state = BT_LISTEN;

done:
	release_sock(sk);
	sock_put(sk);
	return err;
}

static int iso_sock_accept(struct socket *sock, struct socket *newsock,
			   struct proto_accept_arg *arg)
{
	DEFINE_WAIT_FUNC(wait, woken_wake_function);
	struct sock *sk = sock->sk, *ch;
	long timeo;
	int err = 0;

	/* Use explicit nested locking to avoid lockdep warnings generated
	 * because the parent socket and the child socket are locked on the
	 * same thread.
	 */
	lock_sock_nested(sk, SINGLE_DEPTH_NESTING);

	timeo = sock_rcvtimeo(sk, arg->flags & O_NONBLOCK);

	BT_DBG("sk %p timeo %ld", sk, timeo);

	/* Wait for an incoming connection. (wake-one). */
	add_wait_queue_exclusive(sk_sleep(sk), &wait);
	while (1) {
		if (sk->sk_state != BT_LISTEN) {
			err = -EBADFD;
			break;
		}

		ch = bt_accept_dequeue(sk, newsock);
		if (ch) {
			/* Drop the bridging ref from bt_accept_dequeue();
			 * the grafted socket keeps ch alive from here.
			 */
			sock_put(ch);
			break;
		}

		if (!timeo) {
			err = -EAGAIN;
			break;
		}

		if (signal_pending(current)) {
			err = sock_intr_errno(timeo);
			break;
		}

		release_sock(sk);

		timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
		lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
	}
	remove_wait_queue(sk_sleep(sk), &wait);

	if (err)
		goto done;

	newsock->state = SS_CONNECTED;

	BT_DBG("new socket %p", ch);

	/* A Broadcast Sink might require BIG sync to be terminated
	 * and re-established multiple times, while keeping the same
	 * PA sync handle active. To allow this, once all BIS
	 * connections have been accepted on a PA sync parent socket,
	 * "reset" socket state, to allow future BIG re-sync procedures.
	 */
	if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
		/* Iterate through the list of bound BIS indices
		 * and clear each BIS as they are accepted by the
		 * user space, one by one.
		 */
		for (int i = 0; i < iso_pi(sk)->bc_num_bis; i++) {
			if (iso_pi(sk)->bc_bis[i] > 0) {
				iso_pi(sk)->bc_bis[i] = 0;
				iso_pi(sk)->bc_num_bis--;
				break;
			}
		}

		if (iso_pi(sk)->bc_num_bis == 0) {
			/* Once the last BIS was accepted, reset parent
			 * socket parameters to mark that the listening
			 * process for BIS connections has been completed:
			 *
			 * 1. Reset the DEFER setup flag on the parent sk.
			 * 2. Clear the flag marking that the BIG create
			 *    sync command is pending.
			 * 3. Transition socket state from BT_LISTEN to
			 *    BT_CONNECTED.
			 */
			set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
			clear_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags);
			sk->sk_state = BT_CONNECTED;
		}
	}

done:
	release_sock(sk);
	return err;
}

static int iso_sock_getname(struct socket *sock, struct sockaddr *addr,
			    int peer)
{
	struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
	struct sock *sk = sock->sk;
	int len = sizeof(struct sockaddr_iso);

	BT_DBG("sock %p, sk %p", sock, sk);

	addr->sa_family = AF_BLUETOOTH;

	if (peer) {
		struct hci_conn *hcon = iso_pi(sk)->conn ?
					iso_pi(sk)->conn->hcon : NULL;

		bacpy(&sa->iso_bdaddr, &iso_pi(sk)->dst);
		sa->iso_bdaddr_type = iso_pi(sk)->dst_type;

		if (hcon && (hcon->type == BIS_LINK || hcon->type == PA_LINK)) {
			sa->iso_bc->bc_sid = iso_pi(sk)->bc_sid;
			sa->iso_bc->bc_num_bis = iso_pi(sk)->bc_num_bis;
			memcpy(sa->iso_bc->bc_bis, iso_pi(sk)->bc_bis,
			       ISO_MAX_NUM_BIS);
			len += sizeof(struct sockaddr_iso_bc);
		}
	} else {
		bacpy(&sa->iso_bdaddr, &iso_pi(sk)->src);
		sa->iso_bdaddr_type = iso_pi(sk)->src_type;
	}

	return len;
}

static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg,
			    size_t len)
{
	struct sock *sk = sock->sk;
	struct sk_buff *skb, **frag;
	struct sockcm_cookie sockc;
	size_t mtu;
	int err;

	BT_DBG("sock %p, sk %p", sock, sk);

	err = sock_error(sk);
	if (err)
		return err;

	if (msg->msg_flags & MSG_OOB)
		return -EOPNOTSUPP;

	hci_sockcm_init(&sockc, sk);

	if (msg->msg_controllen) {
		err = sock_cmsg_send(sk, msg, &sockc);
		if (err)
			return err;
	}

	lock_sock(sk);

	if (sk->sk_state != BT_CONNECTED) {
		release_sock(sk);
		return -ENOTCONN;
	}

	mtu = iso_pi(sk)->conn->hcon->mtu;

	release_sock(sk);

	skb = bt_skb_sendmsg(sk, msg, len, mtu, HCI_ISO_DATA_HDR_SIZE, 0);
	if (IS_ERR(skb))
		return PTR_ERR(skb);

	len -= skb->len;

	BT_DBG("skb %p len %d", sk, skb->len);

	/* Continuation fragments */
	frag = &skb_shinfo(skb)->frag_list;
	while (len) {
		struct sk_buff *tmp;

		tmp = bt_skb_sendmsg(sk, msg, len, mtu, 0, 0);
		if (IS_ERR(tmp)) {
			kfree_skb(skb);
			return PTR_ERR(tmp);
		}

		*frag = tmp;

		len  -= tmp->len;

		skb->len += tmp->len;
		skb->data_len += tmp->len;

		BT_DBG("frag %p len %d", *frag, tmp->len);

		frag = &(*frag)->next;
	}

	lock_sock(sk);

	if (sk->sk_state == BT_CONNECTED)
		err = iso_send_frame(sk, skb, &sockc);
	else
		err = -ENOTCONN;

	release_sock(sk);

	if (err < 0)
		kfree_skb(skb);
	return err;
}

static void iso_conn_defer_accept(struct hci_conn *conn)
{
	struct hci_cp_le_accept_cis cp;
	struct hci_dev *hdev = conn->hdev;

	BT_DBG("conn %p", conn);

	conn->state = BT_CONFIG;

	cp.handle = cpu_to_le16(conn->handle);

	hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
}

static void iso_conn_big_sync(struct sock *sk)
{
	int err;
	struct hci_dev *hdev;

	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
			     iso_pi(sk)->src_type);

	if (!hdev)
		return;

	/* hci_le_big_create_sync requires hdev lock to be held, since
	 * it enqueues the HCI LE BIG Create Sync command via
	 * hci_cmd_sync_queue_once, which checks hdev flags that might
	 * change.
	 */
	hci_dev_lock(hdev);
	lock_sock(sk);

	if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
		err = hci_conn_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
					       &iso_pi(sk)->qos,
					       iso_pi(sk)->sync_handle,
					       iso_pi(sk)->bc_num_bis,
					       iso_pi(sk)->bc_bis);
		if (err)
			bt_dev_err(hdev, "hci_big_create_sync: %d", err);
	}

	release_sock(sk);
	hci_dev_unlock(hdev);
}

static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
			    size_t len, int flags)
{
	struct sock *sk = sock->sk;
	struct iso_pinfo *pi = iso_pi(sk);
	bool early_ret = false;
	int err = 0;

	BT_DBG("sk %p", sk);

	if (unlikely(flags & MSG_ERRQUEUE))
		return sock_recv_errqueue(sk, msg, len, SOL_BLUETOOTH,
					  BT_SCM_ERROR);

	if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
		sock_hold(sk);
		lock_sock(sk);

		switch (sk->sk_state) {
		case BT_CONNECT2:
			if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
				release_sock(sk);
				iso_conn_big_sync(sk);
				lock_sock(sk);

				sk->sk_state = BT_LISTEN;
			} else {
				iso_conn_defer_accept(pi->conn->hcon);
				sk->sk_state = BT_CONFIG;
			}

			early_ret = true;
			break;
		case BT_CONNECTED:
			if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
				release_sock(sk);
				iso_conn_big_sync(sk);
				lock_sock(sk);

				sk->sk_state = BT_LISTEN;
				early_ret = true;
			}

			break;
		case BT_CONNECT:
			release_sock(sk);
			err = iso_connect_cis(sk);
			lock_sock(sk);

			early_ret = true;
			break;
		default:
			break;
		}

		release_sock(sk);
		sock_put(sk);

		if (early_ret)
			return err;
	}

	return bt_sock_recvmsg(sock, msg, len, flags);
}

static bool check_io_qos(struct bt_iso_io_qos *qos)
{
	/* If no PHY is enable SDU must be 0 */
	if (!qos->phy && qos->sdu)
		return false;

	if (qos->interval && (qos->interval < 0xff || qos->interval > 0xfffff))
		return false;

	if (qos->latency && (qos->latency < 0x05 || qos->latency > 0xfa0))
		return false;

	if (qos->phy > BT_ISO_PHY_ANY)
		return false;

	return true;
}

static bool check_ucast_qos(struct bt_iso_qos *qos)
{
	if (qos->ucast.cig > 0xef && qos->ucast.cig != BT_ISO_QOS_CIG_UNSET)
		return false;

	if (qos->ucast.cis > 0xef && qos->ucast.cis != BT_ISO_QOS_CIS_UNSET)
		return false;

	if (qos->ucast.sca > 0x07)
		return false;

	if (qos->ucast.packing > 0x01)
		return false;

	if (qos->ucast.framing > 0x01)
		return false;

	if (!check_io_qos(&qos->ucast.in))
		return false;

	if (!check_io_qos(&qos->ucast.out))
		return false;

	return true;
}

static bool check_bcast_qos(struct bt_iso_qos *qos)
{
	if (!qos->bcast.sync_factor)
		qos->bcast.sync_factor = 0x01;

	if (qos->bcast.packing > 0x01)
		return false;

	if (qos->bcast.framing > 0x01)
		return false;

	if (!check_io_qos(&qos->bcast.in))
		return false;

	if (!check_io_qos(&qos->bcast.out))
		return false;

	if (qos->bcast.encryption > 0x01)
		return false;

	if (qos->bcast.options > 0x07)
		return false;

	if (qos->bcast.skip > 0x01f3)
		return false;

	if (!qos->bcast.sync_timeout)
		qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;

	if (qos->bcast.sync_timeout < 0x000a || qos->bcast.sync_timeout > 0x4000)
		return false;

	if (qos->bcast.sync_cte_type > 0x1f)
		return false;

	if (qos->bcast.mse > 0x1f)
		return false;

	if (!qos->bcast.timeout)
		qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;

	if (qos->bcast.timeout < 0x000a || qos->bcast.timeout > 0x4000)
		return false;

	return true;
}

static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
			       sockptr_t optval, unsigned int optlen)
{
	struct sock *sk = sock->sk;
	int err = 0;
	struct bt_iso_qos qos = default_qos;
	u32 opt;

	BT_DBG("sk %p", sk);

	lock_sock(sk);

	switch (optname) {
	case BT_DEFER_SETUP:
		if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
			err = -EINVAL;
			break;
		}

		err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
		if (err)
			break;

		if (opt)
			set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
		else
			clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
		break;

	case BT_PKT_STATUS:
		err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
		if (err)
			break;

		if (opt)
			set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
		else
			clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
		break;

	case BT_PKT_SEQNUM:
		err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
		if (err)
			break;

		if (opt)
			set_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags);
		else
			clear_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags);
		break;

	case BT_ISO_QOS:
		if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
		    sk->sk_state != BT_CONNECT2 &&
		    (!test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags) ||
		    sk->sk_state != BT_CONNECTED)) {
			err = -EINVAL;
			break;
		}

		err = copy_safe_from_sockptr(&qos, sizeof(qos), optval, optlen);
		if (err)
			break;

		iso_pi(sk)->qos = qos;
		iso_pi(sk)->qos_user_set = true;

		break;

	case BT_ISO_BASE:
		if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
		    sk->sk_state != BT_CONNECT2) {
			err = -EINVAL;
			break;
		}

		if (optlen > sizeof(iso_pi(sk)->base)) {
			err = -EINVAL;
			break;
		}

		err = copy_safe_from_sockptr(iso_pi(sk)->base, optlen, optval,
					     optlen);
		if (err)
			break;

		iso_pi(sk)->base_len = optlen;

		break;

	default:
		err = -ENOPROTOOPT;
		break;
	}

	release_sock(sk);
	return err;
}

static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
			       char __user *optval, int __user *optlen)
{
	struct sock *sk = sock->sk;
	int len, err = 0;
	struct bt_iso_qos *qos;
	u8 base_len;
	u8 *base;

	BT_DBG("sk %p", sk);

	if (get_user(len, optlen))
		return -EFAULT;

	lock_sock(sk);

	switch (optname) {
	case BT_DEFER_SETUP:
		if (sk->sk_state == BT_CONNECTED) {
			err = -EINVAL;
			break;
		}

		if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
			     (u32 __user *)optval))
			err = -EFAULT;

		break;

	case BT_PKT_STATUS:
		if (put_user(test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags),
			     (int __user *)optval))
			err = -EFAULT;
		break;

	case BT_ISO_QOS:
		qos = iso_sock_get_qos(sk);

		len = min_t(unsigned int, len, sizeof(*qos));
		if (copy_to_user(optval, qos, len))
			err = -EFAULT;

		break;

	case BT_ISO_BASE:
		if (sk->sk_state == BT_CONNECTED &&
		    !bacmp(&iso_pi(sk)->dst, BDADDR_ANY)) {
			base_len = iso_pi(sk)->conn->hcon->le_per_adv_data_len;
			base = iso_pi(sk)->conn->hcon->le_per_adv_data;
		} else {
			base_len = iso_pi(sk)->base_len;
			base = iso_pi(sk)->base;
		}

		len = min_t(unsigned int, len, base_len);
		if (copy_to_user(optval, base, len))
			err = -EFAULT;
		if (put_user(len, optlen))
			err = -EFAULT;

		break;

	default:
		err = -ENOPROTOOPT;
		break;
	}

	release_sock(sk);
	return err;
}

static int iso_sock_shutdown(struct socket *sock, int how)
{
	struct sock *sk = sock->sk;
	int err = 0;

	BT_DBG("sock %p, sk %p, how %d", sock, sk, how);

	if (!sk)
		return 0;

	sock_hold(sk);
	lock_sock(sk);

	switch (how) {
	case SHUT_RD:
		if (sk->sk_shutdown & RCV_SHUTDOWN)
			goto unlock;
		sk->sk_shutdown |= RCV_SHUTDOWN;
		break;
	case SHUT_WR:
		if (sk->sk_shutdown & SEND_SHUTDOWN)
			goto unlock;
		sk->sk_shutdown |= SEND_SHUTDOWN;
		break;
	case SHUT_RDWR:
		if (sk->sk_shutdown & SHUTDOWN_MASK)
			goto unlock;
		sk->sk_shutdown |= SHUTDOWN_MASK;
		break;
	}

	iso_sock_clear_timer(sk);
	__iso_sock_close(sk);

	if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
	    !(current->flags & PF_EXITING))
		err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);

unlock:
	release_sock(sk);
	sock_put(sk);

	return err;
}

static int iso_sock_release(struct socket *sock)
{
	struct sock *sk = sock->sk;
	int err = 0;

	BT_DBG("sock %p, sk %p", sock, sk);

	if (!sk)
		return 0;

	iso_sock_close(sk);

	if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) &&
	    !(current->flags & PF_EXITING)) {
		lock_sock(sk);
		err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
		release_sock(sk);
	}

	sock_orphan(sk);
	iso_sock_kill(sk);
	return err;
}

static void iso_sock_ready(struct sock *sk)
{
	BT_DBG("sk %p", sk);

	if (!sk)
		return;

	lock_sock(sk);
	iso_sock_clear_timer(sk);
	sk->sk_state = BT_CONNECTED;
	sk->sk_state_change(sk);
	release_sock(sk);
}

static bool iso_match_big(struct sock *sk, void *data)
{
	struct hci_evt_le_big_sync_established *ev = data;

	return ev->handle == iso_pi(sk)->qos.bcast.big;
}

static bool iso_match_big_hcon(struct sock *sk, void *data)
{
	struct hci_conn *hcon = data;

	return hcon->iso_qos.bcast.big == iso_pi(sk)->qos.bcast.big;
}

static bool iso_match_pa_sync_flag(struct sock *sk, void *data)
{
	return test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
}

static void iso_conn_ready(struct iso_conn *conn)
{
	struct sock *parent = NULL;
	struct sock *sk = conn->sk;
	struct hci_ev_le_big_sync_established *ev = NULL;
	struct hci_ev_le_pa_sync_established *ev2 = NULL;
	struct hci_ev_le_per_adv_report *ev3 = NULL;
	struct hci_conn *hcon;

	BT_DBG("conn %p", conn);

	if (sk) {
		iso_sock_ready(conn->sk);
	} else {
		hcon = conn->hcon;
		if (!hcon)
			return;

		if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags)) {
			/* A BIS slave hcon is notified to the ISO layer
			 * after the Command Complete for the LE Setup
			 * ISO Data Path command is received. Get the
			 * parent socket that matches the hcon BIG handle.
			 */
			parent = iso_get_sock(&hcon->src, &hcon->dst,
					      BT_LISTEN, iso_match_big_hcon,
					      hcon);
		} else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
			ev = hci_recv_event_data(hcon->hdev,
						 HCI_EVT_LE_BIG_SYNC_ESTABLISHED);

			/* Get reference to PA sync parent socket, if it exists */
			parent = iso_get_sock(&hcon->src, &hcon->dst,
					      BT_LISTEN,
					      iso_match_pa_sync_flag,
					      NULL);
			if (!parent && ev)
				parent = iso_get_sock(&hcon->src,
						      &hcon->dst,
						      BT_LISTEN,
						      iso_match_big, ev);
		} else if (test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
			ev2 = hci_recv_event_data(hcon->hdev,
						  HCI_EV_LE_PA_SYNC_ESTABLISHED);
			if (ev2)
				parent = iso_get_sock(&hcon->src,
						      &hcon->dst,
						      BT_LISTEN,
						      iso_match_sid, ev2);
		} else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
			ev3 = hci_recv_event_data(hcon->hdev,
						  HCI_EV_LE_PER_ADV_REPORT);
			if (ev3)
				parent = iso_get_sock(&hcon->src,
						      &hcon->dst,
						      BT_LISTEN,
						      iso_match_sync_handle_pa_report,
						      ev3);
		}

		if (!parent)
			parent = iso_get_sock(&hcon->src, BDADDR_ANY,
					      BT_LISTEN, NULL, NULL);

		if (!parent)
			return;

		lock_sock(parent);

		sk = iso_sock_alloc(sock_net(parent), NULL,
				    BTPROTO_ISO, GFP_ATOMIC, 0);
		if (!sk) {
			release_sock(parent);
			return;
		}

		iso_sock_init(sk, parent);

		bacpy(&iso_pi(sk)->src, &hcon->src);

		/* Convert from HCI to three-value type */
		if (hcon->src_type == ADDR_LE_DEV_PUBLIC)
			iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
		else
			iso_pi(sk)->src_type = BDADDR_LE_RANDOM;

		/* If hcon has no destination address (BDADDR_ANY) it means it
		 * was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED or
		 * HCI_EV_LE_PA_SYNC_ESTABLISHED so we need to initialize using
		 * the parent socket destination address.
		 */
		if (!bacmp(&hcon->dst, BDADDR_ANY)) {
			bacpy(&hcon->dst, &iso_pi(parent)->dst);
			hcon->dst_type = le_addr_type(iso_pi(parent)->dst_type);
		}

		if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
			iso_pi(sk)->qos = iso_pi(parent)->qos;
			hcon->iso_qos = iso_pi(sk)->qos;
			iso_pi(sk)->bc_sid = iso_pi(parent)->bc_sid;
			iso_pi(sk)->bc_num_bis = iso_pi(parent)->bc_num_bis;
			memcpy(iso_pi(sk)->bc_bis, iso_pi(parent)->bc_bis,
			       ISO_MAX_NUM_BIS);
			set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
		}

		bacpy(&iso_pi(sk)->dst, &hcon->dst);

		/* Convert from HCI to three-value type */
		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
			iso_pi(sk)->dst_type = BDADDR_LE_PUBLIC;
		else
			iso_pi(sk)->dst_type = BDADDR_LE_RANDOM;

		iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
		memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
		iso_pi(sk)->base_len = iso_pi(parent)->base_len;

		hci_conn_hold(hcon);
		iso_chan_add(conn, sk, parent);

		if ((ev && ((struct hci_evt_le_big_sync_established *)ev)->status) ||
		    (ev2 && ev2->status)) {
			/* Trigger error signal on child socket */
			sk->sk_err = ECONNREFUSED;
			sk->sk_error_report(sk);
		}

		if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
			sk->sk_state = BT_CONNECT2;
		else
			sk->sk_state = BT_CONNECTED;

		/* Wake up parent */
		parent->sk_data_ready(parent);

		release_sock(parent);
		sock_put(parent);
	}
}

static bool iso_match_sid(struct sock *sk, void *data)
{
	struct hci_ev_le_pa_sync_established *ev = data;

	if (iso_pi(sk)->bc_sid == HCI_SID_INVALID)
		return true;

	return ev->sid == iso_pi(sk)->bc_sid;
}

static bool iso_match_sync_handle(struct sock *sk, void *data)
{
	struct hci_evt_le_big_info_adv_report *ev = data;

	return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
}

static bool iso_match_sync_handle_pa_report(struct sock *sk, void *data)
{
	struct hci_ev_le_per_adv_report *ev = data;

	return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
}

/* ----- ISO interface with lower layer (HCI) ----- */

int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
{
	struct hci_ev_le_pa_sync_established *ev1;
	struct hci_evt_le_big_info_adv_report *ev2;
	struct hci_ev_le_per_adv_report *ev3;
	struct sock *sk;

	bt_dev_dbg(hdev, "bdaddr %pMR", bdaddr);

	/* Broadcast receiver requires handling of some events before it can
	 * proceed to establishing a BIG sync:
	 *
	 * 1. HCI_EV_LE_PA_SYNC_ESTABLISHED: The socket may specify a specific
	 * SID to listen to and once sync is established its handle needs to
	 * be stored in iso_pi(sk)->sync_handle so it can be matched once
	 * receiving the BIG Info.
	 * 2. HCI_EVT_LE_BIG_INFO_ADV_REPORT: When connect_ind is triggered by a
	 * a BIG Info it attempts to check if there any listening socket with
	 * the same sync_handle and if it does then attempt to create a sync.
	 * 3. HCI_EV_LE_PER_ADV_REPORT: When a PA report is received, it is stored
	 * in iso_pi(sk)->base so it can be passed up to user, in the case of a
	 * broadcast sink.
	 */
	ev1 = hci_recv_event_data(hdev, HCI_EV_LE_PA_SYNC_ESTABLISHED);
	if (ev1) {
		sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
				  iso_match_sid, ev1);
		if (sk && !ev1->status) {
			iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
			iso_pi(sk)->bc_sid = ev1->sid;
		}

		goto done;
	}

	ev2 = hci_recv_event_data(hdev, HCI_EVT_LE_BIG_INFO_ADV_REPORT);
	if (ev2) {
		/* Check if BIGInfo report has already been handled */
		sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECTED,
				  iso_match_sync_handle, ev2);
		if (sk) {
			sock_put(sk);
			sk = NULL;
			goto done;
		}

		/* Try to get PA sync socket, if it exists */
		sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECT2,
				  iso_match_sync_handle, ev2);
		if (!sk)
			sk = iso_get_sock(&hdev->bdaddr, bdaddr,
					  BT_LISTEN,
					  iso_match_sync_handle,
					  ev2);

		if (sk) {
			int err;
			struct hci_conn	*hcon = iso_pi(sk)->conn->hcon;

			iso_pi(sk)->qos.bcast.encryption = ev2->encryption;

			if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
				iso_pi(sk)->bc_num_bis = ev2->num_bis;

			if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
			    !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
				err = hci_conn_big_create_sync(hdev, hcon,
							       &iso_pi(sk)->qos,
							       iso_pi(sk)->sync_handle,
							       iso_pi(sk)->bc_num_bis,
							       iso_pi(sk)->bc_bis);
				if (err) {
					bt_dev_err(hdev, "hci_le_big_create_sync: %d",
						   err);
					sock_put(sk);
					sk = NULL;
				}
			}
		}

		goto done;
	}

	ev3 = hci_recv_event_data(hdev, HCI_EV_LE_PER_ADV_REPORT);
	if (ev3) {
		size_t base_len = 0;
		u8 *base;
		struct hci_conn *hcon;

		sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
				  iso_match_sync_handle_pa_report, ev3);
		if (!sk)
			goto done;

		hcon = iso_pi(sk)->conn->hcon;
		if (!hcon)
			goto done;

		if (ev3->data_status == LE_PA_DATA_TRUNCATED) {
			/* The controller was unable to retrieve PA data. */
			memset(hcon->le_per_adv_data, 0,
			       HCI_MAX_PER_AD_TOT_LEN);
			hcon->le_per_adv_data_len = 0;
			hcon->le_per_adv_data_offset = 0;
			goto done;
		}

		if (hcon->le_per_adv_data_offset + ev3->length >
		    HCI_MAX_PER_AD_TOT_LEN)
			goto done;

		memcpy(hcon->le_per_adv_data + hcon->le_per_adv_data_offset,
		       ev3->data, ev3->length);
		hcon->le_per_adv_data_offset += ev3->length;

		if (ev3->data_status == LE_PA_DATA_COMPLETE) {
			/* All PA data has been received. */
			hcon->le_per_adv_data_len =
				hcon->le_per_adv_data_offset;
			hcon->le_per_adv_data_offset = 0;

			/* Extract BASE */
			base = eir_get_service_data(hcon->le_per_adv_data,
						    hcon->le_per_adv_data_len,
						    EIR_BAA_SERVICE_UUID,
						    &base_len);

			if (!base || base_len > BASE_MAX_LENGTH)
				goto done;

			memcpy(iso_pi(sk)->base, base, base_len);
			iso_pi(sk)->base_len = base_len;
		} else {
			/* This is a PA data fragment. Keep pa_data_len set to 0
			 * until all data has been reassembled.
			 */
			hcon->le_per_adv_data_len = 0;
		}
	} else {
		sk = iso_get_sock(&hdev->bdaddr, BDADDR_ANY,
				  BT_LISTEN, NULL, NULL);
	}

done:
	if (!sk)
		return 0;

	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
		*flags |= HCI_PROTO_DEFER;

	sock_put(sk);

	return HCI_LM_ACCEPT;
}

static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
{
	if (hcon->type != CIS_LINK && hcon->type != BIS_LINK &&
	    hcon->type != PA_LINK) {
		if (hcon->type != LE_LINK)
			return;

		/* Check if LE link has failed */
		if (status) {
			struct hci_link *link, *t;

			list_for_each_entry_safe(link, t, &hcon->link_list,
						 list)
				iso_conn_del(link->conn, bt_to_errno(status));

			return;
		}

		/* Create CIS if pending */
		hci_le_create_cis_pending(hcon->hdev);
		return;
	}

	BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);

	/* Similar to the success case, if HCI_CONN_BIG_SYNC_FAILED or
	 * HCI_CONN_PA_SYNC_FAILED is set, queue the failed connection
	 * into the accept queue of the listening socket and wake up
	 * userspace, to inform the user about the event.
	 */
	if (!status || test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags) ||
	    test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
		struct iso_conn *conn;

		conn = iso_conn_add(hcon);
		if (conn)
			iso_conn_ready(conn);
	} else {
		iso_conn_del(hcon, bt_to_errno(status));
	}
}

static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
{
	if (hcon->type != CIS_LINK && hcon->type !=  BIS_LINK &&
	    hcon->type != PA_LINK)
		return;

	BT_DBG("hcon %p reason %d", hcon, reason);

	iso_conn_del(hcon, bt_to_errno(reason));
}

int iso_recv(struct hci_dev *hdev, u16 handle, struct sk_buff *skb, u16 flags)
{
	struct hci_conn *hcon;
	struct iso_conn *conn;
	struct skb_shared_hwtstamps *hwts;
	__u16 pb, ts, len, sn;

	hci_dev_lock(hdev);

	hcon = hci_conn_hash_lookup_handle(hdev, handle);
	if (!hcon) {
		hci_dev_unlock(hdev);
		kfree_skb(skb);
		return -ENOENT;
	}

	conn = iso_conn_hold_unless_zero(hcon->iso_data);
	hcon = NULL;

	hci_dev_unlock(hdev);

	if (!conn) {
		kfree_skb(skb);
		return -EINVAL;
	}

	pb     = hci_iso_flags_pb(flags);
	ts     = hci_iso_flags_ts(flags);

	BT_DBG("conn %p len %d pb 0x%x ts 0x%x", conn, skb->len, pb, ts);

	switch (pb) {
	case ISO_START:
	case ISO_SINGLE:
		if (conn->rx_len) {
			BT_ERR("Unexpected start frame (len %d)", skb->len);
			kfree_skb(conn->rx_skb);
			conn->rx_skb = NULL;
			conn->rx_len = 0;
		}

		if (ts) {
			struct hci_iso_ts_data_hdr *hdr;

			hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE);
			if (!hdr) {
				BT_ERR("Frame is too short (len %d)", skb->len);
				goto drop;
			}

			/*  Record the timestamp to skb */
			hwts = skb_hwtstamps(skb);
			hwts->hwtstamp = us_to_ktime(le32_to_cpu(hdr->ts));

			sn = __le16_to_cpu(hdr->sn);
			len = __le16_to_cpu(hdr->slen);
		} else {
			struct hci_iso_data_hdr *hdr;

			hdr = skb_pull_data(skb, HCI_ISO_DATA_HDR_SIZE);
			if (!hdr) {
				BT_ERR("Frame is too short (len %d)", skb->len);
				goto drop;
			}

			sn = __le16_to_cpu(hdr->sn);
			len = __le16_to_cpu(hdr->slen);
		}

		flags  = hci_iso_data_flags(len);
		len    = hci_iso_data_len(len);

		BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x sn %d",
		       len, skb->len, flags, sn);

		if (len == skb->len) {
			/* Complete frame received */
			hci_skb_pkt_status(skb) = flags & 0x03;
			hci_skb_pkt_seqnum(skb) = sn;
			iso_recv_frame(conn, skb);
			goto done;
		}

		if (pb == ISO_SINGLE) {
			BT_ERR("Frame malformed (len %d, expected len %d)",
			       skb->len, len);
			goto drop;
		}

		if (skb->len > len) {
			BT_ERR("Frame is too long (len %d, expected len %d)",
			       skb->len, len);
			goto drop;
		}

		/* Allocate skb for the complete frame (with header) */
		conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
		if (!conn->rx_skb)
			goto drop;

		hci_skb_pkt_status(conn->rx_skb) = flags & 0x03;
		hci_skb_pkt_seqnum(conn->rx_skb) = sn;
		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
					  skb->len);
		conn->rx_len = len - skb->len;

		/* Copy hw timestamp from skb to rx_skb if present */
		if (ts) {
			hwts = skb_hwtstamps(conn->rx_skb);
			hwts->hwtstamp = skb_hwtstamps(skb)->hwtstamp;
		}

		break;

	case ISO_CONT:
		BT_DBG("Cont: frag len %d (expecting %d)", skb->len,
		       conn->rx_len);

		if (!conn->rx_len) {
			BT_ERR("Unexpected continuation frame (len %d)",
			       skb->len);
			goto drop;
		}

		if (skb->len > conn->rx_len) {
			BT_ERR("Fragment is too long (len %d, expected %d)",
			       skb->len, conn->rx_len);
			kfree_skb(conn->rx_skb);
			conn->rx_skb = NULL;
			conn->rx_len = 0;
			goto drop;
		}

		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
					  skb->len);
		conn->rx_len -= skb->len;
		break;

	case ISO_END:
		if (!conn->rx_len) {
			BT_ERR("Unexpected end frame (len %d)", skb->len);
			goto drop;
		}

		skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
					  skb->len);
		conn->rx_len -= skb->len;

		if (!conn->rx_len) {
			struct sk_buff *rx_skb = conn->rx_skb;

			/* Complete frame received. iso_recv_frame
			 * takes ownership of the skb so set the global
			 * rx_skb pointer to NULL first.
			 */
			conn->rx_skb = NULL;
			iso_recv_frame(conn, rx_skb);
		}
		break;
	}

drop:
	kfree_skb(skb);
done:
	iso_conn_put(conn);
	return 0;
}

static struct hci_cb iso_cb = {
	.name		= "ISO",
	.connect_cfm	= iso_connect_cfm,
	.disconn_cfm	= iso_disconn_cfm,
};

static int iso_debugfs_show(struct seq_file *f, void *p)
{
	struct sock *sk;

	read_lock(&iso_sk_list.lock);

	sk_for_each(sk, &iso_sk_list.head) {
		seq_printf(f, "%pMR %pMR %d\n", &iso_pi(sk)->src,
			   &iso_pi(sk)->dst, sk->sk_state);
	}

	read_unlock(&iso_sk_list.lock);

	return 0;
}

DEFINE_SHOW_ATTRIBUTE(iso_debugfs);

static struct dentry *iso_debugfs;

static const struct proto_ops iso_sock_ops = {
	.family		= PF_BLUETOOTH,
	.owner		= THIS_MODULE,
	.release	= iso_sock_release,
	.bind		= iso_sock_bind,
	.connect	= iso_sock_connect,
	.listen		= iso_sock_listen,
	.accept		= iso_sock_accept,
	.getname	= iso_sock_getname,
	.sendmsg	= iso_sock_sendmsg,
	.recvmsg	= iso_sock_recvmsg,
	.poll		= bt_sock_poll,
	.ioctl		= bt_sock_ioctl,
	.mmap		= sock_no_mmap,
	.socketpair	= sock_no_socketpair,
	.shutdown	= iso_sock_shutdown,
	.setsockopt	= iso_sock_setsockopt,
	.getsockopt	= iso_sock_getsockopt
};

static const struct net_proto_family iso_sock_family_ops = {
	.family	= PF_BLUETOOTH,
	.owner	= THIS_MODULE,
	.create	= iso_sock_create,
};

static bool inited;

bool iso_inited(void)
{
	return inited;
}

int iso_init(void)
{
	int err;

	BUILD_BUG_ON(sizeof(struct sockaddr_iso) > sizeof(struct sockaddr));

	if (inited)
		return -EALREADY;

	err = proto_register(&iso_proto, 0);
	if (err < 0)
		return err;

	err = bt_sock_register(BTPROTO_ISO, &iso_sock_family_ops);
	if (err < 0) {
		BT_ERR("ISO socket registration failed");
		goto error;
	}

	err = bt_procfs_init(&init_net, "iso", &iso_sk_list, NULL);
	if (err < 0) {
		BT_ERR("Failed to create ISO proc file");
		bt_sock_unregister(BTPROTO_ISO);
		goto error;
	}

	BT_INFO("ISO socket layer initialized");

	hci_register_cb(&iso_cb);

	if (!IS_ERR_OR_NULL(bt_debugfs))
		iso_debugfs = debugfs_create_file("iso", 0444, bt_debugfs,
						  NULL, &iso_debugfs_fops);

	inited = true;

	return 0;

error:
	proto_unregister(&iso_proto);
	return err;
}

int iso_exit(void)
{
	if (!inited)
		return -EALREADY;

	bt_procfs_cleanup(&init_net, "iso");

	debugfs_remove(iso_debugfs);
	iso_debugfs = NULL;

	hci_unregister_cb(&iso_cb);

	bt_sock_unregister(BTPROTO_ISO);

	proto_unregister(&iso_proto);

	inited = false;

	return 0;
}
