aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-02-09 07:27:38 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-13 10:01:36 -0500
commit88c3df13ca06718e5a8f509ae9cbb1228c10d537 (patch)
tree89bd9706f5c1924174b9284239510a3f0de2ebc2 /net
parent124f6e35286c9d8dc96f147a9026081256136615 (diff)
Bluetooth: Update mgmt_disconnect to match latest API
This patch adds an address type parameter to the disconnect command and response in order to match the latest mgmt API specification. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_event.c28
-rw-r--r--net/bluetooth/mgmt.c28
2 files changed, 38 insertions, 18 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index ad5f37b13f77..f0c822db28d9 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1550,6 +1550,28 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1550 hci_dev_unlock(hdev); 1550 hci_dev_unlock(hdev);
1551} 1551}
1552 1552
1553static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1554{
1555 struct hci_cp_disconnect *cp;
1556 struct hci_conn *conn;
1557
1558 if (!status)
1559 return;
1560
1561 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1562 if (!cp)
1563 return;
1564
1565 hci_dev_lock(hdev);
1566
1567 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1568 if (conn)
1569 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1570 conn->dst_type, status);
1571
1572 hci_dev_unlock(hdev);
1573}
1574
1553static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) 1575static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1554{ 1576{
1555 struct hci_cp_le_create_conn *cp; 1577 struct hci_cp_le_create_conn *cp;
@@ -1839,7 +1861,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
1839 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && 1861 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1840 (conn->type == ACL_LINK || conn->type == LE_LINK)) { 1862 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
1841 if (ev->status != 0) 1863 if (ev->status != 0)
1842 mgmt_disconnect_failed(hdev, &conn->dst, ev->status); 1864 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1865 conn->dst_type, ev->status);
1843 else 1866 else
1844 mgmt_device_disconnected(hdev, &conn->dst, conn->type, 1867 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
1845 conn->dst_type); 1868 conn->dst_type);
@@ -2350,8 +2373,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2350 break; 2373 break;
2351 2374
2352 case HCI_OP_DISCONNECT: 2375 case HCI_OP_DISCONNECT:
2353 if (ev->status != 0) 2376 hci_cs_disconnect(hdev, ev->status);
2354 mgmt_disconnect_failed(hdev, NULL, ev->status);
2355 break; 2377 break;
2356 2378
2357 case HCI_OP_LE_CREATE_CONN: 2379 case HCI_OP_LE_CREATE_CONN:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c64e5db7f596..f1257ee5afbc 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1185,9 +1185,10 @@ static int disconnect(struct sock *sk, u16 index, void *data, u16 len)
1185 goto failed; 1185 goto failed;
1186 } 1186 }
1187 1187
1188 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1188 if (cp->addr.type == MGMT_ADDR_BREDR)
1189 if (!conn) 1189 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
1190 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr); 1190 else
1191 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
1191 1192
1192 if (!conn) { 1193 if (!conn) {
1193 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, 1194 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
@@ -2619,7 +2620,8 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2619 struct sock **sk = data; 2620 struct sock **sk = data;
2620 struct mgmt_rp_disconnect rp; 2621 struct mgmt_rp_disconnect rp;
2621 2622
2622 bacpy(&rp.bdaddr, &cp->bdaddr); 2623 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2624 rp.addr.type = cp->addr.type;
2623 rp.status = 0; 2625 rp.status = 0;
2624 2626
2625 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp)); 2627 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
@@ -2672,27 +2674,23 @@ int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
2672 return err; 2674 return err;
2673} 2675}
2674 2676
2675int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status) 2677int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
2678 u8 link_type, u8 addr_type, u8 status)
2676{ 2679{
2680 struct mgmt_rp_disconnect rp;
2677 struct pending_cmd *cmd; 2681 struct pending_cmd *cmd;
2678 u8 mgmt_err = mgmt_status(status);
2679 int err; 2682 int err;
2680 2683
2681 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); 2684 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
2682 if (!cmd) 2685 if (!cmd)
2683 return -ENOENT; 2686 return -ENOENT;
2684 2687
2685 if (bdaddr) { 2688 bacpy(&rp.addr.bdaddr, bdaddr);
2686 struct mgmt_rp_disconnect rp; 2689 rp.addr.type = link_to_mgmt(link_type, addr_type);
2687 2690 rp.status = mgmt_status(status);
2688 bacpy(&rp.bdaddr, bdaddr);
2689 rp.status = status;
2690 2691
2691 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, 2692 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
2692 &rp, sizeof(rp)); 2693 &rp, sizeof(rp));
2693 } else
2694 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT,
2695 mgmt_err);
2696 2694
2697 mgmt_pending_remove(cmd); 2695 mgmt_pending_remove(cmd);
2698 2696