2015-07-17 20:51:35

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH v2 1/6] tools/mgmt-tester: Add RPA Add Device test case

This test verify if kernel correctly responds with error to
Add Device command with Resolvable Private Address.
---
tools/mgmt-tester.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c
index 46b088c..9b71156 100644
--- a/tools/mgmt-tester.c
+++ b/tools/mgmt-tester.c
@@ -3665,6 +3665,24 @@ static const struct generic_data add_device_fail_3 = {
.expect_status = MGMT_STATUS_INVALID_PARAMS,
};

+static const uint8_t add_device_nval_4[] = {
+ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
+ 0x02,
+ 0x02,
+};
+static const uint8_t add_device_rsp_4[] = {
+ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
+ 0x02,
+};
+static const struct generic_data add_device_fail_4 = {
+ .send_opcode = MGMT_OP_ADD_DEVICE,
+ .send_param = add_device_nval_4,
+ .send_len = sizeof(add_device_nval_4),
+ .expect_param = add_device_rsp_4,
+ .expect_len = sizeof(add_device_rsp_4),
+ .expect_status = MGMT_STATUS_INVALID_PARAMS,
+};
+
static const uint8_t add_device_success_param_1[] = {
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
0x00,
@@ -6696,6 +6714,9 @@ int main(int argc, char *argv[])
test_bredrle("Add Device - Invalid Params 3",
&add_device_fail_3,
NULL, test_command_generic);
+ test_bredrle("Add Device - Invalid Params 4",
+ &add_device_fail_4,
+ NULL, test_command_generic);
test_bredrle("Add Device - Success 1",
&add_device_success_1,
NULL, test_command_generic);
--
2.1.4



2015-07-17 20:51:40

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH v2 6/6] tools/l2cap-tester: add close socket test

This patch adds test that checks folowing:
1. Try to connect to existing remote BLE device using socket.
2. Internally in kernel this adds this device to whitelist and start scan.
3. At this moment remote device advertises just once.
4. This causes kernel to stop scan, and send connect request.
5. Call close() on socket, this should cause le_conn_canel request
to controller.
---
tools/l2cap-tester.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 104 insertions(+), 3 deletions(-)

diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index beaec8a..d46fb90 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -88,6 +88,7 @@ struct l2cap_data {
uint8_t addr_type;

uint8_t *client_bdaddr;
+ bool server_not_advertising;
};

static void mgmt_debug(const char *str, void *user_data)
@@ -459,6 +460,11 @@ static const struct l2cap_data le_client_close_socket_test_1 = {
.client_bdaddr = nonexisting_bdaddr,
};

