| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <stdlib.h>
- #include <string.h>
- #include "monitor/bt.h"
- #include "src/shared/hci.h"
- #include "src/shared/util.h"
- #include "src/shared/ecc.h"
- #include "src/shared/tester.h"
- struct user_data {
- const void *test_data;
- uint16_t index_ut;
- uint16_t index_lt;
- struct bt_hci *hci_ut; /* Upper Tester / IUT */
- struct bt_hci *hci_lt; /* Lower Tester / Reference */
- uint8_t bdaddr_ut[6];
- uint8_t bdaddr_lt[6];
- uint16_t handle_ut;
- };
- struct le_keys {
- uint8_t remote_sk[32];
- uint8_t local_pk[64];
- } key_test_data;
- static void swap_buf(const uint8_t *src, uint8_t *dst, uint16_t len)
- {
- int i;
- for (i = 0; i < len; i++)
- dst[len - 1 - i] = src[i];
- }
- static void test_debug(const char *str, void *user_data)
- {
- tester_debug("%s", str);
- }
- static void test_pre_setup_lt_address(const void *data, uint8_t size,
- void *user_data)
- {
- struct user_data *user = tester_get_data();
- const struct bt_hci_rsp_read_bd_addr *rsp = data;
- if (rsp->status) {
- tester_warn("Read lower tester address failed (0x%02x)",
- rsp->status);
- tester_pre_setup_failed();
- return;
- }
- memcpy(user->bdaddr_lt, rsp->bdaddr, 6);
- tester_pre_setup_complete();
- }
- static void test_pre_setup_lt_complete(const void *data, uint8_t size,
- void *user_data)
- {
- struct user_data *user = tester_get_data();
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("Reset lower tester failed (0x%02x)", status);
- tester_pre_setup_failed();
- return;
- }
- if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_READ_BD_ADDR, NULL, 0,
- test_pre_setup_lt_address, NULL, NULL)) {
- tester_warn("Failed to read lower tester address");
- tester_pre_setup_failed();
- return;
- }
- }
- static void test_pre_setup_ut_address(const void *data, uint8_t size,
- void *user_data)
- {
- struct user_data *user = tester_get_data();
- const struct bt_hci_rsp_read_bd_addr *rsp = data;
- if (rsp->status) {
- tester_warn("Read upper tester address failed (0x%02x)",
- rsp->status);
- tester_pre_setup_failed();
- return;
- }
- memcpy(user->bdaddr_ut, rsp->bdaddr, 6);
- user->hci_lt = bt_hci_new_user_channel(user->index_lt);
- if (!user->hci_lt) {
- tester_warn("Failed to setup lower tester user channel");
- tester_pre_setup_failed();
- return;
- }
- if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_RESET, NULL, 0,
- test_pre_setup_lt_complete, NULL, NULL)) {
- tester_warn("Failed to reset lower tester");
- tester_pre_setup_failed();
- return;
- }
- }
- static void test_pre_setup_ut_complete(const void *data, uint8_t size,
- void *user_data)
- {
- struct user_data *user = tester_get_data();
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("Reset upper tester failed (0x%02x)", status);
- tester_pre_setup_failed();
- return;
- }
- if (user->index_lt == 0xffff) {
- tester_pre_setup_complete();
- return;
- }
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_BD_ADDR, NULL, 0,
- test_pre_setup_ut_address, NULL, NULL)) {
- tester_warn("Failed to read upper tester address");
- tester_pre_setup_failed();
- return;
- }
- }
- static void test_pre_setup(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- user->hci_ut = bt_hci_new_user_channel(user->index_ut);
- if (!user->hci_ut) {
- tester_warn("Failed to setup upper tester user channel");
- tester_pre_setup_failed();
- return;
- }
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_RESET, NULL, 0,
- test_pre_setup_ut_complete, NULL, NULL)) {
- tester_warn("Failed to reset upper tester");
- tester_pre_setup_failed();
- return;
- }
- }
- static void test_post_teardown(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- bt_hci_unref(user->hci_lt);
- user->hci_lt = NULL;
- bt_hci_unref(user->hci_ut);
- user->hci_ut = NULL;
- tester_post_teardown_complete();
- }
- static void user_data_free(void *data)
- {
- struct user_data *user = data;
- free(user);
- }
- #define test_hci(name, data, setup, func, teardown) \
- do { \
- struct user_data *user; \
- user = calloc(1, sizeof(struct user_data)); \
- if (!user) \
- break; \
- user->test_data = data; \
- user->index_ut = 0; \
- user->index_lt = 1; \
- tester_add_full(name, data, \
- test_pre_setup, setup, func, teardown, \
- test_post_teardown, 30, user, user_data_free); \
- } while (0)
- #define test_hci_local(name, data, setup, func) \
- do { \
- struct user_data *user; \
- user = calloc(1, sizeof(struct user_data)); \
- if (!user) \
- break; \
- user->test_data = data; \
- user->index_ut = 0; \
- user->index_lt = 0xffff; \
- tester_add_full(name, data, \
- test_pre_setup, setup, func, NULL, \
- test_post_teardown, 30, user, user_data_free); \
- } while (0)
- static void setup_features_complete(const void *data, uint8_t size,
- void *user_data)
- {
- const struct bt_hci_rsp_read_local_features *rsp = data;
- if (rsp->status) {
- tester_warn("Failed to get HCI features (0x%02x)", rsp->status);
- tester_setup_failed();
- return;
- }
- tester_setup_complete();
- }
- static void setup_features(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_LOCAL_FEATURES, NULL, 0,
- setup_features_complete, NULL, NULL)) {
- tester_warn("Failed to send HCI features command");
- tester_setup_failed();
- return;
- }
- }
- static void test_reset(const void *test_data)
- {
- tester_test_passed();
- }
- static void test_command_complete(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("HCI command failed (0x%02x)", status);
- tester_test_failed();
- return;
- }
- tester_test_passed();
- }
- static void test_command(uint16_t opcode)
- {
- struct user_data *user = tester_get_data();
- if (!bt_hci_send(user->hci_ut, opcode, NULL, 0,
- test_command_complete, NULL, NULL)) {
- tester_warn("Failed to send HCI command 0x%04x", opcode);
- tester_test_failed();
- return;
- }
- }
- static void test_read_local_version_information(const void *test_data)
- {
- test_command(BT_HCI_CMD_READ_LOCAL_VERSION);
- }
- static void test_read_local_supported_commands(const void *test_data)
- {
- test_command(BT_HCI_CMD_READ_LOCAL_COMMANDS);
- }
- static void test_read_local_supported_features(const void *test_data)
- {
- test_command(BT_HCI_CMD_READ_LOCAL_FEATURES);
- }
- static void test_local_extended_features_complete(const void *data,
- uint8_t size, void *user_data)
- {
- const struct bt_hci_rsp_read_local_ext_features *rsp = data;
- if (rsp->status) {
- tester_warn("Failed to get HCI extended features (0x%02x)",
- rsp->status);
- tester_test_failed();
- return;
- }
- tester_test_passed();
- }
- static void test_read_local_extended_features(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_read_local_ext_features cmd;
- cmd.page = 0x00;
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_LOCAL_EXT_FEATURES,
- &cmd, sizeof(cmd),
- test_local_extended_features_complete,
- NULL, NULL)) {
- tester_warn("Failed to send HCI extended features command");
- tester_test_failed();
- return;
- }
- }
- static void test_read_buffer_size(const void *test_data)
- {
- test_command(BT_HCI_CMD_READ_BUFFER_SIZE);
- }
- static void test_read_country_code(const void *test_data)
- {
- test_command(BT_HCI_CMD_READ_COUNTRY_CODE);
- }
- static void test_read_bd_addr(const void *test_data)
- {
- test_command(BT_HCI_CMD_READ_BD_ADDR);
- }
- static void test_read_local_supported_codecs(const void *test_data)
- {
- test_command(BT_HCI_CMD_READ_LOCAL_CODECS);
- }
- static void test_le_read_accept_list_size(const void *test_data)
- {
- test_command(BT_HCI_CMD_LE_READ_ACCEPT_LIST_SIZE);
- }
- static void test_le_clear_accept_list(const void *test_data)
- {
- test_command(BT_HCI_CMD_LE_CLEAR_ACCEPT_LIST);
- }
- static void test_le_encrypt_complete(const void *data, uint8_t size,
- void *user_data)
- {
- const struct bt_hci_rsp_le_encrypt *rsp = data;
- uint8_t sample[16] = {
- 0x7d, 0xf7, 0x6b, 0x0c, 0x1a, 0xb8, 0x99, 0xb3,
- 0x3e, 0x42, 0xf0, 0x47, 0xb9, 0x1b, 0x54, 0x6f
- };
- uint8_t enc_data[16];
- if (rsp->status) {
- tester_warn("Failed HCI LE Encrypt (0x%02x)", rsp->status);
- tester_test_failed();
- return;
- }
- swap_buf(rsp->data, enc_data, 16);
- util_hexdump('>', enc_data, 16, test_debug, NULL);
- if (!memcmp(sample, enc_data, 16))
- tester_test_passed();
- else
- tester_test_failed();
- }
- /* Data are taken from RFC 4493 Test Vectors */
- static void test_le_encrypt(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_le_encrypt cmd;
- uint8_t key[16] = {
- 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
- 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
- };
- uint8_t plaintext[16] = { 0 };
- /* Swap bytes since our interface has LE interface, opposed to
- * common crypto interface
- */
- swap_buf(key, cmd.key, 16);
- swap_buf(plaintext, cmd.plaintext, 16);
- util_hexdump('<', cmd.key, 16, test_debug, NULL);
- util_hexdump('<', cmd.plaintext, 16, test_debug, NULL);
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_ENCRYPT, &cmd, sizeof(cmd),
- test_le_encrypt_complete, NULL, NULL)) {
- tester_warn("Failed to send HCI LE Encrypt command");
- tester_test_failed();
- return;
- }
- }
- static void test_le_rand(const void *test_data)
- {
- test_command(BT_HCI_CMD_LE_RAND);
- }
- static void test_le_read_local_pk_complete(const void *data, uint8_t size,
- void *user_data)
- {
- const uint8_t *event = data;
- const struct bt_hci_evt_le_read_local_pk256_complete *evt;
- struct le_keys *keys = user_data;
- if (*event != BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE) {
- tester_warn("Failed Read Local PK256 command");
- tester_test_failed();
- return;
- }
- evt = (void *)(event + 1);
- if (evt->status) {
- tester_warn("HCI Read Local PK complete failed (0x%02x)",
- evt->status);
- tester_test_failed();
- return;
- }
- memcpy(keys->local_pk, evt->local_pk256, 64);
- util_hexdump('>', evt->local_pk256, 64, test_debug, NULL);
- tester_test_passed();
- }
- static void test_le_read_local_pk_status(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("Failed to send Read Local PK256 cmd (0x%02x)", status);
- tester_test_failed();
- return;
- }
- }
- static void test_le_read_local_pk(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_set_event_mask sem;
- struct bt_hci_cmd_le_set_event_mask lsem;
- bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT,
- test_le_read_local_pk_complete,
- (void *)test_data, NULL);
- memset(sem.mask, 0, 8);
- sem.mask[1] |= 0x20; /* Command Complete */
- sem.mask[1] |= 0x40; /* Command Status */
- sem.mask[7] |= 0x20; /* LE Meta */
- bt_hci_send(user->hci_ut, BT_HCI_CMD_SET_EVENT_MASK,
- &sem, sizeof(sem), NULL, NULL, NULL);
- memset(lsem.mask, 0, 8);
- lsem.mask[0] |= 0x80; /* LE Read Local P-256 Public Key Complete */
- bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_EVENT_MASK,
- &lsem, sizeof(lsem), NULL, NULL, NULL);
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_READ_LOCAL_PK256, NULL,
- 0, test_le_read_local_pk_status,
- NULL, NULL)) {
- tester_warn("Failed to send HCI LE Read Local PK256 command");
- tester_test_failed();
- return;
- }
- }
- static void setup_le_read_local_pk_complete(const void *data, uint8_t size,
- void *user_data)
- {
- const uint8_t *event = data;
- const struct bt_hci_evt_le_read_local_pk256_complete *evt;
- struct le_keys *keys = user_data;
- if (*event != BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE) {
- tester_warn("Failed Read Local PK256 command");
- tester_setup_failed();
- return;
- }
- evt = (void *)(event + 1);
- if (evt->status) {
- tester_warn("HCI Read Local PK complete failed (0x%02x)",
- evt->status);
- tester_setup_failed();
- return;
- }
- memcpy(keys->local_pk, evt->local_pk256, 64);
- util_hexdump('>', evt->local_pk256, 64, test_debug, NULL);
- tester_setup_complete();
- }
- static void setup_le_read_local_pk_status(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("Failed to send DHKey gen cmd (0x%02x)", status);
- tester_setup_failed();
- return;
- }
- }
- static void setup_le_generate_dhkey(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_set_event_mask sem;
- struct bt_hci_cmd_le_set_event_mask lsem;
- bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT,
- setup_le_read_local_pk_complete,
- (void *)test_data, NULL);
- memset(sem.mask, 0, 8);
- sem.mask[1] |= 0x20; /* Command Complete */
- sem.mask[1] |= 0x40; /* Command Status */
- sem.mask[7] |= 0x20; /* LE Meta */
- bt_hci_send(user->hci_ut, BT_HCI_CMD_SET_EVENT_MASK,
- &sem, sizeof(sem), NULL, NULL, NULL);
- memset(lsem.mask, 0, 8);
- lsem.mask[0] |= 0x80; /* LE Read Local P-256 Public Key Complete */
- lsem.mask[1] |= 0x01; /* LE Generate DHKey Complete */
- bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_EVENT_MASK,
- &lsem, sizeof(lsem), NULL, NULL, NULL);
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_READ_LOCAL_PK256, NULL,
- 0, setup_le_read_local_pk_status,
- NULL, NULL)) {
- tester_warn("Failed to send HCI LE Read Local PK256 command");
- tester_setup_failed();
- return;
- }
- }
- static void test_le_generate_dhkey_complete(const void *data, uint8_t size,
- void *user_data)
- {
- const uint8_t *event = data;
- const struct bt_hci_evt_le_generate_dhkey_complete *evt;
- struct le_keys *keys = user_data;
- uint8_t dhkey[32];
- if (*event != BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE) {
- tester_warn("Failed DHKey generation command");
- tester_test_failed();
- return;
- }
- evt = (void *)(event + 1);
- if (evt->status) {
- tester_warn("HCI Generate DHKey complete failed (0x%02x)",
- evt->status);
- tester_test_failed();
- return;
- }
- util_hexdump('>', evt->dhkey, 32, test_debug, NULL);
- util_hexdump('S', keys->remote_sk, 32, test_debug, NULL);
- util_hexdump('P', keys->local_pk, 64, test_debug, NULL);
- /* Generate DHKey ourself with local public key and remote
- * private key we got when generated public / private key
- * pair for BT_HCI_CMD_LE_GENERATE_DHKEY argument.
- */
- ecdh_shared_secret(keys->local_pk, keys->remote_sk, dhkey);
- util_hexdump('D', dhkey, 32, test_debug, NULL);
- if (!memcmp(dhkey, evt->dhkey, 32))
- tester_test_passed();
- else
- tester_test_failed();
- }
- static void test_le_generate_dhkey_status(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("Failed to send DHKey gen cmd (0x%02x)", status);
- tester_test_failed();
- return;
- }
- }
- static void test_le_generate_dhkey(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_le_generate_dhkey cmd;
- struct le_keys *keys = (void *)test_data;
- ecc_make_key(cmd.remote_pk256, keys->remote_sk);
- /* Unregister handler for META event */
- bt_hci_unregister(user->hci_ut, 1);
- bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT,
- test_le_generate_dhkey_complete, keys,
- NULL);
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_GENERATE_DHKEY, &cmd,
- sizeof(cmd), test_le_generate_dhkey_status,
- NULL, NULL)) {
- tester_warn("Failed to send HCI LE Encrypt command");
- tester_test_failed();
- return;
- }
- }
- static void test_inquiry_complete(const void *data, uint8_t size,
- void *user_data)
- {
- const struct bt_hci_evt_inquiry_complete *evt = data;
- if (evt->status) {
- tester_warn("HCI inquiry complete failed (0x%02x)",
- evt->status);
- tester_test_failed();
- return;
- }
- tester_test_passed();
- }
- static void test_inquiry_status(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("HCI inquiry command failed (0x%02x)", status);
- tester_test_failed();
- return;
- }
- }
- static void test_inquiry_liac(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_inquiry cmd;
- bt_hci_register(user->hci_ut, BT_HCI_EVT_INQUIRY_COMPLETE,
- test_inquiry_complete, NULL, NULL);
- cmd.lap[0] = 0x00;
- cmd.lap[1] = 0x8b;
- cmd.lap[2] = 0x9e;
- cmd.length = 0x08;
- cmd.num_resp = 0x00;
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_INQUIRY, &cmd, sizeof(cmd),
- test_inquiry_status, NULL, NULL)) {
- tester_warn("Failed to send HCI inquiry command");
- tester_test_failed();
- return;
- }
- }
- static void setup_lt_connectable_complete(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("Failed to set HCI scan enable (0x%02x)", status);
- tester_setup_failed();
- return;
- }
- tester_setup_complete();
- }
- static void setup_lt_connect_request_accept(const void *data, uint8_t size,
- void *user_data)
- {
- struct user_data *user = tester_get_data();
- const struct bt_hci_evt_conn_request *evt = data;
- struct bt_hci_cmd_accept_conn_request cmd;
- memcpy(cmd.bdaddr, evt->bdaddr, 6);
- cmd.role = 0x01;
- if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_ACCEPT_CONN_REQUEST,
- &cmd, sizeof(cmd), NULL, NULL, NULL)) {
- tester_warn("Failed to send HCI accept connection command");
- return;
- }
- }
- static void setup_lt_connectable(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_write_scan_enable cmd;
- bt_hci_register(user->hci_lt, BT_HCI_EVT_CONN_REQUEST,
- setup_lt_connect_request_accept, NULL, NULL);
- cmd.enable = 0x02;
- if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_WRITE_SCAN_ENABLE,
- &cmd, sizeof(cmd),
- setup_lt_connectable_complete, NULL, NULL)) {
- tester_warn("Failed to send HCI scan enable command");
- tester_setup_failed();
- return;
- }
- }
- static void test_create_connection_disconnect(void *user_data)
- {
- tester_test_passed();
- }
- static void test_create_connection_complete(const void *data, uint8_t size,
- void *user_data)
- {
- struct user_data *user = tester_get_data();
- const struct bt_hci_evt_conn_complete *evt = data;
- if (evt->status) {
- tester_warn("HCI create connection complete failed (0x%02x)",
- evt->status);
- tester_test_failed();
- return;
- }
- user->handle_ut = le16_to_cpu(evt->handle);
- tester_wait(2, test_create_connection_disconnect, NULL);
- }
- static void test_create_connection_status(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("HCI create connection command failed (0x%02x)",
- status);
- tester_test_failed();
- return;
- }
- }
- static void test_create_connection(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_create_conn cmd;
- bt_hci_register(user->hci_ut, BT_HCI_EVT_CONN_COMPLETE,
- test_create_connection_complete, NULL, NULL);
- memcpy(cmd.bdaddr, user->bdaddr_lt, 6);
- cmd.pkt_type = cpu_to_le16(0x0008);
- cmd.pscan_rep_mode = 0x02;
- cmd.pscan_mode = 0x00;
- cmd.clock_offset = cpu_to_le16(0x0000);
- cmd.role_switch = 0x01;
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_CREATE_CONN,
- &cmd, sizeof(cmd),
- test_create_connection_status,
- NULL, NULL)) {
- tester_warn("Failed to send HCI create connection command");
- tester_test_failed();
- return;
- }
- }
- static void teardown_timeout(void *user_data)
- {
- tester_teardown_complete();
- }
- static void teardown_disconnect_status(const void *data, uint8_t size,
- void *user_data)
- {
- uint8_t status = *((uint8_t *) data);
- if (status) {
- tester_warn("HCI disconnect failed (0x%02x)", status);
- tester_teardown_failed();
- return;
- }
- tester_wait(1, teardown_timeout, NULL);
- }
- static void teardown_connection(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_disconnect cmd;
- cmd.handle = cpu_to_le16(user->handle_ut);
- cmd.reason = 0x13;
- if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_DISCONNECT,
- &cmd, sizeof(cmd),
- teardown_disconnect_status,
- NULL, NULL)) {
- tester_warn("Failed to send HCI disconnect command");
- tester_test_failed();
- return;
- }
- }
- static void test_adv_report(const void *data, uint8_t size, void *user_data)
- {
- struct user_data *user = tester_get_data();
- uint8_t subevent = *((uint8_t *) data);
- const struct bt_hci_evt_le_adv_report *lar = data + 1;
- switch (subevent) {
- case BT_HCI_EVT_LE_ADV_REPORT:
- if (!memcmp(lar->addr, user->bdaddr_ut, 6))
- tester_setup_complete();
- break;
- }
- }
- static void setup_advertising_initiated(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_set_event_mask sem;
- struct bt_hci_cmd_le_set_event_mask lsem;
- struct bt_hci_cmd_le_set_scan_enable lsse;
- struct bt_hci_cmd_le_set_adv_parameters lsap;
- struct bt_hci_cmd_le_set_adv_enable lsae;
- bt_hci_register(user->hci_lt, BT_HCI_EVT_LE_META_EVENT,
- test_adv_report, NULL, NULL);
- memset(sem.mask, 0, 8);
- sem.mask[1] |= 0x20; /* Command Complete */
- sem.mask[1] |= 0x40; /* Command Status */
- sem.mask[7] |= 0x20; /* LE Meta */
- bt_hci_send(user->hci_lt, BT_HCI_CMD_SET_EVENT_MASK,
- &sem, sizeof(sem), NULL, NULL, NULL);
- memset(lsem.mask, 0, 8);
- lsem.mask[0] |= 0x02; /* LE Advertising Report */
- bt_hci_send(user->hci_lt, BT_HCI_CMD_LE_SET_EVENT_MASK,
- &lsem, sizeof(lsem), NULL, NULL, NULL);
- lsse.enable = 0x01;
- lsse.filter_dup = 0x00;
- bt_hci_send(user->hci_lt, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
- &lsse, sizeof(lsse), NULL, NULL, NULL);
- lsap.min_interval = cpu_to_le16(0x0800);
- lsap.max_interval = cpu_to_le16(0x0800);
- lsap.type = 0x03;
- lsap.own_addr_type = 0x00;
- lsap.direct_addr_type = 0x00;
- memset(lsap.direct_addr, 0, 6);
- lsap.channel_map = 0x07;
- lsap.filter_policy = 0x00;
- bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_ADV_PARAMETERS,
- &lsap, sizeof(lsap), NULL, NULL, NULL);
- lsae.enable = 0x01;
- bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_ADV_ENABLE,
- &lsae, sizeof(lsae), NULL, NULL, NULL);
- }
- static void test_reset_in_advertising_state_timeout(void *user_data)
- {
- struct user_data *user = tester_get_data();
- struct bt_hci_cmd_le_set_adv_enable lsae;
- struct bt_hci_cmd_le_set_scan_enable lsse;
- lsae.enable = 0x00;
- bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_ADV_ENABLE,
- &lsae, sizeof(lsae), NULL, NULL, NULL);
- lsse.enable = 0x00;
- lsse.filter_dup = 0x00;
- bt_hci_send(user->hci_lt, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
- &lsse, sizeof(lsse), NULL, NULL, NULL);
- tester_test_passed();
- }
- static void test_reset_in_advertising_state(const void *test_data)
- {
- struct user_data *user = tester_get_data();
- bt_hci_send(user->hci_ut, BT_HCI_CMD_RESET, NULL, 0, NULL, NULL, NULL);
- tester_wait(5, test_reset_in_advertising_state_timeout, NULL);
- }
- int main(int argc, char *argv[])
- {
- tester_init(&argc, &argv);
- test_hci_local("Reset", NULL, NULL, test_reset);
- test_hci_local("Read Local Version Information", NULL, NULL,
- test_read_local_version_information);
- test_hci_local("Read Local Supported Commands", NULL, NULL,
- test_read_local_supported_commands);
- test_hci_local("Read Local Supported Features", NULL, NULL,
- test_read_local_supported_features);
- test_hci_local("Read Local Extended Features", NULL,
- setup_features,
- test_read_local_extended_features);
- test_hci_local("Read Buffer Size", NULL, NULL,
- test_read_buffer_size);
- test_hci_local("Read Country Code", NULL, NULL,
- test_read_country_code);
- test_hci_local("Read BD_ADDR", NULL, NULL,
- test_read_bd_addr);
- test_hci_local("Read Local Supported Codecs", NULL, NULL,
- test_read_local_supported_codecs);
- test_hci_local("LE Read Accept List Size", NULL, NULL,
- test_le_read_accept_list_size);
- test_hci_local("LE Clear Accept List", NULL, NULL,
- test_le_clear_accept_list);
- test_hci_local("LE Encrypt", NULL, NULL,
- test_le_encrypt);
- test_hci_local("LE Rand", NULL, NULL,
- test_le_rand);
- test_hci_local("LE Read Local PK", &key_test_data, NULL,
- test_le_read_local_pk);
- test_hci_local("LE Generate DHKey", &key_test_data,
- setup_le_generate_dhkey,
- test_le_generate_dhkey);
- test_hci_local("Inquiry (LIAC)", NULL, NULL, test_inquiry_liac);
- test_hci("Create Connection", NULL,
- setup_lt_connectable,
- test_create_connection,
- teardown_connection);
- test_hci("TP/DSU/BV-02-C Reset in Advertising State", NULL,
- setup_advertising_initiated,
- test_reset_in_advertising_state, NULL);
- return tester_run();
- }
|