diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2011-01-21 13:55:44 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2011-01-21 13:55:44 +0200 |
commit | 1e862b561c65fb0d6096cd93d2c9cfe11f0356bb (patch) | |
tree | f1aa8c938a017495e435c5521b78cb3108e3a764 | |
parent | cc0e50e3ab1a612ffb72b9021229f660d54f9388 (diff) | |
download | bluez-1e862b561c65fb0d6096cd93d2c9cfe11f0356bb.tar.gz |
mgmt: add support for get_connections command
-rw-r--r-- | doc/mgmt-api.txt | 12 | ||||
-rw-r--r-- | lib/mgmt.h | 10 | ||||
-rw-r--r-- | plugins/mgmtops.c | 66 |
3 files changed, 86 insertions, 2 deletions
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt index 00b2b37a9..613b7fca3 100644 --- a/doc/mgmt-api.txt +++ b/doc/mgmt-api.txt @@ -191,6 +191,18 @@ Disconnect Command Return Paramters: Controller_Index (2 Octets) Address (6 Octets) +Get Connections Command +======================= + + Command Code: 0x0010 + Command Parameters: Controller_Index (2 Octets) + Return Paramters: Controller_Index (2 Octets) + Connection_Count (2 Octets) + Address1 (6 Octets) + Address2 (6 Octets) + ... + + Read Tracing Buffer Size Command ================================ diff --git a/lib/mgmt.h b/lib/mgmt.h index 11811cd64..e9079fff7 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -139,6 +139,16 @@ struct mgmt_rp_disconnect { bdaddr_t bdaddr; } __packed; +#define MGMT_OP_GET_CONNECTIONS 0x0010 +struct mgmt_cp_get_connections { + uint16_t index; +} __packed; +struct mgmt_rp_get_connections { + uint16_t index; + uint16_t conn_count; + bdaddr_t conn[0]; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { uint16_t opcode; diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c index d80f29d52..ed82f8b53 100644 --- a/plugins/mgmtops.c +++ b/plugins/mgmtops.c @@ -66,6 +66,7 @@ static struct controller_info { gboolean discoverable; gboolean pairable; uint8_t sec_mode; + GSList *connections; } *controllers = NULL; static int mgmt_sock = -1; @@ -128,6 +129,23 @@ static void read_info(int sk, uint16_t index) strerror(errno), errno); } +static void get_connections(int sk, uint16_t index) +{ + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_get_connections)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_get_connections *cp = (void *) &buf[sizeof(*hdr)]; + + memset(buf, 0, sizeof(buf)); + hdr->opcode = htobs(MGMT_OP_GET_CONNECTIONS); + hdr->len = htobs(sizeof(*cp)); + + cp->index = htobs(index); + + if (write(sk, buf, sizeof(buf)) < 0) + error("Unable to send get_connections command: %s (%d)", + strerror(errno), errno); +} + static void mgmt_index_added(int sk, void *buf, size_t len) { struct mgmt_ev_index_added *ev = buf; @@ -601,7 +619,7 @@ static void read_index_list_complete(int sk, void *buf, size_t len) index = btohs(bt_get_unaligned(&rp->index[i])); add_controller(index); - read_info(sk, index); + get_connections(sk, index); clear_uuids(index); } } @@ -824,6 +842,41 @@ static void disconnect_complete(int sk, void *buf, size_t len) btd_event_disconn_complete(&info->bdaddr, &rp->bdaddr); } +static void get_connections_complete(int sk, void *buf, size_t len) +{ + struct mgmt_rp_get_connections *rp = buf; + struct controller_info *info; + uint16_t index; + int i; + + if (len < sizeof(*rp)) { + error("Too small get_connections complete event"); + return; + } + + if (len < (sizeof(*rp) + (rp->conn_count * sizeof(bdaddr_t)))) { + error("Too small get_connections complete event"); + return; + } + + index = btohs(bt_get_unaligned(&rp->index)); + + if (index > max_index) { + error("Unexpected index %u in get_connections complete", + index); + return; + } + + info = &controllers[index]; + + for (i = 0; i < rp->conn_count; i++) { + bdaddr_t *bdaddr = g_memdup(&rp->conn[i], sizeof(bdaddr_t)); + info->connections = g_slist_append(info->connections, bdaddr); + } + + read_info(sk, index); +} + static void mgmt_cmd_complete(int sk, void *buf, size_t len) { struct mgmt_ev_cmd_complete *ev = buf; @@ -882,6 +935,9 @@ static void mgmt_cmd_complete(int sk, void *buf, size_t len) DBG("disconnect complete"); disconnect_complete(sk, ev->data, len - sizeof(*ev)); break; + case MGMT_OP_GET_CONNECTIONS: + get_connections_complete(sk, ev->data, len - sizeof(*ev)); + break; default: error("Unknown command complete for opcode %u", opcode); break; @@ -1204,8 +1260,14 @@ static int mgmt_unblock_device(int index, bdaddr_t *bdaddr) static int mgmt_get_conn_list(int index, GSList **conns) { + struct controller_info *info = &controllers[index]; + DBG("index %d", index); - return -ENOSYS; + + *conns = info->connections; + info->connections = NULL; + + return 0; } static int mgmt_read_local_version(int index, struct hci_version *ver) |