Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80808e43 authored by Gustavo Padovan's avatar Gustavo Padovan
Browse files

Bluetooth: Add l2cap_chan_ops abstraction



Add an abstraction layer between L2CAP core and its users (only
l2cap_sock.c now). The first function implemented is new_connection() that
replaces calls to l2cap_sock_alloc() in l2cap_core.c

Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent dc50a06d
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -354,6 +354,15 @@ struct l2cap_chan {

	struct list_head list;
	struct list_head global_l;

	void		*data;
	struct l2cap_ops *ops;
};

struct l2cap_ops {
	char		*name;

	struct l2cap_chan	*(*new_connection) (void *data);
};

struct l2cap_conn {
@@ -460,9 +469,6 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);

void l2cap_sock_kill(struct sock *sk);
void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
							int proto, gfp_t prio);

struct l2cap_chan *l2cap_chan_create(struct sock *sk);
void l2cap_chan_close(struct l2cap_chan *chan, int reason);
+7 −10
Original line number Diff line number Diff line
@@ -842,18 +842,16 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
		goto clean;
	}

	sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
	if (!sk)
	chan = pchan->ops->new_connection(pchan->data);
	if (!chan)
		goto clean;

	chan = l2cap_pi(sk)->chan;
	sk = chan->sk;

	write_lock_bh(&conn->chan_lock);

	hci_conn_hold(conn->hcon);

	l2cap_sock_init(sk, parent);

	bacpy(&bt_sk(sk)->src, conn->src);
	bacpy(&bt_sk(sk)->dst, conn->dst);

@@ -2329,10 +2327,12 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
		goto response;
	}

	sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
	if (!sk)
	chan = pchan->ops->new_connection(pchan->data);
	if (!chan)
		goto response;

	sk = chan->sk;

	write_lock_bh(&conn->chan_lock);

	/* Check if we already have channel with that dcid */
@@ -2345,9 +2345,6 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd

	hci_conn_hold(conn->hcon);

	chan = l2cap_pi(sk)->chan;

	l2cap_sock_init(sk, parent);
	bacpy(&bt_sk(sk)->src, conn->src);
	bacpy(&bt_sk(sk)->dst, conn->dst);
	chan->psm  = psm;
+27 −2
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include <net/bluetooth/l2cap.h>

static const struct proto_ops l2cap_sock_ops;
static void l2cap_sock_init(struct sock *sk, struct sock *parent);
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio);

static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
@@ -773,6 +775,25 @@ static int l2cap_sock_release(struct socket *sock)
	return err;
}

static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
{
	struct sock *sk, *parent = data;

	sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
								GFP_ATOMIC);
	if (!sk)
		return NULL;

	l2cap_sock_init(sk, parent);

	return l2cap_pi(sk)->chan;
}

static struct l2cap_ops l2cap_chan_ops = {
	.name		= "L2CAP Socket Interface",
	.new_connection	= l2cap_sock_new_connection_cb,
};

static void l2cap_sock_destruct(struct sock *sk)
{
	BT_DBG("sk %p", sk);
@@ -781,7 +802,7 @@ static void l2cap_sock_destruct(struct sock *sk)
	skb_queue_purge(&sk->sk_write_queue);
}

void l2cap_sock_init(struct sock *sk, struct sock *parent)
static void l2cap_sock_init(struct sock *sk, struct sock *parent)
{
	struct l2cap_pinfo *pi = l2cap_pi(sk);
	struct l2cap_chan *chan = pi->chan;
@@ -838,10 +859,14 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
		chan->force_reliable = 0;
		chan->flushable = BT_FLUSHABLE_OFF;
		chan->force_active = BT_POWER_FORCE_ACTIVE_ON;

	}

	/* Default config options */
	chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;

	chan->data = sk;
	chan->ops = &l2cap_chan_ops;
}

static struct proto l2cap_proto = {
@@ -850,7 +875,7 @@ static struct proto l2cap_proto = {
	.obj_size	= sizeof(struct l2cap_pinfo)
};

struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
{
	struct sock *sk;
	struct l2cap_chan *chan;