diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/bluetooth/rfcomm/sock.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 1010 |
1 files changed, 1010 insertions, 0 deletions
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c new file mode 100644 index 000000000000..640028a2183c --- /dev/null +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -0,0 +1,1010 @@ | |||
1 | /* | ||
2 | RFCOMM implementation for Linux Bluetooth stack (BlueZ). | ||
3 | Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com> | ||
4 | Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License version 2 as | ||
8 | published by the Free Software Foundation; | ||
9 | |||
10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
11 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
13 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
14 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
15 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
16 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
17 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | |||
19 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
20 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
21 | SOFTWARE IS DISCLAIMED. | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * RFCOMM sockets. | ||
26 | * | ||
27 | * $Id: sock.c,v 1.24 2002/10/03 01:00:34 maxk Exp $ | ||
28 | */ | ||
29 | |||
30 | #include <linux/config.h> | ||
31 | #include <linux/module.h> | ||
32 | |||
33 | #include <linux/types.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/major.h> | ||
37 | #include <linux/sched.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/poll.h> | ||
40 | #include <linux/fcntl.h> | ||
41 | #include <linux/init.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/socket.h> | ||
44 | #include <linux/skbuff.h> | ||
45 | #include <linux/list.h> | ||
46 | #include <linux/proc_fs.h> | ||
47 | #include <linux/seq_file.h> | ||
48 | #include <net/sock.h> | ||
49 | |||
50 | #include <asm/system.h> | ||
51 | #include <asm/uaccess.h> | ||
52 | |||
53 | #include <net/bluetooth/bluetooth.h> | ||
54 | #include <net/bluetooth/hci_core.h> | ||
55 | #include <net/bluetooth/l2cap.h> | ||
56 | #include <net/bluetooth/rfcomm.h> | ||
57 | |||
58 | #ifndef CONFIG_BT_RFCOMM_DEBUG | ||
59 | #undef BT_DBG | ||
60 | #define BT_DBG(D...) | ||
61 | #endif | ||
62 | |||
63 | static struct proto_ops rfcomm_sock_ops; | ||
64 | |||
65 | static struct bt_sock_list rfcomm_sk_list = { | ||
66 | .lock = RW_LOCK_UNLOCKED | ||
67 | }; | ||
68 | |||
69 | static void rfcomm_sock_close(struct sock *sk); | ||
70 | static void rfcomm_sock_kill(struct sock *sk); | ||
71 | |||
72 | /* ---- DLC callbacks ---- | ||
73 | * | ||
74 | * called under rfcomm_dlc_lock() | ||
75 | */ | ||
76 | static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) | ||
77 | { | ||
78 | struct sock *sk = d->owner; | ||
79 | if (!sk) | ||
80 | return; | ||
81 | |||
82 | atomic_add(skb->len, &sk->sk_rmem_alloc); | ||
83 | skb_queue_tail(&sk->sk_receive_queue, skb); | ||
84 | sk->sk_data_ready(sk, skb->len); | ||
85 | |||
86 | if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) | ||
87 | rfcomm_dlc_throttle(d); | ||
88 | } | ||
89 | |||
90 | static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) | ||
91 | { | ||
92 | struct sock *sk = d->owner, *parent; | ||
93 | if (!sk) | ||
94 | return; | ||
95 | |||
96 | BT_DBG("dlc %p state %ld err %d", d, d->state, err); | ||
97 | |||
98 | bh_lock_sock(sk); | ||
99 | |||
100 | if (err) | ||
101 | sk->sk_err = err; | ||
102 | |||
103 | sk->sk_state = d->state; | ||
104 | |||
105 | parent = bt_sk(sk)->parent; | ||
106 | if (parent) { | ||
107 | if (d->state == BT_CLOSED) { | ||
108 | sock_set_flag(sk, SOCK_ZAPPED); | ||
109 | bt_accept_unlink(sk); | ||
110 | } | ||
111 | parent->sk_data_ready(parent, 0); | ||
112 | } else { | ||
113 | if (d->state == BT_CONNECTED) | ||
114 | rfcomm_session_getaddr(d->session, &bt_sk(sk)->src, NULL); | ||
115 | sk->sk_state_change(sk); | ||
116 | } | ||
117 | |||
118 | bh_unlock_sock(sk); | ||
119 | |||
120 | if (parent && sock_flag(sk, SOCK_ZAPPED)) { | ||
121 | /* We have to drop DLC lock here, otherwise | ||
122 | * rfcomm_sock_destruct() will dead lock. */ | ||
123 | rfcomm_dlc_unlock(d); | ||
124 | rfcomm_sock_kill(sk); | ||
125 | rfcomm_dlc_lock(d); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | /* ---- Socket functions ---- */ | ||
130 | static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) | ||
131 | { | ||
132 | struct sock *sk = NULL; | ||
133 | struct hlist_node *node; | ||
134 | |||
135 | sk_for_each(sk, node, &rfcomm_sk_list.head) { | ||
136 | if (rfcomm_pi(sk)->channel == channel && | ||
137 | !bacmp(&bt_sk(sk)->src, src)) | ||
138 | break; | ||
139 | } | ||
140 | |||
141 | return node ? sk : NULL; | ||
142 | } | ||
143 | |||
144 | /* Find socket with channel and source bdaddr. | ||
145 | * Returns closest match. | ||
146 | */ | ||
147 | static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) | ||
148 | { | ||
149 | struct sock *sk = NULL, *sk1 = NULL; | ||
150 | struct hlist_node *node; | ||
151 | |||
152 | sk_for_each(sk, node, &rfcomm_sk_list.head) { | ||
153 | if (state && sk->sk_state != state) | ||
154 | continue; | ||
155 | |||
156 | if (rfcomm_pi(sk)->channel == channel) { | ||
157 | /* Exact match. */ | ||
158 | if (!bacmp(&bt_sk(sk)->src, src)) | ||
159 | break; | ||
160 | |||
161 | /* Closest match */ | ||
162 | if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) | ||
163 | sk1 = sk; | ||
164 | } | ||
165 | } | ||
166 | return node ? sk : sk1; | ||
167 | } | ||
168 | |||
169 | /* Find socket with given address (channel, src). | ||
170 | * Returns locked socket */ | ||
171 | static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) | ||
172 | { | ||
173 | struct sock *s; | ||
174 | read_lock(&rfcomm_sk_list.lock); | ||
175 | s = __rfcomm_get_sock_by_channel(state, channel, src); | ||
176 | if (s) bh_lock_sock(s); | ||
177 | read_unlock(&rfcomm_sk_list.lock); | ||
178 | return s; | ||
179 | } | ||
180 | |||
181 | static void rfcomm_sock_destruct(struct sock *sk) | ||
182 | { | ||
183 | struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; | ||
184 | |||
185 | BT_DBG("sk %p dlc %p", sk, d); | ||
186 | |||
187 | skb_queue_purge(&sk->sk_receive_queue); | ||
188 | skb_queue_purge(&sk->sk_write_queue); | ||
189 | |||
190 | rfcomm_dlc_lock(d); | ||
191 | rfcomm_pi(sk)->dlc = NULL; | ||
192 | |||
193 | /* Detach DLC if it's owned by this socket */ | ||
194 | if (d->owner == sk) | ||
195 | d->owner = NULL; | ||
196 | rfcomm_dlc_unlock(d); | ||
197 | |||
198 | rfcomm_dlc_put(d); | ||
199 | } | ||
200 | |||
201 | static void rfcomm_sock_cleanup_listen(struct sock *parent) | ||
202 | { | ||
203 | struct sock *sk; | ||
204 | |||
205 | BT_DBG("parent %p", parent); | ||
206 | |||
207 | /* Close not yet accepted dlcs */ | ||
208 | while ((sk = bt_accept_dequeue(parent, NULL))) { | ||
209 | rfcomm_sock_close(sk); | ||
210 | rfcomm_sock_kill(sk); | ||
211 | } | ||
212 | |||
213 | parent->sk_state = BT_CLOSED; | ||
214 | sock_set_flag(parent, SOCK_ZAPPED); | ||
215 | } | ||
216 | |||
217 | /* Kill socket (only if zapped and orphan) | ||
218 | * Must be called on unlocked socket. | ||
219 | */ | ||
220 | static void rfcomm_sock_kill(struct sock *sk) | ||
221 | { | ||
222 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) | ||
223 | return; | ||
224 | |||
225 | BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, atomic_read(&sk->sk_refcnt)); | ||
226 | |||
227 | /* Kill poor orphan */ | ||
228 | bt_sock_unlink(&rfcomm_sk_list, sk); | ||
229 | sock_set_flag(sk, SOCK_DEAD); | ||
230 | sock_put(sk); | ||
231 | } | ||
232 | |||
233 | static void __rfcomm_sock_close(struct sock *sk) | ||
234 | { | ||
235 | struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; | ||
236 | |||
237 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | ||
238 | |||
239 | switch (sk->sk_state) { | ||
240 | case BT_LISTEN: | ||
241 | rfcomm_sock_cleanup_listen(sk); | ||
242 | break; | ||
243 | |||
244 | case BT_CONNECT: | ||
245 | case BT_CONNECT2: | ||
246 | case BT_CONFIG: | ||
247 | case BT_CONNECTED: | ||
248 | rfcomm_dlc_close(d, 0); | ||
249 | |||
250 | default: | ||
251 | sock_set_flag(sk, SOCK_ZAPPED); | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /* Close socket. | ||
257 | * Must be called on unlocked socket. | ||
258 | */ | ||
259 | static void rfcomm_sock_close(struct sock *sk) | ||
260 | { | ||
261 | lock_sock(sk); | ||
262 | __rfcomm_sock_close(sk); | ||
263 | release_sock(sk); | ||
264 | } | ||
265 | |||
266 | static void rfcomm_sock_init(struct sock *sk, struct sock *parent) | ||
267 | { | ||
268 | struct rfcomm_pinfo *pi = rfcomm_pi(sk); | ||
269 | |||
270 | BT_DBG("sk %p", sk); | ||
271 | |||
272 | if (parent) { | ||
273 | sk->sk_type = parent->sk_type; | ||
274 | pi->link_mode = rfcomm_pi(parent)->link_mode; | ||
275 | } else { | ||
276 | pi->link_mode = 0; | ||
277 | } | ||
278 | |||
279 | pi->dlc->link_mode = pi->link_mode; | ||
280 | } | ||
281 | |||
282 | static struct proto rfcomm_proto = { | ||
283 | .name = "RFCOMM", | ||
284 | .owner = THIS_MODULE, | ||
285 | .obj_size = sizeof(struct rfcomm_pinfo) | ||
286 | }; | ||
287 | |||
288 | static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio) | ||
289 | { | ||
290 | struct rfcomm_dlc *d; | ||
291 | struct sock *sk; | ||
292 | |||
293 | sk = sk_alloc(PF_BLUETOOTH, prio, &rfcomm_proto, 1); | ||
294 | if (!sk) | ||
295 | return NULL; | ||
296 | |||
297 | sock_init_data(sock, sk); | ||
298 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); | ||
299 | |||
300 | d = rfcomm_dlc_alloc(prio); | ||
301 | if (!d) { | ||
302 | sk_free(sk); | ||
303 | return NULL; | ||
304 | } | ||
305 | |||
306 | d->data_ready = rfcomm_sk_data_ready; | ||
307 | d->state_change = rfcomm_sk_state_change; | ||
308 | |||
309 | rfcomm_pi(sk)->dlc = d; | ||
310 | d->owner = sk; | ||
311 | |||
312 | sk->sk_destruct = rfcomm_sock_destruct; | ||
313 | sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT; | ||
314 | |||
315 | sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; | ||
316 | sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; | ||
317 | |||
318 | sock_reset_flag(sk, SOCK_ZAPPED); | ||
319 | |||
320 | sk->sk_protocol = proto; | ||
321 | sk->sk_state = BT_OPEN; | ||
322 | |||
323 | bt_sock_link(&rfcomm_sk_list, sk); | ||
324 | |||
325 | BT_DBG("sk %p", sk); | ||
326 | return sk; | ||
327 | } | ||
328 | |||
329 | static int rfcomm_sock_create(struct socket *sock, int protocol) | ||
330 | { | ||
331 | struct sock *sk; | ||
332 | |||
333 | BT_DBG("sock %p", sock); | ||
334 | |||
335 | sock->state = SS_UNCONNECTED; | ||
336 | |||
337 | if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW) | ||
338 | return -ESOCKTNOSUPPORT; | ||
339 | |||
340 | sock->ops = &rfcomm_sock_ops; | ||
341 | |||
342 | if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL))) | ||
343 | return -ENOMEM; | ||
344 | |||
345 | rfcomm_sock_init(sk, NULL); | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | ||
350 | { | ||
351 | struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; | ||
352 | struct sock *sk = sock->sk; | ||
353 | int err = 0; | ||
354 | |||
355 | BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr)); | ||
356 | |||
357 | if (!addr || addr->sa_family != AF_BLUETOOTH) | ||
358 | return -EINVAL; | ||
359 | |||
360 | lock_sock(sk); | ||
361 | |||
362 | if (sk->sk_state != BT_OPEN) { | ||
363 | err = -EBADFD; | ||
364 | goto done; | ||
365 | } | ||
366 | |||
367 | write_lock_bh(&rfcomm_sk_list.lock); | ||
368 | |||
369 | if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { | ||
370 | err = -EADDRINUSE; | ||
371 | } else { | ||
372 | /* Save source address */ | ||
373 | bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr); | ||
374 | rfcomm_pi(sk)->channel = sa->rc_channel; | ||
375 | sk->sk_state = BT_BOUND; | ||
376 | } | ||
377 | |||
378 | write_unlock_bh(&rfcomm_sk_list.lock); | ||
379 | |||
380 | done: | ||
381 | release_sock(sk); | ||
382 | return err; | ||
383 | } | ||
384 | |||
385 | static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) | ||
386 | { | ||
387 | struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; | ||
388 | struct sock *sk = sock->sk; | ||
389 | struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; | ||
390 | int err = 0; | ||
391 | |||
392 | BT_DBG("sk %p", sk); | ||
393 | |||
394 | if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc)) | ||
395 | return -EINVAL; | ||
396 | |||
397 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) | ||
398 | return -EBADFD; | ||
399 | |||
400 | if (sk->sk_type != SOCK_STREAM) | ||
401 | return -EINVAL; | ||
402 | |||
403 | lock_sock(sk); | ||
404 | |||
405 | sk->sk_state = BT_CONNECT; | ||
406 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); | ||
407 | rfcomm_pi(sk)->channel = sa->rc_channel; | ||
408 | |||
409 | err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); | ||
410 | if (!err) | ||
411 | err = bt_sock_wait_state(sk, BT_CONNECTED, | ||
412 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | ||
413 | |||
414 | release_sock(sk); | ||
415 | return err; | ||
416 | } | ||
417 | |||
418 | static int rfcomm_sock_listen(struct socket *sock, int backlog) | ||
419 | { | ||
420 | struct sock *sk = sock->sk; | ||
421 | int err = 0; | ||
422 | |||
423 | BT_DBG("sk %p backlog %d", sk, backlog); | ||
424 | |||
425 | lock_sock(sk); | ||
426 | |||
427 | if (sk->sk_state != BT_BOUND) { | ||
428 | err = -EBADFD; | ||
429 | goto done; | ||
430 | } | ||
431 | |||
432 | if (!rfcomm_pi(sk)->channel) { | ||
433 | bdaddr_t *src = &bt_sk(sk)->src; | ||
434 | u8 channel; | ||
435 | |||
436 | err = -EINVAL; | ||
437 | |||
438 | write_lock_bh(&rfcomm_sk_list.lock); | ||
439 | |||
440 | for (channel = 1; channel < 31; channel++) | ||
441 | if (!__rfcomm_get_sock_by_addr(channel, src)) { | ||
442 | rfcomm_pi(sk)->channel = channel; | ||
443 | err = 0; | ||
444 | break; | ||
445 | } | ||
446 | |||
447 | write_unlock_bh(&rfcomm_sk_list.lock); | ||
448 | |||
449 | if (err < 0) | ||
450 | goto done; | ||
451 | } | ||
452 | |||
453 | sk->sk_max_ack_backlog = backlog; | ||
454 | sk->sk_ack_backlog = 0; | ||
455 | sk->sk_state = BT_LISTEN; | ||
456 | |||
457 | done: | ||
458 | release_sock(sk); | ||
459 | return err; | ||
460 | } | ||
461 | |||
462 | static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags) | ||
463 | { | ||
464 | DECLARE_WAITQUEUE(wait, current); | ||
465 | struct sock *sk = sock->sk, *nsk; | ||
466 | long timeo; | ||
467 | int err = 0; | ||
468 | |||
469 | lock_sock(sk); | ||
470 | |||
471 | if (sk->sk_state != BT_LISTEN) { | ||
472 | err = -EBADFD; | ||
473 | goto done; | ||
474 | } | ||
475 | |||
476 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | ||
477 | |||
478 | BT_DBG("sk %p timeo %ld", sk, timeo); | ||
479 | |||
480 | /* Wait for an incoming connection. (wake-one). */ | ||
481 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | ||
482 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | ||
483 | set_current_state(TASK_INTERRUPTIBLE); | ||
484 | if (!timeo) { | ||
485 | err = -EAGAIN; | ||
486 | break; | ||
487 | } | ||
488 | |||
489 | release_sock(sk); | ||
490 | timeo = schedule_timeout(timeo); | ||
491 | lock_sock(sk); | ||
492 | |||
493 | if (sk->sk_state != BT_LISTEN) { | ||
494 | err = -EBADFD; | ||
495 | break; | ||
496 | } | ||
497 | |||
498 | if (signal_pending(current)) { | ||
499 | err = sock_intr_errno(timeo); | ||
500 | break; | ||
501 | } | ||
502 | } | ||
503 | set_current_state(TASK_RUNNING); | ||
504 | remove_wait_queue(sk->sk_sleep, &wait); | ||
505 | |||
506 | if (err) | ||
507 | goto done; | ||
508 | |||
509 | newsock->state = SS_CONNECTED; | ||
510 | |||
511 | BT_DBG("new socket %p", nsk); | ||
512 | |||
513 | done: | ||
514 | release_sock(sk); | ||
515 | return err; | ||
516 | } | ||
517 | |||
518 | static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) | ||
519 | { | ||
520 | struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; | ||
521 | struct sock *sk = sock->sk; | ||
522 | |||
523 | BT_DBG("sock %p, sk %p", sock, sk); | ||
524 | |||
525 | sa->rc_family = AF_BLUETOOTH; | ||
526 | sa->rc_channel = rfcomm_pi(sk)->channel; | ||
527 | if (peer) | ||
528 | bacpy(&sa->rc_bdaddr, &bt_sk(sk)->dst); | ||
529 | else | ||
530 | bacpy(&sa->rc_bdaddr, &bt_sk(sk)->src); | ||
531 | |||
532 | *len = sizeof(struct sockaddr_rc); | ||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | ||
537 | struct msghdr *msg, size_t len) | ||
538 | { | ||
539 | struct sock *sk = sock->sk; | ||
540 | struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; | ||
541 | struct sk_buff *skb; | ||
542 | int err; | ||
543 | int sent = 0; | ||
544 | |||
545 | if (msg->msg_flags & MSG_OOB) | ||
546 | return -EOPNOTSUPP; | ||
547 | |||
548 | if (sk->sk_shutdown & SEND_SHUTDOWN) | ||
549 | return -EPIPE; | ||
550 | |||
551 | BT_DBG("sock %p, sk %p", sock, sk); | ||
552 | |||
553 | lock_sock(sk); | ||
554 | |||
555 | while (len) { | ||
556 | size_t size = min_t(size_t, len, d->mtu); | ||
557 | |||
558 | skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE, | ||
559 | msg->msg_flags & MSG_DONTWAIT, &err); | ||
560 | if (!skb) | ||
561 | break; | ||
562 | skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE); | ||
563 | |||
564 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | ||
565 | if (err) { | ||
566 | kfree_skb(skb); | ||
567 | sent = err; | ||
568 | break; | ||
569 | } | ||
570 | |||
571 | err = rfcomm_dlc_send(d, skb); | ||
572 | if (err < 0) { | ||
573 | kfree_skb(skb); | ||
574 | break; | ||
575 | } | ||
576 | |||
577 | sent += size; | ||
578 | len -= size; | ||
579 | } | ||
580 | |||
581 | release_sock(sk); | ||
582 | |||
583 | return sent ? sent : err; | ||
584 | } | ||
585 | |||
586 | static long rfcomm_sock_data_wait(struct sock *sk, long timeo) | ||
587 | { | ||
588 | DECLARE_WAITQUEUE(wait, current); | ||
589 | |||
590 | add_wait_queue(sk->sk_sleep, &wait); | ||
591 | for (;;) { | ||
592 | set_current_state(TASK_INTERRUPTIBLE); | ||
593 | |||
594 | if (skb_queue_len(&sk->sk_receive_queue) || sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN) || | ||
595 | signal_pending(current) || !timeo) | ||
596 | break; | ||
597 | |||
598 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | ||
599 | release_sock(sk); | ||
600 | timeo = schedule_timeout(timeo); | ||
601 | lock_sock(sk); | ||
602 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | ||
603 | } | ||
604 | |||
605 | __set_current_state(TASK_RUNNING); | ||
606 | remove_wait_queue(sk->sk_sleep, &wait); | ||
607 | return timeo; | ||
608 | } | ||
609 | |||
610 | static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | ||
611 | struct msghdr *msg, size_t size, int flags) | ||
612 | { | ||
613 | struct sock *sk = sock->sk; | ||
614 | int err = 0; | ||
615 | size_t target, copied = 0; | ||
616 | long timeo; | ||
617 | |||
618 | if (flags & MSG_OOB) | ||
619 | return -EOPNOTSUPP; | ||
620 | |||
621 | msg->msg_namelen = 0; | ||
622 | |||
623 | BT_DBG("sk %p size %d", sk, size); | ||
624 | |||
625 | lock_sock(sk); | ||
626 | |||
627 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); | ||
628 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | ||
629 | |||
630 | do { | ||
631 | struct sk_buff *skb; | ||
632 | int chunk; | ||
633 | |||
634 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
635 | if (!skb) { | ||
636 | if (copied >= target) | ||
637 | break; | ||
638 | |||
639 | if ((err = sock_error(sk)) != 0) | ||
640 | break; | ||
641 | if (sk->sk_shutdown & RCV_SHUTDOWN) | ||
642 | break; | ||
643 | |||
644 | err = -EAGAIN; | ||
645 | if (!timeo) | ||
646 | break; | ||
647 | |||
648 | timeo = rfcomm_sock_data_wait(sk, timeo); | ||
649 | |||
650 | if (signal_pending(current)) { | ||
651 | err = sock_intr_errno(timeo); | ||
652 | goto out; | ||
653 | } | ||
654 | continue; | ||
655 | } | ||
656 | |||
657 | chunk = min_t(unsigned int, skb->len, size); | ||
658 | if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { | ||
659 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
660 | if (!copied) | ||
661 | copied = -EFAULT; | ||
662 | break; | ||
663 | } | ||
664 | copied += chunk; | ||
665 | size -= chunk; | ||
666 | |||
667 | if (!(flags & MSG_PEEK)) { | ||
668 | atomic_sub(chunk, &sk->sk_rmem_alloc); | ||
669 | |||
670 | skb_pull(skb, chunk); | ||
671 | if (skb->len) { | ||
672 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
673 | break; | ||
674 | } | ||
675 | kfree_skb(skb); | ||
676 | |||
677 | } else { | ||
678 | /* put message back and return */ | ||
679 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
680 | break; | ||
681 | } | ||
682 | } while (size); | ||
683 | |||
684 | out: | ||
685 | if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2)) | ||
686 | rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc); | ||
687 | |||
688 | release_sock(sk); | ||
689 | return copied ? : err; | ||
690 | } | ||
691 | |||
692 | static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | ||
693 | { | ||
694 | struct sock *sk = sock->sk; | ||
695 | int err = 0; | ||
696 | u32 opt; | ||
697 | |||
698 | BT_DBG("sk %p", sk); | ||
699 | |||
700 | lock_sock(sk); | ||
701 | |||
702 | switch (optname) { | ||
703 | case RFCOMM_LM: | ||
704 | if (get_user(opt, (u32 __user *) optval)) { | ||
705 | err = -EFAULT; | ||
706 | break; | ||
707 | } | ||
708 | |||
709 | rfcomm_pi(sk)->link_mode = opt; | ||
710 | break; | ||
711 | |||
712 | default: | ||
713 | err = -ENOPROTOOPT; | ||
714 | break; | ||
715 | } | ||
716 | |||
717 | release_sock(sk); | ||
718 | return err; | ||
719 | } | ||
720 | |||
721 | static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | ||
722 | { | ||
723 | struct sock *sk = sock->sk; | ||
724 | struct sock *l2cap_sk; | ||
725 | struct rfcomm_conninfo cinfo; | ||
726 | int len, err = 0; | ||
727 | |||
728 | BT_DBG("sk %p", sk); | ||
729 | |||
730 | if (get_user(len, optlen)) | ||
731 | return -EFAULT; | ||
732 | |||
733 | lock_sock(sk); | ||
734 | |||
735 | switch (optname) { | ||
736 | case RFCOMM_LM: | ||
737 | if (put_user(rfcomm_pi(sk)->link_mode, (u32 __user *) optval)) | ||
738 | err = -EFAULT; | ||
739 | break; | ||
740 | |||
741 | case RFCOMM_CONNINFO: | ||
742 | if (sk->sk_state != BT_CONNECTED) { | ||
743 | err = -ENOTCONN; | ||
744 | break; | ||
745 | } | ||
746 | |||
747 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; | ||
748 | |||
749 | cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle; | ||
750 | memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3); | ||
751 | |||
752 | len = min_t(unsigned int, len, sizeof(cinfo)); | ||
753 | if (copy_to_user(optval, (char *) &cinfo, len)) | ||
754 | err = -EFAULT; | ||
755 | |||
756 | break; | ||
757 | |||
758 | default: | ||
759 | err = -ENOPROTOOPT; | ||
760 | break; | ||
761 | } | ||
762 | |||
763 | release_sock(sk); | ||
764 | return err; | ||
765 | } | ||
766 | |||
767 | static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
768 | { | ||
769 | struct sock *sk = sock->sk; | ||
770 | int err; | ||
771 | |||
772 | lock_sock(sk); | ||
773 | |||
774 | #ifdef CONFIG_BT_RFCOMM_TTY | ||
775 | err = rfcomm_dev_ioctl(sk, cmd, (void __user *)arg); | ||
776 | #else | ||
777 | err = -EOPNOTSUPP; | ||
778 | #endif | ||
779 | |||
780 | release_sock(sk); | ||
781 | return err; | ||
782 | } | ||
783 | |||
784 | static int rfcomm_sock_shutdown(struct socket *sock, int how) | ||
785 | { | ||
786 | struct sock *sk = sock->sk; | ||
787 | int err = 0; | ||
788 | |||
789 | BT_DBG("sock %p, sk %p", sock, sk); | ||
790 | |||
791 | if (!sk) return 0; | ||
792 | |||
793 | lock_sock(sk); | ||
794 | if (!sk->sk_shutdown) { | ||
795 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
796 | __rfcomm_sock_close(sk); | ||
797 | |||
798 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | ||
799 | err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); | ||
800 | } | ||
801 | release_sock(sk); | ||
802 | return err; | ||
803 | } | ||
804 | |||
805 | static int rfcomm_sock_release(struct socket *sock) | ||
806 | { | ||
807 | struct sock *sk = sock->sk; | ||
808 | int err; | ||
809 | |||
810 | BT_DBG("sock %p, sk %p", sock, sk); | ||
811 | |||
812 | if (!sk) | ||
813 | return 0; | ||
814 | |||
815 | err = rfcomm_sock_shutdown(sock, 2); | ||
816 | |||
817 | sock_orphan(sk); | ||
818 | rfcomm_sock_kill(sk); | ||
819 | return err; | ||
820 | } | ||
821 | |||
822 | /* ---- RFCOMM core layer callbacks ---- | ||
823 | * | ||
824 | * called under rfcomm_lock() | ||
825 | */ | ||
826 | int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d) | ||
827 | { | ||
828 | struct sock *sk, *parent; | ||
829 | bdaddr_t src, dst; | ||
830 | int result = 0; | ||
831 | |||
832 | BT_DBG("session %p channel %d", s, channel); | ||
833 | |||
834 | rfcomm_session_getaddr(s, &src, &dst); | ||
835 | |||
836 | /* Check if we have socket listening on channel */ | ||
837 | parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src); | ||
838 | if (!parent) | ||
839 | return 0; | ||
840 | |||
841 | /* Check for backlog size */ | ||
842 | if (sk_acceptq_is_full(parent)) { | ||
843 | BT_DBG("backlog full %d", parent->sk_ack_backlog); | ||
844 | goto done; | ||
845 | } | ||
846 | |||
847 | sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC); | ||
848 | if (!sk) | ||
849 | goto done; | ||
850 | |||
851 | rfcomm_sock_init(sk, parent); | ||
852 | bacpy(&bt_sk(sk)->src, &src); | ||
853 | bacpy(&bt_sk(sk)->dst, &dst); | ||
854 | rfcomm_pi(sk)->channel = channel; | ||
855 | |||
856 | sk->sk_state = BT_CONFIG; | ||
857 | bt_accept_enqueue(parent, sk); | ||
858 | |||
859 | /* Accept connection and return socket DLC */ | ||
860 | *d = rfcomm_pi(sk)->dlc; | ||
861 | result = 1; | ||
862 | |||
863 | done: | ||
864 | bh_unlock_sock(parent); | ||
865 | return result; | ||
866 | } | ||
867 | |||
868 | /* ---- Proc fs support ---- */ | ||
869 | #ifdef CONFIG_PROC_FS | ||
870 | static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos) | ||
871 | { | ||
872 | struct sock *sk; | ||
873 | struct hlist_node *node; | ||
874 | loff_t l = *pos; | ||
875 | |||
876 | read_lock_bh(&rfcomm_sk_list.lock); | ||
877 | |||
878 | sk_for_each(sk, node, &rfcomm_sk_list.head) | ||
879 | if (!l--) | ||
880 | return sk; | ||
881 | return NULL; | ||
882 | } | ||
883 | |||
884 | static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos) | ||
885 | { | ||
886 | struct sock *sk = e; | ||
887 | (*pos)++; | ||
888 | return sk_next(sk); | ||
889 | } | ||
890 | |||
891 | static void rfcomm_seq_stop(struct seq_file *seq, void *e) | ||
892 | { | ||
893 | read_unlock_bh(&rfcomm_sk_list.lock); | ||
894 | } | ||
895 | |||
896 | static int rfcomm_seq_show(struct seq_file *seq, void *e) | ||
897 | { | ||
898 | struct sock *sk = e; | ||
899 | seq_printf(seq, "%s %s %d %d\n", | ||
900 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | ||
901 | sk->sk_state, rfcomm_pi(sk)->channel); | ||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | static struct seq_operations rfcomm_seq_ops = { | ||
906 | .start = rfcomm_seq_start, | ||
907 | .next = rfcomm_seq_next, | ||
908 | .stop = rfcomm_seq_stop, | ||
909 | .show = rfcomm_seq_show | ||
910 | }; | ||
911 | |||
912 | static int rfcomm_seq_open(struct inode *inode, struct file *file) | ||
913 | { | ||
914 | return seq_open(file, &rfcomm_seq_ops); | ||
915 | } | ||
916 | |||
917 | static struct file_operations rfcomm_seq_fops = { | ||
918 | .owner = THIS_MODULE, | ||
919 | .open = rfcomm_seq_open, | ||
920 | .read = seq_read, | ||
921 | .llseek = seq_lseek, | ||
922 | .release = seq_release, | ||
923 | }; | ||
924 | |||
925 | static int __init rfcomm_sock_proc_init(void) | ||
926 | { | ||
927 | struct proc_dir_entry *p = create_proc_entry("sock", S_IRUGO, proc_bt_rfcomm); | ||
928 | if (!p) | ||
929 | return -ENOMEM; | ||
930 | p->proc_fops = &rfcomm_seq_fops; | ||
931 | return 0; | ||
932 | } | ||
933 | |||
934 | static void __exit rfcomm_sock_proc_cleanup(void) | ||
935 | { | ||
936 | remove_proc_entry("sock", proc_bt_rfcomm); | ||
937 | } | ||
938 | |||
939 | #else /* CONFIG_PROC_FS */ | ||
940 | |||
941 | static int __init rfcomm_sock_proc_init(void) | ||
942 | { | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | static void __exit rfcomm_sock_proc_cleanup(void) | ||
947 | { | ||
948 | return; | ||
949 | } | ||
950 | #endif /* CONFIG_PROC_FS */ | ||
951 | |||
952 | static struct proto_ops rfcomm_sock_ops = { | ||
953 | .family = PF_BLUETOOTH, | ||
954 | .owner = THIS_MODULE, | ||
955 | .release = rfcomm_sock_release, | ||
956 | .bind = rfcomm_sock_bind, | ||
957 | .connect = rfcomm_sock_connect, | ||
958 | .listen = rfcomm_sock_listen, | ||
959 | .accept = rfcomm_sock_accept, | ||
960 | .getname = rfcomm_sock_getname, | ||
961 | .sendmsg = rfcomm_sock_sendmsg, | ||
962 | .recvmsg = rfcomm_sock_recvmsg, | ||
963 | .shutdown = rfcomm_sock_shutdown, | ||
964 | .setsockopt = rfcomm_sock_setsockopt, | ||
965 | .getsockopt = rfcomm_sock_getsockopt, | ||
966 | .ioctl = rfcomm_sock_ioctl, | ||
967 | .poll = bt_sock_poll, | ||
968 | .socketpair = sock_no_socketpair, | ||
969 | .mmap = sock_no_mmap | ||
970 | }; | ||
971 | |||
972 | static struct net_proto_family rfcomm_sock_family_ops = { | ||
973 | .family = PF_BLUETOOTH, | ||
974 | .owner = THIS_MODULE, | ||
975 | .create = rfcomm_sock_create | ||
976 | }; | ||
977 | |||
978 | int __init rfcomm_init_sockets(void) | ||
979 | { | ||
980 | int err; | ||
981 | |||
982 | err = proto_register(&rfcomm_proto, 0); | ||
983 | if (err < 0) | ||
984 | return err; | ||
985 | |||
986 | err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops); | ||
987 | if (err < 0) | ||
988 | goto error; | ||
989 | |||
990 | rfcomm_sock_proc_init(); | ||
991 | |||
992 | BT_INFO("RFCOMM socket layer initialized"); | ||
993 | |||
994 | return 0; | ||
995 | |||
996 | error: | ||
997 | BT_ERR("RFCOMM socket layer registration failed"); | ||
998 | proto_unregister(&rfcomm_proto); | ||
999 | return err; | ||
1000 | } | ||
1001 | |||
1002 | void __exit rfcomm_cleanup_sockets(void) | ||
1003 | { | ||
1004 | rfcomm_sock_proc_cleanup(); | ||
1005 | |||
1006 | if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) | ||
1007 | BT_ERR("RFCOMM socket layer unregistration failed"); | ||
1008 | |||
1009 | proto_unregister(&rfcomm_proto); | ||
1010 | } | ||