mgmt: Add User Confirmation request support

This commit is contained in:
Johan Hedberg 2011-02-16 22:46:20 +02:00
parent 0439aea808
commit 50102905d9
3 changed files with 123 additions and 10 deletions

View File

@ -243,6 +243,28 @@ Pair Device Command
Status (1 Octet) Status (1 Octet)
User Confirmation Reply Command
===============================
Command Code: 0x0015
Command Parameters: Controller_Index (2 Octets)
Address (6 Octets)
Return Paramters: Controller_Index (2 Octets)
Address (6 Octets)
Status (1 Octet)
User Confirmation Negative Reply Command
========================================
Command Code: 0x0016
Command Parameters: Controller_Index (2 Octets)
Address (6 Octets)
Return Paramters: Controller_Index (2 Octets)
Address (6 Octets)
Status (1 Octet)
Read Tracing Buffer Size Command Read Tracing Buffer Size Command
================================ ================================
@ -400,3 +422,12 @@ PIN Code Request Event
Event Code 0x000E Event Code 0x000E
Event Parameters Controller_Index (2 Octets) Event Parameters Controller_Index (2 Octets)
Address (6 Octets) Address (6 Octets)
User Confirmation Request Event
===============================
Event Code 0x000F
Event Parameters Controller_Index (2 Octets)
Address (6 Octets)
Value (4 Octets)

View File

@ -181,6 +181,19 @@ struct mgmt_rp_pair_device {
uint8_t status; uint8_t status;
} __packed; } __packed;
#define MGMT_OP_USER_CONFIRM_REPLY 0x0015
struct mgmt_cp_user_confirm_reply {
uint16_t index;
bdaddr_t bdaddr;
} __packed;
struct mgmt_rp_user_confirm_reply {
uint16_t index;
bdaddr_t bdaddr;
uint8_t status;
} __packed;
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016
#define MGMT_EV_CMD_COMPLETE 0x0001 #define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete { struct mgmt_ev_cmd_complete {
uint16_t opcode; uint16_t opcode;
@ -248,3 +261,10 @@ struct mgmt_ev_pin_code_request {
uint16_t index; uint16_t index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
uint16_t index;
bdaddr_t bdaddr;
uint32_t value;
} __packed;

View File

@ -615,6 +615,69 @@ static void mgmt_pin_code_request(int sk, void *buf, size_t len)
} }
} }
static int mgmt_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success)
{
char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_user_confirm_reply)];
struct mgmt_hdr *hdr = (void *) buf;
struct mgmt_cp_user_confirm_reply *cp;
char addr[18];
ba2str(bdaddr, addr);
DBG("index %d addr %s success %d", index, addr, success);
memset(buf, 0, sizeof(buf));
if (success)
hdr->opcode = htobs(MGMT_OP_USER_CONFIRM_REPLY);
else
hdr->opcode = htobs(MGMT_OP_USER_CONFIRM_NEG_REPLY);
hdr->len = htobs(sizeof(*cp));
cp = (void *) &buf[sizeof(*hdr)];
cp->index = htobs(index);
bacpy(&cp->bdaddr, bdaddr);
if (write(mgmt_sock, buf, sizeof(buf)) < 0)
return -errno;
return 0;
}
static void mgmt_user_confirm_request(int sk, void *buf, size_t len)
{
struct mgmt_ev_user_confirm_request *ev = buf;
struct controller_info *info;
uint16_t index;
char addr[18];
int err;
if (len < sizeof(*ev)) {
error("Too small user_confirm_request event");
return;
}
index = btohs(bt_get_unaligned(&ev->index));
ba2str(&ev->bdaddr, addr);
DBG("hci%u %s", index, addr);
if (index > max_index) {
error("Unexpected index %u in user_confirm_request event",
index);
return;
}
info = &controllers[index];
err = btd_event_user_confirm(&info->bdaddr, &ev->bdaddr,
btohl(ev->value), FALSE);
if (err < 0) {
error("btd_event_user_confirm: %s", strerror(-err));
mgmt_confirm_reply(index, &ev->bdaddr, FALSE);
}
}
static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid) static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
{ {
if (uuid->type == SDP_UUID16) if (uuid->type == SDP_UUID16)
@ -1057,6 +1120,12 @@ static void mgmt_cmd_complete(int sk, void *buf, size_t len)
case MGMT_OP_PAIR_DEVICE: case MGMT_OP_PAIR_DEVICE:
pair_device_complete(sk, ev->data, len - sizeof(*ev)); pair_device_complete(sk, ev->data, len - sizeof(*ev));
break; break;
case MGMT_OP_USER_CONFIRM_REPLY:
DBG("user_confirm_reply complete");
break;
case MGMT_OP_USER_CONFIRM_NEG_REPLY:
DBG("user_confirm_net_reply complete");
break;
default: default:
error("Unknown command complete for opcode %u", opcode); error("Unknown command complete for opcode %u", opcode);
break; break;
@ -1178,6 +1247,9 @@ static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data
case MGMT_EV_PIN_CODE_REQUEST: case MGMT_EV_PIN_CODE_REQUEST:
mgmt_pin_code_request(sk, buf + MGMT_HDR_SIZE, len); mgmt_pin_code_request(sk, buf + MGMT_HDR_SIZE, len);
break; break;
case MGMT_EV_USER_CONFIRM_REQUEST:
mgmt_user_confirm_request(sk, buf + MGMT_HDR_SIZE, len);
break;
default: default:
error("Unknown Management opcode %u", opcode); error("Unknown Management opcode %u", opcode);
break; break;
@ -1470,16 +1542,6 @@ static int mgmt_remove_bonding(int index, bdaddr_t *bdaddr)
return 0; return 0;
} }
static int mgmt_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success)
{
char addr[18];
ba2str(bdaddr, addr);
DBG("index %d addr %s success %d", index, addr, success);
return -ENOSYS;
}
static int mgmt_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey) static int mgmt_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey)
{ {
char addr[18]; char addr[18];