Commit 9e4425fff9e0a0fb6a8c705777ed861f991f8747
1 parent
7cbc9bd995
Exists in
master
and in
7 other branches
Bluetooth: Add l2cap_add_psm() and l2cap_add_scid()
The intention is to get rid of the l2cap_sk_list usage inside l2cap_core.c. l2cap_sk_list will soon be replaced by a list that does not depend on socket usage. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Showing 3 changed files with 59 additions and 33 deletions Side-by-side Diff
include/net/bluetooth/l2cap.h
... | ... | @@ -458,6 +458,10 @@ |
458 | 458 | void l2cap_streaming_send(struct l2cap_chan *chan); |
459 | 459 | int l2cap_ertm_send(struct l2cap_chan *chan); |
460 | 460 | |
461 | +struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src); | |
462 | +int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); | |
463 | +int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); | |
464 | + | |
461 | 465 | void l2cap_sock_set_timer(struct sock *sk, long timeout); |
462 | 466 | void l2cap_sock_clear_timer(struct sock *sk); |
463 | 467 | void __l2cap_sock_close(struct sock *sk, int reason); |
net/bluetooth/l2cap_core.c
... | ... | @@ -135,6 +135,50 @@ |
135 | 135 | return c; |
136 | 136 | } |
137 | 137 | |
138 | +struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) | |
139 | +{ | |
140 | + struct sock *sk; | |
141 | + struct hlist_node *node; | |
142 | + sk_for_each(sk, node, &l2cap_sk_list.head) { | |
143 | + struct l2cap_chan *chan = l2cap_pi(sk)->chan; | |
144 | + | |
145 | + if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src)) | |
146 | + goto found; | |
147 | + } | |
148 | + | |
149 | + sk = NULL; | |
150 | +found: | |
151 | + return sk; | |
152 | +} | |
153 | + | |
154 | +int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm) | |
155 | +{ | |
156 | + write_lock_bh(&l2cap_sk_list.lock); | |
157 | + | |
158 | + if (__l2cap_get_sock_by_addr(psm, src)) { | |
159 | + write_unlock_bh(&l2cap_sk_list.lock); | |
160 | + return -EADDRINUSE; | |
161 | + } | |
162 | + | |
163 | + chan->psm = psm; | |
164 | + chan->sport = psm; | |
165 | + | |
166 | + write_unlock_bh(&l2cap_sk_list.lock); | |
167 | + | |
168 | + return 0; | |
169 | +} | |
170 | + | |
171 | +int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid) | |
172 | +{ | |
173 | + write_lock_bh(&l2cap_sk_list.lock); | |
174 | + | |
175 | + chan->scid = scid; | |
176 | + | |
177 | + write_unlock_bh(&l2cap_sk_list.lock); | |
178 | + | |
179 | + return 0; | |
180 | +} | |
181 | + | |
138 | 182 | static u16 l2cap_alloc_cid(struct l2cap_conn *conn) |
139 | 183 | { |
140 | 184 | u16 cid = L2CAP_CID_DYN_START; |
net/bluetooth/l2cap_sock.c
... | ... | @@ -78,22 +78,6 @@ |
78 | 78 | sk_stop_timer(sk, &sk->sk_timer); |
79 | 79 | } |
80 | 80 | |
81 | -static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) | |
82 | -{ | |
83 | - struct sock *sk; | |
84 | - struct hlist_node *node; | |
85 | - sk_for_each(sk, node, &l2cap_sk_list.head) { | |
86 | - struct l2cap_chan *chan = l2cap_pi(sk)->chan; | |
87 | - | |
88 | - if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src)) | |
89 | - goto found; | |
90 | - } | |
91 | - | |
92 | - sk = NULL; | |
93 | -found: | |
94 | - return sk; | |
95 | -} | |
96 | - | |
97 | 81 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
98 | 82 | { |
99 | 83 | struct sock *sk = sock->sk; |
100 | 84 | |
101 | 85 | |
102 | 86 | |
... | ... | @@ -136,26 +120,20 @@ |
136 | 120 | } |
137 | 121 | } |
138 | 122 | |
139 | - write_lock_bh(&l2cap_sk_list.lock); | |
123 | + if (la.l2_cid) | |
124 | + err = l2cap_add_scid(chan, la.l2_cid); | |
125 | + else | |
126 | + err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm); | |
140 | 127 | |
141 | - if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) { | |
142 | - err = -EADDRINUSE; | |
143 | - } else { | |
144 | - /* Save source address */ | |
145 | - bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); | |
146 | - chan->psm = la.l2_psm; | |
147 | - chan->sport = la.l2_psm; | |
148 | - sk->sk_state = BT_BOUND; | |
128 | + if (err < 0) | |
129 | + goto done; | |
149 | 130 | |
150 | - if (__le16_to_cpu(la.l2_psm) == 0x0001 || | |
151 | - __le16_to_cpu(la.l2_psm) == 0x0003) | |
152 | - chan->sec_level = BT_SECURITY_SDP; | |
153 | - } | |
131 | + if (__le16_to_cpu(la.l2_psm) == 0x0001 || | |
132 | + __le16_to_cpu(la.l2_psm) == 0x0003) | |
133 | + chan->sec_level = BT_SECURITY_SDP; | |
154 | 134 | |
155 | - if (la.l2_cid) | |
156 | - chan->scid = la.l2_cid; | |
157 | - | |
158 | - write_unlock_bh(&l2cap_sk_list.lock); | |
135 | + bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); | |
136 | + sk->sk_state = BT_BOUND; | |
159 | 137 | |
160 | 138 | done: |
161 | 139 | release_sock(sk); |