diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-07 17:21:06 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-12-07 20:03:38 -0500 |
commit | 0381101fd6a73c7d6b545044dc1472d019fc64e3 (patch) | |
tree | 8b7ec25d3e97e3bd7918135fa3fe3b29941e0db4 /net/bluetooth/hci_sock.c | |
parent | c02178d22b3ef2d18c38c96151600ee1c7ed94f0 (diff) |
Bluetooth: Add initial Bluetooth Management interface callbacks
Add initial code for handling Bluetooth Management interface messages.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Acked-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r-- | net/bluetooth/hci_sock.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index b3753bad2a55..207be7abda9f 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #include <net/bluetooth/bluetooth.h> | 49 | #include <net/bluetooth/bluetooth.h> |
50 | #include <net/bluetooth/hci_core.h> | 50 | #include <net/bluetooth/hci_core.h> |
51 | 51 | ||
52 | static int enable_mgmt; | ||
53 | |||
52 | /* ----- HCI socket interface ----- */ | 54 | /* ----- HCI socket interface ----- */ |
53 | 55 | ||
54 | static inline int hci_test_bit(int nr, void *addr) | 56 | static inline int hci_test_bit(int nr, void *addr) |
@@ -353,25 +355,35 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a | |||
353 | 355 | ||
354 | static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | 356 | static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) |
355 | { | 357 | { |
356 | struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; | 358 | struct sockaddr_hci haddr; |
357 | struct sock *sk = sock->sk; | 359 | struct sock *sk = sock->sk; |
358 | struct hci_dev *hdev = NULL; | 360 | struct hci_dev *hdev = NULL; |
359 | int err = 0; | 361 | int len, err = 0; |
360 | 362 | ||
361 | BT_DBG("sock %p sk %p", sock, sk); | 363 | BT_DBG("sock %p sk %p", sock, sk); |
362 | 364 | ||
363 | if (!haddr || haddr->hci_family != AF_BLUETOOTH) | 365 | if (!addr) |
366 | return -EINVAL; | ||
367 | |||
368 | memset(&haddr, 0, sizeof(haddr)); | ||
369 | len = min_t(unsigned int, sizeof(haddr), addr_len); | ||
370 | memcpy(&haddr, addr, len); | ||
371 | |||
372 | if (haddr.hci_family != AF_BLUETOOTH) | ||
373 | return -EINVAL; | ||
374 | |||
375 | if (haddr.hci_channel != HCI_CHANNEL_RAW && !enable_mgmt) | ||
364 | return -EINVAL; | 376 | return -EINVAL; |
365 | 377 | ||
366 | lock_sock(sk); | 378 | lock_sock(sk); |
367 | 379 | ||
368 | if (hci_pi(sk)->hdev) { | 380 | if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) { |
369 | err = -EALREADY; | 381 | err = -EALREADY; |
370 | goto done; | 382 | goto done; |
371 | } | 383 | } |
372 | 384 | ||
373 | if (haddr->hci_dev != HCI_DEV_NONE) { | 385 | if (haddr.hci_dev != HCI_DEV_NONE) { |
374 | hdev = hci_dev_get(haddr->hci_dev); | 386 | hdev = hci_dev_get(haddr.hci_dev); |
375 | if (!hdev) { | 387 | if (!hdev) { |
376 | err = -ENODEV; | 388 | err = -ENODEV; |
377 | goto done; | 389 | goto done; |
@@ -380,6 +392,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le | |||
380 | atomic_inc(&hdev->promisc); | 392 | atomic_inc(&hdev->promisc); |
381 | } | 393 | } |
382 | 394 | ||
395 | hci_pi(sk)->channel = haddr.hci_channel; | ||
383 | hci_pi(sk)->hdev = hdev; | 396 | hci_pi(sk)->hdev = hdev; |
384 | sk->sk_state = BT_BOUND; | 397 | sk->sk_state = BT_BOUND; |
385 | 398 | ||
@@ -502,6 +515,17 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
502 | 515 | ||
503 | lock_sock(sk); | 516 | lock_sock(sk); |
504 | 517 | ||
518 | switch (hci_pi(sk)->channel) { | ||
519 | case HCI_CHANNEL_RAW: | ||
520 | break; | ||
521 | case HCI_CHANNEL_CONTROL: | ||
522 | err = mgmt_control(sk, msg, len); | ||
523 | goto done; | ||
524 | default: | ||
525 | err = -EINVAL; | ||
526 | goto done; | ||
527 | } | ||
528 | |||
505 | hdev = hci_pi(sk)->hdev; | 529 | hdev = hci_pi(sk)->hdev; |
506 | if (!hdev) { | 530 | if (!hdev) { |
507 | err = -EBADFD; | 531 | err = -EBADFD; |
@@ -831,3 +855,6 @@ void __exit hci_sock_cleanup(void) | |||
831 | 855 | ||
832 | proto_unregister(&hci_sk_proto); | 856 | proto_unregister(&hci_sk_proto); |
833 | } | 857 | } |
858 | |||
859 | module_param(enable_mgmt, bool, 0644); | ||
860 | MODULE_PARM_DESC(enable_mgmt, "Enable Management interface"); | ||