aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-02-13 09:59:33 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-15 07:28:07 -0500
commite70bb2e89959983aebcfce28f645a1104ffa9ab2 (patch)
tree721c67618b45cce0d6adc610f59589d5ef9bc816 /net/bluetooth/mgmt.c
parent9ab875affbe61b2c88685c342461c9a367ab7a3e (diff)
Bluetooth: Implement Read Supported Commands commands for mgmt
This patch implements the Read Supported Commands mgmt command which was recently added to the API specification. It returns a list of supported commands and events to user space. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a2c2e12516c6..8efbd8eaa1b3 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -35,6 +35,69 @@
35#define MGMT_VERSION 0 35#define MGMT_VERSION 0
36#define MGMT_REVISION 1 36#define MGMT_REVISION 1
37 37
38static const u16 mgmt_commands[] = {
39 MGMT_OP_READ_INDEX_LIST,
40 MGMT_OP_READ_INFO,
41 MGMT_OP_SET_POWERED,
42 MGMT_OP_SET_DISCOVERABLE,
43 MGMT_OP_SET_CONNECTABLE,
44 MGMT_OP_SET_FAST_CONNECTABLE,
45 MGMT_OP_SET_PAIRABLE,
46 MGMT_OP_SET_LINK_SECURITY,
47 MGMT_OP_SET_SSP,
48 MGMT_OP_SET_HS,
49 MGMT_OP_SET_LE,
50 MGMT_OP_SET_DEV_CLASS,
51 MGMT_OP_SET_LOCAL_NAME,
52 MGMT_OP_ADD_UUID,
53 MGMT_OP_REMOVE_UUID,
54 MGMT_OP_LOAD_LINK_KEYS,
55 MGMT_OP_LOAD_LONG_TERM_KEYS,
56 MGMT_OP_DISCONNECT,
57 MGMT_OP_GET_CONNECTIONS,
58 MGMT_OP_PIN_CODE_REPLY,
59 MGMT_OP_PIN_CODE_NEG_REPLY,
60 MGMT_OP_SET_IO_CAPABILITY,
61 MGMT_OP_PAIR_DEVICE,
62 MGMT_OP_CANCEL_PAIR_DEVICE,
63 MGMT_OP_UNPAIR_DEVICE,
64 MGMT_OP_USER_CONFIRM_REPLY,
65 MGMT_OP_USER_CONFIRM_NEG_REPLY,
66 MGMT_OP_USER_PASSKEY_REPLY,
67 MGMT_OP_USER_PASSKEY_NEG_REPLY,
68 MGMT_OP_READ_LOCAL_OOB_DATA,
69 MGMT_OP_ADD_REMOTE_OOB_DATA,
70 MGMT_OP_REMOVE_REMOTE_OOB_DATA,
71 MGMT_OP_START_DISCOVERY,
72 MGMT_OP_STOP_DISCOVERY,
73 MGMT_OP_CONFIRM_NAME,
74 MGMT_OP_BLOCK_DEVICE,
75 MGMT_OP_UNBLOCK_DEVICE,
76};
77
78static const u16 mgmt_events[] = {
79 MGMT_EV_CONTROLLER_ERROR,
80 MGMT_EV_INDEX_ADDED,
81 MGMT_EV_INDEX_REMOVED,
82 MGMT_EV_NEW_SETTINGS,
83 MGMT_EV_CLASS_OF_DEV_CHANGED,
84 MGMT_EV_LOCAL_NAME_CHANGED,
85 MGMT_EV_NEW_LINK_KEY,
86 MGMT_EV_NEW_LONG_TERM_KEY,
87 MGMT_EV_DEVICE_CONNECTED,
88 MGMT_EV_DEVICE_DISCONNECTED,
89 MGMT_EV_CONNECT_FAILED,
90 MGMT_EV_PIN_CODE_REQUEST,
91 MGMT_EV_USER_CONFIRM_REQUEST,
92 MGMT_EV_USER_PASSKEY_REQUEST,
93 MGMT_EV_AUTH_FAILED,
94 MGMT_EV_DEVICE_FOUND,
95 MGMT_EV_DISCOVERING,
96 MGMT_EV_DEVICE_BLOCKED,
97 MGMT_EV_DEVICE_UNBLOCKED,
98 MGMT_EV_DEVICE_UNPAIRED,
99};
100
38/* 101/*
39 * These LE scan and inquiry parameters were chosen according to LE General 102 * These LE scan and inquiry parameters were chosen according to LE General
40 * Discovery Procedure specification. 103 * Discovery Procedure specification.
@@ -206,6 +269,39 @@ static int read_version(struct sock *sk)
206 sizeof(rp)); 269 sizeof(rp));
207} 270}
208 271
272static int read_commands(struct sock *sk)
273{
274 struct mgmt_rp_read_commands *rp;
275 u16 num_commands = ARRAY_SIZE(mgmt_commands);
276 u16 num_events = ARRAY_SIZE(mgmt_events);
277 u16 *opcode;
278 size_t rp_size;
279 int i, err;
280
281 BT_DBG("sock %p", sk);
282
283 rp_size = sizeof(*rp) + ((num_commands + num_events) * sizeof(u16));
284
285 rp = kmalloc(rp_size, GFP_KERNEL);
286 if (!rp)
287 return -ENOMEM;
288
289 put_unaligned_le16(num_commands, &rp->num_commands);
290 put_unaligned_le16(num_events, &rp->num_events);
291
292 for (i = 0, opcode = rp->opcodes; i < num_commands; i++, opcode++)
293 put_unaligned_le16(mgmt_commands[i], opcode);
294
295 for (i = 0; i < num_events; i++, opcode++)
296 put_unaligned_le16(mgmt_events[i], opcode);
297
298 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, rp,
299 rp_size);
300 kfree(rp);
301
302 return err;
303}
304
209static int read_index_list(struct sock *sk) 305static int read_index_list(struct sock *sk)
210{ 306{
211 struct mgmt_rp_read_index_list *rp; 307 struct mgmt_rp_read_index_list *rp;
@@ -2323,6 +2419,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
2323 case MGMT_OP_READ_VERSION: 2419 case MGMT_OP_READ_VERSION:
2324 err = read_version(sk); 2420 err = read_version(sk);
2325 break; 2421 break;
2422 case MGMT_OP_READ_COMMANDS:
2423 err = read_commands(sk);
2424 break;
2326 case MGMT_OP_READ_INDEX_LIST: 2425 case MGMT_OP_READ_INDEX_LIST:
2327 err = read_index_list(sk); 2426 err = read_index_list(sk);
2328 break; 2427 break;