[PATCH 04/11] android/tester: Add HIDhost Connect test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Emulated HID SDP and L2CAP Control and Interrupt channels.
---
 android/android-tester.c | 231 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 221 insertions(+), 10 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 6f0e962..0888a68 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -69,6 +69,16 @@ struct socket_data {
 	bool test_channel;
 };
 
+struct hidhost_generic_data {
+	bthh_status_t expected_status;
+	int expected_conn_state;
+	int expected_cb_count;
+	bthh_protocol_mode_t expected_protocol_mode;
+	int expected_report;
+	bthh_callbacks_t expected_hal_cb;
+	int expected_report_size;
+};
+
 #define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
 #define EMULATOR_SIGNAL "emulator_started"
 
@@ -97,6 +107,14 @@ struct test_data {
 
 	int cb_count;
 	GSList *expected_properties_list;
+
+	/* hidhost */
+	uint16_t sdp_handle;
+	uint16_t sdp_cid;
+	uint16_t ctrl_handle;
+	uint16_t ctrl_cid;
+	uint16_t intr_handle;
+	uint16_t intr_cid;
 };
 
 static char exec_dir[PATH_MAX + 1];
@@ -1933,15 +1951,6 @@ static bt_callbacks_t bt_callbacks = {
 	.le_test_mode_cb = NULL
 };
 
-static bthh_callbacks_t bthh_callbacks = {
-	.size = sizeof(bthh_callbacks),
-	.connection_state_cb = NULL,
-	.hid_info_cb = NULL,
-	.protocol_mode_cb = NULL,
-	.idle_time_cb = NULL,
-	.get_report_cb = NULL,
-	.virtual_unplug_cb = NULL
-};
 
 static void setup(struct test_data *data)
 {
@@ -3076,7 +3085,80 @@ clean:
 		close(sock_fd);
 }
 
-static void setup_hidhost_interface(const void *test_data)
+static void hidhost_connection_state_cb(bt_bdaddr_t *bd_addr,
+						bthh_connection_state_t state)
+{
+	struct test_data *data = tester_get_data();
+	const struct hidhost_generic_data *test = data->test_data;
+
+	data->cb_count++;
+
+	if (state == BTHH_CONN_STATE_CONNECTED)
+		tester_setup_complete();
+
+	if (test && test->expected_hal_cb.connection_state_cb)
+		test->expected_hal_cb.connection_state_cb(bd_addr, state);
+}
+
+static void hidhost_virual_unplug_cb(bt_bdaddr_t *bd_addr, bthh_status_t status)
+{
+	struct test_data *data = tester_get_data();
+	const struct hidhost_generic_data *test = data->test_data;
+
+	data->cb_count++;
+
+	if (test && test->expected_hal_cb.virtual_unplug_cb)
+		test->expected_hal_cb.virtual_unplug_cb(bd_addr, status);
+}
+
+static void hidhost_hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid)
+{
+	struct test_data *data = tester_get_data();
+	const struct hidhost_generic_data *test = data->test_data;
+
+	data->cb_count++;
+
+	if (test && test->expected_hal_cb.hid_info_cb)
+		test->expected_hal_cb.hid_info_cb(bd_addr, hid);
+}
+
+static void hidhost_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;
+
+	data->cb_count++;
+
+	if (test && test->expected_hal_cb.protocol_mode_cb)
+		test->expected_hal_cb.protocol_mode_cb(bd_addr, status, mode);
+}
+
+static void hidhost_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;
+
+	data->cb_count++;
+
+	if (test && test->expected_hal_cb.get_report_cb)
+		test->expected_hal_cb.get_report_cb(bd_addr, status, report,
+									size);
+}
+
+static bthh_callbacks_t bthh_callbacks = {
+	.size = sizeof(bthh_callbacks),
+	.connection_state_cb = hidhost_connection_state_cb,
+	.hid_info_cb = hidhost_hid_info_cb,
+	.protocol_mode_cb = hidhost_protocol_mode_cb,
+	.idle_time_cb = NULL,
+	.get_report_cb = hidhost_get_report_cb,
+	.virtual_unplug_cb = hidhost_virual_unplug_cb
+};
+
+static void setup_hidhost(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 	bt_status_t status;
@@ -3105,10 +3187,135 @@ static void setup_hidhost_interface(const void *test_data)
 		tester_setup_failed();
 		return;
 	}
+}
 
+static void setup_hidhost_interface(const void *test_data)
+{
+	setup_hidhost(test_data);
 	tester_setup_complete();
 }
 
+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);
+	uint8_t pdu[] = { 0x07, /* PDU id */
+				0x00, 0x00, /* 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 */};
+
+	bthost_send_cid(bthost, t_data->sdp_handle, t_data->sdp_cid,
+						(void *)pdu, sizeof(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;
+
+	setup_hidhost(test_data);
+
+	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, NULL, NULL);
+	/* Emulate Interrupt Channel (PSM = 19) */
+	bthost_add_l2cap_server(bthost, 19, NULL, NULL);
+
+	bthost_set_cmd_complete_cb(bthost, emu_powered_complete, data);
+	bthost_write_scan_enable(bthost, 0x03);
+}
+
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
 	do { \
 		struct test_data *user; \
@@ -3454,5 +3661,9 @@ int main(int argc, char *argv[])
 	test_bredrle("HIDHost Init", NULL, setup_hidhost_interface,
 						test_dummy, teardown);
 
+	test_bredrle("HIDHost Connect Success",
+				NULL, setup_hidhost_connect,
+				test_dummy, teardown);
+
 	return tester_run();
 }
-- 
1.8.3.2

--
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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux