Skip to content

Commit

Permalink
Bluetooth: Update mgmt_disconnect to match latest API
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johan Hedberg committed Feb 13, 2012
1 parent 124f6e3 commit 88c3df1
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 21 deletions.
3 changes: 2 additions & 1 deletion include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,8 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 *dev_class);
int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type);
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status);
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status);
int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
Expand Down
4 changes: 2 additions & 2 deletions include/net/bluetooth/mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ struct mgmt_cp_load_long_term_keys {

#define MGMT_OP_DISCONNECT 0x0014
struct mgmt_cp_disconnect {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
struct mgmt_rp_disconnect {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
__u8 status;
} __packed;

Expand Down
28 changes: 25 additions & 3 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -1550,6 +1550,28 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
hci_dev_unlock(hdev);
}

static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
{
struct hci_cp_disconnect *cp;
struct hci_conn *conn;

if (!status)
return;

cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
if (!cp)
return;

hci_dev_lock(hdev);

conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (conn)
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, status);

hci_dev_unlock(hdev);
}

static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
{
struct hci_cp_le_create_conn *cp;
Expand Down Expand Up @@ -1839,7 +1861,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
(conn->type == ACL_LINK || conn->type == LE_LINK)) {
if (ev->status != 0)
mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, ev->status);
else
mgmt_device_disconnected(hdev, &conn->dst, conn->type,
conn->dst_type);
Expand Down Expand Up @@ -2350,8 +2373,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
break;

case HCI_OP_DISCONNECT:
if (ev->status != 0)
mgmt_disconnect_failed(hdev, NULL, ev->status);
hci_cs_disconnect(hdev, ev->status);
break;

case HCI_OP_LE_CREATE_CONN:
Expand Down
28 changes: 13 additions & 15 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1185,9 +1185,10 @@ static int disconnect(struct sock *sk, u16 index, void *data, u16 len)
goto failed;
}

conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
if (!conn)
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr);
if (cp->addr.type == MGMT_ADDR_BREDR)
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
else
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);

if (!conn) {
err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
Expand Down Expand Up @@ -2619,7 +2620,8 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
struct sock **sk = data;
struct mgmt_rp_disconnect rp;

bacpy(&rp.bdaddr, &cp->bdaddr);
bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
rp.addr.type = cp->addr.type;
rp.status = 0;

cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
Expand Down Expand Up @@ -2672,27 +2674,23 @@ int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
return err;
}

int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status)
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status)
{
struct mgmt_rp_disconnect rp;
struct pending_cmd *cmd;
u8 mgmt_err = mgmt_status(status);
int err;

cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
if (!cmd)
return -ENOENT;

if (bdaddr) {
struct mgmt_rp_disconnect rp;

bacpy(&rp.bdaddr, bdaddr);
rp.status = status;
bacpy(&rp.addr.bdaddr, bdaddr);
rp.addr.type = link_to_mgmt(link_type, addr_type);
rp.status = mgmt_status(status);

err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
&rp, sizeof(rp));
} else
err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT,
mgmt_err);

mgmt_pending_remove(cmd);

Expand Down

0 comments on commit 88c3df1

Please sign in to comment.