diff --git a/lib/mgmt.h b/lib/mgmt.h
index f121b12..83f9f77 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
} __packed;
#define MGMT_EV_DEVICE_CONNECTED 0x000A
+struct mgmt_ev_device_connected {
+ struct mgmt_addr_info addr;
+ uint16_t eir_len;
+ uint8_t eir[0];
+} __packed;
#define MGMT_EV_DEVICE_DISCONNECTED 0x000B
diff --git a/mgmt/main.c b/mgmt/main.c
index 20d7bf8..69ec248 100644
--- a/mgmt/main.c
+++ b/mgmt/main.c
return "(unknown)";
}
-static int mgmt_connected(int mgmt_sk, uint16_t index, bool connected,
- struct mgmt_addr_info *ev, uint16_t len)
+static int mgmt_connected(int mgmt_sk, uint16_t index,
+ struct mgmt_ev_device_connected *ev,
+ uint16_t len)
{
- const char *ev_name = connected ? "connected" : "disconnected";
+ uint16_t eir_len;
+
+ if (len != sizeof(*ev)) {
+ fprintf(stderr,
+ "Invalid connected event length (%u bytes)\n", len);
+ return -EINVAL;
+ }
+
+ eir_len = bt_get_le16(&ev->eir_len);
+ if (len != sizeof(*ev) + eir_len) {
+ fprintf(stderr, "Invalid connected event length "
+ "(%u bytes, eir_len %u bytes)\n", len, eir_len);
+ return -EINVAL;
+ }
+ if (monitor) {
+ char addr[18];
+ ba2str(&ev->addr.bdaddr, addr);
+ printf("hci%u %s type %s connected eir_len %u\n", index, addr,
+ typestr(ev->addr.type), eir_len);
+ }
+
+ return 0;
+}
+
+static int mgmt_disconnected(int mgmt_sk, uint16_t index,
+ struct mgmt_addr_info *ev, uint16_t len)
+{
if (len != sizeof(*ev)) {
fprintf(stderr,
- "Invalid %s event length (%u bytes)\n", ev_name, len);
+ "Invalid disconnected event length (%u bytes)\n", len);
return -EINVAL;
}
if (monitor) {
char addr[18];
ba2str(&ev->bdaddr, addr);
- printf("hci%u %s type %s %s\n", index, addr,
- typestr(ev->type), ev_name);
+ printf("hci%u %s type %s disconnected\n", index, addr,
+ typestr(ev->type));
}
return 0;
case MGMT_EV_NEW_LINK_KEY:
return mgmt_new_link_key(mgmt_sk, index, data, len);
case MGMT_EV_DEVICE_CONNECTED:
- return mgmt_connected(mgmt_sk, index, true, data, len);
+ return mgmt_connected(mgmt_sk, index, data, len);
case MGMT_EV_DEVICE_DISCONNECTED:
- return mgmt_connected(mgmt_sk, index, false, data, len);
+ return mgmt_disconnected(mgmt_sk, index, data, len);
case MGMT_EV_CONNECT_FAILED:
return mgmt_conn_failed(mgmt_sk, index, data, len);
case MGMT_EV_AUTH_FAILED:
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 77d2421..0ebf533 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
conn = get_connection(dev, &evt->bdaddr);
conn->handle = btohs(evt->handle);
- btd_event_conn_complete(&dev->bdaddr, &evt->bdaddr);
+ btd_event_conn_complete(&dev->bdaddr, &evt->bdaddr, NULL, NULL);
if (conn->secmode3)
bonding_complete(dev, conn, 0);
conn = get_connection(dev, &evt->peer_bdaddr);
conn->handle = btohs(evt->handle);
- btd_event_conn_complete(&dev->bdaddr, &evt->peer_bdaddr);
+ btd_event_conn_complete(&dev->bdaddr, &evt->peer_bdaddr, NULL, NULL);
/* check if the remote version needs be requested */
ba2str(&dev->bdaddr, local_addr);
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 23dc552..470266b 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
#include "device.h"
#include "event.h"
#include "oob.h"
+#include "eir.h"
#define MGMT_BUF_SIZE 1024
static void mgmt_device_connected(int sk, uint16_t index, void *buf, size_t len)
{
- struct mgmt_addr_info *ev = buf;
+ struct mgmt_ev_device_connected *ev = buf;
+ struct eir_data eir_data;
struct controller_info *info;
+ uint16_t eir_len;
char addr[18];
if (len < sizeof(*ev)) {
return;
}
- ba2str(&ev->bdaddr, addr);
+ eir_len = bt_get_le16(&ev->eir_len);
+ if (len < sizeof(*ev) + eir_len) {
+ error("Too small device_connected event");
+ return;
+ }
+
+ ba2str(&ev->addr.bdaddr, addr);
DBG("hci%u device %s connected", index, addr);
info = &controllers[index];
- btd_event_conn_complete(&info->bdaddr, &ev->bdaddr);
+ memset(&eir_data, 0, sizeof(eir_data));
+ if (eir_len > 0)
+ eir_parse(&eir_data, ev->eir, eir_len);
+
+ btd_event_conn_complete(&info->bdaddr, &ev->addr.bdaddr,
+ eir_data.name, eir_data.dev_class);
}
static void mgmt_device_disconnected(int sk, uint16_t index, void *buf,
diff --git a/src/event.c b/src/event.c
index 6854990..d0e192b 100644
--- a/src/event.c
+++ b/src/event.c
return ret;
}
-void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer)
+void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer,
+ char *name, uint8_t *dev_class)
{
struct btd_adapter *adapter;
struct btd_device *device;
update_lastused(local, peer);
adapter_add_connection(adapter, device);
+
+ if (name != NULL)
+ btd_event_remote_name(local, peer, name);
}
void btd_event_conn_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status)
diff --git a/src/event.h b/src/event.h
index 708eeb9..57b7fd9 100644
--- a/src/event.h
+++ b/src/event.h
void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean legacy);
void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class);
void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name);
-void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer);
+void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer,
+ char *name, uint8_t *dev_class);
void btd_event_conn_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
void btd_event_disconn_complete(bdaddr_t *local, bdaddr_t *peer);
void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);