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 | err = 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 | spin_lock(lock: &sk->sk_receive_queue.lock); |
569 | skb = skb_peek(list_: &sk->sk_receive_queue); |
570 | amount = skb ? skb->len : 0; |
571 | spin_unlock(lock: &sk->sk_receive_queue.lock); |
572 | |
573 | err = put_user(amount, (int __user *)arg); |
574 | break; |
575 | |
576 | default: |
577 | err = -ENOIOCTLCMD; |
578 | break; |
579 | } |
580 | |
581 | return err; |
582 | } |
583 | EXPORT_SYMBOL(bt_sock_ioctl); |
584 | |
585 | /* This function expects the sk lock to be held when called */ |
586 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) |
587 | { |
588 | DECLARE_WAITQUEUE(wait, current); |
589 | int err = 0; |
590 | |
591 | BT_DBG("sk %p" , sk); |
592 | |
593 | add_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
594 | set_current_state(TASK_INTERRUPTIBLE); |
595 | while (sk->sk_state != state) { |
596 | if (!timeo) { |
597 | err = -EINPROGRESS; |
598 | break; |
599 | } |
600 | |
601 | if (signal_pending(current)) { |
602 | err = sock_intr_errno(timeo); |
603 | break; |
604 | } |
605 | |
606 | release_sock(sk); |
607 | timeo = schedule_timeout(timeout: timeo); |
608 | lock_sock(sk); |
609 | set_current_state(TASK_INTERRUPTIBLE); |
610 | |
611 | err = sock_error(sk); |
612 | if (err) |
613 | break; |
614 | } |
615 | __set_current_state(TASK_RUNNING); |
616 | remove_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
617 | return err; |
618 | } |
619 | EXPORT_SYMBOL(bt_sock_wait_state); |
620 | |
621 | /* This function expects the sk lock to be held when called */ |
622 | int bt_sock_wait_ready(struct sock *sk, unsigned int msg_flags) |
623 | { |
624 | DECLARE_WAITQUEUE(wait, current); |
625 | unsigned long timeo; |
626 | int err = 0; |
627 | |
628 | BT_DBG("sk %p" , sk); |
629 | |
630 | timeo = sock_sndtimeo(sk, noblock: !!(msg_flags & MSG_DONTWAIT)); |
631 | |
632 | add_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
633 | set_current_state(TASK_INTERRUPTIBLE); |
634 | while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) { |
635 | if (!timeo) { |
636 | err = -EAGAIN; |
637 | break; |
638 | } |
639 | |
640 | if (signal_pending(current)) { |
641 | err = sock_intr_errno(timeo); |
642 | break; |
643 | } |
644 | |
645 | release_sock(sk); |
646 | timeo = schedule_timeout(timeout: timeo); |
647 | lock_sock(sk); |
648 | set_current_state(TASK_INTERRUPTIBLE); |
649 | |
650 | err = sock_error(sk); |
651 | if (err) |
652 | break; |
653 | } |
654 | __set_current_state(TASK_RUNNING); |
655 | remove_wait_queue(wq_head: sk_sleep(sk), wq_entry: &wait); |
656 | |
657 | return err; |
658 | } |
659 | EXPORT_SYMBOL(bt_sock_wait_ready); |
660 | |
661 | #ifdef CONFIG_PROC_FS |
662 | static void *bt_seq_start(struct seq_file *seq, loff_t *pos) |
663 | __acquires(seq->private->l->lock) |
664 | { |
665 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
666 | |
667 | read_lock(&l->lock); |
668 | return seq_hlist_start_head(head: &l->head, pos: *pos); |
669 | } |
670 | |
671 | static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
672 | { |
673 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
674 | |
675 | return seq_hlist_next(v, head: &l->head, ppos: pos); |
676 | } |
677 | |
678 | static void bt_seq_stop(struct seq_file *seq, void *v) |
679 | __releases(seq->private->l->lock) |
680 | { |
681 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
682 | |
683 | read_unlock(&l->lock); |
684 | } |
685 | |
686 | static int bt_seq_show(struct seq_file *seq, void *v) |
687 | { |
688 | struct bt_sock_list *l = pde_data(inode: file_inode(f: seq->file)); |
689 | |
690 | if (v == SEQ_START_TOKEN) { |
691 | seq_puts(m: seq, s: "sk RefCnt Rmem Wmem User Inode Parent" ); |
692 | |
693 | if (l->custom_seq_show) { |
694 | seq_putc(m: seq, c: ' '); |
695 | l->custom_seq_show(seq, v); |
696 | } |
697 | |
698 | seq_putc(m: seq, c: '\n'); |
699 | } else { |
700 | struct sock *sk = sk_entry(node: v); |
701 | struct bt_sock *bt = bt_sk(sk); |
702 | |
703 | seq_printf(m: seq, |
704 | fmt: "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu" , |
705 | sk, |
706 | refcount_read(r: &sk->sk_refcnt), |
707 | sk_rmem_alloc_get(sk), |
708 | sk_wmem_alloc_get(sk), |
709 | from_kuid(to: seq_user_ns(seq), uid: sock_i_uid(sk)), |
710 | sock_i_ino(sk), |
711 | bt->parent ? sock_i_ino(sk: bt->parent) : 0LU); |
712 | |
713 | if (l->custom_seq_show) { |
714 | seq_putc(m: seq, c: ' '); |
715 | l->custom_seq_show(seq, v); |
716 | } |
717 | |
718 | seq_putc(m: seq, c: '\n'); |
719 | } |
720 | return 0; |
721 | } |
722 | |
723 | static const struct seq_operations bt_seq_ops = { |
724 | .start = bt_seq_start, |
725 | .next = bt_seq_next, |
726 | .stop = bt_seq_stop, |
727 | .show = bt_seq_show, |
728 | }; |
729 | |
730 | int bt_procfs_init(struct net *net, const char *name, |
731 | struct bt_sock_list *sk_list, |
732 | int (*seq_show)(struct seq_file *, void *)) |
733 | { |
734 | sk_list->custom_seq_show = seq_show; |
735 | |
736 | if (!proc_create_seq_data(name, 0, net->proc_net, &bt_seq_ops, sk_list)) |
737 | return -ENOMEM; |
738 | return 0; |
739 | } |
740 | |
741 | void bt_procfs_cleanup(struct net *net, const char *name) |
742 | { |
743 | remove_proc_entry(name, net->proc_net); |
744 | } |
745 | #else |
746 | int bt_procfs_init(struct net *net, const char *name, |
747 | struct bt_sock_list *sk_list, |
748 | int (*seq_show)(struct seq_file *, void *)) |
749 | { |
750 | return 0; |
751 | } |
752 | |
753 | void bt_procfs_cleanup(struct net *net, const char *name) |
754 | { |
755 | } |
756 | #endif |
757 | EXPORT_SYMBOL(bt_procfs_init); |
758 | EXPORT_SYMBOL(bt_procfs_cleanup); |
759 | |
760 | static const struct net_proto_family bt_sock_family_ops = { |
761 | .owner = THIS_MODULE, |
762 | .family = PF_BLUETOOTH, |
763 | .create = bt_sock_create, |
764 | }; |
765 | |
766 | struct dentry *bt_debugfs; |
767 | EXPORT_SYMBOL_GPL(bt_debugfs); |
768 | |
769 | #define VERSION __stringify(BT_SUBSYS_VERSION) "." \ |
770 | __stringify(BT_SUBSYS_REVISION) |
771 | |
772 | static int __init bt_init(void) |
773 | { |
774 | int err; |
775 | |
776 | sock_skb_cb_check_size(sizeof(struct bt_skb_cb)); |
777 | |
778 | BT_INFO("Core ver %s" , VERSION); |
779 | |
780 | err = bt_selftest(); |
781 | if (err < 0) |
782 | return err; |
783 | |
784 | bt_debugfs = debugfs_create_dir(name: "bluetooth" , NULL); |
785 | |
786 | bt_leds_init(); |
787 | |
788 | err = bt_sysfs_init(); |
789 | if (err < 0) |
790 | goto cleanup_led; |
791 | |
792 | err = sock_register(fam: &bt_sock_family_ops); |
793 | if (err) |
794 | goto cleanup_sysfs; |
795 | |
796 | BT_INFO("HCI device and connection manager initialized" ); |
797 | |
798 | err = hci_sock_init(); |
799 | if (err) |
800 | goto unregister_socket; |
801 | |
802 | err = l2cap_init(); |
803 | if (err) |
804 | goto cleanup_socket; |
805 | |
806 | err = sco_init(); |
807 | if (err) |
808 | goto cleanup_cap; |
809 | |
810 | err = mgmt_init(); |
811 | if (err) |
812 | goto cleanup_sco; |
813 | |
814 | return 0; |
815 | |
816 | cleanup_sco: |
817 | sco_exit(); |
818 | cleanup_cap: |
819 | l2cap_exit(); |
820 | cleanup_socket: |
821 | hci_sock_cleanup(); |
822 | unregister_socket: |
823 | sock_unregister(PF_BLUETOOTH); |
824 | cleanup_sysfs: |
825 | bt_sysfs_cleanup(); |
826 | cleanup_led: |
827 | bt_leds_cleanup(); |
828 | return err; |
829 | } |
830 | |
831 | static void __exit bt_exit(void) |
832 | { |
833 | mgmt_exit(); |
834 | |
835 | sco_exit(); |
836 | |
837 | l2cap_exit(); |
838 | |
839 | hci_sock_cleanup(); |
840 | |
841 | sock_unregister(PF_BLUETOOTH); |
842 | |
843 | bt_sysfs_cleanup(); |
844 | |
845 | bt_leds_cleanup(); |
846 | |
847 | debugfs_remove_recursive(dentry: bt_debugfs); |
848 | } |
849 | |
850 | subsys_initcall(bt_init); |
851 | module_exit(bt_exit); |
852 | |
853 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>" ); |
854 | MODULE_DESCRIPTION("Bluetooth Core ver " VERSION); |
855 | MODULE_VERSION(VERSION); |
856 | MODULE_LICENSE("GPL" ); |
857 | MODULE_ALIAS_NETPROTO(PF_BLUETOOTH); |
858 | |