diff options
| author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-03 17:50:35 -0500 |
|---|---|---|
| committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-07 22:43:30 -0500 |
| commit | bb58f747e519aba07a6f05a78d58cf8a0788e2d5 (patch) | |
| tree | d65743650d5f1a164bbb709a8aa7df4b13250623 | |
| parent | 0a708f8fc46fde3be2116b8d79f7469a24097c90 (diff) | |
Bluetooth: Initial work for L2CAP split.
This patch tries to do the minimal to move l2cap_sock_create() and its
dependencies to l2cap_sock.c. It create a API to initialize and cleanup
the L2CAP sockets from l2cap_core.c through l2cap_init_sockets() and
l2cap_cleanup_sockets().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
| -rw-r--r-- | include/net/bluetooth/l2cap.h | 15 | ||||
| -rw-r--r-- | net/bluetooth/Makefile | 2 | ||||
| -rw-r--r-- | net/bluetooth/l2cap_core.c | 187 | ||||
| -rw-r--r-- | net/bluetooth/l2cap_sock.c | 213 |
4 files changed, 240 insertions, 177 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7f88a87d7a46..fce5274a4f7b 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
| @@ -424,6 +424,21 @@ static inline int l2cap_tx_window_full(struct sock *sk) | |||
| 424 | #define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) | 424 | #define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) |
| 425 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) | 425 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) |
| 426 | 426 | ||
| 427 | extern int disable_ertm; | ||
| 428 | extern const struct proto_ops l2cap_sock_ops; | ||
| 429 | extern struct bt_sock_list l2cap_sk_list; | ||
| 430 | |||
| 431 | int l2cap_init_sockets(void); | ||
| 432 | void l2cap_cleanup_sockets(void); | ||
| 433 | |||
| 434 | void l2cap_sock_set_timer(struct sock *sk, long timeout); | ||
| 435 | void __l2cap_sock_close(struct sock *sk, int reason); | ||
| 436 | void l2cap_sock_kill(struct sock *sk); | ||
| 437 | void l2cap_sock_init(struct sock *sk, struct sock *parent); | ||
| 438 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | ||
| 439 | int proto, gfp_t prio); | ||
| 440 | |||
| 441 | |||
| 427 | void l2cap_load(void); | 442 | void l2cap_load(void); |
| 428 | 443 | ||
| 429 | #endif /* __L2CAP_H */ | 444 | #endif /* __L2CAP_H */ |
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index bf2945e1d9ef..339b42932b33 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile | |||
| @@ -11,4 +11,4 @@ obj-$(CONFIG_BT_CMTP) += cmtp/ | |||
| 11 | obj-$(CONFIG_BT_HIDP) += hidp/ | 11 | obj-$(CONFIG_BT_HIDP) += hidp/ |
| 12 | 12 | ||
| 13 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o | 13 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o |
| 14 | l2cap-y := l2cap_core.o | 14 | l2cap-y := l2cap_core.o l2cap_sock.o |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 28d2954f94a4..af678efec15f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | SOFTWARE IS DISCLAIMED. | 24 | SOFTWARE IS DISCLAIMED. |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | /* Bluetooth L2CAP core and sockets. */ | 27 | /* Bluetooth L2CAP core. */ |
| 28 | 28 | ||
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | 30 | ||
| @@ -57,24 +57,20 @@ | |||
| 57 | 57 | ||
| 58 | #define VERSION "2.15" | 58 | #define VERSION "2.15" |
| 59 | 59 | ||
| 60 | static int disable_ertm; | 60 | int disable_ertm; |
| 61 | 61 | ||
| 62 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 62 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
| 63 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 63 | static u8 l2cap_fixed_chan[8] = { 0x02, }; |
| 64 | 64 | ||
| 65 | static const struct proto_ops l2cap_sock_ops; | ||
| 66 | |||
| 67 | static struct workqueue_struct *_busy_wq; | 65 | static struct workqueue_struct *_busy_wq; |
| 68 | 66 | ||
| 69 | static struct bt_sock_list l2cap_sk_list = { | 67 | struct bt_sock_list l2cap_sk_list = { |
| 70 | .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) | 68 | .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) |
| 71 | }; | 69 | }; |
| 72 | 70 | ||
| 73 | static void l2cap_busy_work(struct work_struct *work); | 71 | static void l2cap_busy_work(struct work_struct *work); |
| 74 | 72 | ||
| 75 | static void __l2cap_sock_close(struct sock *sk, int reason); | ||
| 76 | static void l2cap_sock_close(struct sock *sk); | 73 | static void l2cap_sock_close(struct sock *sk); |
| 77 | static void l2cap_sock_kill(struct sock *sk); | ||
| 78 | 74 | ||
| 79 | static int l2cap_build_conf_req(struct sock *sk, void *data); | 75 | static int l2cap_build_conf_req(struct sock *sk, void *data); |
| 80 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 76 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
| @@ -83,7 +79,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | |||
| 83 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | 79 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); |
| 84 | 80 | ||
| 85 | /* ---- L2CAP timers ---- */ | 81 | /* ---- L2CAP timers ---- */ |
| 86 | static void l2cap_sock_set_timer(struct sock *sk, long timeout) | 82 | void l2cap_sock_set_timer(struct sock *sk, long timeout) |
| 87 | { | 83 | { |
| 88 | BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); | 84 | BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); |
| 89 | sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); | 85 | sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); |
| @@ -95,39 +91,6 @@ static void l2cap_sock_clear_timer(struct sock *sk) | |||
| 95 | sk_stop_timer(sk, &sk->sk_timer); | 91 | sk_stop_timer(sk, &sk->sk_timer); |
| 96 | } | 92 | } |
| 97 | 93 | ||
| 98 | static void l2cap_sock_timeout(unsigned long arg) | ||
| 99 | { | ||
| 100 | struct sock *sk = (struct sock *) arg; | ||
| 101 | int reason; | ||
| 102 | |||
| 103 | BT_DBG("sock %p state %d", sk, sk->sk_state); | ||
| 104 | |||
| 105 | bh_lock_sock(sk); | ||
| 106 | |||
| 107 | if (sock_owned_by_user(sk)) { | ||
| 108 | /* sk is owned by user. Try again later */ | ||
| 109 | l2cap_sock_set_timer(sk, HZ / 5); | ||
| 110 | bh_unlock_sock(sk); | ||
| 111 | sock_put(sk); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | |||
| 115 | if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) | ||
| 116 | reason = ECONNREFUSED; | ||
| 117 | else if (sk->sk_state == BT_CONNECT && | ||
| 118 | l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) | ||
| 119 | reason = ECONNREFUSED; | ||
| 120 | else | ||
| 121 | reason = ETIMEDOUT; | ||
| 122 | |||
| 123 | __l2cap_sock_close(sk, reason); | ||
| 124 | |||
| 125 | bh_unlock_sock(sk); | ||
| 126 | |||
| 127 | l2cap_sock_kill(sk); | ||
| 128 | sock_put(sk); | ||
| 129 | } | ||
| 130 | |||
| 131 | /* ---- L2CAP channels ---- */ | 94 | /* ---- L2CAP channels ---- */ |
| 132 | static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) | 95 | static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) |
| 133 | { | 96 | { |
| @@ -801,14 +764,6 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) | |||
| 801 | return node ? sk : sk1; | 764 | return node ? sk : sk1; |
| 802 | } | 765 | } |
| 803 | 766 | ||
| 804 | static void l2cap_sock_destruct(struct sock *sk) | ||
| 805 | { | ||
| 806 | BT_DBG("sk %p", sk); | ||
| 807 | |||
| 808 | skb_queue_purge(&sk->sk_receive_queue); | ||
| 809 | skb_queue_purge(&sk->sk_write_queue); | ||
| 810 | } | ||
| 811 | |||
| 812 | static void l2cap_sock_cleanup_listen(struct sock *parent) | 767 | static void l2cap_sock_cleanup_listen(struct sock *parent) |
| 813 | { | 768 | { |
| 814 | struct sock *sk; | 769 | struct sock *sk; |
| @@ -826,7 +781,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) | |||
| 826 | /* Kill socket (only if zapped and orphan) | 781 | /* Kill socket (only if zapped and orphan) |
| 827 | * Must be called on unlocked socket. | 782 | * Must be called on unlocked socket. |
| 828 | */ | 783 | */ |
| 829 | static void l2cap_sock_kill(struct sock *sk) | 784 | void l2cap_sock_kill(struct sock *sk) |
| 830 | { | 785 | { |
| 831 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) | 786 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) |
| 832 | return; | 787 | return; |
| @@ -839,7 +794,7 @@ static void l2cap_sock_kill(struct sock *sk) | |||
| 839 | sock_put(sk); | 794 | sock_put(sk); |
| 840 | } | 795 | } |
| 841 | 796 | ||
| 842 | static void __l2cap_sock_close(struct sock *sk, int reason) | 797 | void __l2cap_sock_close(struct sock *sk, int reason) |
| 843 | { | 798 | { |
| 844 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | 799 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); |
| 845 | 800 | ||
| @@ -904,111 +859,6 @@ static void l2cap_sock_close(struct sock *sk) | |||
| 904 | l2cap_sock_kill(sk); | 859 | l2cap_sock_kill(sk); |
| 905 | } | 860 | } |
| 906 | 861 | ||
| 907 | static void l2cap_sock_init(struct sock *sk, struct sock *parent) | ||
| 908 | { | ||
| 909 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
| 910 | |||
| 911 | BT_DBG("sk %p", sk); | ||
| 912 | |||
| 913 | if (parent) { | ||
| 914 | sk->sk_type = parent->sk_type; | ||
| 915 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; | ||
| 916 | |||
| 917 | pi->imtu = l2cap_pi(parent)->imtu; | ||
| 918 | pi->omtu = l2cap_pi(parent)->omtu; | ||
| 919 | |||
