diff --git a/lib/mgmt.h b/lib/mgmt.h
index ad4781d..22912d4 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
struct mgmt_ltk_info keys[0];
} __packed;
-#define MGMT_OP_REMOVE_KEYS 0x0014
-struct mgmt_cp_remove_keys {
- bdaddr_t bdaddr;
- uint8_t disconnect;
-} __packed;
-struct mgmt_rp_remove_keys {
- bdaddr_t bdaddr;
- uint8_t status;
-} __packed;
-
-#define MGMT_OP_DISCONNECT 0x0015
+#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;
uint8_t status;
} __packed;
-#define MGMT_OP_GET_CONNECTIONS 0x0016
+#define MGMT_OP_GET_CONNECTIONS 0x0015
struct mgmt_rp_get_connections {
uint16_t conn_count;
struct mgmt_addr_info addr[0];
} __packed;
-#define MGMT_OP_PIN_CODE_REPLY 0x0017
+#define MGMT_OP_PIN_CODE_REPLY 0x0016
struct mgmt_cp_pin_code_reply {
bdaddr_t bdaddr;
uint8_t pin_len;
uint8_t pin_code[16];
} __packed;
-#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0018
+#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0017
struct mgmt_cp_pin_code_neg_reply {
bdaddr_t bdaddr;
} __packed;
-#define MGMT_OP_SET_IO_CAPABILITY 0x0019
+#define MGMT_OP_SET_IO_CAPABILITY 0x0018
struct mgmt_cp_set_io_capability {
uint8_t io_capability;
} __packed;
-#define MGMT_OP_PAIR_DEVICE 0x001A
+#define MGMT_OP_PAIR_DEVICE 0x0019
struct mgmt_cp_pair_device {
struct mgmt_addr_info addr;
uint8_t io_cap;
uint8_t status;
} __packed;
-#define MGMT_OP_CANCEL_PAIR_DEVICE 0x001B
+#define MGMT_OP_CANCEL_PAIR_DEVICE 0x001A
+
+#define MGMT_OP_UNPAIR_DEVICE 0x001B
+struct mgmt_cp_unpair_device {
+ struct mgmt_addr_info addr;
+ uint8_t disconnect;
+} __packed;
+struct mgmt_rp_unpair_device {
+ struct mgmt_addr_info addr;
+ uint8_t status;
+} __packed;
#define MGMT_OP_USER_CONFIRM_REPLY 0x001C
struct mgmt_cp_user_confirm_reply {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
} __packed;
struct mgmt_rp_user_confirm_reply {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
uint8_t status;
} __packed;
#define MGMT_OP_USER_PASSKEY_REPLY 0x001E
struct mgmt_cp_user_passkey_reply {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
uint32_t passkey;
} __packed;
struct mgmt_rp_user_passkey_reply {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
uint8_t status;
} __packed;
#define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x001F
struct mgmt_cp_user_passkey_neg_reply {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0020
#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021
struct mgmt_cp_add_remote_oob_data {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
uint8_t hash[16];
uint8_t randomizer[16];
} __packed;
#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0022
struct mgmt_cp_remove_remote_oob_data {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_START_DISCOVERY 0x0023
#define MGMT_OP_BLOCK_DEVICE 0x0026
struct mgmt_cp_block_device {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_UNBLOCK_DEVICE 0x0027
struct mgmt_cp_unblock_device {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
} __packed;
#define MGMT_EV_CMD_COMPLETE 0x0001
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
uint8_t confirm_hint;
uint32_t value;
} __packed;
#define MGMT_EV_USER_PASSKEY_REQUEST 0x0010
struct mgmt_ev_user_passkey_request {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
} __packed;
#define MGMT_EV_AUTH_FAILED 0x0011
struct mgmt_ev_auth_failed {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
uint8_t status;
} __packed;
#define MGMT_EV_DEVICE_BLOCKED 0x0014
struct mgmt_ev_device_blocked {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
} __packed;
#define MGMT_EV_DEVICE_UNBLOCKED 0x0015
struct mgmt_ev_device_unblocked {
- bdaddr_t bdaddr;
+ struct mgmt_addr_info addr;
+} __packed;
+
+#define MGMT_EV_DEVICE_UNPAIRED 0x0016
+struct mgmt_ev_device_unpaired {
+ struct mgmt_addr_info addr;
} __packed;
diff --git a/mgmt/main.c b/mgmt/main.c
index af0a302..8c9e51d 100644
--- a/mgmt/main.c
+++ b/mgmt/main.c
if (monitor) {
char addr[18];
- ba2str(&ev->bdaddr, addr);
+ ba2str(&ev->addr.bdaddr, addr);
printf("hci%u %s auth failed with status 0x%02x (%s)\n",
index, addr, ev->status, mgmt_errstr(ev->status));
}
struct mgmt_cp_user_confirm_reply cp;
memset(&cp, 0, sizeof(cp));
- bacpy(&cp.bdaddr, bdaddr);
+ bacpy(&cp.addr.bdaddr, bdaddr);
return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_REPLY, index,
&cp, sizeof(cp), confirm_rsp, NULL);
struct mgmt_cp_user_confirm_reply cp;
memset(&cp, 0, sizeof(cp));
- bacpy(&cp.bdaddr, bdaddr);
+ bacpy(&cp.addr.bdaddr, bdaddr);
return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_NEG_REPLY, index,
&cp, sizeof(cp), confirm_neg_rsp, NULL);
return -EINVAL;
}
- ba2str(&ev->bdaddr, addr);
+ ba2str(&ev->addr.bdaddr, addr);
val = bt_get_le32(&ev->value);
if (monitor)
memset(rsp, 0, sizeof(rsp));
if (fgets(rsp, sizeof(rsp), stdin) == NULL || rsp[0] == '\n')
- return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->bdaddr);
+ return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
rsp_len = strlen(rsp);
if (rsp[rsp_len - 1] == '\n') {
}
if (rsp[0] == 'y' || rsp[0] == 'Y')
- return mgmt_confirm_reply(mgmt_sk, index, &ev->bdaddr);
+ return mgmt_confirm_reply(mgmt_sk, index, &ev->addr.bdaddr);
else
- return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->bdaddr);
+ return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
}
static int mgmt_handle_event(int mgmt_sk, uint16_t ev, uint16_t index,
exit(EXIT_FAILURE);
}
- ba2str(&rp->bdaddr, addr);
+ ba2str(&rp->addr.bdaddr, addr);
if (rp->status == 0) {
printf("%s disconnected\n", addr);
exit(EXIT_FAILURE);
}
- str2ba(argv[1], &cp.bdaddr);
+ str2ba(argv[1], &cp.addr.bdaddr);
if (index == MGMT_INDEX_NONE)
index = 0;
}
}
-static void remove_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
+static void unpair_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
void *rsp, uint16_t len, void *user_data)
{
- struct mgmt_rp_remove_keys *rp = rsp;
+ struct mgmt_rp_unpair_device *rp = rsp;
char addr[18];
if (status != 0) {
- fprintf(stderr, "Remove keys failed with status 0x%02x (%s)\n",
+ fprintf(stderr, "Unpair device failed. status 0x%02x (%s)\n",
status, mgmt_errstr(status));
exit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
- fprintf(stderr, "Unexpected remove_keys_rsp len %u\n", len);
+ fprintf(stderr, "Unexpected unpair_device_rsp len %u\n", len);
exit(EXIT_FAILURE);
}
- ba2str(&rp->bdaddr, addr);
+ ba2str(&rp->addr.bdaddr, addr);
if (rp->status != 0) {
fprintf(stderr,
- "Removing keys for %s failed. status 0x%02x (%s)\n",
+ "Unpairing %s failed. status 0x%02x (%s)\n",
addr, rp->status, mgmt_errstr(rp->status));
exit(EXIT_FAILURE);
}
- printf("Removed keys for %s\n", addr);
+ printf("%s unpaired\n", addr);
exit(EXIT_SUCCESS);
}
-static void cmd_remove(int mgmt_sk, uint16_t index, int argc, char **argv)
+static void cmd_unpair(int mgmt_sk, uint16_t index, int argc, char **argv)
{
- struct mgmt_cp_remove_keys cp;
+ struct mgmt_cp_unpair_device cp;
if (argc < 2) {
printf("Usage: btmgmt %s <remote address>\n", argv[0]);
index = 0;
memset(&cp, 0, sizeof(cp));
- str2ba(argv[1], &cp.bdaddr);
+ str2ba(argv[1], &cp.addr.bdaddr);
cp.disconnect = 1;
- if (mgmt_send_cmd(mgmt_sk, MGMT_OP_REMOVE_KEYS, index, &cp, sizeof(cp),
- remove_rsp, NULL) < 0) {
- fprintf(stderr, "Unable to send remove_keys cmd\n");
+ if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNPAIR_DEVICE, index, &cp,
+ sizeof(cp), unpair_rsp, NULL) < 0) {
+ fprintf(stderr, "Unable to send unpair_device cmd\n");
exit(EXIT_FAILURE);
}
}
{ "find", cmd_find, "Discover nearby devices" },
{ "name", cmd_name, "Set local name" },
{ "pair", cmd_pair, "Pair with a remote device" },
- { "remove", cmd_remove, "Remove pairing (all keys)" },
+ { "unpair", cmd_unpair, "Unpair device" },
{ "keys", cmd_keys, "Load Keys" },
{ NULL, NULL, 0 }
};
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 4424ec9..519e34c 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
hdr->index = htobs(index);
cp = (void *) &buf[sizeof(*hdr)];
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
if (write(mgmt_sock, buf, sizeof(buf)) < 0)
return -errno;
hdr->len = htobs(sizeof(*cp));
cp = (void *) &buf[sizeof(*hdr)];
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
buf_len = sizeof(*hdr) + sizeof(*cp);
} else {
hdr->len = htobs(sizeof(*cp));
cp = (void *) &buf[sizeof(*hdr)];
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
cp->passkey = htobl(passkey);
buf_len = sizeof(*hdr) + sizeof(*cp);
return;
}
- ba2str(&ev->bdaddr, addr);
+ ba2str(&ev->addr.bdaddr, addr);
DBG("hci%u %s", index, addr);
info = &controllers[index];
- err = btd_event_user_passkey(&info->bdaddr, &ev->bdaddr);
+ err = btd_event_user_passkey(&info->bdaddr, &ev->addr.bdaddr);
if (err < 0) {
error("btd_event_user_passkey: %s", strerror(-err));
- mgmt_passkey_reply(index, &ev->bdaddr, INVALID_PASSKEY);
+ mgmt_passkey_reply(index, &ev->addr.bdaddr, INVALID_PASSKEY);
}
}
return;
}
- ba2str(&ev->bdaddr, addr);
+ ba2str(&ev->addr.bdaddr, addr);
DBG("hci%u %s confirm_hint %u", index, addr, ev->confirm_hint);
data = g_new0(struct confirm_data, 1);
data->index = index;
- bacpy(&data->bdaddr, &ev->bdaddr);
+ bacpy(&data->bdaddr, &ev->addr.bdaddr);
g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1,
confirm_accept, data, g_free);
info = &controllers[index];
- err = btd_event_user_confirm(&info->bdaddr, &ev->bdaddr,
+ err = btd_event_user_confirm(&info->bdaddr, &ev->addr.bdaddr,
btohl(ev->value));
if (err < 0) {
error("btd_event_user_confirm: %s", strerror(-err));
- mgmt_confirm_reply(index, &ev->bdaddr, FALSE);
+ mgmt_confirm_reply(index, &ev->addr.bdaddr, FALSE);
}
}
return;
}
- ba2str(&rp->bdaddr, addr);
+ ba2str(&rp->addr.bdaddr, addr);
if (rp->status != 0) {
error("Disconnecting %s failed with status %u",
info = &controllers[index];
- btd_event_disconn_complete(&info->bdaddr, &rp->bdaddr);
+ btd_event_disconn_complete(&info->bdaddr, &rp->addr.bdaddr);
- bonding_complete(info, &rp->bdaddr, HCI_CONNECTION_TERMINATED);
+ bonding_complete(info, &rp->addr.bdaddr, HCI_CONNECTION_TERMINATED);
}
static void pair_device_complete(int sk, uint16_t index, void *buf, size_t len)
case MGMT_OP_LOAD_LINK_KEYS:
DBG("load_link_keys complete");
break;
- case MGMT_OP_REMOVE_KEYS:
- DBG("remove_keys complete");
+ case MGMT_OP_UNPAIR_DEVICE:
+ DBG("unpair_device complete");
break;
case MGMT_OP_DISCONNECT:
DBG("disconnect complete");
info = &controllers[index];
- bonding_complete(info, &ev->bdaddr, ev->status);
+ bonding_complete(info, &ev->addr.bdaddr, ev->status);
}
static void mgmt_local_name_changed(int sk, uint16_t index, void *buf, size_t len)
return;
}
- ba2str(&ev->bdaddr, addr);
+ ba2str(&ev->addr.bdaddr, addr);
DBG("Device blocked, index %u, addr %s", index, addr);
if (index > max_index) {
info = &controllers[index];
- btd_event_device_blocked(&info->bdaddr, &ev->bdaddr);
+ btd_event_device_blocked(&info->bdaddr, &ev->addr.bdaddr);
}
static void mgmt_device_unblocked(int sk, uint16_t index, void *buf, size_t len)
return;
}
- ba2str(&ev->bdaddr, addr);
+ ba2str(&ev->addr.bdaddr, addr);
DBG("Device unblocked, index %u, addr %s", index, addr);
if (index > max_index) {
info = &controllers[index];
- btd_event_device_unblocked(&info->bdaddr, &ev->bdaddr);
+ btd_event_device_unblocked(&info->bdaddr, &ev->addr.bdaddr);
}
static void mgmt_new_ltk(int sk, uint16_t index, void *buf, size_t len)
hdr->index = htobs(index);
cp = (void *) &buf[sizeof(*hdr)];
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
buf_len = sizeof(*hdr) + sizeof(*cp);
hdr->index = htobs(index);
cp = (void *) &buf[sizeof(*hdr)];
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
buf_len = sizeof(*hdr) + sizeof(*cp);
hdr->len = htobs(sizeof(*cp));
hdr->index = htobs(index);
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
if (write(mgmt_sock, buf, sizeof(buf)) < 0)
error("write: %s (%d)", strerror(errno), errno);
return 0;
}
-static int mgmt_remove_bonding(int index, bdaddr_t *bdaddr)
+static int mgmt_unpair_device(int index, bdaddr_t *bdaddr)
{
- char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_keys)];
+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_unpair_device)];
struct mgmt_hdr *hdr = (void *) buf;
- struct mgmt_cp_remove_keys *cp = (void *) &buf[sizeof(*hdr)];
+ struct mgmt_cp_unpair_device *cp = (void *) &buf[sizeof(*hdr)];
char addr[18];
ba2str(bdaddr, addr);
DBG("index %d addr %s", index, addr);
memset(buf, 0, sizeof(buf));
- hdr->opcode = htobs(MGMT_OP_REMOVE_KEYS);
+ hdr->opcode = htobs(MGMT_OP_UNPAIR_DEVICE);
hdr->len = htobs(sizeof(*cp));
hdr->index = htobs(index);
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
cp->disconnect = 1;
if (write(mgmt_sock, buf, sizeof(buf)) < 0)
hdr->index = htobs(index);
hdr->len = htobs(sizeof(*cp));
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
memcpy(cp->hash, hash, 16);
memcpy(cp->randomizer, randomizer, 16);
hdr->index = htobs(index);
hdr->len = htobs(sizeof(*cp));
- bacpy(&cp->bdaddr, bdaddr);
+ bacpy(&cp->addr.bdaddr, bdaddr);
if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
return -errno;
.unblock_device = mgmt_unblock_device,
.get_conn_list = mgmt_get_conn_list,
.disconnect = mgmt_disconnect,
- .remove_bonding = mgmt_remove_bonding,
+ .remove_bonding = mgmt_unpair_device,
.pincode_reply = mgmt_pincode_reply,
.confirm_reply = mgmt_confirm_reply,
.passkey_reply = mgmt_passkey_reply,