diff --git a/android/android-tester.c b/android/android-tester.c
index 7f384ce..1167e98 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
static gint scheduled_cbacks_num = 0;
-static gboolean check_callbacks_called(gpointer user_data)
-{
- /*
- * Wait for all callbacks scheduled in current test context to execute
- * in main loop. This will avoid late callback calls after test case has
- * already failed or timed out.
- */
-
- if (g_atomic_int_get(&scheduled_cbacks_num) == 0) {
- tester_teardown_complete();
- return FALSE;
- }
-
- return TRUE;
-}
-static void check_daemon_term(void)
-{
- int status;
- pid_t pid;
- struct test_data *data = tester_get_data();
-
- if (!data)
- return;
-
- pid = waitpid(data->bluetoothd_pid, &status, WNOHANG);
- if (pid != data->bluetoothd_pid)
- return;
-
- data->bluetoothd_pid = 0;
-
- if (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS)) {
- g_idle_add(check_callbacks_called, NULL);
- return;
- }
-
- tester_warn("Unexpected Daemon shutdown with status %d", status);
-}
-
-static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
- gpointer user_data)
-{
- struct signalfd_siginfo si;
- ssize_t result;
- int fd;
-
- if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
- return FALSE;
-
- fd = g_io_channel_unix_get_fd(channel);
-
- result = read(fd, &si, sizeof(si));
- if (result != sizeof(si))
- return FALSE;
-
- switch (si.ssi_signo) {
- case SIGCHLD:
- check_daemon_term();
- break;
- }
-
- return TRUE;
-}
-
-static guint setup_signalfd(void)
-{
- GIOChannel *channel;
- guint source;
- sigset_t mask;
- int fd;
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGCHLD);
-
- if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
- return 0;
-
- fd = signalfd(-1, &mask, 0);
- if (fd < 0)
- return 0;
-
- channel = g_io_channel_unix_new(fd);
-
- g_io_channel_set_close_on_unref(channel, TRUE);
- g_io_channel_set_encoding(channel, NULL, NULL);
- g_io_channel_set_buffered(channel, FALSE);
-
- source = g_io_add_watch(channel,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- signal_handler, NULL);
-
- g_io_channel_unref(channel);
-
- return source;
-}
-
-static void mgmt_debug(const char *str, void *user_data)
-{
- const char *prefix = user_data;
-
- tester_print("%s%s", prefix, str);
-}
-
static void test_update_state(void)
{
struct test_data *data = tester_get_data();
return true;
}
-static void read_info_callback(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- struct test_data *data = tester_get_data();
- const struct mgmt_rp_read_info *rp = param;
- char addr[18];
- uint16_t manufacturer;
- uint32_t supported_settings, current_settings;
-
- tester_print("Read Info callback");
- tester_print(" Status: 0x%02x", status);
-
- if (status || !param) {
- tester_pre_setup_failed();
- return;
- }
-
- ba2str(&rp->bdaddr, addr);
- manufacturer = btohs(rp->manufacturer);
- supported_settings = btohl(rp->supported_settings);
- current_settings = btohl(rp->current_settings);
-
- tester_print(" Address: %s", addr);
- tester_print(" Version: 0x%02x", rp->version);
- tester_print(" Manufacturer: 0x%04x", manufacturer);
- tester_print(" Supported settings: 0x%08x", supported_settings);
- tester_print(" Current settings: 0x%08x", current_settings);
- tester_print(" Class: 0x%02x%02x%02x",
- rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
- tester_print(" Name: %s", rp->name);
- tester_print(" Short name: %s", rp->short_name);
-
- if (strcmp(hciemu_get_address(data->hciemu), addr)) {
- tester_pre_setup_failed();
- return;
- }
-
- tester_pre_setup_complete();
-}
-
-static void index_added_callback(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- struct test_data *data = tester_get_data();
-
- tester_print("Index Added callback");
- tester_print(" Index: 0x%04x", index);
-
- data->mgmt_index = index;
-
- mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
- read_info_callback, NULL, NULL);
-}
-
-static void index_removed_callback(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- struct test_data *data = tester_get_data();
-
- tester_print("Index Removed callback");
- tester_print(" Index: 0x%04x", index);
-
- if (index != data->mgmt_index)
- return;
-
- mgmt_unregister_index(data->mgmt, data->mgmt_index);
-
- mgmt_unref(data->mgmt);
- data->mgmt = NULL;
-
- tester_post_teardown_complete();
-}
-
-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();
-
- tester_print("Read Index List callback");
- tester_print(" Status: 0x%02x", status);
-
- if (status || !param) {
- tester_pre_setup_failed();
- return;
- }
-
- mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
- index_added_callback, NULL, NULL);
-
- mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
- index_removed_callback, NULL, NULL);
-
- data->hciemu = hciemu_new(data->hciemu_type);
- if (!data->hciemu) {
- tester_warn("Failed to setup HCI emulation");
- tester_pre_setup_failed();
- return;
- }
-
- tester_print("New hciemu instance created");
-}
-
-static void test_pre_setup(const void *test_data)
-{
- struct test_data *data = tester_get_data();
-
- data->signalfd = setup_signalfd();
- if (!data->signalfd) {
- tester_warn("Failed to setup signalfd");
- tester_pre_setup_failed();
- return;
- }
-
- data->mgmt = mgmt_new_default();
- if (!data->mgmt) {
- tester_warn("Failed to setup management interface");
- tester_pre_setup_failed();
- return;
- }
-
- if (!tester_use_debug())
- fclose(stderr);
- else
- mgmt_set_debug(data->mgmt, mgmt_debug, "mgmt: ", NULL);
-
- mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
- NULL, read_index_list_callback, NULL, NULL);
-}
-
-static void test_post_teardown(const void *test_data)
-{
- struct test_data *data = tester_get_data();
-
- hciemu_unref(data->hciemu);
- data->hciemu = NULL;
-
- g_source_remove(data->signalfd);
- data->signalfd = 0;
-}
-
-static void bluetoothd_start(int hci_index)
-{
- char prg_name[PATH_MAX];
- char index[8];
- char *prg_argv[5];
-
- snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
- snprintf(index, sizeof(index), "%d", hci_index);
-
- prg_argv[0] = prg_name;
- prg_argv[1] = "-i";
- prg_argv[2] = index;
- prg_argv[3] = "-d";
- prg_argv[4] = NULL;
-
- if (!tester_use_debug())
- fclose(stderr);
-
- execve(prg_argv[0], prg_argv, NULL);
-}
-
-static void emulator(int pipe, int hci_index)
-{
- static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
- char buf[1024];
- struct sockaddr_un addr;
- struct timeval tv;
- int fd;
- ssize_t len;
-
- fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (fd < 0)
- goto failed;
-
- tv.tv_sec = WAIT_FOR_SIGNAL_TIME;
- tv.tv_usec = 0;
- setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
-
- if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("Failed to bind system socket");
- goto failed;
- }
-
- len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL));
- if (len != sizeof(EMULATOR_SIGNAL))
- goto failed;
-
- memset(buf, 0, sizeof(buf));
-
- len = read(fd, buf, sizeof(buf));
- if (len <= 0 || strcmp(buf, "bluetooth.start=daemon"))
- goto failed;
-
- close(pipe);
- close(fd);
- return bluetoothd_start(hci_index);
-
-failed:
- close(pipe);
-
- if (fd >= 0)
- close(fd);
-}
-
static void emu_connectable_complete(uint16_t opcode, uint8_t status,
const void *param, uint8_t len,
void *user_data)
.le_test_mode_cb = NULL
};
-static bool setup(struct test_data *data)
-{
- const hw_module_t *module;
- hw_device_t *device;
- int signal_fd[2];
- char buf[1024];
- pid_t pid;
- int len;
- int err;
-
- if (pipe(signal_fd))
- return false;
-
- pid = fork();
-
- if (pid < 0) {
- close(signal_fd[0]);
- close(signal_fd[1]);
- return false;
- }
-
- if (pid == 0) {
- if (!tester_use_debug())
- fclose(stderr);
-
- close(signal_fd[0]);
- emulator(signal_fd[1], data->mgmt_index);
- exit(0);
- }
-
- close(signal_fd[1]);
- data->bluetoothd_pid = pid;
-
- len = read(signal_fd[0], buf, sizeof(buf));
- if (len <= 0 || strcmp(buf, EMULATOR_SIGNAL)) {
- close(signal_fd[0]);
- return false;
- }
-
- close(signal_fd[0]);
-
- err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
- if (err)
- return false;
-
- err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
- if (err)
- return false;
-
- data->device = device;
-
- data->if_bluetooth = ((bluetooth_device_t *)
- device)->get_bluetooth_interface();
- if (!data->if_bluetooth)
- return false;
-
- return true;
-}
-
-static void teardown(const void *test_data)
-{
- struct test_data *data = tester_get_data();
-
- if (data->if_hid) {
- data->if_hid->cleanup();
- data->if_hid = NULL;
- }
-
- if (data->if_bluetooth) {
- data->if_bluetooth->cleanup();
- data->if_bluetooth = NULL;
- }
-
- /* Test result already known, no need to check further */
- data->test_checks_valid = false;
-
- if (data->expected_properties_list)
- g_slist_free(data->expected_properties_list);
-
- data->device->close(data->device);
-
- if (!data->bluetoothd_pid)
- tester_teardown_complete();
-}
-
-static void test_dummy(const void *test_data)
-{
- tester_test_passed();
-}
-
const bt_bdaddr_t bdaddr_dummy = {
.address = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55}
};
.virtual_unplug_cb = hidhost_virual_unplug_cb
};
-static bool setup_hidhost(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- bt_status_t status;
- const void *hid;
-
- if (!setup(data))
- return false;
-
- status = data->if_bluetooth->init(&bt_callbacks);
- if (status != BT_STATUS_SUCCESS) {
- data->if_bluetooth = NULL;
- return false;
- }
-
- hid = data->if_bluetooth->get_profile_interface(BT_PROFILE_HIDHOST_ID);
- if (!hid)
- return false;
-
- data->if_hid = hid;
-
- status = data->if_hid->init(&bthh_callbacks);
- if (status != BT_STATUS_SUCCESS) {
- data->if_hid = NULL;
- return false;
- }
-
- return true;
-}
-
-static void setup_hidhost_interface(const void *test_data)
-{
- if (setup_hidhost(test_data))
- tester_setup_complete();
- else
- tester_setup_failed();
-}
-
-#define HID_GET_REPORT_PROTOCOL 0x60
-#define HID_GET_BOOT_PROTOCOL 0x61
-#define HID_SET_REPORT_PROTOCOL 0x70
-#define HID_SET_BOOT_PROTOCOL 0x71
-
-#define HID_SET_INPUT_REPORT 0x51
-#define HID_SET_OUTPUT_REPORT 0x52
-#define HID_SET_FEATURE_REPORT 0x53
-
-#define HID_SEND_DATA 0xa2
-
-#define HID_GET_INPUT_REPORT 0x49
-#define HID_GET_OUTPUT_REPORT 0x4a
-#define HID_GET_FEATURE_REPORT 0x4b
-
-static void hid_prepare_reply_protocol_mode(const void *data, uint16_t len)
-{
- struct test_data *t_data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- uint8_t pdu[2] = { 0, 0 };
- uint16_t pdu_len = 0;
-
- pdu_len = 2;
- pdu[0] = 0xa0;
- pdu[1] = 0x00;
-
- bthost_send_cid(bthost, t_data->ctrl_handle, t_data->ctrl_cid,
- (void *)pdu, pdu_len);
-}
-
-static void hid_prepare_reply_report(const void *data, uint16_t len)
-{
- struct test_data *t_data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- uint8_t pdu[3] = { 0, 0, 0 };
- uint16_t pdu_len = 0;
-
- pdu_len = 3;
- pdu[0] = 0xa2;
- pdu[1] = 0x01;
- pdu[2] = 0x00;
-
- bthost_send_cid(bthost, t_data->ctrl_handle, t_data->ctrl_cid,
- (void *)pdu, pdu_len);
-}
-
-static void hid_intr_cid_hook_cb(const void *data, uint16_t len,
- void *user_data)
-{
- uint8_t header = ((uint8_t *) data)[0];
-
- switch (header) {
- case HID_SEND_DATA:
- tester_test_passed();
- break;
- }
-}
-
-static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
-{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
-
- data->intr_handle = handle;
- data->intr_cid = cid;
-
- bthost_add_cid_hook(bthost, handle, cid, hid_intr_cid_hook_cb, NULL);
-}
-
-static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
- void *user_data)
-{
- uint8_t header = ((uint8_t *) data)[0];
-
- switch (header) {
- case HID_GET_REPORT_PROTOCOL:
- case HID_GET_BOOT_PROTOCOL:
- case HID_SET_REPORT_PROTOCOL:
- case HID_SET_BOOT_PROTOCOL:
- hid_prepare_reply_protocol_mode(data, len);
- break;
- case HID_GET_INPUT_REPORT:
- case HID_GET_OUTPUT_REPORT:
- case HID_GET_FEATURE_REPORT:
- hid_prepare_reply_report(data, len);
- break;
- /*
- * HID device doesnot reply for this commads, so reaching pdu's
- * to hid device means assuming test passed
- */
- case HID_SET_INPUT_REPORT:
- case HID_SET_OUTPUT_REPORT:
- case HID_SET_FEATURE_REPORT:
- case HID_SEND_DATA:
- tester_test_passed();
- break;
- }
-}
-
-static void hid_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
-{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
-
- data->ctrl_handle = handle;
- data->ctrl_cid = cid;
-
- bthost_add_cid_hook(bthost, handle, cid, hid_ctrl_cid_hook_cb, NULL);
-}
-
-static const uint8_t did_req_pdu[] = { 0x06, /* PDU id */
- 0x00, 0x00, /* Transaction id */
- 0x00, 0x0f, /* Req length */
- 0x35, 0x03, /* Attributes length */
- 0x19, 0x12, 0x00, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00,
- 0x00, 0xff, 0xff, 0x00 }; /* no continuation */
-
-static const uint8_t did_rsp_pdu[] = { 0x07, /* PDU id */
- 0x00, 0x00, /* Transaction id */
- 0x00, 0x4f, /* Response length */
- 0x00, 0x4c, /* Attributes length */
- 0x35, 0x4a, 0x35, 0x48, 0x09, 0x00, 0x00, 0x0a, 0x00,
- 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19,
- 0x12, 0x00, 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10,
- 0x02, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19,
- 0x12, 0x00, 0x09, 0x01, 0x03, 0x09, 0x02, 0x00, 0x09,
- 0x01, 0x03, 0x09, 0x02, 0x01, 0x09, 0x1d, 0x6b, 0x09,
- 0x02, 0x02, 0x09, 0x02, 0x46, 0x09, 0x02, 0x03, 0x09,
- 0x05, 0x0e, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09, 0x02,
- 0x05, 0x09, 0x00, 0x02,
- 0x00 }; /* no continuation */
-
-static const uint8_t hid_rsp_pdu[] = { 0x07, /* PDU id */
- 0x00, 0x01, /* Transaction id */
- 0x01, 0x71, /* Response length */
- 0x01, 0x6E, /* Attributes length */
- 0x36, 0x01, 0x6b, 0x36, 0x01, 0x68, 0x09, 0x00, 0x00,
- 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35,
- 0x03, 0x19, 0x11, 0x24, 0x09, 0x00, 0x04, 0x35, 0x0d,
- 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, 0x35,
- 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x05, 0x35, 0x03,
- 0x19, 0x10, 0x02, 0x09, 0x00, 0x06, 0x35, 0x09, 0x09,
- 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, 0x09,
- 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24,
- 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35,
- 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x13,
- 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, 0x25,
- 0x1e, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, 0x68,
- 0x20, 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74,
- 0x68, 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x4d,
- 0x35, 0x35, 0x35, 0x62, 0x09, 0x01, 0x01, 0x25, 0x0f,
- 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68,
- 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x09, 0x01, 0x02,
- 0x25, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63,
- 0x68, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02,
- 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, 0x02, 0x08, 0x80,
- 0x09, 0x02, 0x03, 0x08, 0x21, 0x09, 0x02, 0x04, 0x28,
- 0x01, 0x09, 0x02, 0x05, 0x28, 0x01, 0x09, 0x02, 0x06,
- 0x35, 0x74, 0x35, 0x72, 0x08, 0x22, 0x25, 0x6e, 0x05,
- 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01,
- 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15,
- 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02,
- 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xf8,
- 0x26, 0xff, 0x07, 0x75, 0x0c, 0x95, 0x02, 0x81, 0x06,
- 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95,
- 0x01, 0x81, 0x06, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x81,
- 0x06, 0x05, 0x09, 0x19, 0x09, 0x29, 0x10, 0x15, 0x00,
- 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0xc0,
- 0xc0, 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85,
- 0x10, 0x75, 0x08, 0x95, 0x06, 0x15, 0x00, 0x26, 0xff,
- 0x00, 0x09, 0x01, 0x81, 0x00, 0x09, 0x01, 0x91, 0x00,
- 0xc0, 0x09, 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09,
- 0x04, 0x09, 0x09, 0x01, 0x00, 0x09, 0x02, 0x08, 0x28,
- 0x00, 0x09, 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a,
- 0x28, 0x01, 0x09, 0x02, 0x0b, 0x09, 0x01, 0x00, 0x09,
- 0x02, 0x0c, 0x09, 0x0c, 0x80, 0x09, 0x02, 0x0d, 0x28,
- 0x00, 0x09, 0x02, 0x0e, 0x28, 0x01,
- 0x00 }; /* no continuation */
-
-static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
-{
- struct test_data *t_data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
-
- if (!memcmp(did_req_pdu, data, len)) {
- bthost_send_cid(bthost, t_data->sdp_handle, t_data->sdp_cid,
- did_rsp_pdu, sizeof(did_rsp_pdu));
- return;
- }
-
- bthost_send_cid(bthost, t_data->sdp_handle, t_data->sdp_cid,
- hid_rsp_pdu, sizeof(hid_rsp_pdu));
-}
-
-static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
-{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
-
- data->sdp_handle = handle;
- data->sdp_cid = cid;
-
- bthost_add_cid_hook(bthost, handle, cid, hid_sdp_cid_hook_cb, NULL);
-}
-
-static void emu_powered_complete(uint16_t opcode, uint8_t status,
- const void *param, uint8_t len,
- void *user_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
-
- switch (opcode) {
- case BT_HCI_CMD_WRITE_SCAN_ENABLE:
- case BT_HCI_CMD_LE_SET_ADV_ENABLE:
- break;
- default:
- return;
- }
-
- if (status) {
- tester_setup_failed();
- return;
- }
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->connect(&bdaddr);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_setup_failed();
-}
-
-static void setup_hidhost_connect(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- struct bthost *bthost;
-
- if (!setup_hidhost(test_data)) {
- tester_setup_failed();
- return;
- }
-
- bthost = hciemu_client_get_host(data->hciemu);
-
- /* Emulate SDP (PSM = 1) */
- bthost_add_l2cap_server(bthost, 1, hid_sdp_search_cb, NULL);
- /* Emulate Control Channel (PSM = 17) */
- bthost_add_l2cap_server(bthost, 17, hid_ctrl_connect_cb, NULL);
- /* Emulate Interrupt Channel (PSM = 19) */
- bthost_add_l2cap_server(bthost, 19, hid_intr_connect_cb, NULL);
-
- bthost_set_cmd_complete_cb(bthost, emu_powered_complete, data);
- bthost_write_scan_enable(bthost, 0x03);
-}
-
-static void hid_discon_cb(bt_bdaddr_t *bd_addr, bthh_connection_state_t state)
-{
- if (state == BTHH_CONN_STATE_DISCONNECTED)
- tester_test_passed();
-}
-
-static const struct hidhost_generic_data hidhost_test_disconnect = {
- .expected_hal_cb.connection_state_cb = hid_discon_cb,
-};
-
-static void test_hidhost_disconnect(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->disconnect(&bdaddr);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_test_failed();
-}
-
-static void test_hidhost_virtual_unplug(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->virtual_unplug(&bdaddr);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_test_failed();
-}
-
-static void hid_protocol_mode_cb(bt_bdaddr_t *bd_addr, bthh_status_t status,
- bthh_protocol_mode_t mode)
-{
- struct test_data *data = tester_get_data();
- const struct hidhost_generic_data *test = data->test_data;
-
- if (data->cb_count == test->expected_cb_count &&
- status == test->expected_status &&
- mode == test->expected_protocol_mode)
- tester_test_passed();
- else
- tester_test_failed();
-}
-
-static const struct hidhost_generic_data hidhost_test_get_protocol = {
- .expected_hal_cb.protocol_mode_cb = hid_protocol_mode_cb,
- .expected_cb_count = 1,
- .expected_protocol_mode = BTHH_BOOT_MODE,
- .expected_status = BTHH_OK,
-};
-
-static void test_hidhost_get_protocol(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->get_protocol(&bdaddr, BTHH_REPORT_MODE);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_test_failed();
-}
-
-static void test_hidhost_set_protocol(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->set_protocol(&bdaddr, BTHH_REPORT_MODE);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_test_failed();
-}
-
-static void test_hidhost_set_report(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
- char *buf = "010101";
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->set_report(&bdaddr, BTHH_INPUT_REPORT, buf);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_test_failed();
-}
-
-static void test_hidhost_send_data(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
- char *buf = "fe0201";
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->send_data(&bdaddr, buf);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_test_failed();
-}
-
-static void hid_get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t status,
- uint8_t *report, int size)
-{
- struct test_data *data = tester_get_data();
- const struct hidhost_generic_data *test = data->test_data;
-
- if (data->cb_count == test->expected_cb_count &&
- status == test->expected_status &&
- size == test->expected_report_size)
- tester_test_passed();
- else
- tester_test_failed();
-}
-
-static const struct hidhost_generic_data hidhost_test_get_report = {
- .expected_hal_cb.get_report_cb = hid_get_report_cb,
- .expected_cb_count = 1,
- .expected_status = BTHH_OK,
- .expected_report_size = 2,
-};
-
-static void test_hidhost_get_report(const void *test_data)
-{
- struct test_data *data = tester_get_data();
- const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
- bt_bdaddr_t bdaddr;
- bt_status_t bt_status;
-
- data->cb_count = 0;
- bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
- bt_status = data->if_hid->get_report(&bdaddr, BTHH_INPUT_REPORT, 1, 20);
- if (bt_status != BT_STATUS_SUCCESS)
- tester_test_failed();
-}
-
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
tester_init(&argc, &argv);
- test_bredrle("HIDHost Init", NULL, setup_hidhost_interface,
- test_dummy, teardown);
-
- test_bredrle("HIDHost Connect Success",
- NULL, setup_hidhost_connect,
- test_dummy, teardown);
-
- test_bredrle("HIDHost Disconnect Success",
- &hidhost_test_disconnect, setup_hidhost_connect,
- test_hidhost_disconnect, teardown);
-
- test_bredrle("HIDHost VirtualUnplug Success",
- &hidhost_test_disconnect, setup_hidhost_connect,
- test_hidhost_virtual_unplug, teardown);
-
- test_bredrle("HIDHost GetProtocol Success",
- &hidhost_test_get_protocol, setup_hidhost_connect,
- test_hidhost_get_protocol, teardown);
-
- test_bredrle("HIDHost SetProtocol Success",
- &hidhost_test_get_protocol, setup_hidhost_connect,
- test_hidhost_set_protocol, teardown);
-
- test_bredrle("HIDHost GetReport Success",
- &hidhost_test_get_report, setup_hidhost_connect,
- test_hidhost_get_report, teardown);
-
- test_bredrle("HIDHost SetReport Success",
- NULL, setup_hidhost_connect,
- test_hidhost_set_report, teardown);
-
- test_bredrle("HIDHost SendData Success",
- NULL, setup_hidhost_connect,
- test_hidhost_send_data, teardown);
return tester_run();
}