aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-03-17 07:48:50 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-03-17 13:03:08 -0400
commitfa4335d71a1408d0112c15874538f3f4e153ba01 (patch)
treef67bac624e402bc5f0ce84936d3cf9c573849355
parent88b94ce925cb103851f39bfa7e23e09823573d30 (diff)
Bluetooth: Move generic mgmt command dispatcher to hci_sock.c
The mgmt.c file should be reserved purely for HCI_CHANNEL_CONTROL. The mgmt_control() function in it is already completely generic and has a single user in hci_sock.c. This patch moves the function there and renames it a bit more appropriately to hci_mgmt_cmd() (as it's a command dispatcher). Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/hci_core.h3
-rw-r--r--net/bluetooth/hci_sock.c116
-rw-r--r--net/bluetooth/mgmt.c111
3 files changed, 115 insertions, 115 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 93e7b2b05a17..b65c53de6a69 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1330,9 +1330,6 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);
1330#define DISCOV_BREDR_INQUIRY_LEN 0x08 1330#define DISCOV_BREDR_INQUIRY_LEN 0x08
1331#define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */ 1331#define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */
1332 1332
1333int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk,
1334 struct msghdr *msg, size_t msglen);
1335
1336int mgmt_new_settings(struct hci_dev *hdev); 1333int mgmt_new_settings(struct hci_dev *hdev);
1337void mgmt_index_added(struct hci_dev *hdev); 1334void mgmt_index_added(struct hci_dev *hdev);
1338void mgmt_index_removed(struct hci_dev *hdev); 1335void mgmt_index_removed(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 9ba1a2667eaa..85a44a7dc150 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -30,6 +30,9 @@
30#include <net/bluetooth/bluetooth.h> 30#include <net/bluetooth/bluetooth.h>
31#include <net/bluetooth/hci_core.h> 31#include <net/bluetooth/hci_core.h>
32#include <net/bluetooth/hci_mon.h> 32#include <net/bluetooth/hci_mon.h>
33#include <net/bluetooth/mgmt.h>
34
35#include "mgmt_util.h"
33 36
34static LIST_HEAD(mgmt_chan_list); 37static LIST_HEAD(mgmt_chan_list);
35static DEFINE_MUTEX(mgmt_chan_list_lock); 38static DEFINE_MUTEX(mgmt_chan_list_lock);
@@ -951,6 +954,117 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
951 return err ? : copied; 954 return err ? : copied;
952} 955}
953 956
957static int hci_mgmt_cmd(struct hci_mgmt_chan *chan, struct sock *sk,
958 struct msghdr *msg, size_t msglen)
959{
960 void *buf;
961 u8 *cp;
962 struct mgmt_hdr *hdr;
963 u16 opcode, index, len;
964 struct hci_dev *hdev = NULL;
965 const struct hci_mgmt_handler *handler;
966 bool var_len, no_hdev;
967 int err;
968
969 BT_DBG("got %zu bytes", msglen);
970
971 if (msglen < sizeof(*hdr))
972 return -EINVAL;
973
974 buf = kmalloc(msglen, GFP_KERNEL);
975 if (!buf)
976 return -ENOMEM;
977
978 if (memcpy_from_msg(buf, msg, msglen)) {
979 err = -EFAULT;
980 goto done;
981 }
982
983 hdr = buf;
984 opcode = __le16_to_cpu(hdr->opcode);
985 index = __le16_to_cpu(hdr->index);
986 len = __le16_to_cpu(hdr->len);
987
988 if (len != msglen - sizeof(*hdr)) {
989 err = -EINVAL;
990 goto done;
991 }
992
993 if (opcode >= chan->handler_count ||
994 chan->handlers[opcode].func == NULL) {
995 BT_DBG("Unknown op %u", opcode);
996 err = mgmt_cmd_status(sk, index, opcode,
997 MGMT_STATUS_UNKNOWN_COMMAND);
998 goto done;
999 }
1000
1001 handler = &chan->handlers[opcode];
1002
1003 if (!hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) &&
1004 !(handler->flags & HCI_MGMT_UNTRUSTED)) {
1005 err = mgmt_cmd_status(sk, index, opcode,
1006 MGMT_STATUS_PERMISSION_DENIED);
1007 goto done;
1008 }
1009
1010 if (index != MGMT_INDEX_NONE) {
1011 hdev = hci_dev_get(index);
1012 if (!hdev) {
1013 err = mgmt_cmd_status(sk, index, opcode,
1014 MGMT_STATUS_INVALID_INDEX);
1015 goto done;
1016 }
1017
1018 if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1019 hci_dev_test_flag(hdev, HCI_CONFIG) ||
1020 hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1021 err = mgmt_cmd_status(sk, index, opcode,
1022 MGMT_STATUS_INVALID_INDEX);
1023 goto done;
1024 }
1025
1026 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1027 !(handler->flags & HCI_MGMT_UNCONFIGURED)) {
1028 err = mgmt_cmd_status(sk, index, opcode,
1029 MGMT_STATUS_INVALID_INDEX);
1030 goto done;
1031 }
1032 }
1033
1034 no_hdev = (handler->flags & HCI_MGMT_NO_HDEV);
1035 if (no_hdev != !hdev) {
1036 err = mgmt_cmd_status(sk, index, opcode,
1037 MGMT_STATUS_INVALID_INDEX);
1038 goto done;
1039 }
1040
1041 var_len = (handler->flags & HCI_MGMT_VAR_LEN);
1042 if ((var_len && len < handler->data_len) ||
1043 (!var_len && len != handler->data_len)) {
1044 err = mgmt_cmd_status(sk, index, opcode,
1045 MGMT_STATUS_INVALID_PARAMS);
1046 goto done;
1047 }
1048
1049 if (hdev && chan->hdev_init)
1050 chan->hdev_init(sk, hdev);
1051
1052 cp = buf + sizeof(*hdr);
1053
1054 err = handler->func(sk, hdev, cp, len);
1055 if (err < 0)
1056 goto done;
1057
1058 err = msglen;
1059
1060done:
1061 if (hdev)
1062 hci_dev_put(hdev);
1063
1064 kfree(buf);
1065 return err;
1066}
1067
954static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, 1068static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
955 size_t len) 1069 size_t len)
956{ 1070{
@@ -984,7 +1098,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
984 mutex_lock(&mgmt_chan_list_lock); 1098 mutex_lock(&mgmt_chan_list_lock);
985 chan = __hci_mgmt_chan_find(hci_pi(sk)->channel); 1099 chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
986 if (chan) 1100 if (chan)
987 err = mgmt_control(chan, sk, msg, len); 1101 err = hci_mgmt_cmd(chan, sk, msg, len);
988 else 1102 else
989 err = -EINVAL; 1103 err = -EINVAL;
990 1104
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ac897e676d5e..f3a957905193 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -6401,117 +6401,6 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
6401 { read_adv_features, MGMT_READ_ADV_FEATURES_SIZE }, 6401 { read_adv_features, MGMT_READ_ADV_FEATURES_SIZE },
6402}; 6402};
6403 6403
6404int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk,
6405 struct msghdr *msg, size_t msglen)
6406{
6407 void *buf;
6408 u8 *cp;
6409 struct mgmt_hdr *hdr;
6410 u16 opcode, index, len;
6411 struct hci_dev *hdev = NULL;
6412 const struct hci_mgmt_handler *handler;
6413 bool var_len, no_hdev;
6414 int err;
6415
6416 BT_DBG("got %zu bytes", msglen);
6417
6418 if (msglen < sizeof(*hdr))
6419 return -EINVAL;
6420
6421 buf = kmalloc(msglen, GFP_KERNEL);
6422 if (!buf)
6423 return -ENOMEM;
6424
6425 if (memcpy_from_msg(buf, msg, msglen)) {
6426 err = -EFAULT;
6427 goto done;
6428 }
6429
6430 hdr = buf;
6431 opcode = __le16_to_cpu(hdr->opcode);
6432 index = __le16_to_cpu(hdr->index);
6433 len = __le16_to_cpu(hdr->len);
6434
6435 if (len != msglen - sizeof(*hdr)) {
6436 err = -EINVAL;
6437 goto done;
6438 }
6439
6440 if (opcode >= chan->handler_count ||
6441 chan->handlers[opcode].func == NULL) {
6442 BT_DBG("Unknown op %u", opcode);
6443 err = mgmt_cmd_status(sk, index, opcode,
6444 MGMT_STATUS_UNKNOWN_COMMAND);
6445 goto done;
6446 }
6447
6448 handler = &chan->handlers[opcode];
6449
6450 if (!hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) &&
6451 !(handler->flags & HCI_MGMT_UNTRUSTED)) {
6452 err = mgmt_cmd_status(sk, index, opcode,
6453 MGMT_STATUS_PERMISSION_DENIED);
6454 goto done;
6455 }
6456
6457 if (index != MGMT_INDEX_NONE) {
6458 hdev = hci_dev_get(index);
6459 if (!hdev) {
6460 err = mgmt_cmd_status(sk, index, opcode,
6461 MGMT_STATUS_INVALID_INDEX);
6462 goto done;
6463 }
6464
6465 if (hci_dev_test_flag(hdev, HCI_SETUP) ||
6466 hci_dev_test_flag(hdev, HCI_CONFIG) ||
6467 hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6468 err = mgmt_cmd_status(sk, index, opcode,
6469 MGMT_STATUS_INVALID_INDEX);
6470 goto done;
6471 }
6472
6473 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
6474 !(handler->flags & HCI_MGMT_UNCONFIGURED)) {
6475 err = mgmt_cmd_status(sk, index, opcode,
6476 MGMT_STATUS_INVALID_INDEX);
6477 goto done;
6478 }
6479 }
6480
6481 no_hdev = (handler->flags & HCI_MGMT_NO_HDEV);
6482 if (no_hdev != !hdev) {
6483 err = mgmt_cmd_status(sk, index, opcode,
6484 MGMT_STATUS_INVALID_INDEX);
6485 goto done;
6486 }
6487
6488 var_len = (handler->flags & HCI_MGMT_VAR_LEN);
6489 if ((var_len && len < handler->data_len) ||
6490 (!var_len && len != handler->data_len)) {
6491 err = mgmt_cmd_status(sk, index, opcode,
6492 MGMT_STATUS_INVALID_PARAMS);
6493 goto done;
6494 }
6495
6496 if (hdev && chan->hdev_init)
6497 chan->hdev_init(sk, hdev);
6498
6499 cp = buf + sizeof(*hdr);
6500
6501 err = handler->func(sk, hdev, cp, len);
6502 if (err < 0)
6503 goto done;
6504
6505 err = msglen;
6506
6507done:
6508 if (hdev)
6509 hci_dev_put(hdev);
6510
6511 kfree(buf);
6512 return err;
6513}
6514
6515void mgmt_index_added(struct hci_dev *hdev) 6404void mgmt_index_added(struct hci_dev *hdev)
6516{ 6405{
6517 struct mgmt_ev_ext_index ev; 6406 struct mgmt_ev_ext_index ev;