Following patches should get in if kernel fix for HCI_LE_ENABLE
gets upstream
[PATCH 1/2] Bluetooth: Do not allow LE connection if LE is not
enabled
Here we have 2 test cases on mgmt and l2cap level verifying that
LE connection will be rejected if LE host support is not enabled.
Also small update to error codes in mgmt-api has been added as now
Pair Device might return MGMT_RESULT_REJECT if user tries to make
connection on transport which is not enabled
Lukasz Rymanowski (3):
tools/mgmt-tester: Add test for LE pair reject on BREDR controller
tools/l2cap-tester: Add L2CAP LE Connection Reject test
doc/mgmt-api: Update error code for Pair Device
doc/mgmt-api.txt | 3 ++-
tools/l2cap-tester.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
tools/mgmt-tester.c | 26 ++++++++++++++++++++++++--
3 files changed, 69 insertions(+), 5 deletions(-)
--
1.8.4
Reject error code is used when given transport is not available.
E.g. User wants to do LE pair but LE support is not enabled. Similar
with BREDR
---
doc/mgmt-api.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index e1a5e69..51a8d3e 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -1023,7 +1023,8 @@ Pair Device Command
This command generates a Command Complete event on success
or failure.
- Possible errors: Connect Failed
+ Possible errors: Rejected
+ Connect Failed
Busy
Invalid Parameters
Not Powered
--
1.8.4
This test checks if kernel correctly rejects LE connection when host is
not configured to support LE.
---
tools/l2cap-tester.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index cf0fa38..7f03591 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -82,6 +82,9 @@ struct l2cap_data {
const void *pin;
uint8_t client_pin_len;
const void *client_pin;
+
+ bool addr_type_avail;
+ uint8_t addr_type;
};
static void mgmt_debug(const char *str, void *user_data)
@@ -441,6 +444,12 @@ static const struct l2cap_data le_client_connect_reject_test_1 = {
.expect_err = ECONNREFUSED,
};
+static const struct l2cap_data le_client_connect_reject_test_2 = {
+ .client_psm = 0x0080,
+ .addr_type_avail = true,
+ .addr_type = BDADDR_LE_PUBLIC,
+};
+
static const struct l2cap_data le_client_connect_nval_psm_test = {
.client_psm = 0x0080,
.expect_err = ECONNREFUSED,
@@ -943,6 +952,7 @@ failed:
static int create_l2cap_sock(struct test_data *data, uint16_t psm,
uint16_t cid, int sec_level)
{
+ const struct l2cap_data *l2data = data->test_data;
const uint8_t *master_bdaddr;
struct sockaddr_l2 addr;
int sk, err;
@@ -968,7 +978,10 @@ static int create_l2cap_sock(struct test_data *data, uint16_t psm,
addr.l2_psm = htobs(psm);
addr.l2_cid = htobs(cid);
bacpy(&addr.l2_bdaddr, (void *) master_bdaddr);
- if (data->hciemu_type == HCIEMU_TYPE_LE)
+
+ if (l2data && l2data->addr_type_avail)
+ addr.l2_bdaddr_type = l2data->addr_type;
+ else if (data->hciemu_type == HCIEMU_TYPE_LE)
addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
else
addr.l2_bdaddr_type = BDADDR_BREDR;
@@ -1003,6 +1016,7 @@ static int create_l2cap_sock(struct test_data *data, uint16_t psm,
static int connect_l2cap_sock(struct test_data *data, int sk, uint16_t psm,
uint16_t cid)
{
+ const struct l2cap_data *l2data = data->test_data;
const uint8_t *client_bdaddr;
struct sockaddr_l2 addr;
int err;
@@ -1018,7 +1032,10 @@ static int connect_l2cap_sock(struct test_data *data, int sk, uint16_t psm,
bacpy(&addr.l2_bdaddr, (void *) client_bdaddr);
addr.l2_psm = htobs(psm);
addr.l2_cid = htobs(cid);
- if (data->hciemu_type == HCIEMU_TYPE_LE)
+
+ if (l2data && l2data->addr_type_avail)
+ addr.l2_bdaddr_type = l2data->addr_type;
+ else if (data->hciemu_type == HCIEMU_TYPE_LE)
addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
else
addr.l2_bdaddr_type = BDADDR_BREDR;
@@ -1084,6 +1101,27 @@ static void test_connect(const void *test_data)
tester_print("Connect in progress");
}
+static void test_connect_reject(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct l2cap_data *l2data = data->test_data;
+ int sk;
+
+ sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level);
+ if (sk < 0) {
+ tester_test_failed();
+ return;
+ }
+
+ if (connect_l2cap_sock(data, sk, l2data->client_psm,
+ l2data->cid) < 0)
+ tester_test_passed();
+ else
+ tester_test_failed();
+
+ close(sk);
+}
+
static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
@@ -1396,6 +1434,9 @@ int main(int argc, char *argv[])
test_l2cap_le("L2CAP LE Client - Command Reject",
&le_client_connect_reject_test_1,
setup_powered_client, test_connect);
+ test_l2cap_bredr("L2CAP LE Client - Connection Reject",
+ &le_client_connect_reject_test_2,
+ setup_powered_client, test_connect_reject);
test_l2cap_le("L2CAP LE Client - Invalid PSM",
&le_client_connect_nval_psm_test,
setup_powered_client, test_connect);
--
1.8.4
With this test we make sure that on dual mode controllers, le pairing is
possible only when LE support is enabled on the HOST.
---
tools/mgmt-tester.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c
index 92351e4..9c986a3 100644
--- a/tools/mgmt-tester.c
+++ b/tools/mgmt-tester.c
@@ -406,6 +406,8 @@ struct generic_data {
bool client_enable_sc;
bool expect_sc_key;
bool force_power_off;
+ bool addr_type_avail;
+ uint8_t addr_type;
};
static const char dummy_data[] = { 0x00 };
@@ -2395,7 +2397,10 @@ static const void *pair_device_send_param_func(uint16_t *len)
static uint8_t param[8];
memcpy(param, hciemu_get_client_bdaddr(data->hciemu), 6);
- if (data->hciemu_type == HCIEMU_TYPE_LE)
+
+ if (test->addr_type_avail)
+ param[6] = test->addr_type;
+ else if (data->hciemu_type == HCIEMU_TYPE_LE)
param[6] = 0x01; /* Address type */
else
param[6] = 0x00; /* Address type */
@@ -2409,10 +2414,14 @@ static const void *pair_device_send_param_func(uint16_t *len)
static const void *pair_device_expect_param_func(uint16_t *len)
{
struct test_data *data = tester_get_data();
+ const struct generic_data *test = data->test_data;
static uint8_t param[7];
memcpy(param, hciemu_get_client_bdaddr(data->hciemu), 6);
- if (data->hciemu_type == HCIEMU_TYPE_LE)
+
+ if (test->addr_type_avail)
+ param[6] = test->addr_type;
+ else if (data->hciemu_type == HCIEMU_TYPE_LE)
param[6] = 0x01; /* Address type */
else
param[6] = 0x00; /* Address type */
@@ -2865,6 +2874,16 @@ static const struct generic_data pair_device_le_reject_test_1 = {
.reject_confirm = true,
};
+static const struct generic_data pair_device_le_reject_test_2 = {
+ .setup_settings = settings_powered_bondable,
+ .send_opcode = MGMT_OP_PAIR_DEVICE,
+ .send_func = pair_device_send_param_func,
+ .expect_status = MGMT_STATUS_REJECTED,
+ .expect_func = pair_device_expect_param_func,
+ .addr_type_avail = true,
+ .addr_type = BDADDR_LE_PUBLIC,
+};
+
static uint16_t settings_powered_sc_bondable[] = { MGMT_OP_SET_BONDABLE,
MGMT_OP_SET_SECURE_CONN,
MGMT_OP_SET_POWERED, 0 };
@@ -5132,6 +5151,9 @@ int main(int argc, char *argv[])
test_le("Pair Device - LE Reject 1",
&pair_device_le_reject_test_1,
NULL, test_command_generic);
+ test_bredrle("Pair Device - LE Reject 2",
+ &pair_device_le_reject_test_2,
+ NULL, test_command_generic);
test_le("Pair Device - LE SC Legacy 1",
&pair_device_le_sc_legacy_test_1,
NULL, test_command_generic);
--
1.8.4