+static const struct l2cap_data le_client_close_socket_test_2 = {
+ .client_psm = 0x0080,
+ .server_not_advertising = true,
+};
+
static const struct l2cap_data le_client_connect_nval_psm_test = {
.client_psm = 0x0080,
.expect_err = ECONNREFUSED,
@@ -543,6 +549,7 @@ static void setup_powered_client_callback(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
struct test_data *data = tester_get_data();
+ const struct l2cap_data *l2data = data->test_data;
struct bthost *bthost;

if (status != MGMT_STATUS_SUCCESS) {
@@ -554,10 +561,15 @@ static void setup_powered_client_callback(uint8_t status, uint16_t length,

bthost = hciemu_client_get_host(data->hciemu);
bthost_set_cmd_complete_cb(bthost, client_cmd_complete, user_data);
- if (data->hciemu_type == HCIEMU_TYPE_LE)
- bthost_set_adv_enable(bthost, 0x01);
- else
+
+ if (data->hciemu_type == HCIEMU_TYPE_LE) {
+ if (!l2data || !l2data->server_not_advertising)
+ bthost_set_adv_enable(bthost, 0x01);
+ else
+ tester_setup_complete();
+ } else {
bthost_write_scan_enable(bthost, 0x03);
+ }
}

static void setup_powered_server_callback(uint8_t status, uint16_t length,
@@ -1231,6 +1243,90 @@ static void test_close_socket_1(const void *test_data)
tester_print("Connect in progress");
}

+static gboolean test_close_socket_2_part_3(gpointer arg)
+{
+ struct test_data *data = tester_get_data();
+ int sk = data->sk;
+ int err;
+
+ /* Scan should be already over, we're trying to create connection */
+ if (hciemu_is_master_le_scan_enabled(data->hciemu)) {
+ tester_print("Error - should no longer scan");
+ tester_test_failed();
+ return FALSE;
+ }
+
+ /* Calling close() should eventually cause CMD_LE_CREATE_CONN_CANCEL */
+ err = close(sk);
+ if (err < 0) {
+ tester_print("Error when closing socket");
+ tester_test_failed();
+ return FALSE;
+ }
+
+ /* CMD_LE_CREATE_CONN_CANCEL will trigger test pass. */
+ return FALSE;
+}
+
+static gboolean test_close_socket_2_part_2(gpointer arg)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+ /* Make sure CMD_LE_CREATE_CONN will not immediately result in
+ * BT_HCI_EVT_CONN_COMPLETE.
+ */
+ hciemu_set_client_le_noresp_conn_request(data->hciemu, true);
+
+ /* Advertise once. After that, kernel should stop scanning, and trigger
+ * BT_HCI_CMD_LE_CREATE_CONN_CANCEL.
+ */
+ bthost_set_adv_enable(bthost, 0x01);
+ bthost_set_adv_enable(bthost, 0x00);
+}
+
+static void test_close_socket_2_router(uint16_t opcode, const void *param,
+ uint8_t length, void *user_data)
+{
+ /* tester_print("HCI Command 0x%04x length %u", opcode, length); */
+
+ if (opcode == BT_HCI_CMD_LE_SET_SCAN_ENABLE) {
+ const struct bt_hci_cmd_le_set_scan_enable *scan_params = param;
+
+ if (scan_params->enable == true)
+ g_idle_add(test_close_socket_2_part_2, NULL);
+ else
+ g_idle_add(test_close_socket_2_part_3, NULL);
+ } else if (opcode == BT_HCI_CMD_LE_CREATE_CONN_CANCEL)
+ tester_test_passed();
+}
+
+static void test_close_socket_2(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct l2cap_data *l2data = data->test_data;
+ int sk;
+
+ hciemu_add_master_post_command_hook(data->hciemu,
+ test_close_socket_2_router, data);
+
+ sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level);
+ if (sk < 0) {
+ tester_test_failed();
+ return;
+ }
+
+ data->sk = sk;
+ if (connect_l2cap_sock(data, sk, l2data->client_psm,
+ l2data->cid) < 0) {
+ close(sk);
+ tester_test_failed();
+ return;
+ }
+
+ tester_print("Connect in progress");
+}
+
static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
@@ -1552,6 +1648,11 @@ int main(int argc, char *argv[])
setup_powered_client,
test_close_socket_1);

+ test_l2cap_le("L2CAP LE Client - Close socket 2",
+ &le_client_close_socket_test_2,
+ setup_powered_client,
+ test_close_socket_2);
+
test_l2cap_le("L2CAP LE Client - Invalid PSM",
&le_client_connect_nval_psm_test,
setup_powered_client, test_connect);
--
2.1.4


2015-07-17 20:51:39

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH v2 5/6] emulator: add BT_HCI_CMD_LE_CREATE_CONN_CANCEL handling

This patch adds handling of BT_HCI_CMD_LE_CREATE_CONN_CANCEL command.

If btdev_set_le_noresp_conn_request is called on btdev, other devices will
stuck on BT_HCI_CMD_LE_CREATE_CONN request to this device, by not sending
bt_hci_evt_le_conn_complete event back. Thanks to that,
BT_HCI_CMD_LE_CREATE_CONN_CANCEL can be triggered to cancel connect
attempt.
---
emulator/btdev.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
emulator/btdev.h | 2 ++
emulator/hciemu.c | 8 ++++++++
emulator/hciemu.h | 3 +++
4 files changed, 58 insertions(+)

