aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-05-16 16:24:37 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-13 13:55:32 -0400
commit80808e431e1ef25856457de82ce141bed6a6313a (patch)
tree021d6affd8b8f6bf81ba51fadb9951b0b9e47d27
parentdc50a06dac61d7ca7ddb3d9bb8921ca5d68f51b6 (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.h12
-rw-r--r--net/bluetooth/l2cap_core.c17
-rw-r--r--net/bluetooth/l2cap_sock.c29
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
362struct l2cap_ops {
363 char *name;
364
365 struct l2cap_chan *(*new_connection) (void *data);
357}; 366};
358 367
359struct l2cap_conn { 368struct l2cap_conn {
@@ -460,9 +469,6 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
460int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); 469int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
461 470
462void l2cap_sock_kill(struct sock *sk); 471void l2cap_sock_kill(struct sock *sk);
463void l2cap_sock_init(struct sock *sk, struct sock *parent);
464struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
465 int proto, gfp_t prio);
466 472
467struct l2cap_chan *l2cap_chan_create(struct sock *sk); 473struct l2cap_chan *l2cap_chan_create(struct sock *sk);
468void l2cap_chan_close(struct l2cap_chan *chan, int reason); 474void 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
33static const struct proto_ops l2cap_sock_ops; 33static const struct proto_ops l2cap_sock_ops;
34static void l2cap_sock_init(struct sock *sk, struct sock *parent);
35static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio);
34 36
35static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) 37static 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
778static 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
792static struct l2cap_ops l2cap_chan_ops = {
793 .name = "L2CAP Socket Interface",
794 .new_connection = l2cap_sock_new_connection_cb,
795};
796
776static void l2cap_sock_destruct(struct sock *sk) 797static 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
784void l2cap_sock_init(struct sock *sk, struct sock *parent) 805static 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
847static struct proto l2cap_proto = { 872static 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
853struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) 878static 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;