--- android/android-tester.c | 881 ----------------------------------------------- 1 file changed, 881 deletions(-) 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 @@ -151,108 +151,6 @@ static char exec_dir[PATH_MAX]; 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(); @@ -374,214 +272,6 @@ static bool check_test_property(bt_property_t received_prop, 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) @@ -1963,96 +1653,6 @@ static bt_callbacks_t bt_callbacks = { .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} }; @@ -2295,453 +1895,6 @@ static bthh_callbacks_t bthh_callbacks = { .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; \ @@ -2774,39 +1927,5 @@ int main(int argc, char *argv[]) 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(); } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html