diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-11-07 16:13:38 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-11-08 10:03:25 -0500 |
commit | 86742e1eca319069490f6f20c2892baafc2a6922 (patch) | |
tree | 4274953eb153f00aaa600d46ca587dc2395a8ff8 | |
parent | bd2d1334e1dd64765b29f9e1b592777c410ed121 (diff) |
Bluetooth: Update link key mgmt APIs to match latest spec.
BR/EDR link keys have their own commands and events (separate from SMP)
and the remove_keys command (previously remove_key) removes keys of any
kind for the specified remote address.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | include/net/bluetooth/hci_core.h | 2 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt.h | 18 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 4 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 43 |
4 files changed, 35 insertions, 32 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index bca53aa754e3..4ebc882385f9 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -911,7 +911,7 @@ int mgmt_powered(u16 index, u8 powered); | |||
911 | int mgmt_discoverable(u16 index, u8 discoverable); | 911 | int mgmt_discoverable(u16 index, u8 discoverable); |
912 | int mgmt_connectable(u16 index, u8 connectable); | 912 | int mgmt_connectable(u16 index, u8 connectable); |
913 | int mgmt_write_scan_failed(u16 index, u8 scan, u8 status); | 913 | int mgmt_write_scan_failed(u16 index, u8 scan, u8 status); |
914 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent); | 914 | int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent); |
915 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type); | 915 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type); |
916 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); | 916 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); |
917 | int mgmt_disconnect_failed(u16 index); | 917 | int mgmt_disconnect_failed(u16 index); |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index b5320aa9b085..fa33bc6c485f 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -100,22 +100,22 @@ struct mgmt_cp_set_service_cache { | |||
100 | __u8 enable; | 100 | __u8 enable; |
101 | } __packed; | 101 | } __packed; |
102 | 102 | ||
103 | struct mgmt_key_info { | 103 | struct mgmt_link_key_info { |
104 | bdaddr_t bdaddr; | 104 | bdaddr_t bdaddr; |
105 | u8 type; | 105 | u8 type; |
106 | u8 val[16]; | 106 | u8 val[16]; |
107 | u8 pin_len; | 107 | u8 pin_len; |
108 | } __packed; | 108 | } __packed; |
109 | 109 | ||
110 | #define MGMT_OP_LOAD_KEYS 0x000D | 110 | #define MGMT_OP_LOAD_LINK_KEYS 0x000D |
111 | struct mgmt_cp_load_keys { | 111 | struct mgmt_cp_load_link_keys { |
112 | __u8 debug_keys; | 112 | __u8 debug_keys; |
113 | __le16 key_count; | 113 | __le16 key_count; |
114 | struct mgmt_key_info keys[0]; | 114 | struct mgmt_link_key_info keys[0]; |
115 | } __packed; | 115 | } __packed; |
116 | 116 | ||
117 | #define MGMT_OP_REMOVE_KEY 0x000E | 117 | #define MGMT_OP_REMOVE_KEYS 0x000E |
118 | struct mgmt_cp_remove_key { | 118 | struct mgmt_cp_remove_keys { |
119 | bdaddr_t bdaddr; | 119 | bdaddr_t bdaddr; |
120 | __u8 disconnect; | 120 | __u8 disconnect; |
121 | } __packed; | 121 | } __packed; |
@@ -247,10 +247,10 @@ struct mgmt_ev_controller_error { | |||
247 | 247 | ||
248 | #define MGMT_EV_PAIRABLE 0x0009 | 248 | #define MGMT_EV_PAIRABLE 0x0009 |
249 | 249 | ||
250 | #define MGMT_EV_NEW_KEY 0x000A | 250 | #define MGMT_EV_NEW_LINK_KEY 0x000A |
251 | struct mgmt_ev_new_key { | 251 | struct mgmt_ev_new_link_key { |
252 | __u8 store_hint; | 252 | __u8 store_hint; |
253 | struct mgmt_key_info key; | 253 | struct mgmt_link_key_info key; |
254 | } __packed; | 254 | } __packed; |
255 | 255 | ||
256 | #define MGMT_EV_CONNECTED 0x000B | 256 | #define MGMT_EV_CONNECTED 0x000B |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e4ddf36d1701..693c0dfc6b9d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1140,7 +1140,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, | |||
1140 | 1140 | ||
1141 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); | 1141 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); |
1142 | 1142 | ||
1143 | mgmt_new_key(hdev->id, key, persistent); | 1143 | mgmt_new_link_key(hdev->id, key, persistent); |
1144 | 1144 | ||
1145 | if (!persistent) { | 1145 | if (!persistent) { |
1146 | list_del(&key->list); | 1146 | list_del(&key->list); |
@@ -1183,7 +1183,7 @@ int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | |||
1183 | memcpy(id->rand, rand, sizeof(id->rand)); | 1183 | memcpy(id->rand, rand, sizeof(id->rand)); |
1184 | 1184 | ||
1185 | if (new_key) | 1185 | if (new_key) |
1186 | mgmt_new_key(hdev->id, key, old_key_type); | 1186 | mgmt_new_link_key(hdev->id, key, old_key_type); |
1187 | 1187 | ||
1188 | return 0; | 1188 | return 0; |
1189 | } | 1189 | } |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index af077abdfa98..1939053c3fcd 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -908,30 +908,32 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | |||
908 | return err; | 908 | return err; |
909 | } | 909 | } |
910 | 910 | ||
911 | static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | 911 | static int load_link_keys(struct sock *sk, u16 index, unsigned char *data, |
912 | u16 len) | ||
912 | { | 913 | { |
913 | struct hci_dev *hdev; | 914 | struct hci_dev *hdev; |
914 | struct mgmt_cp_load_keys *cp; | 915 | struct mgmt_cp_load_link_keys *cp; |
915 | u16 key_count, expected_len; | 916 | u16 key_count, expected_len; |
916 | int i; | 917 | int i; |
917 | 918 | ||
918 | cp = (void *) data; | 919 | cp = (void *) data; |
919 | 920 | ||
920 | if (len < sizeof(*cp)) | 921 | if (len < sizeof(*cp)) |
921 | return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, EINVAL); | 922 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, EINVAL); |
922 | 923 | ||
923 | key_count = get_unaligned_le16(&cp->key_count); | 924 | key_count = get_unaligned_le16(&cp->key_count); |
924 | 925 | ||
925 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); | 926 | expected_len = sizeof(*cp) + key_count * |
927 | sizeof(struct mgmt_link_key_info); | ||
926 | if (expected_len != len) { | 928 | if (expected_len != len) { |
927 | BT_ERR("load_keys: expected %u bytes, got %u bytes", | 929 | BT_ERR("load_link_keys: expected %u bytes, got %u bytes", |
928 | len, expected_len); | 930 | len, expected_len); |
929 | return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, EINVAL); | 931 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, EINVAL); |
930 | } | 932 | } |
931 | 933 | ||
932 | hdev = hci_dev_get(index); | 934 | hdev = hci_dev_get(index); |
933 | if (!hdev) | 935 | if (!hdev) |
934 | return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV); | 936 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, ENODEV); |
935 | 937 | ||
936 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, | 938 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, |
937 | key_count); | 939 | key_count); |
@@ -948,7 +950,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
948 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); | 950 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); |
949 | 951 | ||
950 | for (i = 0; i < key_count; i++) { | 952 | for (i = 0; i < key_count; i++) { |
951 | struct mgmt_key_info *key = &cp->keys[i]; | 953 | struct mgmt_link_key_info *key = &cp->keys[i]; |
952 | 954 | ||
953 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, | 955 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, |
954 | key->pin_len); | 956 | key->pin_len); |
@@ -960,27 +962,28 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
960 | return 0; | 962 | return 0; |
961 | } | 963 | } |
962 | 964 | ||
963 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | 965 | static int remove_keys(struct sock *sk, u16 index, unsigned char *data, |
966 | u16 len) | ||
964 | { | 967 | { |
965 | struct hci_dev *hdev; | 968 | struct hci_dev *hdev; |
966 | struct mgmt_cp_remove_key *cp; | 969 | struct mgmt_cp_remove_keys *cp; |
967 | struct hci_conn *conn; | 970 | struct hci_conn *conn; |
968 | int err; | 971 | int err; |
969 | 972 | ||
970 | cp = (void *) data; | 973 | cp = (void *) data; |
971 | 974 | ||
972 | if (len != sizeof(*cp)) | 975 | if (len != sizeof(*cp)) |
973 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL); | 976 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, EINVAL); |
974 | 977 | ||
975 | hdev = hci_dev_get(index); | 978 | hdev = hci_dev_get(index); |
976 | if (!hdev) | 979 | if (!hdev) |
977 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); | 980 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, ENODEV); |
978 | 981 | ||
979 | hci_dev_lock_bh(hdev); | 982 | hci_dev_lock_bh(hdev); |
980 | 983 | ||
981 | err = hci_remove_link_key(hdev, &cp->bdaddr); | 984 | err = hci_remove_link_key(hdev, &cp->bdaddr); |
982 | if (err < 0) { | 985 | if (err < 0) { |
983 | err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err); | 986 | err = cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, -err); |
984 | goto unlock; | 987 | goto unlock; |
985 | } | 988 | } |
986 | 989 | ||
@@ -1860,11 +1863,11 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1860 | case MGMT_OP_SET_SERVICE_CACHE: | 1863 | case MGMT_OP_SET_SERVICE_CACHE: |
1861 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); | 1864 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); |
1862 | break; | 1865 | break; |
1863 | case MGMT_OP_LOAD_KEYS: | 1866 | case MGMT_OP_LOAD_LINK_KEYS: |
1864 | err = load_keys(sk, index, buf + sizeof(*hdr), len); | 1867 | err = load_link_keys(sk, index, buf + sizeof(*hdr), len); |
1865 | break; | 1868 | break; |
1866 | case MGMT_OP_REMOVE_KEY: | 1869 | case MGMT_OP_REMOVE_KEYS: |
1867 | err = remove_key(sk, index, buf + sizeof(*hdr), len); | 1870 | err = remove_keys(sk, index, buf + sizeof(*hdr), len); |
1868 | break; | 1871 | break; |
1869 | case MGMT_OP_DISCONNECT: | 1872 | case MGMT_OP_DISCONNECT: |
1870 | err = disconnect(sk, index, buf + sizeof(*hdr), len); | 1873 | err = disconnect(sk, index, buf + sizeof(*hdr), len); |
@@ -2055,9 +2058,9 @@ int mgmt_write_scan_failed(u16 index, u8 scan, u8 status) | |||
2055 | return 0; | 2058 | return 0; |
2056 | } | 2059 | } |
2057 | 2060 | ||
2058 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | 2061 | int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent) |
2059 | { | 2062 | { |
2060 | struct mgmt_ev_new_key ev; | 2063 | struct mgmt_ev_new_link_key ev; |
2061 | 2064 | ||
2062 | memset(&ev, 0, sizeof(ev)); | 2065 | memset(&ev, 0, sizeof(ev)); |
2063 | 2066 | ||
@@ -2067,7 +2070,7 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | |||
2067 | memcpy(ev.key.val, key->val, 16); | 2070 | memcpy(ev.key.val, key->val, 16); |
2068 | ev.key.pin_len = key->pin_len; | 2071 | ev.key.pin_len = key->pin_len; |
2069 | 2072 | ||
2070 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); | 2073 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, index, &ev, sizeof(ev), NULL); |
2071 | } | 2074 | } |
2072 | 2075 | ||
2073 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) | 2076 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) |