aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_sock.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2010-12-07 17:21:06 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2010-12-07 20:03:38 -0500
commit0381101fd6a73c7d6b545044dc1472d019fc64e3 (patch)
tree8b7ec25d3e97e3bd7918135fa3fe3b29941e0db4 /net/bluetooth/hci_sock.c
parentc02178d22b3ef2d18c38c96151600ee1c7ed94f0 (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.c39
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
52static int enable_mgmt;
53
52/* ----- HCI socket interface ----- */ 54/* ----- HCI socket interface ----- */
53 55
54static inline int hci_test_bit(int nr, void *addr) 56static 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
354static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) 356static 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
859module_param(enable_mgmt, bool, 0644);
860MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");