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_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 client_cmd_complete(uint16_t opcode, uint8_t status, const void *param, uint8_t len, void *user_data) { struct test_data *data = tester_get_data(); const struct l2cap_data *test = data->test_data; struct bthost *bthost; bthost = hciemu_client_get_host(data->hciemu); switch (opcode) { case BT_HCI_CMD_WRITE_SCAN_ENABLE: case BT_HCI_CMD_LE_SET_ADV_ENABLE: tester_print("Client set connectable status 0x%02x", status); if (!status && test && test->enable_ssp) { bthost_write_ssp_mode(bthost, 0x01); return; } break; case BT_HCI_CMD_WRITE_SIMPLE_PAIRING_MODE: tester_print("Client enable SSP status 0x%02x", status); break; default: return; } if (status) tester_setup_failed(); else tester_setup_complete(); }
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) { tester_setup_failed(); return; } tester_print("Controller powered on"); 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) { 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 make_pk(struct test_data *data) { if (!ecc_make_key(data->local_pk, data->local_sk)) { tester_print("Failed to general local ECDH keypair"); tester_setup_failed(); return; } }
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_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 setup_powered_server_callback(uint8_t status, uint16_t length, const void *param, void *user_data) { if (status != MGMT_STATUS_SUCCESS) { tester_setup_failed(); return; } tester_print("Controller powered on"); tester_setup_complete(); }
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_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 client_connectable_complete(uint16_t opcode, uint8_t status, const void *param, uint8_t len, void *user_data) { if (opcode != BT_HCI_CMD_LE_SET_ADV_ENABLE) return; tester_print("Client set connectable status 0x%02x", status); if (status) tester_setup_failed(); else tester_setup_complete(); }
static void setup_le_generate_dhkey(const void *test_data) { struct user_data *user = tester_get_data(); bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT, setup_le_read_local_pk_complete, (void *)test_data, 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; } }
void tester_pre_setup_failed(void) { struct test_case *test; if (!test_current) return; test = test_current->data; if (test->stage != TEST_STAGE_PRE_SETUP) return; test->stage = TEST_STAGE_SETUP; tester_setup_failed(); }
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(); struct bthost *bthost; if (status != MGMT_STATUS_SUCCESS) { tester_setup_failed(); return; } tester_print("Controller powered on"); bthost = hciemu_client_get_host(data->hciemu); bthost_set_cmd_complete_cb(bthost, client_connectable_complete, data); bthost_set_adv_enable(bthost, 0x01, 0x00); }
static void server_cmd_complete(uint16_t opcode, uint8_t status, const void *param, uint8_t len, void *user_data) { switch (opcode) { case BT_HCI_CMD_WRITE_SIMPLE_PAIRING_MODE: tester_print("Server enable SSP status 0x%02x", status); break; default: return; } if (status) tester_setup_failed(); else tester_setup_complete(); }
static void toggle_powered_client_callback(uint8_t status, uint16_t length, const void *param, void *user_data) { bool power = PTR_TO_INT(user_data); if (status != MGMT_STATUS_SUCCESS) { tester_setup_failed(); return; } tester_print("Controller powered %s", power ? "on" : "off"); if (power) toggle_powered(false); else tester_setup_complete(); }
static void client_connectable_complete(uint16_t opcode, uint8_t status, const void *param, uint8_t len, void *user_data) { switch (opcode) { case BT_HCI_CMD_WRITE_SCAN_ENABLE: break; default: return; } tester_print("Client set connectable status 0x%02x", status); if (status) tester_setup_failed(); else tester_setup_complete(); }
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 setup_powered_server_callback(uint8_t status, uint16_t length, const void *param, void *user_data) { struct test_data *data = tester_get_data(); const struct l2cap_data *test = data->test_data; struct bthost *bthost; if (status != MGMT_STATUS_SUCCESS) { tester_setup_failed(); return; } tester_print("Controller powered on"); if (!test->enable_ssp) { tester_setup_complete(); return; } bthost = hciemu_client_get_host(data->hciemu); bthost_set_cmd_complete_cb(bthost, server_cmd_complete, user_data); bthost_write_ssp_mode(bthost, 0x01); }
static gboolean check_for_daemon(gpointer user_data) { int status; struct test_data *data = user_data; if ((waitpid(data->bluetoothd_pid, &status, WNOHANG)) != data->bluetoothd_pid) return true; if (data->setup_done) { if (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS)) { tester_test_passed(); return false; } tester_test_failed(); } else { tester_setup_failed(); test_post_teardown(data); } tester_warn("Unexpected Daemon shutdown with status %d", status); return false; }