diff --git a/emulator/btdev.c b/emulator/btdev.c
index 526f97a..8ea0b93 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -145,6 +145,11 @@ struct btdev {
uint16_t sync_train_interval;
uint32_t sync_train_timeout;
uint8_t sync_train_service_data;
+
+ bool le_noresp_conn_request;
+ bool pending_le_conn;
+ uint8_t pending_le_conn_addr[6];
+ uint8_t pending_le_conn_addr_type;
};

struct inquiry_data {
@@ -665,6 +670,11 @@ bool btdev_is_le_scan_enabled(struct btdev *btdev)
return btdev->le_scan_enable;
}

+void btdev_set_le_noresp_conn_request(struct btdev *btdev, bool value)
+{
+ btdev->le_noresp_conn_request = value;
+}
+
static bool use_ssp(struct btdev *btdev1, struct btdev *btdev2)
{
if (btdev1->auth_enable || btdev2->auth_enable)
@@ -1125,6 +1135,9 @@ static void le_conn_complete(struct btdev *btdev,
cc->handle = cpu_to_le16(42);
}

+ if (btdev->pending_le_conn)
+ btdev->pending_le_conn = false;
+
cc->status = status;
cc->peer_addr_type = bdaddr_type;
memcpy(cc->peer_addr, bdaddr, 6);
@@ -1174,6 +1187,13 @@ static void le_conn_request(struct btdev *btdev, const uint8_t *bdaddr,
{
struct btdev *remote = find_btdev_by_bdaddr_type(bdaddr, bdaddr_type);

+ if (remote && remote->le_noresp_conn_request) {
+ btdev->pending_le_conn = true;
+ memcpy(btdev->pending_le_conn_addr, bdaddr, 6);
+ btdev->pending_le_conn_addr_type = bdaddr_type;
+ return;
+ }
+
if (remote && adv_connectable(remote) && adv_match(btdev, remote) &&
remote->le_adv_own_addr == bdaddr_type)
le_conn_complete(btdev, bdaddr, bdaddr_type, 0);
@@ -1182,6 +1202,14 @@ static void le_conn_request(struct btdev *btdev, const uint8_t *bdaddr,
BT_HCI_ERR_CONN_FAILED_TO_ESTABLISH);
}

+static void le_conn_cancel_request(struct btdev *btdev)
+{
+ if (btdev->pending_le_conn)
+ le_conn_complete(btdev, btdev->pending_le_conn_addr,
+ btdev->pending_le_conn_addr_type,
+ BT_HCI_ERR_UNKNOWN_CONN_ID);
+}
+
static void conn_request(struct btdev *btdev, const uint8_t *bdaddr)
{
struct btdev *remote = find_btdev_by_bdaddr(bdaddr);
@@ -2954,6 +2982,17 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
cmd_status(btdev, BT_HCI_ERR_SUCCESS, opcode);
break;

+ case BT_HCI_CMD_LE_CREATE_CONN_CANCEL:
+ if (btdev->type == BTDEV_TYPE_BREDR)
+ goto unsupported;
+
+ if (btdev->pending_le_conn)
+ cmd_status(btdev, BT_HCI_ERR_SUCCESS, opcode);
+ else
+ cmd_status(btdev, BT_HCI_ERR_COMMAND_DISALLOWED,
+ opcode);
+ break;
+
case BT_HCI_CMD_LE_READ_WHITE_LIST_SIZE:
if (btdev->type == BTDEV_TYPE_BREDR)
goto unsupported;
@@ -3322,6 +3361,12 @@ static void default_cmd_completion(struct btdev *btdev, uint16_t opcode,
le_conn_request(btdev, lecc->peer_addr, lecc->peer_addr_type);
break;

+ case BT_HCI_CMD_LE_CREATE_CONN_CANCEL:
+ if (btdev->type == BTDEV_TYPE_BREDR)
+ return;
+ le_conn_cancel_request(btdev);
+ break;
+
case BT_HCI_CMD_LE_CONN_UPDATE:
if (btdev->type == BTDEV_TYPE_BREDR)
return;
diff --git a/emulator/btdev.h b/emulator/btdev.h
index 8b116e4..e0e9f15 100644
--- a/emulator/btdev.h
+++ b/emulator/btdev.h
@@ -82,6 +82,8 @@ uint8_t *btdev_get_features(struct btdev *btdev);

bool btdev_is_le_scan_enabled(struct btdev *btdev);

+void btdev_set_le_noresp_conn_request(struct btdev *btdev, bool value);
+
void btdev_set_command_handler(struct btdev *btdev, btdev_command_func handler,
void *user_data);

diff --git a/emulator/hciemu.c b/emulator/hciemu.c
index c04aa6d..2e57b1f 100644
--- a/emulator/hciemu.c
+++ b/emulator/hciemu.c
@@ -435,6 +435,14 @@ const bool hciemu_is_master_le_scan_enabled(struct hciemu *hciemu)
return btdev_is_le_scan_enabled(hciemu->master_dev);
}

+void hciemu_set_client_le_noresp_conn_request(struct hciemu *hciemu, bool value)
+{
+ if (!hciemu || !hciemu->client_dev)
+ return;
+
+ btdev_set_le_noresp_conn_request(hciemu->client_dev, value);
+}
+
bool hciemu_add_master_post_command_hook(struct hciemu *hciemu,
hciemu_command_func_t function, void *user_data)
{
diff --git a/emulator/hciemu.h b/emulator/hciemu.h
index a526d8c..3c2d098 100644
--- a/emulator/hciemu.h
+++ b/emulator/hciemu.h
@@ -55,6 +55,9 @@ const uint8_t *hciemu_get_client_bdaddr(struct hciemu *hciemu);

const bool hciemu_is_master_le_scan_enabled(struct hciemu *hciemu);

+void hciemu_set_client_le_noresp_conn_request(struct hciemu *hciemu,
+ bool value);
+
typedef void (*hciemu_command_func_t)(uint16_t opcode, const void *data,
uint8_t len, void *user_data);

--
2.1.4


2015-07-17 20:51:38

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH v2 4/6] tools/l2cap-tester: add close socket test

This patch adds test that checks folowing:
1. Try to connect to non-existing remote BLE device using socket.
2. Internally in kernel this adds this device to whitelist and enable scan.
3. At this moment test would try to close socket.
4. That should cause scan to be stopped.
---
tools/l2cap-tester.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 1 deletion(-)

diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 2b89045..beaec8a 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -53,6 +53,7 @@ struct test_data {
uint16_t handle;
uint16_t scid;
uint16_t dcid;
+ int sk;
};

struct l2cap_data {
@@ -85,6 +86,8 @@ struct l2cap_data {

bool addr_type_avail;
uint8_t addr_type;
+
+ uint8_t *client_bdaddr;
};

static void mgmt_debug(const char *str, void *user_data)
@@ -450,6 +453,12 @@ static const struct l2cap_data le_client_connect_reject_test_2 = {
.addr_type = BDADDR_LE_PUBLIC,
};

+static uint8_t nonexisting_bdaddr[] = {0x00, 0xAA, 0x01, 0x02, 0x00, 0x00};
+static const struct l2cap_data le_client_close_socket_test_1 = {
+ .client_psm = 0x0080,
+ .client_bdaddr = nonexisting_bdaddr,
+};
+
static const struct l2cap_data le_client_connect_nval_psm_test = {
.client_psm = 0x0080,
.expect_err = ECONNREFUSED,
@@ -1021,7 +1030,11 @@ static int connect_l2cap_sock(struct test_data *data, int sk, uint16_t psm,
struct sockaddr_l2 addr;
int err;

- client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
+ if (l2data->client_bdaddr != NULL)
+ client_bdaddr = l2data->client_bdaddr;
+ else
+ client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
+
if (!client_bdaddr) {
tester_warn("No client bdaddr");
return -ENODEV;
@@ -1122,6 +1135,102 @@ static void test_connect_reject(const void *test_data)
close(sk);
}

+static gboolean test_close_socket_1_part_3(gpointer arg)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Checking wether scan was properly stopped...");
+
+ if (data->sk != -1) {
+ tester_print("Error - scan was not enabled yet");
+ tester_test_failed();
+ return FALSE;
+ }
+
+ if (hciemu_is_master_le_scan_enabled(data->hciemu)) {
+ tester_print("Delayed check wether scann is off failed");
+ tester_test_failed();
+ return FALSE;
+ }
+
+ tester_test_passed();
+ return FALSE;
+}
+
+static gboolean test_close_socket_1_part_2(gpointer args)
+{
+ struct test_data *data = tester_get_data();
+ const struct l2cap_data *l2data = data->test_data;
+ GIOChannel *io;
+ int sk = data->sk;
+
+ tester_print("Will close socket during scan phase...");
+
+ /* We tried to conect to LE device that is not advertising. It was added
+ * to kernel whitelist, and scan was started. We should be still
+ * scanning.
+ */
+ if (!hciemu_is_master_le_scan_enabled(data->hciemu)) {
+ tester_print("Error - should be still scanning");
+ tester_test_failed();
+ return FALSE;
+ }
+
+ /* Calling close() should remove device from whitelist, and stop
+ * the scan.
+ */
+ if (close(sk) < 0) {
+ tester_print("Error when closing socket");
+ tester_test_failed();
+ return FALSE;
+ }
+
+ data->sk = -1;
+ /* tester_test_passed will be called when scan is stopped. */
+ return FALSE;
+}
+
+static void test_close_socket_1_router(uint16_t opcode, const void *param,
+ uint8_t length, void *user_data)
+{
+ /* tester_print("HCI Command 0x%04x length %u", opcode, length); */
+
+ if (opcode == BT_HCI_CMD_LE_SET_SCAN_ENABLE) {
+ const struct bt_hci_cmd_le_set_scan_enable *scan_params = param;
+
+ if (scan_params->enable == true)
+ g_idle_add(test_close_socket_1_part_2, NULL);
+ else
+ g_idle_add(test_close_socket_1_part_3, NULL);
+ }
+}
+
+static void test_close_socket_1(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct l2cap_data *l2data = data->test_data;
+ int sk;
+
+ hciemu_add_master_post_command_hook(data->hciemu,
+ test_close_socket_1_router, data);
+
+ sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level);
+ if (sk < 0) {
+ tester_test_failed();
+ return;
+ }
+
+ data->sk = sk;
+ if (connect_l2cap_sock(data, sk, l2data->client_psm,
+ l2data->cid) < 0) {
+ close(sk);
+ tester_test_failed();
+ return;
+ }
+
+ tester_print("Connect in progress");
+}
+
static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
@@ -1437,6 +1546,12 @@ int main(int argc, char *argv[])
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 - Close socket 1",
+ &le_client_close_socket_test_1,
+ setup_powered_client,
+ test_close_socket_1);
+
test_l2cap_le("L2CAP LE Client - Invalid PSM",
&le_client_connect_nval_psm_test,
setup_powered_client, test_connect);
--
2.1.4


2015-07-17 20:51:37

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH v2 3/6] emulator: add support for checking le scan state

---
emulator/btdev.c | 5 +++++
emulator/btdev.h | 2 ++
emulator/hciemu.c | 8 ++++++++
emulator/hciemu.h | 2 ++
4 files changed, 17 insertions(+)

diff --git a/emulator/btdev.c b/emulator/btdev.c
index cd211ef..526f97a 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -660,6 +660,11 @@ uint8_t *btdev_get_features(struct btdev *btdev)
return btdev->features;
}

+bool btdev_is_le_scan_enabled(struct btdev *btdev)
+{
+ return btdev->le_scan_enable;
+}
+
static bool use_ssp(struct btdev *btdev1, struct btdev *btdev2)
{
if (btdev1->auth_enable || btdev2->auth_enable)
diff --git a/emulator/btdev.h b/emulator/btdev.h
index 4b724a7..8b116e4 100644
--- a/emulator/btdev.h
+++ b/emulator/btdev.h
@@ -80,6 +80,8 @@ void btdev_destroy(struct btdev *btdev);
const uint8_t *btdev_get_bdaddr(struct btdev *btdev);
uint8_t *btdev_get_features(struct btdev *btdev);

+bool btdev_is_le_scan_enabled(struct btdev *btdev);
+
void btdev_set_command_handler(struct btdev *btdev, btdev_command_func handler,
void *user_data);

diff --git a/emulator/hciemu.c b/emulator/hciemu.c
index 4881a24..c04aa6d 100644
--- a/emulator/hciemu.c
+++ b/emulator/hciemu.c
@@ -427,6 +427,14 @@ const uint8_t *hciemu_get_client_bdaddr(struct hciemu *hciemu)
return btdev_get_bdaddr(hciemu->client_dev);
}

+const bool hciemu_is_master_le_scan_enabled(struct hciemu *hciemu)
+{
+ if (!hciemu || !hciemu->master_dev)
+ return NULL;
+
+ return btdev_is_le_scan_enabled(hciemu->master_dev);
+}
+
bool hciemu_add_master_post_command_hook(struct hciemu *hciemu,
hciemu_command_func_t function, void *user_data)
{
diff --git a/emulator/hciemu.h b/emulator/hciemu.h
index 41ca3fc..a526d8c 100644
--- a/emulator/hciemu.h
+++ b/emulator/hciemu.h
@@ -53,6 +53,8 @@ uint8_t *hciemu_get_features(struct hciemu *hciemu);
const uint8_t *hciemu_get_master_bdaddr(struct hciemu *hciemu);
const uint8_t *hciemu_get_client_bdaddr(struct hciemu *hciemu);

+const bool hciemu_is_master_le_scan_enabled(struct hciemu *hciemu);
+
typedef void (*hciemu_command_func_t)(uint16_t opcode, const void *data,
uint8_t len, void *user_data);

--
2.1.4


2015-07-17 20:51:36

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH v2 2/6] tools/mgmt-tester: Add RPA Remove Device test case

This test verify if kernel correctly responds with error to
Remove Device command with Resolvable Private Address.
---
tools/mgmt-tester.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c
index 9b71156..9ace20a 100644
--- a/tools/mgmt-tester.c
+++ b/tools/mgmt-tester.c
@@ -3797,6 +3797,19 @@ static const struct generic_data remove_device_fail_2 = {
.expect_status = MGMT_STATUS_INVALID_PARAMS,
};

+static const uint8_t remove_device_param_3[] = {
+ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
+ 0x02,
+};
+static const struct generic_data remove_device_fail_3 = {
+ .send_opcode = MGMT_OP_REMOVE_DEVICE,
+ .send_param = remove_device_param_3,
+ .send_len = sizeof(remove_device_param_3),
+ .expect_param = remove_device_param_3,
+ .expect_len = sizeof(remove_device_param_3),
+ .expect_status = MGMT_STATUS_INVALID_PARAMS,
+};
+
static const struct generic_data remove_device_success_1 = {
.send_opcode = MGMT_OP_REMOVE_DEVICE,
.send_param = remove_device_param_1,
@@ -6739,6 +6752,9 @@ int main(int argc, char *argv[])
test_bredrle("Remove Device - Invalid Params 2",
&remove_device_fail_2,
NULL, test_command_generic);
+ test_bredrle("Remove Device - Invalid Params 3",
+ &remove_device_fail_3,
+ NULL, test_command_generic);
test_bredrle("Remove Device - Success 1",
&remove_device_success_1,
setup_add_device, test_command_generic);
--
2.1.4