diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-04-18 18:36:44 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-05-05 12:47:41 -0400 |
commit | 73b2ec18532f45e9028ce4c7bc8d7f8818eabd2a (patch) | |
tree | e4ec31e6f06d1e84ad4eff0f6ee2a5f7e004a1b8 /net/bluetooth | |
parent | 9e4425fff9e0a0fb6a8c705777ed861f991f8747 (diff) |
Bluetooth: Handle psm == 0 case inside l2cap_add_psm()
When the user doesn't specify a psm we have the choose one for the
channel. Now we do this inside l2cap_add_psm().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 32 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 22 |
2 files changed, 24 insertions, 30 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 98ddd867cfd4..9e3f64f05d49 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -135,7 +135,7 @@ static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn | |||
135 | return c; | 135 | return c; |
136 | } | 136 | } |
137 | 137 | ||
138 | struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) | 138 | static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) |
139 | { | 139 | { |
140 | struct sock *sk; | 140 | struct sock *sk; |
141 | struct hlist_node *node; | 141 | struct hlist_node *node; |
@@ -153,19 +153,35 @@ found: | |||
153 | 153 | ||
154 | int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm) | 154 | int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm) |
155 | { | 155 | { |
156 | int err; | ||
157 | |||
156 | write_lock_bh(&l2cap_sk_list.lock); | 158 | write_lock_bh(&l2cap_sk_list.lock); |
157 | 159 | ||
158 | if (__l2cap_get_sock_by_addr(psm, src)) { | 160 | if (psm && __l2cap_get_sock_by_addr(psm, src)) { |
159 | write_unlock_bh(&l2cap_sk_list.lock); | 161 | err = -EADDRINUSE; |
160 | return -EADDRINUSE; | 162 | goto done; |
161 | } | 163 | } |
162 | 164 | ||
163 | chan->psm = psm; | 165 | if (psm) { |
164 | chan->sport = psm; | 166 | chan->psm = psm; |
167 | chan->sport = psm; | ||
168 | err = 0; | ||
169 | } else { | ||
170 | u16 p; | ||
165 | 171 | ||
166 | write_unlock_bh(&l2cap_sk_list.lock); | 172 | err = -EINVAL; |
173 | for (p = 0x1001; p < 0x1100; p += 2) | ||
174 | if (!__l2cap_get_sock_by_addr(cpu_to_le16(p), src)) { | ||
175 | chan->psm = cpu_to_le16(p); | ||
176 | chan->sport = cpu_to_le16(p); | ||
177 | err = 0; | ||
178 | break; | ||
179 | } | ||
180 | } | ||
167 | 181 | ||
168 | return 0; | 182 | done: |
183 | write_unlock_bh(&l2cap_sk_list.lock); | ||
184 | return err; | ||
169 | } | 185 | } |
170 | 186 | ||
171 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid) | 187 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid) |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 2156dcecec0b..aca99cd5377d 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -256,28 +256,6 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
256 | goto done; | 256 | goto done; |
257 | } | 257 | } |
258 | 258 | ||
259 | if (!chan->psm && !chan->scid) { | ||
260 | bdaddr_t *src = &bt_sk(sk)->src; | ||
261 | u16 psm; | ||
262 | |||
263 | err = -EINVAL; | ||
264 | |||
265 | write_lock_bh(&l2cap_sk_list.lock); | ||
266 | |||
267 | for (psm = 0x1001; psm < 0x1100; psm += 2) | ||
268 | if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) { | ||
269 | chan->psm = cpu_to_le16(psm); | ||
270 | chan->sport = cpu_to_le16(psm); | ||
271 | err = 0; | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | write_unlock_bh(&l2cap_sk_list.lock); | ||
276 | |||
277 | if (err < 0) | ||
278 | goto done; | ||
279 | } | ||
280 | |||
281 | sk->sk_max_ack_backlog = backlog; | 259 | sk->sk_max_ack_backlog = backlog; |
282 | sk->sk_ack_backlog = 0; | 260 | sk->sk_ack_backlog = 0; |
283 | sk->sk_state = BT_LISTEN; | 261 | sk->sk_state = BT_LISTEN; |