aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2011-11-07 16:13:39 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-11-08 10:05:57 -0500
commit4c659c3976e81f9def48993cd00988d53d7379f2 (patch)
tree57cdd17455a2b71ab545bcb609baa4990afa8dda
parent86742e1eca319069490f6f20c2892baafc2a6922 (diff)
Bluetooth: Add address type fields to mgmt messages that need them
This patch adds address type info (typically BR/EDR vs LE) to management messages that need this. This also ensures conformance to the latest management API specification. 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.h10
-rw-r--r--include/net/bluetooth/mgmt.h23
-rw-r--r--net/bluetooth/hci_event.c20
-rw-r--r--net/bluetooth/mgmt.c47
4 files changed, 64 insertions, 36 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4ebc882385f9..e6071d0ea20f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -912,10 +912,10 @@ int mgmt_discoverable(u16 index, u8 discoverable);
912int mgmt_connectable(u16 index, u8 connectable); 912int mgmt_connectable(u16 index, u8 connectable);
913int mgmt_write_scan_failed(u16 index, u8 scan, u8 status); 913int mgmt_write_scan_failed(u16 index, u8 scan, u8 status);
914int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent); 914int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent);
915int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type); 915int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 type);
916int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); 916int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type);
917int mgmt_disconnect_failed(u16 index); 917int mgmt_disconnect_failed(u16 index);
918int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); 918int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status);
919int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure); 919int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure);
920int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); 920int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
921int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); 921int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
@@ -928,8 +928,8 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
928int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status); 928int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status);
929int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, 929int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
930 u8 status); 930 u8 status);
931int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, 931int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class,
932 u8 *eir); 932 s8 rssi, u8 *eir);
933int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name); 933int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name);
934int mgmt_inquiry_failed(u16 index, u8 status); 934int mgmt_inquiry_failed(u16 index, u8 status);
935int mgmt_discovering(u16 index, u8 discovering); 935int mgmt_discovering(u16 index, u8 discovering);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index fa33bc6c485f..3e320c9cae8f 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -128,10 +128,20 @@ struct mgmt_rp_disconnect {
128 bdaddr_t bdaddr; 128 bdaddr_t bdaddr;
129} __packed; 129} __packed;
130 130
131#define MGMT_ADDR_BREDR 0x00
132#define MGMT_ADDR_LE 0x01
133#define MGMT_ADDR_BREDR_LE 0x02
134#define MGMT_ADDR_INVALID 0xff
135
136struct mgmt_addr_info {
137 bdaddr_t bdaddr;
138 __u8 type;
139} __packed;
140
131#define MGMT_OP_GET_CONNECTIONS 0x0010 141#define MGMT_OP_GET_CONNECTIONS 0x0010
132struct mgmt_rp_get_connections { 142struct mgmt_rp_get_connections {
133 __le16 conn_count; 143 __le16 conn_count;
134 bdaddr_t conn[0]; 144 struct mgmt_addr_info addr[0];
135} __packed; 145} __packed;
136 146
137#define MGMT_OP_PIN_CODE_REPLY 0x0011 147#define MGMT_OP_PIN_CODE_REPLY 0x0011
@@ -254,19 +264,12 @@ struct mgmt_ev_new_link_key {
254} __packed; 264} __packed;
255 265
256#define MGMT_EV_CONNECTED 0x000B 266#define MGMT_EV_CONNECTED 0x000B
257struct mgmt_ev_connected {
258 bdaddr_t bdaddr;
259 __u8 link_type;
260} __packed;
261 267
262#define MGMT_EV_DISCONNECTED 0x000C 268#define MGMT_EV_DISCONNECTED 0x000C
263struct mgmt_ev_disconnected {
264 bdaddr_t bdaddr;
265} __packed;
266 269
267#define MGMT_EV_CONNECT_FAILED 0x000D 270#define MGMT_EV_CONNECT_FAILED 0x000D
268struct mgmt_ev_connect_failed { 271struct mgmt_ev_connect_failed {
269 bdaddr_t bdaddr; 272 struct mgmt_addr_info addr;
270 __u8 status; 273 __u8 status;
271} __packed; 274} __packed;
272 275
@@ -296,7 +299,7 @@ struct mgmt_ev_local_name_changed {
296 299
297#define MGMT_EV_DEVICE_FOUND 0x0012 300#define MGMT_EV_DEVICE_FOUND 0x0012
298struct mgmt_ev_device_found { 301struct mgmt_ev_device_found {
299 bdaddr_t bdaddr; 302 struct mgmt_addr_info addr;
300 __u8 dev_class[3]; 303 __u8 dev_class[3];
301 __s8 rssi; 304 __s8 rssi;
302 __u8 eir[HCI_MAX_EIR_LENGTH]; 305 __u8 eir[HCI_MAX_EIR_LENGTH];
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 176cecae4b42..2fced8c43258 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1404,8 +1404,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
1404 data.rssi = 0x00; 1404 data.rssi = 0x00;
1405 data.ssp_mode = 0x00; 1405 data.ssp_mode = 0x00;
1406 hci_inquiry_cache_update(hdev, &data); 1406 hci_inquiry_cache_update(hdev, &data);
1407 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0, 1407 mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
1408 NULL); 1408 info->dev_class, 0, NULL);
1409 } 1409 }
1410 1410
1411 hci_dev_unlock(hdev); 1411 hci_dev_unlock(hdev);
@@ -1471,7 +1471,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
1471 } else { 1471 } else {
1472 conn->state = BT_CLOSED; 1472 conn->state = BT_CLOSED;
1473 if (conn->type == ACL_LINK) 1473 if (conn->type == ACL_LINK)
1474 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status); 1474 mgmt_connect_failed(hdev->id, &ev->bdaddr, conn->type,
1475 ev->status);
1475 } 1476 }
1476 1477
1477 if (conn->type == ACL_LINK) 1478 if (conn->type == ACL_LINK)
@@ -1584,7 +1585,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
1584 conn->state = BT_CLOSED; 1585 conn->state = BT_CLOSED;
1585 1586
1586 if (conn->type == ACL_LINK || conn->type == LE_LINK) 1587 if (conn->type == ACL_LINK || conn->type == LE_LINK)
1587 mgmt_disconnected(hdev->id, &conn->dst); 1588 mgmt_disconnected(hdev->id, &conn->dst, conn->type);
1588 1589
1589 hci_proto_disconn_cfm(conn, ev->reason); 1590 hci_proto_disconn_cfm(conn, ev->reason);
1590 hci_conn_del(conn); 1591 hci_conn_del(conn);
@@ -2408,7 +2409,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
2408 data.rssi = info->rssi; 2409 data.rssi = info->rssi;
2409 data.ssp_mode = 0x00; 2410 data.ssp_mode = 0x00;
2410 hci_inquiry_cache_update(hdev, &data); 2411 hci_inquiry_cache_update(hdev, &data);
2411 mgmt_device_found(hdev->id, &info->bdaddr, 2412 mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
2412 info->dev_class, info->rssi, 2413 info->dev_class, info->rssi,
2413 NULL); 2414 NULL);
2414 } 2415 }
@@ -2425,7 +2426,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
2425 data.rssi = info->rssi; 2426 data.rssi = info->rssi;
2426 data.ssp_mode = 0x00; 2427 data.ssp_mode = 0x00;
2427 hci_inquiry_cache_update(hdev, &data); 2428 hci_inquiry_cache_update(hdev, &data);
2428 mgmt_device_found(hdev->id, &info->bdaddr, 2429 mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
2429 info->dev_class, info->rssi, 2430 info->dev_class, info->rssi,
2430 NULL); 2431 NULL);
2431 } 2432 }
@@ -2568,8 +2569,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
2568 data.rssi = info->rssi; 2569 data.rssi = info->rssi;
2569 data.ssp_mode = 0x01; 2570 data.ssp_mode = 0x01;
2570 hci_inquiry_cache_update(hdev, &data); 2571 hci_inquiry_cache_update(hdev, &data);
2571 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 2572 mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK,
2572 info->rssi, info->data); 2573 info->dev_class, info->rssi, info->data);
2573 } 2574 }
2574 2575
2575 hci_dev_unlock(hdev); 2576 hci_dev_unlock(hdev);
@@ -2832,7 +2833,8 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
2832 } 2833 }
2833 2834
2834 if (ev->status) { 2835 if (ev->status) {
2835 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status); 2836 mgmt_connect_failed(hdev->id, &ev->bdaddr, conn->type,
2837 ev->status);
2836 hci_proto_connect_cfm(conn, ev->status); 2838 hci_proto_connect_cfm(conn, ev->status);
2837 conn->state = BT_CLOSED; 2839 conn->state = BT_CLOSED;
2838 hci_conn_del(conn); 2840 hci_conn_del(conn);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 1939053c3fcd..4cb2f958fb10 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1069,6 +1069,18 @@ failed:
1069 return err; 1069 return err;
1070} 1070}
1071 1071
1072static u8 link_to_mgmt(u8 link_type)
1073{
1074 switch (link_type) {
1075 case LE_LINK:
1076 return MGMT_ADDR_LE;
1077 case ACL_LINK:
1078 return MGMT_ADDR_BREDR;
1079 default:
1080 return MGMT_ADDR_INVALID;
1081 }
1082}
1083
1072static int get_connections(struct sock *sk, u16 index) 1084static int get_connections(struct sock *sk, u16 index)
1073{ 1085{
1074 struct mgmt_rp_get_connections *rp; 1086 struct mgmt_rp_get_connections *rp;
@@ -1092,7 +1104,7 @@ static int get_connections(struct sock *sk, u16 index)
1092 count++; 1104 count++;
1093 } 1105 }
1094 1106
1095 rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t)); 1107 rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info));
1096 rp = kmalloc(rp_len, GFP_ATOMIC); 1108 rp = kmalloc(rp_len, GFP_ATOMIC);
1097 if (!rp) { 1109 if (!rp) {
1098 err = -ENOMEM; 1110 err = -ENOMEM;
@@ -1102,8 +1114,16 @@ static int get_connections(struct sock *sk, u16 index)
1102 put_unaligned_le16(count, &rp->conn_count); 1114 put_unaligned_le16(count, &rp->conn_count);
1103 1115
1104 i = 0; 1116 i = 0;
1105 list_for_each_entry(c, &hdev->conn_hash.list, list) 1117 list_for_each_entry(c, &hdev->conn_hash.list, list) {
1106 bacpy(&rp->conn[i++], &c->dst); 1118 bacpy(&rp->addr[i].bdaddr, &c->dst);
1119 rp->addr[i].type = link_to_mgmt(c->type);
1120 if (rp->addr[i].type == MGMT_ADDR_INVALID)
1121 continue;
1122 i++;
1123 }
1124
1125 /* Recalculate length in case of filtered SCO connections, etc */
1126 rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
1107 1127
1108 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); 1128 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
1109 1129
@@ -2075,10 +2095,10 @@ int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent)
2075 2095
2076int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) 2096int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type)
2077{ 2097{
2078 struct mgmt_ev_connected ev; 2098 struct mgmt_addr_info ev;
2079 2099
2080 bacpy(&ev.bdaddr, bdaddr); 2100 bacpy(&ev.bdaddr, bdaddr);
2081 ev.link_type = link_type; 2101 ev.type = link_to_mgmt(link_type);
2082 2102
2083 return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL); 2103 return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL);
2084} 2104}
@@ -2099,15 +2119,16 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2099 mgmt_pending_remove(cmd); 2119 mgmt_pending_remove(cmd);
2100} 2120}
2101 2121
2102int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) 2122int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type)
2103{ 2123{
2104 struct mgmt_ev_disconnected ev; 2124 struct mgmt_addr_info ev;
2105 struct sock *sk = NULL; 2125 struct sock *sk = NULL;
2106 int err; 2126 int err;
2107 2127
2108 mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); 2128 mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
2109 2129
2110 bacpy(&ev.bdaddr, bdaddr); 2130 bacpy(&ev.bdaddr, bdaddr);
2131 ev.type = link_to_mgmt(type);
2111 2132
2112 err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk); 2133 err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
2113 2134
@@ -2133,11 +2154,12 @@ int mgmt_disconnect_failed(u16 index)
2133 return err; 2154 return err;
2134} 2155}
2135 2156
2136int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status) 2157int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status)
2137{ 2158{
2138 struct mgmt_ev_connect_failed ev; 2159 struct mgmt_ev_connect_failed ev;
2139 2160
2140 bacpy(&ev.bdaddr, bdaddr); 2161 bacpy(&ev.addr.bdaddr, bdaddr);
2162 ev.addr.type = link_to_mgmt(type);
2141 ev.status = status; 2163 ev.status = status;
2142 2164
2143 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); 2165 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
@@ -2325,14 +2347,15 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
2325 return err; 2347 return err;
2326} 2348}
2327 2349
2328int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, 2350int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class,
2329 u8 *eir) 2351 s8 rssi, u8 *eir)
2330{ 2352{
2331 struct mgmt_ev_device_found ev; 2353 struct mgmt_ev_device_found ev;
2332 2354
2333 memset(&ev, 0, sizeof(ev)); 2355 memset(&ev, 0, sizeof(ev));
2334 2356
2335 bacpy(&ev.bdaddr, bdaddr); 2357 bacpy(&ev.addr.bdaddr, bdaddr);
2358 ev.addr.type = link_to_mgmt(type);
2336 ev.rssi = rssi; 2359 ev.rssi = rssi;
2337 2360
2338 if (eir) 2361 if (eir)