1 | /* |
2 | BlueZ - Bluetooth protocol stack for Linux |
3 | Copyright (C) 2000-2001 Qualcomm Incorporated |
4 | |
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License version 2 as |
9 | published by the Free Software Foundation; |
10 | |
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. |
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY |
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES |
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
19 | |
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, |
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS |
22 | SOFTWARE IS DISCLAIMED. |
23 | */ |
24 | |
25 | /* Bluetooth address family and sockets. */ |
26 | |
27 | #include <linux/module.h> |
28 | #include <linux/debugfs.h> |
29 | #include <linux/stringify.h> |
30 | #include <linux/sched/signal.h> |
31 | |
32 | #include <asm/ioctls.h> |
33 | |
34 | #include <net/bluetooth/bluetooth.h> |
35 | #include <linux/proc_fs.h> |
36 | |
37 | #include "leds.h" |
38 | #include "selftest.h" |
39 | |
40 | /* Bluetooth sockets */ |
41 | #define BT_MAX_PROTO (BTPROTO_LAST + 1) |
42 | static const struct net_proto_family *bt_proto[BT_MAX_PROTO]; |
43 | static DEFINE_RWLOCK(bt_proto_lock); |
44 | |
45 | static struct lock_class_key bt_lock_key[BT_MAX_PROTO]; |
46 | static const char *const bt_key_strings[BT_MAX_PROTO] = { |
47 | "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP" , |
48 | "sk_lock-AF_BLUETOOTH-BTPROTO_HCI" , |
49 | "sk_lock-AF_BLUETOOTH-BTPROTO_SCO" , |
50 | "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM" , |
51 | "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP" , |
52 | "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP" , |
53 | "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP" , |
54 | "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP" , |
55 | "sk_lock-AF_BLUETOOTH-BTPROTO_ISO" , |
56 | }; |
57 | |
58 | static struct lock_class_key bt_slock_key[BT_MAX_PROTO]; |
59 | static const char *const bt_slock_key_strings[BT_MAX_PROTO] = { |
60 | "slock-AF_BLUETOOTH-BTPROTO_L2CAP" , |
61 | "slock-AF_BLUETOOTH-BTPROTO_HCI" , |
62 | "slock-AF_BLUETOOTH-BTPROTO_SCO" , |
63 | "slock-AF_BLUETOOTH-BTPROTO_RFCOMM" , |
64 | "slock-AF_BLUETOOTH-BTPROTO_BNEP" , |
65 | "slock-AF_BLUETOOTH-BTPROTO_CMTP" , |
66 | "slock-AF_BLUETOOTH-BTPROTO_HIDP" , |
67 | "slock-AF_BLUETOOTH-BTPROTO_AVDTP" , |
68 | "slock-AF_BLUETOOTH-BTPROTO_ISO" , |
69 | }; |
70 | |
71 | void bt_sock_reclassify_lock(struct sock *sk, int proto) |
72 | { |
73 | BUG_ON(!sk); |
74 | BUG_ON(!sock_allow_reclassification(sk)); |
75 | |
76 | sock_lock_init_class_and_name(sk, |
77 | bt_slock_key_strings[proto], &bt_slock_key[proto], |
78 | bt_key_strings[proto], &bt_lock_key[proto]); |
79 | } |
80 | EXPORT_SYMBOL(bt_sock_reclassify_lock); |
81 | |
82 | int bt_sock_register(int proto, const struct net_proto_family *ops) |
83 | { |
84 | int err = 0; |
85 | |
86 | if (proto < 0 || proto >= BT_MAX_PROTO) |
87 | return -EINVAL; |
88 | |
89 | write_lock(&bt_proto_lock); |
90 | |
91 | if (bt_proto[proto]) |
92 | err = -EEXIST; |
93 | else |
94 | bt_proto[proto] = ops; |
95 | |
96 | write_unlock(&bt_proto_lock); |
97 | |
98 | return err; |
99 | } |
100 | EXPORT_SYMBOL(bt_sock_register); |
101 | |
102 | void bt_sock_unregister(int proto) |
103 | { |
104 | if (proto < 0 || proto >= BT_MAX_PROTO) |
105 | return; |
106 | |
107 | write_lock(&bt_proto_lock); |
108 | bt_proto[proto] = NULL; |
109 | write_unlock(&bt_proto_lock); |
110 | } |
111 | EXPORT_SYMBOL(bt_sock_unregister); |
112 | |
113 | static int bt_sock_create(struct net *net, struct socket *sock, int proto, |
114 | int kern) |
115 | { |
116 | int err; |
117 | |
118 | if (net != &init_net) |
119 | return -EAFNOSUPPORT; |
120 | |
121 | if (proto < 0 || proto >= BT_MAX_PROTO) |
122 | return -EINVAL; |
123 | |
124 | if (!bt_proto[proto]) |
125 | request_module("bt-proto-%d" , proto); |
126 | |
127 | err = -EPROTONOSUPPORT; |
128 | |
129 | read_lock(&bt_proto_lock); |
130 | |
131 | if (bt_proto[proto] && try_module_get(module: bt_proto[proto]->owner)) { |
132 | err = bt_proto[proto]->create(net, sock, proto, kern); |
133 | if (!err) |
134 | bt_sock_reclassify_lock(sock->sk, proto); |
135 | module_put(module: bt_proto[proto]->owner); |
136 | } |
137 | |
138 | read_unlock(&bt_proto_lock); |
139 | |
140 | return err; |
141 | } |
142 | |
143 | struct sock *bt_sock_alloc(struct net *net, struct socket *sock, |
144 | struct proto *prot, int proto, gfp_t prio, int kern) |
145 | { |
146 | struct sock *sk; |
147 | |
148 | sk = sk_alloc(net, PF_BLUETOOTH, priority: prio, prot, kern); |
149 | if (!sk) |
150 | return NULL; |
151 | |
152 | sock_init_data(sock, sk); |
153 | INIT_LIST_HEAD(list: &bt_sk(sk)->accept_q); |
154 | |
155 | sock_reset_flag(sk, flag: SOCK_ZAPPED); |
156 | |
157 | sk->sk_protocol = proto; |
158 | sk->sk_state = BT_OPEN; |
159 | |
160 | /* Init peer information so it can be properly monitored */ |
161 | if (!kern) { |
162 | spin_lock(lock: &sk->sk_peer_lock); |
163 | sk->sk_peer_pid = get_pid(pid: task_tgid(current)); |
164 | sk->sk_peer_cred = get_current_cred(); |
165 | spin_unlock(lock: &sk->sk_peer_lock); |
166 | } |
167 | |
168 | return sk; |
169 | } |
170 | EXPORT_SYMBOL(bt_sock_alloc); |
171 | |
172 | void bt_sock_link(struct bt_sock_list *l, struct sock *sk) |
173 | { |
174 | write_lock(&l->lock); |
175 | sk_add_node(sk, list: &l->head); |
176 | write_unlock(&l->lock); |
177 | } |
178 | EXPORT_SYMBOL(bt_sock_link); |
179 | |
180 | void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk) |
181 | { |
182 | write_lock(&l->lock); |
183 | sk_del_node_init(sk); |
184 | write_unlock(&l->lock); |
185 | } |
186 | EXPORT_SYMBOL(bt_sock_unlink); |
187 | |
188 | void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh) |
189 | { |
190 | const struct cred *old_cred; |
191 | struct pid *old_pid; |
192 | |
193 | BT_DBG("parent %p, sk %p" , parent, sk); |
194 | |
195 | sock_hold(sk); |
196 | |
197 | if (bh) |
198 | bh_lock_sock_nested(sk); |
199 | else |
200 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); |
201 | |
202 | list_add_tail(new: &bt_sk(sk)->accept_q, head: &bt_sk(parent)->accept_q); |
203 | bt_sk(sk)->parent = parent; |
204 | |
205 | /* Copy credentials from parent since for incoming connections the |
206 | * socket is allocated by the kernel. |
207 | */ |
208 | spin_lock(lock: &sk->sk_peer_lock); |
209 | old_pid = sk->sk_peer_pid; |
210 | old_cred = sk->sk_peer_cred; |
211 | sk->sk_peer_pid = get_pid(pid: parent->sk_peer_pid); |
212 | sk->sk_peer_cred = get_cred(cred: parent->sk_peer_cred); |
213 | spin_unlock(lock: &sk->sk_peer_lock); |
214 | |
215 | put_pid(pid: old_pid); |
216 | put_cred(cred: old_cred); |
217 | |
218 | if (bh) |
219 | bh_unlock_sock(sk); |
220 | else |
221 | release_sock(sk); |
222 | |
223 | sk_acceptq_added(sk: parent); |
224 | } |
225 | EXPORT_SYMBOL(bt_accept_enqueue); |
226 | |
227 | /* Calling function must hold the sk lock. |
228 | * bt_sk(sk)->parent must be non-NULL meaning sk is in the parent list. |
229 | */ |
230 | void bt_accept_unlink(struct sock *sk) |
231 | { |
232 | BT_DBG("sk %p state %d" , sk, sk->sk_state); |
233 | |
234 | list_del_init(entry: &bt_sk(sk)->accept_q); |
235 | sk_acceptq_removed(bt_sk(sk)->parent); |
236 | bt_sk(sk)->parent = NULL; |
237 | sock_put(sk); |
238 | } |
239 | EXPORT_SYMBOL(bt_accept_unlink); |
240 | |
241 | struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) |
242 | { |
243 | struct bt_sock *s, *n; |
244 | struct sock *sk; |
245 | |
246 | BT_DBG("parent %p" , parent); |
247 | |
248 | restart: |
249 | list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) { |
250 | sk = (struct sock *)s; |
251 | |
252 | /* Prevent early freeing of sk due to unlink and sock_kill */ |
253 | sock_hold(sk); |
254 | lock_sock(sk); |
255 | |
256 | /* Check sk has not already been unlinked via |
257 | * bt_accept_unlink() due to serialisation caused by sk locking |
258 | */ |
259 | if (!bt_sk(sk)->parent) { |
260 | BT_DBG("sk %p, already unlinked" , sk); |
261 | release_sock(sk); |
262 | sock_put(sk); |
263 | |
264 | /* Restart the loop as sk is no longer in the list |
265 | * and also avoid a potential infinite loop because |
266 | * list_for_each_entry_safe() is not thread safe. |
267 | */ |
268 | goto restart; |
269 | } |
270 | |
271 | /* sk is safely in the parent list so reduce reference count */ |
272 | sock_put(sk); |
273 | |
274 | /* FIXME: Is this check still needed */ |
275 | if (sk->sk_state == BT_CLOSED) { |
276 | bt_accept_unlink(sk); |
277 | release_sock(sk); |
278 | continue; |
279 | } |
280 | |
281 | if (sk->sk_state == BT_CONNECTED || !newsock || |
282 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) { |
283 | bt_accept_unlink(sk); |
284 | if (newsock) |
285 | sock_graft(sk, parent: newsock); |
286 | |
287 | release_sock(sk); |
288 | return sk; |
289 | } |
290 | |
291 | release_sock(sk); |
292 | } |
293 | |
294 | return NULL; |
295 | } |
296 | EXPORT_SYMBOL(bt_accept_dequeue); |
297 | |
298 | int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, |
299 | int flags) |
300 | { |
301 | struct sock *sk = sock->sk; |
302 | struct sk_buff *skb; |
303 | size_t copied; |
304 | size_t skblen; |
305 | int err; |
306 | |
307 | BT_DBG("sock %p sk %p len %zu" , sock, sk, len); |
308 | |
309 | if (flags & MSG_OOB) |
310 | return -EOPNOTSUPP; |
311 | |
312 | skb = skb_recv_datagram(sk, flags, err: &err); |
313 | if (!skb) { |
314 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
315 | return 0; |
316 | |
317 | return err; |
318 | } |
319 | |
320 | skblen = skb->len; |
321 | copied = skb->len; |
322 | if (len < copied) { |
323 | msg->msg_flags |= MSG_TRUNC; |
324 | copied = len; |
325 | } |
326 | |
327 | skb_reset_transport_header(skb); |
328 | err = skb_copy_datagram_msg(from: skb, offset: 0, msg, size: copied); |
329 | if (err == 0) { |
330 | sock_recv_cmsgs(msg, sk, skb); |
331 | |
332 | if (msg->msg_name && bt_sk(sk)->skb_msg_name) |
333 | bt_sk(sk)->skb_msg_name(skb, msg->msg_name, |
334 | &msg->msg_namelen); |
335 | |
336 | if (test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags)) { |
337 | u8 pkt_status = hci_skb_pkt_status(skb); |
338 | |
339 | put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS, |
340 | len: sizeof(pkt_status), data: &pkt_status); |
341 | } |
342 | } |
343 | |
344 | skb_free_datagram(sk, skb); |
345 | |
346 | if (flags & MSG_TRUNC) |
347 | copied = skblen; |
348 | |
349 | return err ? : copied; |
350 | } |
351 | EXPORT_SYMBOL(bt_sock_recvmsg); |
352 | |
353 | static long bt_sock_data_wait(struct sock *sk, long timeo) |
354 | { |
355 | DECLARE_WAITQUEUE(wait, current); |
356 | |
357 | add_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
358 | for (;;) { |
359 | set_current_state(TASK_INTERRUPTIBLE); |
360 | |
361 | if (!skb_queue_empty(list: &sk->sk_receive_queue)) |
362 | break; |
363 | |
364 | if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN)) |
365 | break; |
366 | |
367 | if (signal_pending(current) || !timeo) |
368 | break; |
369 | |
370 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
371 | release_sock(sk); |
372 | timeo = schedule_timeout(timeout: timeo); |
373 | lock_sock(sk); |
374 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
375 | } |
376 | |
377 | __set_current_state(TASK_RUNNING); |
378 | remove_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
379 | return timeo; |
380 | } |
381 | |
382 | int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg, |
383 | size_t size, int flags) |
384 | { |
385 | struct sock *sk = sock->sk; |
386 | int err = 0; |
387 | size_t target, copied = 0; |
388 | long timeo; |
389 | |
390 | if (flags & MSG_OOB) |
391 | return -EOPNOTSUPP; |
392 | |
393 | BT_DBG("sk %p size %zu" , sk, size); |
394 | |
395 | lock_sock(sk); |
396 | |
397 | target = sock_rcvlowat(sk, waitall: flags & MSG_WAITALL, len: size); |
398 | timeo = sock_rcvtimeo(sk, noblock: flags & MSG_DONTWAIT); |
399 | |
400 | do { |
401 | struct sk_buff *skb; |
402 | int chunk; |
403 | |
404 | skb = skb_dequeue(list: &sk->sk_receive_queue); |
405 | if (!skb) { |
406 | if (copied >= target) |
407 | break; |
408 | |
409 | err = sock_error(sk); |
410 | if (err) |
411 | break; |
412 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
413 | break; |
414 | |
415 | err = -EAGAIN; |
416 | if (!timeo) |
417 | break; |
418 | |
419 | timeo = bt_sock_data_wait(sk, timeo); |
420 | |
421 | if (signal_pending(current)) { |
422 | err = sock_intr_errno(timeo); |
423 | goto out; |
424 | } |
425 | continue; |
426 | } |
427 | |
428 | chunk = min_t(unsigned int, skb->len, size); |
429 | if (skb_copy_datagram_msg(from: skb, offset: 0, msg, size: chunk)) { |
430 | skb_queue_head(list: &sk->sk_receive_queue, newsk: skb); |
431 | if (!copied) |
432 | copied = -EFAULT; |
433 | break; |
434 | } |
435 | copied += chunk; |
436 | size -= chunk; |
437 | |
438 | sock_recv_cmsgs(msg, sk, skb); |
439 | |
440 | if (!(flags & MSG_PEEK)) { |
441 | int skb_len = skb_headlen(skb); |
442 | |
443 | if (chunk <= skb_len) { |
444 | __skb_pull(skb, len: chunk); |
445 | } else { |
446 | struct sk_buff *frag; |
447 | |
448 | __skb_pull(skb, len: skb_len); |
449 | chunk -= skb_len; |
450 | |
451 | skb_walk_frags(skb, frag) { |
452 | if (chunk <= frag->len) { |
453 | /* Pulling partial data */ |
454 | skb->len -= chunk; |
455 | skb->data_len -= chunk; |
456 | __skb_pull(skb: frag, len: chunk); |
457 | break; |
458 | } else if (frag->len) { |
459 | /* Pulling all frag data */ |
460 | chunk -= frag->len; |
461 | skb->len -= frag->len; |
462 | skb->data_len -= frag->len; |
463 | __skb_pull(skb: frag, len: frag->len); |
464 | } |
465 | } |
466 | } |
467 | |
468 | if (skb->len) { |
469 | skb_queue_head(list: &sk->sk_receive_queue, newsk: skb); |
470 | break; |
471 | } |
472 | kfree_skb(skb); |
473 | |
474 | } else { |
475 | /* put message back and return */ |
476 | skb_queue_head(list: &sk->sk_receive_queue, newsk: skb); |
477 | break; |
478 | } |
479 | } while (size); |
480 | |
481 | out: |
482 | release_sock(sk); |
483 | return copied ? : err; |
484 | } |
485 | EXPORT_SYMBOL(bt_sock_stream_recvmsg); |
486 | |
487 | static inline __poll_t bt_accept_poll(struct sock *parent) |
488 | { |
489 | struct bt_sock *s, *n; |
490 | struct sock *sk; |
491 | |
492 | list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) { |
493 | sk = (struct sock *)s; |
494 | if (sk->sk_state == BT_CONNECTED || |
495 | (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) && |
496 | sk->sk_state == BT_CONNECT2)) |
497 | return EPOLLIN | EPOLLRDNORM; |
498 | } |
499 | |
500 | return 0; |
501 | } |
502 | |
503 | __poll_t bt_sock_poll(struct file *file, struct socket *sock, |
504 | poll_table *wait) |
505 | { |
506 | struct sock *sk = sock->sk; |
507 | __poll_t mask = 0; |
508 | |
509 | poll_wait(filp: file, wait_address: sk_sleep(sk), p: wait); |
510 | |
511 | if (sk->sk_state == BT_LISTEN) |
512 | return bt_accept_poll(parent: sk); |
513 | |
514 | if (sk->sk_err || !skb_queue_empty_lockless(list: &sk->sk_error_queue)) |
515 | mask |= EPOLLERR | |
516 | (sock_flag(sk, flag: SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); |
517 | |
518 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
519 | mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM; |
520 | |
521 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
522 | mask |= EPOLLHUP; |
523 | |
524 | if (!skb_queue_empty_lockless(list: &sk->sk_receive_queue)) |
525 | mask |= EPOLLIN | EPOLLRDNORM; |
526 | |
527 | if (sk->sk_state == BT_CLOSED) |
528 | mask |= EPOLLHUP; |
529 | |
530 | if (sk->sk_state == BT_CONNECT || |
531 | sk->sk_state == BT_CONNECT2 || |
532 | sk->sk_state == BT_CONFIG) |
533 | return mask; |
534 | |
535 | if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk)) |
536 | mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND; |
537 | else |
538 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
539 | |
540 | return mask; |
541 | } |
542 | EXPORT_SYMBOL(bt_sock_poll); |
543 | |
544 | int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
545 | { |
546 | struct sock *sk = sock->sk; |
547 | struct sk_buff *skb; |
548 | long amount; |
549 | int err; |
550 | |
551 | BT_DBG("sk %p cmd %x arg %lx" , sk, cmd, arg); |
552 | |
553 | switch (cmd) { |
554 | case TIOCOUTQ: |
555 | if (sk->sk_state == BT_LISTEN) |
556 | return -EINVAL; |
557 | |
558 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
559 | if (amount < 0) |
560 | amount = 0; |
561 | err = put_user(amount, (int __user *)arg); |
562 | break; |
563 | |
564 | case TIOCINQ: |
565 | if (sk->sk_state == BT_LISTEN) |
566 | return -EINVAL; |
567 | |
568 | lock_sock(sk); |
569 | skb = skb_peek(list_: &sk->sk_receive_queue); |
570 | amount = skb ? skb->len : 0; |
571 | release_sock(sk); |
572 | err = put_user(amount, (int __user *)arg); |
573 | break; |
574 | |
575 | default: |
576 | err = -ENOIOCTLCMD; |
577 | break; |
578 | } |
579 | |
580 | return err; |
581 | } |
582 | EXPORT_SYMBOL(bt_sock_ioctl); |
583 | |
584 | /* This function expects the sk lock to be held when called */ |
585 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) |
586 | { |
587 | DECLARE_WAITQUEUE(wait, current); |
588 | int err = 0; |
589 | |
590 | BT_DBG("sk %p" , sk); |
591 | |
592 | add_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
593 | set_current_state(TASK_INTERRUPTIBLE); |
594 | while (sk->sk_state != state) { |
595 | if (!timeo) { |
596 | err = -EINPROGRESS; |
597 | break; |
598 | } |
599 | |
600 | if (signal_pending(current)) { |
601 | err = sock_intr_errno(timeo); |
602 | break; |
603 | } |
604 | |
605 | release_sock(sk); |
606 | timeo = schedule_timeout(timeout: timeo); |
607 | lock_sock(sk); |
608 | set_current_state(TASK_INTERRUPTIBLE); |
609 | |
610 | err = sock_error(sk); |
611 | if (err) |
612 | break; |
613 | } |
614 | __set_current_state(TASK_RUNNING); |
615 | remove_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
616 | return err; |
617 | } |
618 | EXPORT_SYMBOL(bt_sock_wait_state); |
619 | |
620 | /* This function expects the sk lock to be held when called */ |
621 | int bt_sock_wait_ready(struct sock *sk, unsigned int msg_flags) |
622 | { |
623 | DECLARE_WAITQUEUE(wait, current); |
624 | unsigned long timeo; |
625 | int err = 0; |
626 | |
627 | BT_DBG("sk %p" , sk); |
628 | |
629 | timeo = sock_sndtimeo(sk, noblock: !!(msg_flags & MSG_DONTWAIT)); |
630 | |
631 | add_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
632 | set_current_state(TASK_INTERRUPTIBLE); |
633 | while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) { |
634 | if (!timeo) { |
635 | err = -EAGAIN; |
636 | break; |
637 | } |
638 | |
639 | if (signal_pending(current)) { |
640 | err = sock_intr_errno(timeo); |
641 | break; |
642 | } |
643 | |
644 | release_sock(sk); |
645 | timeo = schedule_timeout(timeout: timeo); |
646 | lock_sock(sk); |
647 | set_current_state(TASK_INTERRUPTIBLE); |
648 | |
649 | err = sock_error(sk); |
650 | if (err) |
651 | break; |
652 | } |
653 | __set_current_state(TASK_RUNNING); |
654 | remove_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
655 | |
656 | return err; |
657 | } |
658 | EXPORT_SYMBOL(bt_sock_wait_ready); |
659 | |
660 | #ifdef CONFIG_PROC_FS |
661 | static void *bt_seq_start(struct seq_file *seq, loff_t *pos) |
662 | __acquires(seq->private->l->lock) |
663 | { |
664 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
665 | |
666 | read_lock(&l->lock); |
667 | return seq_hlist_start_head(head: &l->head, pos: *pos); |
668 | } |
669 | |
670 | static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
671 | { |
672 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
673 | |
674 | return seq_hlist_next(v, head: &l->head, ppos: pos); |
675 | } |
676 | |
677 | static void bt_seq_stop(struct seq_file *seq, void *v) |
678 | __releases(seq->private->l->lock) |
679 | { |
680 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
681 | |
682 | read_unlock(&l->lock); |
683 | } |
684 | |
685 | static int bt_seq_show(struct seq_file *seq, void *v) |
686 | { |
687 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
688 | |
689 | if (v == SEQ_START_TOKEN) { |
690 | seq_puts(m: seq, s: "sk RefCnt Rmem Wmem User Inode Parent" ); |
691 | |
692 | if (l->custom_seq_show) { |
693 | seq_putc(m: seq, c: ' '); |
694 | l->custom_seq_show(seq, v); |
695 | } |
696 | |
697 | seq_putc(m: seq, c: '\n'); |
698 | } else { |
699 | struct sock *sk = sk_entry(node: v); |
700 | struct bt_sock *bt = bt_sk(sk); |
701 | |
702 | seq_printf(m: seq, |
703 | fmt: "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu" , |
704 | sk, |
705 | refcount_read(r: &sk->sk_refcnt), |
706 | sk_rmem_alloc_get(sk), |
707 | sk_wmem_alloc_get(sk), |
708 | from_kuid(to: seq_user_ns(seq), uid: sock_i_uid(sk)), |
709 | sock_i_ino(sk), |
710 | bt->parent ? sock_i_ino(sk: bt->parent) : 0LU); |
711 | |
712 | if (l->custom_seq_show) { |
713 | seq_putc(m: seq, c: ' '); |
714 | l->custom_seq_show(seq, v); |
715 | } |
716 | |
717 | seq_putc(m: seq, c: '\n'); |
718 | } |
719 | return 0; |
720 | } |
721 | |
722 | static const struct seq_operations bt_seq_ops = { |
723 | .start = bt_seq_start, |
724 | .next = bt_seq_next, |
725 | .stop = bt_seq_stop, |
726 | .show = bt_seq_show, |
727 | }; |
728 | |
729 | int bt_procfs_init(struct net *net, const char *name, |
730 | struct bt_sock_list *sk_list, |
731 | int (*seq_show)(struct seq_file *, void *)) |
732 | { |
733 | sk_list->custom_seq_show = seq_show; |
734 | |
735 | if (!proc_create_seq_data(name, 0, net->proc_net, &bt_seq_ops, sk_list)) |
736 | return -ENOMEM; |
737 | return 0; |
738 | } |
739 | |
740 | void bt_procfs_cleanup(struct net *net, const char *name) |
741 | { |
742 | remove_proc_entry(name, net->proc_net); |
743 | } |
744 | #else |
745 | int bt_procfs_init(struct net *net, const char *name, |
746 | struct bt_sock_list *sk_list, |
747 | int (*seq_show)(struct seq_file *, void *)) |
748 | { |
749 | return 0; |
750 | } |
751 | |
752 | void bt_procfs_cleanup(struct net *net, const char *name) |
753 | { |
754 | } |
755 | #endif |
756 | EXPORT_SYMBOL(bt_procfs_init); |
757 | EXPORT_SYMBOL(bt_procfs_cleanup); |
758 | |
759 | static const struct net_proto_family bt_sock_family_ops = { |
760 | .owner = THIS_MODULE, |
761 | .family = PF_BLUETOOTH, |
762 | .create = bt_sock_create, |
763 | }; |
764 | |
765 | struct dentry *bt_debugfs; |
766 | EXPORT_SYMBOL_GPL(bt_debugfs); |
767 | |
768 | #define VERSION __stringify(BT_SUBSYS_VERSION) "." \ |
769 | __stringify(BT_SUBSYS_REVISION) |
770 | |
771 | static int __init bt_init(void) |
772 | { |
773 | int err; |
774 | |
775 | sock_skb_cb_check_size(sizeof(struct bt_skb_cb)); |
776 | |
777 | BT_INFO("Core ver %s" , VERSION); |
778 | |
779 | err = bt_selftest(); |
780 | if (err < 0) |
781 | return err; |
782 | |
783 | bt_debugfs = debugfs_create_dir(name: "bluetooth" , NULL); |
784 | |
785 | bt_leds_init(); |
786 | |
787 | err = bt_sysfs_init(); |
788 | if (err < 0) |
789 | goto cleanup_led; |
790 | |
791 | err = sock_register(fam: &bt_sock_family_ops); |
792 | if (err) |
793 | goto cleanup_sysfs; |
794 | |
795 | BT_INFO("HCI device and connection manager initialized" ); |
796 | |
797 | err = hci_sock_init(); |
798 | if (err) |
799 | goto unregister_socket; |
800 | |
801 | err = l2cap_init(); |
802 | if (err) |
803 | goto cleanup_socket; |
804 | |
805 | err = sco_init(); |
806 | if (err) |
807 | goto cleanup_cap; |
808 | |
809 | err = mgmt_init(); |
810 | if (err) |
811 | goto cleanup_sco; |
812 | |
813 | return 0; |
814 | |
815 | cleanup_sco: |
816 | sco_exit(); |
817 | cleanup_cap: |
818 | l2cap_exit(); |
819 | cleanup_socket: |
820 | hci_sock_cleanup(); |
821 | unregister_socket: |
822 | sock_unregister(PF_BLUETOOTH); |
823 | cleanup_sysfs: |
824 | bt_sysfs_cleanup(); |
825 | cleanup_led: |
826 | bt_leds_cleanup(); |
827 | return err; |
828 | } |
829 | |
830 | static void __exit bt_exit(void) |
831 | { |
832 | mgmt_exit(); |
833 | |
834 | sco_exit(); |
835 | |
836 | l2cap_exit(); |
837 | |
838 | hci_sock_cleanup(); |
839 | |
840 | sock_unregister(PF_BLUETOOTH); |
841 | |
842 | bt_sysfs_cleanup(); |
843 | |
844 | bt_leds_cleanup(); |
845 | |
846 | debugfs_remove_recursive(dentry: bt_debugfs); |
847 | } |
848 | |
849 | subsys_initcall(bt_init); |
850 | module_exit(bt_exit); |
851 | |
852 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>" ); |
853 | MODULE_DESCRIPTION("Bluetooth Core ver " VERSION); |
854 | MODULE_VERSION(VERSION); |
855 | MODULE_LICENSE("GPL" ); |
856 | MODULE_ALIAS_NETPROTO(PF_BLUETOOTH); |
857 | |