diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-05-16 16:24:37 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-06-13 13:55:32 -0400 |
commit | 80808e431e1ef25856457de82ce141bed6a6313a (patch) | |
tree | 021d6affd8b8f6bf81ba51fadb9951b0b9e47d27 | |
parent | dc50a06dac61d7ca7ddb3d9bb8921ca5d68f51b6 (diff) |
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: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | include/net/bluetooth/l2cap.h | 12 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 17 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 29 |
3 files changed, 43 insertions, 15 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 0529d278e068..d3a150955c44 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -354,6 +354,15 @@ struct l2cap_chan { | |||
354 | 354 | ||
355 | struct list_head list; | 355 | struct list_head list; |
356 | struct list_head global_l; | 356 | struct list_head global_l; |
357 | |||
358 | void *data; | ||
359 | struct l2cap_ops *ops; | ||
360 | }; | ||
361 | |||
362 | struct l2cap_ops { | ||
363 | char *name; | ||
364 | |||
365 | struct l2cap_chan *(*new_connection) (void *data); | ||
357 | }; | 366 | }; |
358 | 367 | ||
359 | struct l2cap_conn { | 368 | struct l2cap_conn { |
@@ -460,9 +469,6 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); | |||
460 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); | 469 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); |
461 | 470 | ||
462 | void l2cap_sock_kill(struct sock *sk); | 471 | void l2cap_sock_kill(struct sock *sk); |
463 | void l2cap_sock_init(struct sock *sk, struct sock *parent); | ||
464 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | ||
465 | int proto, gfp_t prio); | ||
466 | 472 | ||
467 | struct l2cap_chan *l2cap_chan_create(struct sock *sk); | 473 | struct l2cap_chan *l2cap_chan_create(struct sock *sk); |
468 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); | 474 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 49f890bce312..8369f5680391 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -842,18 +842,16 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
842 | goto clean; | 842 | goto clean; |
843 | } | 843 | } |
844 | 844 | ||
845 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); | 845 | chan = pchan->ops->new_connection(pchan->data); |
846 | if (!sk) | 846 | if (!chan) |
847 | goto clean; | 847 | goto clean; |
848 | 848 | ||
849 | chan = l2cap_pi(sk)->chan; | 849 | sk = chan->sk; |
850 | 850 | ||
851 | write_lock_bh(&conn->chan_lock); | 851 | write_lock_bh(&conn->chan_lock); |
852 | 852 | ||
853 | hci_conn_hold(conn->hcon); | 853 | hci_conn_hold(conn->hcon); |
854 | 854 | ||
855 | l2cap_sock_init(sk, parent); | ||
856 | |||
857 | bacpy(&bt_sk(sk)->src, conn->src); | 855 | bacpy(&bt_sk(sk)->src, conn->src); |
858 | bacpy(&bt_sk(sk)->dst, conn->dst); | 856 | bacpy(&bt_sk(sk)->dst, conn->dst); |
859 | 857 | ||
@@ -2329,10 +2327,12 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2329 | goto response; | 2327 | goto response; |
2330 | } | 2328 | } |
2331 | 2329 | ||
2332 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); | 2330 | chan = pchan->ops->new_connection(pchan->data); |
2333 | if (!sk) | 2331 | if (!chan) |
2334 | goto response; | 2332 | goto response; |
2335 | 2333 | ||
2334 | sk = chan->sk; | ||
2335 | |||
2336 | write_lock_bh(&conn->chan_lock); | 2336 | write_lock_bh(&conn->chan_lock); |
2337 | 2337 | ||
2338 | /* Check if we already have channel with that dcid */ | 2338 | /* 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 | |||
2345 | 2345 | ||
2346 | hci_conn_hold(conn->hcon); | 2346 | hci_conn_hold(conn->hcon); |
2347 | 2347 | ||
2348 | chan = l2cap_pi(sk)->chan; | ||
2349 | |||
2350 | l2cap_sock_init(sk, parent); | ||
2351 | bacpy(&bt_sk(sk)->src, conn->src); | 2348 | bacpy(&bt_sk(sk)->src, conn->src); |
2352 | bacpy(&bt_sk(sk)->dst, conn->dst); | 2349 | bacpy(&bt_sk(sk)->dst, conn->dst); |
2353 | chan->psm = psm; | 2350 | chan->psm = psm; |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 2f4fd5751a46..4050edeaf78b 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <net/bluetooth/l2cap.h> | 31 | #include <net/bluetooth/l2cap.h> |
32 | 32 | ||
33 | static const struct proto_ops l2cap_sock_ops; | 33 | static const struct proto_ops l2cap_sock_ops; |
34 | static void l2cap_sock_init(struct sock *sk, struct sock *parent); | ||
35 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); | ||
34 | 36 | ||
35 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | 37 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
36 | { | 38 | { |
@@ -773,6 +775,25 @@ static int l2cap_sock_release(struct socket *sock) | |||
773 | return err; | 775 | return err; |
774 | } | 776 | } |
775 | 777 | ||
778 | static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) | ||
779 | { | ||
780 | struct sock *sk, *parent = data; | ||
781 | |||
782 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, | ||
783 | GFP_ATOMIC); | ||
784 | if (!sk) | ||
785 | return NULL; | ||
786 | |||
787 | l2cap_sock_init(sk, parent); | ||
788 | |||
789 | return l2cap_pi(sk)->chan; | ||
790 | } | ||
791 | |||
792 | static struct l2cap_ops l2cap_chan_ops = { | ||
793 | .name = "L2CAP Socket Interface", | ||
794 | .new_connection = l2cap_sock_new_connection_cb, | ||
795 | }; | ||
796 | |||
776 | static void l2cap_sock_destruct(struct sock *sk) | 797 | static void l2cap_sock_destruct(struct sock *sk) |
777 | { | 798 | { |
778 | BT_DBG("sk %p", sk); | 799 | BT_DBG("sk %p", sk); |
@@ -781,7 +802,7 @@ static void l2cap_sock_destruct(struct sock *sk) | |||
781 | skb_queue_purge(&sk->sk_write_queue); | 802 | skb_queue_purge(&sk->sk_write_queue); |
782 | } | 803 | } |
783 | 804 | ||
784 | void l2cap_sock_init(struct sock *sk, struct sock *parent) | 805 | static void l2cap_sock_init(struct sock *sk, struct sock *parent) |
785 | { | 806 | { |
786 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 807 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
787 | struct l2cap_chan *chan = pi->chan; | 808 | struct l2cap_chan *chan = pi->chan; |
@@ -838,10 +859,14 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
838 | chan->force_reliable = 0; | 859 | chan->force_reliable = 0; |
839 | chan->flushable = BT_FLUSHABLE_OFF; | 860 | chan->flushable = BT_FLUSHABLE_OFF; |
840 | chan->force_active = BT_POWER_FORCE_ACTIVE_ON; | 861 | chan->force_active = BT_POWER_FORCE_ACTIVE_ON; |
862 | |||
841 | } | 863 | } |
842 | 864 | ||
843 | /* Default config options */ | 865 | /* Default config options */ |
844 | chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; | 866 | chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; |
867 | |||
868 | chan->data = sk; | ||
869 | chan->ops = &l2cap_chan_ops; | ||
845 | } | 870 | } |
846 | 871 | ||
847 | static struct proto l2cap_proto = { | 872 | static struct proto l2cap_proto = { |
@@ -850,7 +875,7 @@ static struct proto l2cap_proto = { | |||
850 | .obj_size = sizeof(struct l2cap_pinfo) | 875 | .obj_size = sizeof(struct l2cap_pinfo) |
851 | }; | 876 | }; |
852 | 877 | ||
853 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) | 878 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) |
854 | { | 879 | { |
855 | struct sock *sk; | 880 | struct sock *sk; |
856 | struct l2cap_chan *chan; | 881 | struct l2cap_chan *chan; |