* [PATCH BlueZ 0/3] mgmt-tested: Advertising while connected testcases
@ 2018-02-09 17:26 Łukasz Rymanowski
2018-02-09 17:26 ` [PATCH BlueZ 1/3] emulator: Add initial LE states to btdev and API to set new one Łukasz Rymanowski
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Łukasz Rymanowski @ 2018-02-09 17:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Łukasz Rymanowski
This set adds testcases which tests kernel patch:
9e1e9f20ca96 Bluetooth: Add support to advertise when connected
and fix to above:
[PATCH] Bluetooth: Fix incorrect bits for LE states
Not sure if it fits to mgmt-tester. If not let me know where it
should go.
Łukasz Rymanowski (3):
emulator: Add initial LE states to btdev and API to set new one
mgmt-tester: Add test_le_full
mgmt-tester: Add testcases for advertising while connected
emulator/btdev.c | 18 +++
emulator/btdev.h | 3 +-
emulator/hciemu.c | 8 ++
emulator/hciemu.h | 3 +
tools/mgmt-tester.c | 372 ++++++++++++++++++++++++++++++++++++++++++++--------
5 files changed, 346 insertions(+), 58 deletions(-)
--
2.14.1
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH BlueZ 1/3] emulator: Add initial LE states to btdev and API to set new one 2018-02-09 17:26 [PATCH BlueZ 0/3] mgmt-tested: Advertising while connected testcases Łukasz Rymanowski @ 2018-02-09 17:26 ` Łukasz Rymanowski 2018-02-12 9:09 ` Szymon Janc 2018-02-09 17:26 ` [PATCH BlueZ 2/3] mgmt-tester: Add test_le_full Łukasz Rymanowski 2018-02-09 17:26 ` [PATCH BlueZ 3/3] mgmt-tester: Add testcases for advertising while connected Łukasz Rymanowski 2 siblings, 1 reply; 6+ messages in thread From: Łukasz Rymanowski @ 2018-02-09 17:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Łukasz Rymanowski --- emulator/btdev.c | 18 ++++++++++++++++++ emulator/btdev.h | 3 ++- emulator/hciemu.c | 8 ++++++++ emulator/hciemu.h | 3 +++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/emulator/btdev.c b/emulator/btdev.c index a9b225a24..69d84a5fc 100644 --- a/emulator/btdev.c +++ b/emulator/btdev.c @@ -570,6 +570,17 @@ static void set_le_features(struct btdev *btdev) btdev->le_features[0] |= 0x08; /* Slave-initiated Features Exchange */ } +static void set_le_states(struct btdev *btdev) +{ + /* Set all 41 bits as per Bluetooth 5.0 specification */ + btdev->le_states[0] = 0xff; + btdev->le_states[1] = 0xff; + btdev->le_states[2] = 0xff; + btdev->le_states[3] = 0xff; + btdev->le_states[4] = 0xff; + btdev->le_states[5] = 0x03; +} + static void set_amp_features(struct btdev *btdev) { } @@ -603,6 +614,7 @@ struct btdev *btdev_create(enum btdev_type type, uint16_t id) btdev->version = 0x09; set_bredrle_features(btdev); set_bredrle_commands(btdev); + set_le_states(btdev); break; case BTDEV_TYPE_BREDR: btdev->version = 0x05; @@ -613,6 +625,7 @@ struct btdev *btdev_create(enum btdev_type type, uint16_t id) btdev->version = 0x09; set_le_features(btdev); set_le_commands(btdev); + set_le_states(btdev); break; case BTDEV_TYPE_AMP: btdev->version = 0x01; @@ -685,6 +698,11 @@ uint8_t btdev_get_le_scan_enable(struct btdev *btdev) return btdev->le_scan_enable; } +void btdev_set_le_states(struct btdev *btdev, const uint8_t *le_states) +{ + memcpy(btdev->le_states, le_states, sizeof(btdev->le_states)); +} + 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 40c72199b..ba06a1015 100644 --- a/emulator/btdev.h +++ b/emulator/btdev.h @@ -84,12 +84,13 @@ uint8_t btdev_get_scan_enable(struct btdev *btdev); uint8_t btdev_get_le_scan_enable(struct btdev *btdev); +void btdev_set_le_states(struct btdev *btdev, const uint8_t *le_states); + void btdev_set_command_handler(struct btdev *btdev, btdev_command_func handler, void *user_data); void btdev_set_send_handler(struct btdev *btdev, btdev_send_func handler, void *user_data); - void btdev_receive_h4(struct btdev *btdev, const void *data, uint16_t len); int btdev_add_hook(struct btdev *btdev, enum btdev_hook_type type, diff --git a/emulator/hciemu.c b/emulator/hciemu.c index 7debb8f27..1787a6c0d 100644 --- a/emulator/hciemu.c +++ b/emulator/hciemu.c @@ -444,6 +444,14 @@ uint8_t hciemu_get_master_le_scan_enable(struct hciemu *hciemu) return btdev_get_le_scan_enable(hciemu->master_dev); } +void hciemu_set_master_le_states(struct hciemu *hciemu, const uint8_t *le_states) +{ + if (!hciemu || !hciemu->master_dev) + return; + + btdev_set_le_states(hciemu->master_dev, le_states); +} + 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 783f99cf1..5c0c4c306 100644 --- a/emulator/hciemu.h +++ b/emulator/hciemu.h @@ -57,6 +57,9 @@ uint8_t hciemu_get_master_scan_enable(struct hciemu *hciemu); uint8_t hciemu_get_master_le_scan_enable(struct hciemu *hciemu); +void hciemu_set_master_le_states(struct hciemu *hciemu, + const uint8_t *le_states); + typedef void (*hciemu_command_func_t)(uint16_t opcode, const void *data, uint8_t len, void *user_data); -- 2.14.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH BlueZ 1/3] emulator: Add initial LE states to btdev and API to set new one 2018-02-09 17:26 ` [PATCH BlueZ 1/3] emulator: Add initial LE states to btdev and API to set new one Łukasz Rymanowski @ 2018-02-12 9:09 ` Szymon Janc 0 siblings, 0 replies; 6+ messages in thread From: Szymon Janc @ 2018-02-12 9:09 UTC (permalink / raw) To: Łukasz Rymanowski; +Cc: linux-bluetooth Hi =C5=81ukasz, On Friday, 9 February 2018 18:26:25 CET =C5=81ukasz Rymanowski wrote: > --- > emulator/btdev.c | 18 ++++++++++++++++++ > emulator/btdev.h | 3 ++- > emulator/hciemu.c | 8 ++++++++ > emulator/hciemu.h | 3 +++ > 4 files changed, 31 insertions(+), 1 deletion(-) >=20 > diff --git a/emulator/btdev.c b/emulator/btdev.c > index a9b225a24..69d84a5fc 100644 > --- a/emulator/btdev.c > +++ b/emulator/btdev.c > @@ -570,6 +570,17 @@ static void set_le_features(struct btdev *btdev) > btdev->le_features[0] |=3D 0x08; /* Slave-initiated Features Exchange */ > } >=20 > +static void set_le_states(struct btdev *btdev) > +{ > + /* Set all 41 bits as per Bluetooth 5.0 specification */ > + btdev->le_states[0] =3D 0xff; > + btdev->le_states[1] =3D 0xff; > + btdev->le_states[2] =3D 0xff; > + btdev->le_states[3] =3D 0xff; > + btdev->le_states[4] =3D 0xff; > + btdev->le_states[5] =3D 0x03; > +} > + > static void set_amp_features(struct btdev *btdev) > { > } > @@ -603,6 +614,7 @@ struct btdev *btdev_create(enum btdev_type type, > uint16_t id) btdev->version =3D 0x09; > set_bredrle_features(btdev); > set_bredrle_commands(btdev); > + set_le_states(btdev); > break; > case BTDEV_TYPE_BREDR: > btdev->version =3D 0x05; > @@ -613,6 +625,7 @@ struct btdev *btdev_create(enum btdev_type type, > uint16_t id) btdev->version =3D 0x09; > set_le_features(btdev); > set_le_commands(btdev); > + set_le_states(btdev); > break; > case BTDEV_TYPE_AMP: > btdev->version =3D 0x01; > @@ -685,6 +698,11 @@ uint8_t btdev_get_le_scan_enable(struct btdev *btdev) > return btdev->le_scan_enable; > } >=20 > +void btdev_set_le_states(struct btdev *btdev, const uint8_t *le_states) > +{ > + memcpy(btdev->le_states, le_states, sizeof(btdev->le_states)); > +} > + > 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 40c72199b..ba06a1015 100644 > --- a/emulator/btdev.h > +++ b/emulator/btdev.h > @@ -84,12 +84,13 @@ uint8_t btdev_get_scan_enable(struct btdev *btdev); >=20 > uint8_t btdev_get_le_scan_enable(struct btdev *btdev); >=20 > +void btdev_set_le_states(struct btdev *btdev, const uint8_t *le_states); > + > void btdev_set_command_handler(struct btdev *btdev, btdev_command_func > handler, void *user_data); >=20 > void btdev_set_send_handler(struct btdev *btdev, btdev_send_func handler, > void *user_data); > - > void btdev_receive_h4(struct btdev *btdev, const void *data, uint16_t le= n); >=20 > int btdev_add_hook(struct btdev *btdev, enum btdev_hook_type type, > diff --git a/emulator/hciemu.c b/emulator/hciemu.c > index 7debb8f27..1787a6c0d 100644 > --- a/emulator/hciemu.c > +++ b/emulator/hciemu.c > @@ -444,6 +444,14 @@ uint8_t hciemu_get_master_le_scan_enable(struct hcie= mu > *hciemu) return btdev_get_le_scan_enable(hciemu->master_dev); > } >=20 > +void hciemu_set_master_le_states(struct hciemu *hciemu, const uint8_t > *le_states) +{ > + if (!hciemu || !hciemu->master_dev) > + return; > + > + btdev_set_le_states(hciemu->master_dev, le_states); > +} > + > 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 783f99cf1..5c0c4c306 100644 > --- a/emulator/hciemu.h > +++ b/emulator/hciemu.h > @@ -57,6 +57,9 @@ uint8_t hciemu_get_master_scan_enable(struct hciemu > *hciemu); >=20 > uint8_t hciemu_get_master_le_scan_enable(struct hciemu *hciemu); >=20 > +void hciemu_set_master_le_states(struct hciemu *hciemu, > + const uint8_t *le_states); > + > typedef void (*hciemu_command_func_t)(uint16_t opcode, const void *data, > uint8_t len, void *user_data); Patches 1 and 2 are now applied, thanks. =2D-=20 pozdrawiam Szymon Janc ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH BlueZ 2/3] mgmt-tester: Add test_le_full 2018-02-09 17:26 [PATCH BlueZ 0/3] mgmt-tested: Advertising while connected testcases Łukasz Rymanowski 2018-02-09 17:26 ` [PATCH BlueZ 1/3] emulator: Add initial LE states to btdev and API to set new one Łukasz Rymanowski @ 2018-02-09 17:26 ` Łukasz Rymanowski 2018-02-09 17:26 ` [PATCH BlueZ 3/3] mgmt-tester: Add testcases for advertising while connected Łukasz Rymanowski 2 siblings, 0 replies; 6+ messages in thread From: Łukasz Rymanowski @ 2018-02-09 17:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Łukasz Rymanowski --- tools/mgmt-tester.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c index 1078d185e..191c1cd4d 100644 --- a/tools/mgmt-tester.c +++ b/tools/mgmt-tester.c @@ -373,7 +373,7 @@ static void test_condition_complete(struct test_data *data) test_post_teardown, 2, user, free); \ } while (0) -#define test_le(name, data, setup, func) \ +#define test_le_full(name, data, setup, func, timeout) \ do { \ struct test_data *user; \ user = new0(struct test_data, 1); \ @@ -386,9 +386,12 @@ static void test_condition_complete(struct test_data *data) user->initial_settings = 0x00000200; \ tester_add_full(name, data, \ test_pre_setup, test_setup, func, NULL, \ - test_post_teardown, 2, user, free); \ + test_post_teardown, timeout, user, free); \ } while (0) +#define test_le(name, data, setup, func) \ + test_le_full(name, data, setup, func, 2) + static void controller_setup(const void *test_data) { tester_test_passed(); -- 2.14.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH BlueZ 3/3] mgmt-tester: Add testcases for advertising while connected 2018-02-09 17:26 [PATCH BlueZ 0/3] mgmt-tested: Advertising while connected testcases Łukasz Rymanowski 2018-02-09 17:26 ` [PATCH BlueZ 1/3] emulator: Add initial LE states to btdev and API to set new one Łukasz Rymanowski 2018-02-09 17:26 ` [PATCH BlueZ 2/3] mgmt-tester: Add test_le_full Łukasz Rymanowski @ 2018-02-09 17:26 ` Łukasz Rymanowski 2018-02-12 9:06 ` Szymon Janc 2 siblings, 1 reply; 6+ messages in thread From: Łukasz Rymanowski @ 2018-02-09 17:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Łukasz Rymanowski This patch adds testcases which verifies if Linux Kernel properly enables advertising while is connected (LE) based on supported LE states in the controller --- tools/mgmt-tester.c | 365 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 310 insertions(+), 55 deletions(-) diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c index 191c1cd4d..1be245c84 100644 --- a/tools/mgmt-tester.c +++ b/tools/mgmt-tester.c @@ -28,6 +28,8 @@ #include <stdlib.h> #include <stdbool.h> #include <sys/ioctl.h> +#include <errno.h> +#include <unistd.h> #include <glib.h> @@ -35,6 +37,7 @@ #include "lib/hci.h" #include "lib/hci_lib.h" #include "lib/mgmt.h" +#include "lib/l2cap.h" #include "monitor/bt.h" #include "emulator/bthost.h" @@ -64,6 +67,7 @@ struct test_data { enum hciemu_type hciemu_type; int unmet_conditions; int unmet_setup_conditions; + int sk; }; static void mgmt_debug(const char *str, void *user_data) @@ -211,10 +215,68 @@ static void index_removed_callback(uint16_t index, uint16_t length, tester_post_teardown_complete(); } +struct generic_data { + bool setup_le_states; + const uint8_t *le_states; + const uint16_t *setup_settings; + bool setup_nobredr; + bool setup_limited_discov; + uint16_t setup_expect_hci_command; + const void *setup_expect_hci_param; + uint8_t setup_expect_hci_len; + uint16_t setup_send_opcode; + const void *setup_send_param; + uint16_t setup_send_len; + const struct setup_mgmt_cmd *setup_mgmt_cmd_arr; + bool send_index_none; + uint16_t send_opcode; + const void *send_param; + uint16_t send_len; + const void * (*send_func)(uint16_t *len); + uint8_t expect_status; + bool expect_ignore_param; + const void *expect_param; + uint16_t expect_len; + const void * (*expect_func)(uint16_t *len); + uint32_t expect_settings_set; + uint32_t expect_settings_unset; + uint16_t expect_alt_ev; + const void *expect_alt_ev_param; + bool (*verify_alt_ev_func)(const void *param, uint16_t length); + uint16_t expect_alt_ev_len; + uint16_t expect_hci_command; + const void *expect_hci_param; + uint8_t expect_hci_len; + const void * (*expect_hci_func)(uint8_t *len); + bool expect_pin; + uint8_t pin_len; + const void *pin; + uint8_t client_pin_len; + const void *client_pin; + bool client_enable_ssp; + uint8_t io_cap; + uint8_t client_io_cap; + uint8_t client_auth_req; + bool reject_confirm; + bool client_reject_confirm; + bool just_works; + bool client_enable_le; + bool client_enable_sc; + bool client_enable_adv; + bool expect_sc_key; + bool force_power_off; + bool addr_type_avail; + uint8_t addr_type; + bool set_adv; + const uint8_t *adv_data; + uint8_t adv_data_len; +}; + static void read_index_list_callback(uint8_t status, uint16_t length, const void *param, void *user_data) { struct test_data *data = tester_get_data(); + const struct generic_data *test = data->test_data; tester_print("Read Index List callback"); tester_print(" Status: %s (0x%02x)", mgmt_errstr(status), status); @@ -235,6 +297,9 @@ static void read_index_list_callback(uint8_t status, uint16_t length, tester_warn("Failed to setup HCI emulation"); tester_pre_setup_failed(); } + + if (test && test->setup_le_states) + hciemu_set_master_le_states(data->hciemu, test->le_states); } static void test_pre_setup(const void *test_data) @@ -271,12 +336,17 @@ static void test_pre_setup(const void *test_data) mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL, read_index_list_callback, NULL, NULL); + + data->sk = -1; } static void test_post_teardown(const void *test_data) { struct test_data *data = tester_get_data(); + if (data->sk >= 0) + close(data->sk); + hciemu_unref(data->hciemu); data->hciemu = NULL; } @@ -403,61 +473,6 @@ struct setup_mgmt_cmd { uint16_t send_len; }; -struct generic_data { - const uint16_t *setup_settings; - bool setup_nobredr; - bool setup_limited_discov; - uint16_t setup_expect_hci_command; - const void *setup_expect_hci_param; - uint8_t setup_expect_hci_len; - uint16_t setup_send_opcode; - const void *setup_send_param; - uint16_t setup_send_len; - const struct setup_mgmt_cmd *setup_mgmt_cmd_arr; - bool send_index_none; - uint16_t send_opcode; - const void *send_param; - uint16_t send_len; - const void * (*send_func)(uint16_t *len); - uint8_t expect_status; - bool expect_ignore_param; - const void *expect_param; - uint16_t expect_len; - const void * (*expect_func)(uint16_t *len); - uint32_t expect_settings_set; - uint32_t expect_settings_unset; - uint16_t expect_alt_ev; - const void *expect_alt_ev_param; - bool (*verify_alt_ev_func)(const void *param, uint16_t length); - uint16_t expect_alt_ev_len; - uint16_t expect_hci_command; - const void *expect_hci_param; - uint8_t expect_hci_len; - const void * (*expect_hci_func)(uint8_t *len); - bool expect_pin; - uint8_t pin_len; - const void *pin; - uint8_t client_pin_len; - const void *client_pin; - bool client_enable_ssp; - uint8_t io_cap; - uint8_t client_io_cap; - uint8_t client_auth_req; - bool reject_confirm; - bool client_reject_confirm; - bool just_works; - bool client_enable_le; - bool client_enable_sc; - bool client_enable_adv; - bool expect_sc_key; - bool force_power_off; - bool addr_type_avail; - uint8_t addr_type; - bool set_adv; - const uint8_t *adv_data; - uint8_t adv_data_len; -}; - static const char dummy_data[] = { 0x00 }; static const struct generic_data invalid_command_test = { @@ -5002,6 +5017,45 @@ static const struct generic_data read_local_oob_success_sc_test = { .expect_hci_command = BT_HCI_CMD_READ_LOCAL_OOB_EXT_DATA, }; +static uint8_t le_states_conn_slave_adv_connectable[] = { + 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00}; +static uint8_t le_states_conn_slave_adv_non_connectable[] = { + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}; +static uint8_t le_states_conn_master_adv_connectable[] = { + 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00}; +static uint8_t le_states_conn_master_adv_non_connectable[] = { + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static const struct generic_data conn_slave_adv_conneactable_test = { + .setup_le_states = true, + .le_states = le_states_conn_slave_adv_connectable, + .setup_settings = settings_powered_le, + .client_enable_le = true +}; + +static const struct generic_data conn_slave_adv_non_conneactable_test = { + .setup_le_states = true, + .le_states = le_states_conn_slave_adv_non_connectable, + .setup_settings = settings_powered_le, + .client_enable_le = true +}; + +static const struct generic_data conn_master_adv_conneactable_test = { + .setup_le_states = true, + .le_states = le_states_conn_master_adv_connectable, + .setup_settings = settings_powered_le, + .client_enable_le = true, + .client_enable_adv = 1 +}; + +static const struct generic_data conn_master_adv_non_conneactable_test = { + .setup_le_states = true, + .le_states = le_states_conn_master_adv_non_connectable, + .setup_settings = settings_powered_le, + .client_enable_le = true, + .client_enable_adv = 1 +}; + static const char ext_ctrl_info1[] = { 0x00, 0x00, 0x00, 0x01, 0xaa, 0x00, /* btaddr */ 0x09, /* version */ @@ -5671,6 +5725,77 @@ static void setup_add_advertising_connectable(const void *test_data) NULL, NULL); } +static int create_le_att_sock(struct test_data *data) +{ + struct sockaddr_l2 addr; + int sk, err; + + sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, + BTPROTO_L2CAP); + if (sk < 0) { + err = -errno; + tester_warn("Can't create socket: %s (%d)", strerror(errno), + errno); + return err; + } + + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + addr.l2_psm = 0; + addr.l2_cid = htobs(0x0004); + addr.l2_bdaddr_type = BDADDR_LE_PUBLIC; + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + err = -errno; + tester_warn("Can't bind socket: %s (%d)", strerror(errno), + errno); + close(sk); + return err; + } + + if (listen(sk, 1) < 0) { + err = -errno; + tester_warn("Can't bind socket: %s (%d)", strerror(errno), + errno); + close(sk); + return err; + } + + data->sk = sk; + + return sk; +} + +static void setup_advertise_while_connected(const void *test_data) +{ + struct test_data *data = tester_get_data(); + struct mgmt_cp_add_advertising *cp; + unsigned char adv_param[sizeof(*cp) + TESTER_ADD_ADV_DATA_LEN]; + + tester_print("Adding advertising instances"); + + cp = (struct mgmt_cp_add_advertising *) adv_param; + setup_add_adv_param(cp, 1); + + cp->flags |= MGMT_ADV_FLAG_CONNECTABLE; + mgmt_send(data->mgmt, MGMT_OP_ADD_ADVERTISING, data->mgmt_index, + sizeof(adv_param), adv_param, + NULL, NULL, NULL); + + cp->flags &= ~MGMT_ADV_FLAG_CONNECTABLE; + cp->instance = 2; + + mgmt_send(data->mgmt, MGMT_OP_ADD_ADVERTISING, data->mgmt_index, + sizeof(adv_param), adv_param, + setup_add_advertising_callback, + NULL, NULL); + + /* Listen on the socket so Kernel does not drop connection just after + * connect. Socket is closed in test_post_teardown + */ + create_le_att_sock(data); +} + static void setup_add_advertising_timeout(const void *test_data) { struct test_data *data = tester_get_data(); @@ -6982,6 +7107,116 @@ static void test_command_generic_connect(const void *test_data) bthost_hci_connect(bthost, master_bdaddr, addr_type); } +static bool test_adv_enable_hook(const void *data, uint16_t len, + void *user_data) +{ + struct test_data *test_data = user_data; + const uint8_t *status = data; + + if (*status == 0) { + tester_print("Advertising enabled"); + test_condition_complete(test_data); + } else { + tester_print("Advertising enabled error 0x%02x", *status); + } + + return true; +} + +static void disconnected_event(uint16_t index, uint16_t length, + const void *param, void *user_data) +{ + tester_test_failed(); +} + +static void le_connected_event(uint16_t index, uint16_t length, + const void *param, void *user_data) +{ + struct test_data *data = tester_get_data(); + + tester_print("Device connected"); + + test_add_condition(data); + hciemu_add_hook(data->hciemu, HCIEMU_HOOK_POST_CMD, + BT_HCI_CMD_LE_SET_ADV_ENABLE, + test_adv_enable_hook, data); + + /* Make sure we get not disconnected during the testaces */ + mgmt_register(data->mgmt_alt, MGMT_EV_DEVICE_DISCONNECTED, + data->mgmt_index, disconnected_event, + + NULL, NULL); + + test_condition_complete(data); +} + +static void add_device_callback(uint8_t status, uint16_t len, const void *param, + void *user_data) +{ + struct test_data *data = user_data; + const struct generic_data *test = data->test_data; + struct bthost *bthost; + const uint8_t *master_bdaddr; + + if (status != 0) + tester_test_failed(); + + tester_print("Device added"); + + /* If advertising is enabled on client that means we can stop here and + * just wait for connection + */ + if (test->client_enable_adv) + return; + + master_bdaddr = hciemu_get_master_bdaddr(data->hciemu); + if (!master_bdaddr) { + tester_warn("No master bdaddr"); + tester_test_failed(); + return; + } + + bthost = hciemu_client_get_host(data->hciemu); + bthost_hci_connect(bthost, master_bdaddr, BDADDR_LE_PUBLIC); +} + +static void test_connected_and_advertising(const void *test_data) +{ + struct test_data *data = tester_get_data(); + const struct generic_data *test = data->test_data; + const uint8_t *client_bdaddr; + struct mgmt_cp_add_device cp; + + tester_print("Registering %s notification", + mgmt_evstr(MGMT_EV_DEVICE_CONNECTED)); + + test_add_condition(data); + mgmt_register(data->mgmt_alt, MGMT_EV_DEVICE_CONNECTED, + data->mgmt_index, le_connected_event, + NULL, NULL); + + client_bdaddr = hciemu_get_client_bdaddr(data->hciemu); + if (!client_bdaddr) { + tester_warn("No client bdaddr"); + tester_test_failed(); + return; + } + + memset(&cp, 0, sizeof(cp)); + memcpy(&cp.addr.bdaddr, client_bdaddr, 6); + cp.addr.type = BDADDR_LE_PUBLIC; + + if (test->client_enable_adv) + cp.action = 0x02; // Auto connect + else + cp.action = 0x01; // Allow incoming connection + + mgmt_send(data->mgmt_alt, MGMT_OP_ADD_DEVICE, data->mgmt_index, + sizeof(cp), &cp, + add_device_callback, + data, NULL); +} + int main(int argc, char *argv[]) { tester_init(&argc, &argv); @@ -8004,6 +8239,26 @@ int main(int argc, char *argv[]) setup_command_generic, test_command_generic); + test_le_full("Adv. connectable & connected (slave) - Success", + &conn_slave_adv_conneactable_test, + setup_advertise_while_connected, + test_connected_and_advertising, 10); + + test_le_full("Adv. non-connectable & connected (slave) - Success", + &conn_slave_adv_non_conneactable_test, + setup_advertise_while_connected, + test_connected_and_advertising, 10); + + test_le_full("Adv. connectable & connected (master) - Success", + &conn_master_adv_conneactable_test, + setup_advertise_while_connected, + test_connected_and_advertising, 10); + + test_le_full("Adv. non-connectable & connected (master) - Success", + &conn_master_adv_non_conneactable_test, + setup_advertise_while_connected, + test_connected_and_advertising, 10); + test_bredrle("Remove Advertising - Invalid Params 1", &remove_advertising_fail_1, NULL, test_command_generic); -- 2.14.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH BlueZ 3/3] mgmt-tester: Add testcases for advertising while connected 2018-02-09 17:26 ` [PATCH BlueZ 3/3] mgmt-tester: Add testcases for advertising while connected Łukasz Rymanowski @ 2018-02-12 9:06 ` Szymon Janc 0 siblings, 0 replies; 6+ messages in thread From: Szymon Janc @ 2018-02-12 9:06 UTC (permalink / raw) To: Łukasz Rymanowski; +Cc: linux-bluetooth Hi =C5=81ukasz, On Friday, 9 February 2018 18:26:27 CET =C5=81ukasz Rymanowski wrote: > This patch adds testcases which verifies if Linux Kernel properly > enables advertising while is connected (LE) based on supported LE states > in the controller > --- > tools/mgmt-tester.c | 365 > ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 310 > insertions(+), 55 deletions(-) >=20 > diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c > index 191c1cd4d..1be245c84 100644 > --- a/tools/mgmt-tester.c > +++ b/tools/mgmt-tester.c > @@ -28,6 +28,8 @@ > #include <stdlib.h> > #include <stdbool.h> > #include <sys/ioctl.h> > +#include <errno.h> > +#include <unistd.h> >=20 > #include <glib.h> >=20 > @@ -35,6 +37,7 @@ > #include "lib/hci.h" > #include "lib/hci_lib.h" > #include "lib/mgmt.h" > +#include "lib/l2cap.h" >=20 > #include "monitor/bt.h" > #include "emulator/bthost.h" > @@ -64,6 +67,7 @@ struct test_data { > enum hciemu_type hciemu_type; > int unmet_conditions; > int unmet_setup_conditions; > + int sk; > }; >=20 > static void mgmt_debug(const char *str, void *user_data) > @@ -211,10 +215,68 @@ static void index_removed_callback(uint16_t index, > uint16_t length, tester_post_teardown_complete(); > } >=20 > +struct generic_data { > + bool setup_le_states; > + const uint8_t *le_states; > + const uint16_t *setup_settings; > + bool setup_nobredr; > + bool setup_limited_discov; > + uint16_t setup_expect_hci_command; > + const void *setup_expect_hci_param; > + uint8_t setup_expect_hci_len; > + uint16_t setup_send_opcode; > + const void *setup_send_param; > + uint16_t setup_send_len; > + const struct setup_mgmt_cmd *setup_mgmt_cmd_arr; > + bool send_index_none; > + uint16_t send_opcode; > + const void *send_param; > + uint16_t send_len; > + const void * (*send_func)(uint16_t *len); > + uint8_t expect_status; > + bool expect_ignore_param; > + const void *expect_param; > + uint16_t expect_len; > + const void * (*expect_func)(uint16_t *len); > + uint32_t expect_settings_set; > + uint32_t expect_settings_unset; > + uint16_t expect_alt_ev; > + const void *expect_alt_ev_param; > + bool (*verify_alt_ev_func)(const void *param, uint16_t length); > + uint16_t expect_alt_ev_len; > + uint16_t expect_hci_command; > + const void *expect_hci_param; > + uint8_t expect_hci_len; > + const void * (*expect_hci_func)(uint8_t *len); > + bool expect_pin; > + uint8_t pin_len; > + const void *pin; > + uint8_t client_pin_len; > + const void *client_pin; > + bool client_enable_ssp; > + uint8_t io_cap; > + uint8_t client_io_cap; > + uint8_t client_auth_req; > + bool reject_confirm; > + bool client_reject_confirm; > + bool just_works; > + bool client_enable_le; > + bool client_enable_sc; > + bool client_enable_adv; > + bool expect_sc_key; > + bool force_power_off; > + bool addr_type_avail; > + uint8_t addr_type; > + bool set_adv; > + const uint8_t *adv_data; > + uint8_t adv_data_len; > +}; > + > static void read_index_list_callback(uint8_t status, uint16_t length, > const void *param, void *user_data) > { > struct test_data *data =3D tester_get_data(); > + const struct generic_data *test =3D data->test_data; >=20 > tester_print("Read Index List callback"); > tester_print(" Status: %s (0x%02x)", mgmt_errstr(status), status); > @@ -235,6 +297,9 @@ static void read_index_list_callback(uint8_t status, > uint16_t length, tester_warn("Failed to setup HCI emulation"); > tester_pre_setup_failed(); > } > + > + if (test && test->setup_le_states) > + hciemu_set_master_le_states(data->hciemu, test->le_states); > } >=20 > static void test_pre_setup(const void *test_data) > @@ -271,12 +336,17 @@ static void test_pre_setup(const void *test_data) >=20 > mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL, > read_index_list_callback, NULL, NULL); > + > + data->sk =3D -1; > } >=20 > static void test_post_teardown(const void *test_data) > { > struct test_data *data =3D tester_get_data(); >=20 > + if (data->sk >=3D 0) > + close(data->sk); > + > hciemu_unref(data->hciemu); > data->hciemu =3D NULL; > } > @@ -403,61 +473,6 @@ struct setup_mgmt_cmd { > uint16_t send_len; > }; >=20 > -struct generic_data { > - const uint16_t *setup_settings; > - bool setup_nobredr; > - bool setup_limited_discov; > - uint16_t setup_expect_hci_command; > - const void *setup_expect_hci_param; > - uint8_t setup_expect_hci_len; > - uint16_t setup_send_opcode; > - const void *setup_send_param; > - uint16_t setup_send_len; > - const struct setup_mgmt_cmd *setup_mgmt_cmd_arr; > - bool send_index_none; > - uint16_t send_opcode; > - const void *send_param; > - uint16_t send_len; > - const void * (*send_func)(uint16_t *len); > - uint8_t expect_status; > - bool expect_ignore_param; > - const void *expect_param; > - uint16_t expect_len; > - const void * (*expect_func)(uint16_t *len); > - uint32_t expect_settings_set; > - uint32_t expect_settings_unset; > - uint16_t expect_alt_ev; > - const void *expect_alt_ev_param; > - bool (*verify_alt_ev_func)(const void *param, uint16_t length); > - uint16_t expect_alt_ev_len; > - uint16_t expect_hci_command; > - const void *expect_hci_param; > - uint8_t expect_hci_len; > - const void * (*expect_hci_func)(uint8_t *len); > - bool expect_pin; > - uint8_t pin_len; > - const void *pin; > - uint8_t client_pin_len; > - const void *client_pin; > - bool client_enable_ssp; > - uint8_t io_cap; > - uint8_t client_io_cap; > - uint8_t client_auth_req; > - bool reject_confirm; > - bool client_reject_confirm; > - bool just_works; > - bool client_enable_le; > - bool client_enable_sc; > - bool client_enable_adv; > - bool expect_sc_key; > - bool force_power_off; > - bool addr_type_avail; > - uint8_t addr_type; > - bool set_adv; > - const uint8_t *adv_data; > - uint8_t adv_data_len; > -}; > - > static const char dummy_data[] =3D { 0x00 }; >=20 > static const struct generic_data invalid_command_test =3D { > @@ -5002,6 +5017,45 @@ static const struct generic_data > read_local_oob_success_sc_test =3D { .expect_hci_command =3D > BT_HCI_CMD_READ_LOCAL_OOB_EXT_DATA, > }; >=20 > +static uint8_t le_states_conn_slave_adv_connectable[] =3D { > + 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00}; > +static uint8_t le_states_conn_slave_adv_non_connectable[] =3D { > + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}; > +static uint8_t le_states_conn_master_adv_connectable[] =3D { > + 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00}; > +static uint8_t le_states_conn_master_adv_non_connectable[] =3D { > + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; > + Could be static const. > +static const struct generic_data conn_slave_adv_conneactable_test =3D { > + .setup_le_states =3D true, > + .le_states =3D le_states_conn_slave_adv_connectable, > + .setup_settings =3D settings_powered_le, > + .client_enable_le =3D true > +}; > + > +static const struct generic_data conn_slave_adv_non_conneactable_test = =3D { > + .setup_le_states =3D true, > + .le_states =3D le_states_conn_slave_adv_non_connectable, > + .setup_settings =3D settings_powered_le, > + .client_enable_le =3D true > +}; > + > +static const struct generic_data conn_master_adv_conneactable_test =3D { > + .setup_le_states =3D true, > + .le_states =3D le_states_conn_master_adv_connectable, > + .setup_settings =3D settings_powered_le, > + .client_enable_le =3D true, > + .client_enable_adv =3D 1 > +}; > + > +static const struct generic_data conn_master_adv_non_conneactable_test = =3D { > + .setup_le_states =3D true, > + .le_states =3D le_states_conn_master_adv_non_connectable, > + .setup_settings =3D settings_powered_le, > + .client_enable_le =3D true, > + .client_enable_adv =3D 1 > +}; > + > static const char ext_ctrl_info1[] =3D { > 0x00, 0x00, 0x00, 0x01, 0xaa, 0x00, /* btaddr */ > 0x09, /* version */ > @@ -5671,6 +5725,77 @@ static void setup_add_advertising_connectable(const > void *test_data) NULL, NULL); > } >=20 > +static int create_le_att_sock(struct test_data *data) > +{ > + struct sockaddr_l2 addr; > + int sk, err; > + > + sk =3D socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, > + BTPROTO_L2CAP); > + if (sk < 0) { > + err =3D -errno; > + tester_warn("Can't create socket: %s (%d)", strerror(errno), > + errno); > + return err; > + } > + > + memset(&addr, 0, sizeof(addr)); > + addr.l2_family =3D AF_BLUETOOTH; > + addr.l2_psm =3D 0; > + addr.l2_cid =3D htobs(0x0004); > + addr.l2_bdaddr_type =3D BDADDR_LE_PUBLIC; > + > + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { > + err =3D -errno; > + tester_warn("Can't bind socket: %s (%d)", strerror(errno), > + errno); > + close(sk); > + return err; > + } > + > + if (listen(sk, 1) < 0) { > + err =3D -errno; > + tester_warn("Can't bind socket: %s (%d)", strerror(errno), > + errno); > + close(sk); > + return err; > + } > + > + data->sk =3D sk; > + > + return sk; > +} > + > +static void setup_advertise_while_connected(const void *test_data) > +{ > + struct test_data *data =3D tester_get_data(); > + struct mgmt_cp_add_advertising *cp; > + unsigned char adv_param[sizeof(*cp) + TESTER_ADD_ADV_DATA_LEN]; uint8_t > + > + tester_print("Adding advertising instances"); > + > + cp =3D (struct mgmt_cp_add_advertising *) adv_param; > + setup_add_adv_param(cp, 1); > + > + cp->flags |=3D MGMT_ADV_FLAG_CONNECTABLE; > + mgmt_send(data->mgmt, MGMT_OP_ADD_ADVERTISING, data->mgmt_index, > + sizeof(adv_param), adv_param, > + NULL, NULL, NULL); > + > + cp->flags &=3D ~MGMT_ADV_FLAG_CONNECTABLE; > + cp->instance =3D 2; > + > + mgmt_send(data->mgmt, MGMT_OP_ADD_ADVERTISING, data->mgmt_index, > + sizeof(adv_param), adv_param, > + setup_add_advertising_callback, > + NULL, NULL); > + > + /* Listen on the socket so Kernel does not drop connection just after > + * connect. Socket is closed in test_post_teardown > + */ > + create_le_att_sock(data); > +} > + > static void setup_add_advertising_timeout(const void *test_data) > { > struct test_data *data =3D tester_get_data(); > @@ -6982,6 +7107,116 @@ static void test_command_generic_connect(const vo= id > *test_data) bthost_hci_connect(bthost, master_bdaddr, addr_type); > } >=20 > +static bool test_adv_enable_hook(const void *data, uint16_t len, > + void *user_data) > +{ > + struct test_data *test_data =3D user_data; > + const uint8_t *status =3D data; > + > + if (*status =3D=3D 0) { > + tester_print("Advertising enabled"); > + test_condition_complete(test_data); > + } else { > + tester_print("Advertising enabled error 0x%02x", *status); > + } > + > + return true; > +} > + > +static void disconnected_event(uint16_t index, uint16_t length, > + const void *param, void *user_data) > +{ > + tester_test_failed(); > +} > + > +static void le_connected_event(uint16_t index, uint16_t length, > + const void *param, void *user_data) > +{ > + struct test_data *data =3D tester_get_data(); > + > + tester_print("Device connected"); > + > + test_add_condition(data); > + hciemu_add_hook(data->hciemu, HCIEMU_HOOK_POST_CMD, > + BT_HCI_CMD_LE_SET_ADV_ENABLE, > + test_adv_enable_hook, data); > + > + /* Make sure we get not disconnected during the testaces */ > + mgmt_register(data->mgmt_alt, MGMT_EV_DEVICE_DISCONNECTED, > + data->mgmt_index, disconnected_event, > + > + NULL, NULL); > + > + test_condition_complete(data); > +} > + > +static void add_device_callback(uint8_t status, uint16_t len, const void > *param, + void *user_data) > +{ > + struct test_data *data =3D user_data; > + const struct generic_data *test =3D data->test_data; > + struct bthost *bthost; > + const uint8_t *master_bdaddr; > + > + if (status !=3D 0) > + tester_test_failed(); missign return here? > + > + tester_print("Device added"); > + > + /* If advertising is enabled on client that means we can stop here and > + * just wait for connection > + */ > + if (test->client_enable_adv) > + return; > + > + master_bdaddr =3D hciemu_get_master_bdaddr(data->hciemu); > + if (!master_bdaddr) { > + tester_warn("No master bdaddr"); > + tester_test_failed(); > + return; > + } > + > + bthost =3D hciemu_client_get_host(data->hciemu); > + bthost_hci_connect(bthost, master_bdaddr, BDADDR_LE_PUBLIC); > +} > + > +static void test_connected_and_advertising(const void *test_data) > +{ > + struct test_data *data =3D tester_get_data(); > + const struct generic_data *test =3D data->test_data; > + const uint8_t *client_bdaddr; > + struct mgmt_cp_add_device cp; > + > + tester_print("Registering %s notification", > + mgmt_evstr(MGMT_EV_DEVICE_CONNECTED)); > + > + test_add_condition(data); > + mgmt_register(data->mgmt_alt, MGMT_EV_DEVICE_CONNECTED, > + data->mgmt_index, le_connected_event, > + NULL, NULL); > + > + client_bdaddr =3D hciemu_get_client_bdaddr(data->hciemu); > + if (!client_bdaddr) { > + tester_warn("No client bdaddr"); > + tester_test_failed(); > + return; > + } > + > + memset(&cp, 0, sizeof(cp)); > + memcpy(&cp.addr.bdaddr, client_bdaddr, 6); > + cp.addr.type =3D BDADDR_LE_PUBLIC; > + > + if (test->client_enable_adv) > + cp.action =3D 0x02; // Auto connect > + else > + cp.action =3D 0x01; // Allow incoming connection No C++ style comments. > + > + mgmt_send(data->mgmt_alt, MGMT_OP_ADD_DEVICE, data->mgmt_index, > + sizeof(cp), &cp, > + add_device_callback, > + data, NULL); > +} > + > int main(int argc, char *argv[]) > { > tester_init(&argc, &argv); > @@ -8004,6 +8239,26 @@ int main(int argc, char *argv[]) > setup_command_generic, > test_command_generic); >=20 > + test_le_full("Adv. connectable & connected (slave) - Success", > + &conn_slave_adv_conneactable_test, > + setup_advertise_while_connected, > + test_connected_and_advertising, 10); > + > + test_le_full("Adv. non-connectable & connected (slave) - Success", > + &conn_slave_adv_non_conneactable_test, > + setup_advertise_while_connected, > + test_connected_and_advertising, 10); > + > + test_le_full("Adv. connectable & connected (master) - Success", > + &conn_master_adv_conneactable_test, > + setup_advertise_while_connected, > + test_connected_and_advertising, 10); > + > + test_le_full("Adv. non-connectable & connected (master) - Success", > + &conn_master_adv_non_conneactable_test, > + setup_advertise_while_connected, > + test_connected_and_advertising, 10); > + > test_bredrle("Remove Advertising - Invalid Params 1", > &remove_advertising_fail_1, > NULL, test_command_generic); =2D-=20 pozdrawiam Szymon Janc ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-02-12 9:09 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-02-09 17:26 [PATCH BlueZ 0/3] mgmt-tested: Advertising while connected testcases Łukasz Rymanowski 2018-02-09 17:26 ` [PATCH BlueZ 1/3] emulator: Add initial LE states to btdev and API to set new one Łukasz Rymanowski 2018-02-12 9:09 ` Szymon Janc 2018-02-09 17:26 ` [PATCH BlueZ 2/3] mgmt-tester: Add test_le_full Łukasz Rymanowski 2018-02-09 17:26 ` [PATCH BlueZ 3/3] mgmt-tester: Add testcases for advertising while connected Łukasz Rymanowski 2018-02-12 9:06 ` Szymon Janc
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox