---
lib/mgmt.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/mgmt.h b/lib/mgmt.h
index ab45735..bab0f99 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -365,6 +365,17 @@ struct mgmt_cp_load_irks {
struct mgmt_irk_info irks[0];
} __packed;
+#define MGMT_OP_GET_CONN_INFO 0x0031
+struct mgmt_cp_get_conn_info {
+ struct mgmt_addr_info addr;
+} __packed;
+struct mgmt_rp_get_conn_info {
+ struct mgmt_addr_info addr;
+ int8_t rssi;
+ int8_t tx_power;
+ int8_t max_tx_power;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
@@ -570,6 +581,7 @@ static const char *mgmt_op[] = {
"Set Debug Keys",
"Set Privacy",
"Load Identity Resolving Keys",
+ "Get Connection Information",
};
static const char *mgmt_ev[] = {
--
1.9.3
Hi,
On Monday 19 of May 2014 08:23:08 Johan Hedberg wrote:
> Hi,
>
> On Fri, May 16, 2014, Andrzej Kaczmarek wrote:
> > ---
> > lib/mgmt.h | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
>
> I've applied the first two patches from this set for the conn-info
> support.
>
> Johan
Patches 3 and 4 are now also upstream, thanks.
--
Best regards,
Szymon Janc
Hi,
On Fri, May 16, 2014, Andrzej Kaczmarek wrote:
> ---
> lib/mgmt.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
I've applied the first two patches from this set for the conn-info
support.
Johan
---
android/gatt.c | 45 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 9 deletions(-)
diff --git a/android/gatt.c b/android/gatt.c
index 9d90f3a..a01257f 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -3194,11 +3194,35 @@ failed:
HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION, status);
}
+static void send_client_remote_rssi_notify(int32_t client_if,
+ const bdaddr_t *addr,
+ int32_t rssi, int32_t status)
+{
+ struct hal_ev_gatt_client_read_remote_rssi ev;
+
+ ev.client_if = client_if;
+ bdaddr2android(addr, &ev.address);
+ ev.rssi = rssi;
+ ev.status = status;
+
+ ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT,
+ HAL_EV_GATT_CLIENT_READ_REMOTE_RSSI, sizeof(ev), &ev);
+}
+
+static void read_remote_rssi_cb(uint8_t status, const bdaddr_t *addr,
+ int8_t rssi, void *user_data)
+{
+ int32_t client_if = PTR_TO_INT(user_data);
+ int32_t gatt_status = status ? GATT_FAILURE : GATT_SUCCESS;
+
+ send_client_remote_rssi_notify(client_if, addr, rssi, gatt_status);
+}
+
static void handle_client_read_remote_rssi(const void *buf, uint16_t len)
{
const struct hal_cmd_gatt_client_read_remote_rssi *cmd = buf;
- struct hal_ev_gatt_client_read_remote_rssi ev;
uint8_t status;
+ bdaddr_t bdaddr;
DBG("");
@@ -3207,20 +3231,23 @@ static void handle_client_read_remote_rssi(const void *buf, uint16_t len)
goto failed;
}
- /* TODO fake RSSI until kernel support is added */
- ev.client_if = cmd->client_if;
- memcpy(ev.address, cmd->bdaddr, sizeof(ev.address));
- ev.status = HAL_STATUS_SUCCESS;
- ev.rssi = -50 - (rand() % 40);
-
- ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT,
- HAL_EV_GATT_CLIENT_READ_REMOTE_RSSI, sizeof(ev), &ev);
+ android2bdaddr(cmd->bdaddr, &bdaddr);
+ if (!bt_read_device_rssi(&bdaddr, read_remote_rssi_cb,
+ INT_TO_PTR(cmd->client_if))) {
+ error("gatt: Could not read RSSI");
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
status = HAL_STATUS_SUCCESS;
failed:
ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI, status);
+
+ if (status != HAL_STATUS_SUCCESS)
+ send_client_remote_rssi_notify(cmd->client_if, &bdaddr, 0,
+ GATT_FAILURE);
}
static void handle_client_get_device_type(const void *buf, uint16_t len)
--
1.9.3
---
android/bluetooth.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++
android/bluetooth.h | 5 +++++
2 files changed, 61 insertions(+)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 1e760d4..e1dc965 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -3033,6 +3033,62 @@ bool bt_le_discovery_start(bt_le_device_found cb)
return false;
}
+struct read_rssi_user_data {
+ bt_read_device_rssi_done cb;
+ void *user_data;
+};
+
+static void read_device_rssi_cb(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_get_conn_info *rp = param;
+ struct read_rssi_user_data *data = user_data;
+
+ DBG("");
+
+ if (status)
+ error("Failed to get conn info: %s (0x%02x))",
+ mgmt_errstr(status), status);
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of get conn info response");
+ return;
+ }
+
+ data->cb(status, &rp->addr.bdaddr, rp->rssi, data->user_data);
+}
+
+bool bt_read_device_rssi(const bdaddr_t *addr, bt_read_device_rssi_done cb,
+ void *user_data)
+{
+ struct device *dev;
+ struct read_rssi_user_data *data;
+ struct mgmt_cp_get_conn_info cp;
+
+ dev = find_device(addr);
+ if (!dev)
+ return false;
+
+ memcpy(&cp.addr.bdaddr, addr, sizeof(cp.addr.bdaddr));
+ cp.addr.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
+
+ data = new0(struct read_rssi_user_data, 1);
+ if (!data)
+ return false;
+
+ data->cb = cb;
+ data->user_data = user_data;
+
+ if (!mgmt_send(mgmt_if, MGMT_OP_GET_CONN_INFO, adapter.index,
+ sizeof(cp), &cp, read_device_rssi_cb, data, free)) {
+ free(data);
+ error("Failed to get conn info");
+ return false;
+ }
+
+ return true;
+}
+
static uint8_t set_adapter_scan_mode(const void *buf, uint16_t len)
{
const uint8_t *mode = buf;
diff --git a/android/bluetooth.h b/android/bluetooth.h
index 3eef7a4..6a3e766 100644
--- a/android/bluetooth.h
+++ b/android/bluetooth.h
@@ -50,3 +50,8 @@ bool bt_le_set_advertising(bool advertising, bt_le_set_advertising_done cb,
uint8_t bt_get_device_android_type(const bdaddr_t *addr);
const char *bt_get_adapter_name(void);
bool bt_device_is_bonded(const bdaddr_t *bdaddr);
+
+typedef void (*bt_read_device_rssi_done)(uint8_t status, const bdaddr_t *addr,
+ int8_t rssi, void *user_data);
+bool bt_read_device_rssi(const bdaddr_t *addr, bt_read_device_rssi_done cb,
+ void *user_data);
--
1.9.3
From: Lukasz Rymanowski <[email protected]>
---
tools/btmgmt.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 48d42a3..0618de1 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -2137,6 +2137,94 @@ static void cmd_debug_keys(struct mgmt *mgmt, uint16_t index,
cmd_setting(mgmt, index, MGMT_OP_SET_DEBUG_KEYS, argc, argv);
}
+static void conn_info_rsp(uint8_t status, uint16_t len, const void *param,
+ void *user_data)
+{
+ const struct mgmt_rp_get_conn_info *rp = param; char addr[18];
+
+ if (len == 0 && status != 0) {
+ fprintf(stderr, "Get Conn Info failed, status 0x%02x (%s)\n",
+ status, mgmt_errstr(status));
+ goto done;
+ }
+
+ if (len < sizeof(*rp)) {
+ fprintf(stderr, "Unexpected Get Conn Info len %u\n", len);
+ goto done;
+ }
+
+ ba2str(&rp->addr.bdaddr, addr);
+
+ if (status != 0) {
+ fprintf(stderr, "Get Conn Info for %s (%s) failed. status 0x%02x (%s)\n",
+ addr, typestr(rp->addr.type),
+ status, mgmt_errstr(status));
+ goto done;
+ }
+
+ printf("Connection Information for %s (%s)\n",
+ addr, typestr(rp->addr.type));
+ printf("\tRSSI %d\n\tTX power %d\n\tmaximum TX power %d\n",
+ rp->rssi, rp->tx_power, rp->max_tx_power);
+
+done:
+ mainloop_quit();
+}
+
+static void conn_info_usage(void)
+{
+ printf("Usage: btmgmt conn-info [-t type] <remote address>\n");
+}
+
+static struct option conn_info_options[] = {
+ { "help", 0, 0, 'h' },
+ { "type", 1, 0, 't' },
+ { 0, 0, 0, 0 }
+};
+
+static void cmd_conn_info(struct mgmt *mgmt, uint16_t index,
+ int argc, char **argv)
+{
+ struct mgmt_cp_get_conn_info cp;
+ uint8_t type = BDADDR_BREDR;
+ int opt;
+
+ while ((opt = getopt_long(argc, argv, "+t:h", conn_info_options,
+ NULL)) != -1) {
+ switch (opt) {
+ case 't':
+ type = strtol(optarg, NULL, 0);
+ break;
+ case 'h':
+ default:
+ conn_info_usage();
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ optind = 0;
+
+ if (argc < 1) {
+ conn_info_usage();
+ exit(EXIT_FAILURE);
+ }
+
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ memset(&cp, 0, sizeof(cp));
+ str2ba(argv[0], &cp.addr.bdaddr);
+ cp.addr.type = type;
+
+ if (mgmt_send(mgmt, MGMT_OP_GET_CONN_INFO, index, sizeof(cp), &cp,
+ conn_info_rsp, NULL, NULL) == 0) {
+ fprintf(stderr, "Unable to send get_conn_info cmd\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
static struct {
char *cmd;
void (*func)(struct mgmt *mgmt, uint16_t index, int argc, char **argv);
@@ -2179,6 +2267,7 @@ static struct {
{ "did", cmd_did, "Set Device ID" },
{ "static-addr",cmd_static_addr,"Set static address" },
{ "debug-keys", cmd_debug_keys, "Toogle debug keys" },
+ { "conn-info", cmd_conn_info, "Get connection information" },
{ }
};
--
1.9.3