Bluetooth: Add status parameter to mgmt_disconnect response
Since disconnecting may fail the status needs to be communicated to user space. This also updates the implementation to match the latest mgmt API specification. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
This commit is contained in:
parent
a8a1d19e9d
commit
37d9ef76c2
|
@ -919,7 +919,7 @@ int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
||||||
u8 addr_type);
|
u8 addr_type);
|
||||||
int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
||||||
u8 addr_type);
|
u8 addr_type);
|
||||||
int mgmt_disconnect_failed(struct hci_dev *hdev);
|
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
|
||||||
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
||||||
u8 addr_type, u8 status);
|
u8 addr_type, u8 status);
|
||||||
int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
|
int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
|
||||||
|
|
|
@ -130,6 +130,7 @@ struct mgmt_cp_disconnect {
|
||||||
} __packed;
|
} __packed;
|
||||||
struct mgmt_rp_disconnect {
|
struct mgmt_rp_disconnect {
|
||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
|
__u8 status;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define MGMT_ADDR_BREDR 0x00
|
#define MGMT_ADDR_BREDR 0x00
|
||||||
|
|
|
@ -1605,27 +1605,27 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
|
||||||
|
|
||||||
BT_DBG("%s status %d", hdev->name, ev->status);
|
BT_DBG("%s status %d", hdev->name, ev->status);
|
||||||
|
|
||||||
if (ev->status) {
|
|
||||||
hci_dev_lock(hdev);
|
|
||||||
mgmt_disconnect_failed(hdev);
|
|
||||||
hci_dev_unlock(hdev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
|
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
|
||||||
if (!conn)
|
if (!conn)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
conn->state = BT_CLOSED;
|
if (ev->status == 0)
|
||||||
|
conn->state = BT_CLOSED;
|
||||||
|
|
||||||
if (conn->type == ACL_LINK || conn->type == LE_LINK)
|
if (conn->type == ACL_LINK || conn->type == LE_LINK) {
|
||||||
mgmt_disconnected(hdev, &conn->dst, conn->type,
|
if (ev->status != 0)
|
||||||
|
mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
|
||||||
|
else
|
||||||
|
mgmt_disconnected(hdev, &conn->dst, conn->type,
|
||||||
conn->dst_type);
|
conn->dst_type);
|
||||||
|
}
|
||||||
|
|
||||||
hci_proto_disconn_cfm(conn, ev->reason);
|
if (ev->status == 0) {
|
||||||
hci_conn_del(conn);
|
hci_proto_disconn_cfm(conn, ev->reason);
|
||||||
|
hci_conn_del(conn);
|
||||||
|
}
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
|
@ -2098,7 +2098,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
|
|
||||||
case HCI_OP_DISCONNECT:
|
case HCI_OP_DISCONNECT:
|
||||||
if (ev->status != 0)
|
if (ev->status != 0)
|
||||||
mgmt_disconnect_failed(hdev);
|
mgmt_disconnect_failed(hdev, NULL, ev->status);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_OP_LE_CREATE_CONN:
|
case HCI_OP_LE_CREATE_CONN:
|
||||||
|
|
|
@ -2128,6 +2128,7 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
|
||||||
struct mgmt_rp_disconnect rp;
|
struct mgmt_rp_disconnect rp;
|
||||||
|
|
||||||
bacpy(&rp.bdaddr, &cp->bdaddr);
|
bacpy(&rp.bdaddr, &cp->bdaddr);
|
||||||
|
rp.status = 0;
|
||||||
|
|
||||||
cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
|
cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
|
||||||
|
|
||||||
|
@ -2176,7 +2177,7 @@ int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mgmt_disconnect_failed(struct hci_dev *hdev)
|
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status)
|
||||||
{
|
{
|
||||||
struct pending_cmd *cmd;
|
struct pending_cmd *cmd;
|
||||||
int err;
|
int err;
|
||||||
|
@ -2185,7 +2186,17 @@ int mgmt_disconnect_failed(struct hci_dev *hdev)
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT, EIO);
|
if (bdaddr) {
|
||||||
|
struct mgmt_rp_disconnect rp;
|
||||||
|
|
||||||
|
bacpy(&rp.bdaddr, bdaddr);
|
||||||
|
rp.status = status;
|
||||||
|
|
||||||
|
err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
|
||||||
|
&rp, sizeof(rp));
|
||||||
|
} else
|
||||||
|
err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT,
|
||||||
|
status);
|
||||||
|
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_remove(cmd);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue