2014-09-04 12:54:55

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 0/6] android/tester: Cases for HIDHost security checks

This adds cases checking if Hidhost rejects connection from unknown HID Devices
and if proper security level is used for devices which requires encryption.

V2 changes:
* removed btdev hacks for which proper fix was already pushed
* smal function flow improvement for emu_remote_connect_hci_action()
* slightly reordered patch order

Jakub Tyszkowski (6):
android/tester: Allow HIDHost to use custom sdp response
android/tester: Add action to verify encryption change
android/tester: Add case verifying encryption on HIDHost
android/tester: Fix HIDHost cases sending fixed tid sdp responses
android/tester: Add support for rejected connections
android/tester: Add Hidhost rejecting connection case

android/tester-hidhost.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++-
android/tester-main.c | 64 +++++++++++++-
android/tester-main.h | 6 ++
3 files changed, 287 insertions(+), 5 deletions(-)

--
1.9.1



2014-09-04 12:54:56

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 1/6] android/tester: Allow HIDHost to use custom sdp response

This is needed to test security levels for different devices. So far we
had Mouse device but, we need to test security level elevation for
keyboards.
---
android/tester-hidhost.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index c7e3a67..b454db4 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -55,10 +55,17 @@ struct emu_cid_data {
uint16_t ctrl_cid;
uint16_t intr_handle;
uint16_t intr_cid;
+
+ void *user_data;
};

static struct emu_cid_data cid_data;

+struct raw_dataset {
+ const void *pdu;
+ int len;
+};
+
static const uint8_t did_req_pdu[] = { 0x06, /* PDU id */
0x00, 0x00, /* Transaction id */
0x00, 0x0f, /* Req length */
@@ -128,11 +135,17 @@ static const uint8_t hid_rsp_pdu[] = { 0x07, /* PDU id */
0x00, 0x09, 0x02, 0x0e, 0x28, 0x01,
0x00 }; /* no continuation */

+static struct raw_dataset hid_rsp_data = {
+ .pdu = hid_rsp_pdu,
+ .len = sizeof(hid_rsp_pdu),
+};
+
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);
struct emu_cid_data *cid_data = user_data;
+ struct raw_dataset *sdp_data = cid_data->user_data;

if (!memcmp(did_req_pdu, data, len)) {
bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
@@ -141,7 +154,7 @@ static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
}

bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
- hid_rsp_pdu, sizeof(hid_rsp_pdu));
+ sdp_data->pdu, sdp_data->len);
}
static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
{
@@ -150,6 +163,7 @@ static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)

cid_data.sdp_handle = handle;
cid_data.sdp_cid = cid;
+ cid_data.user_data = user_data;

bthost_add_cid_hook(bthost, handle, cid, hid_sdp_cid_hook_cb,
&cid_data);
@@ -267,7 +281,7 @@ static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
static struct emu_set_l2cap_data l2cap_setup_sdp_data = {
.psm = 1,
.func = hid_sdp_search_cb,
- .user_data = NULL,
+ .user_data = &hid_rsp_data,
};

/* Emulate Control Channel (PSM = 17) */
--
1.9.1


2014-09-04 12:54:58

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 3/6] android/tester: Add case verifying encryption on HIDHost

This case verifies if encryption is enabled when connecting to
HID Keyboard device.
---
android/tester-hidhost.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index b454db4..479be1e 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -140,6 +140,74 @@ static struct raw_dataset hid_rsp_data = {
.len = sizeof(hid_rsp_pdu),
};

+static const uint8_t hid_keyboard_rsp_pdu[] = { 0x07,
+ 0x00, 0x01, /* Transaction id */
+ 0x02, 0x04, /* Response length */
+ 0x02, 0x01, /* Attributes length */
+ 0x36, 0x01, 0xfe, 0x36, 0x01, 0x93, 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, 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, 0x10, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47,
+ 0x20, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64,
+ 0x09, 0x01, 0x01, 0x25, 0x08, 0x4b, 0x65, 0x79, 0x62,
+ 0x6f, 0x61, 0x72, 0x64, 0x09, 0x01, 0x02, 0x25, 0x0d,
+ 0x43, 0x53, 0x52, 0x20, 0x48, 0x49, 0x44, 0x45, 0x6e,
+ 0x67, 0x69, 0x6e, 0x65, 0x09, 0x02, 0x00, 0x09, 0x01,
+ 0x00, 0x09, 0x02, 0x01, 0x09, 0x01, 0x11, 0x09, 0x02,
+ 0x02, 0x08, 0x40, 0x09, 0x02, 0x03, 0x08, 0x23, 0x09,
+ 0x02, 0x04, 0x28, 0x01, 0x09, 0x02, 0x05, 0x28, 0x01,
+ 0x09, 0x02, 0x06, 0x35, 0xb7, 0x35, 0xb5, 0x08, 0x22,
+ 0x25, 0xb1, 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05,
+ 0x07, 0x85, 0x01, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00,
+ 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95,
+ 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05, 0x75, 0x01,
+ 0x05, 0x08, 0x85, 0x01, 0x19, 0x01, 0x29, 0x05, 0x91,
+ 0x02, 0x95, 0x01, 0x75, 0x03, 0x91, 0x03, 0x95, 0x06,
+ 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19,
+ 0x00, 0x29, 0x6f, 0x81, 0x00, 0xc0, 0x05, 0x0c, 0x09,
+ 0x01, 0xa1, 0x01, 0x85, 0x02, 0x05, 0x0c, 0x15, 0x00,
+ 0x25, 0x01, 0x75, 0x01, 0x95, 0x18, 0x09, 0xe2, 0x09,
+ 0xea, 0x09, 0xe9, 0x09, 0xb7, 0x09, 0xcd, 0x0a, 0x23,
+ 0x02, 0x0a, 0x8a, 0x01, 0x0a, 0x21, 0x02, 0x75, 0x01,
+ 0x95, 0x03, 0x81, 0x02, 0x75, 0x01, 0x95, 0x05, 0x81,
+ 0x01, 0x05, 0x08, 0x85, 0xff, 0x95, 0x01, 0x75, 0x02,
+ 0x09, 0x24, 0x09, 0x26, 0x81, 0x02, 0x75, 0x06, 0x81,
+ 0x01, 0xc0, 0x06, 0x7f, 0xff, 0x09, 0x01, 0xa1, 0x01,
+ 0x85, 0x03, 0x15, 0x00, 0x25, 0x01, 0x09, 0xb9, 0x09,
+ 0xb5, 0x09, 0xba, 0x09, 0xbb, 0x09, 0xbc, 0x09, 0xbd,
+ 0x09, 0xb6, 0x09, 0xb7, 0x75, 0x01, 0x95, 0x06, 0x81,
+ 0x02, 0x75, 0x01, 0x95, 0x02, 0x81, 0x01, 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, 0x1f, 0x40, 0x09, 0x02, 0x0d, 0x28, 0x00, 0x09,
+ 0x02, 0x0e, 0x28, 0x01, 0x36, 0x00, 0x65, 0x09, 0x00,
+ 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01,
+ 0x35, 0x03, 0x19, 0x12, 0x00, 0x09, 0x00, 0x04, 0x35,
+ 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x01,
+ 0x35, 0x03, 0x19, 0x00, 0x01, 0x09, 0x00, 0x06, 0x35,
+ 0x09, 0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01,
+ 0x00, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19,
+ 0x12, 0x00, 0x09, 0x01, 0x00, 0x09, 0x01, 0x01, 0x25,
+ 0x00, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02,
+ 0x01, 0x09, 0x23, 0x3d, 0x09, 0x02, 0x02, 0x09, 0x01,
+ 0x3d, 0x09, 0x02, 0x03, 0x09, 0x00, 0x00, 0x09, 0x02,
+ 0x04, 0x28, 0x01, 0x09, 0x02, 0x05, 0x09, 0x00, 0x02,
+ 0x00 }; /* no continuation */
+
+static struct raw_dataset hid_keyboard_rsp_data = {
+ .pdu = hid_keyboard_rsp_pdu,
+ .len = sizeof(hid_keyboard_rsp_pdu),
+};
+
static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
struct test_data *t_data = tester_get_data();
@@ -284,6 +352,12 @@ static struct emu_set_l2cap_data l2cap_setup_sdp_data = {
.user_data = &hid_rsp_data,
};

+static struct emu_set_l2cap_data l2cap_setup_keyboard_sdp_data = {
+ .psm = 1,
+ .func = hid_sdp_search_cb,
+ .user_data = &hid_keyboard_rsp_data,
+};
+
/* Emulate Control Channel (PSM = 17) */
static struct emu_set_l2cap_data l2cap_setup_cc_data = {
.psm = 17,
@@ -571,6 +645,28 @@ static struct test_case test_cases[] = {
BTHH_CONN_STATE_CONNECTED),
ACTION_SUCCESS(hidhost_send_data_action, NULL),
),
+ TEST_CASE_BREDRLE("HidHost Encrypted Out. Conn. Success",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
+ ACTION_SUCCESS(emu_add_l2cap_server_action,
+ &l2cap_setup_keyboard_sdp_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action,
+ &l2cap_setup_cc_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action,
+ &l2cap_setup_ic_data),
+ ACTION_SUCCESS(hidhost_connect_action, NULL),
+ CALLBACK_STATE(CB_HH_CONNECTION_STATE,
+ BTHH_CONN_STATE_CONNECTED),
+ ACTION_SUCCESS(hidhost_send_data_action, NULL),
+ ACTION_SUCCESS(bt_verify_encryption_action, NULL),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_HH_CONNECTION_STATE,
+ BTHH_CONN_STATE_DISCONNECTED),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};

struct queue *get_hidhost_tests(void)
--
1.9.1


2014-09-04 12:54:57

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 2/6] android/tester: Add action to verify encryption change

When encryption change is verified, encryption flag is cleared so we can
detect another encryption change when device reconnects during execution
of another step in the same test case.
---
android/tester-main.c | 38 ++++++++++++++++++++++++++++++++++++++
android/tester-main.h | 2 ++
2 files changed, 40 insertions(+)

diff --git a/android/tester-main.c b/android/tester-main.c
index f5f46fb..50aa12b 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -28,6 +28,8 @@ static gint scheduled_cbacks_num;
#define EMULATOR_SIGNAL_TIMEOUT 2 /* in seconds */
#define EMULATOR_SIGNAL "emulator_started"

+static const uint8_t hci_encr_change_hdr[] = { 0x04, 0x08, 0x04, 0x00 };
+
static gboolean check_callbacks_called(gpointer user_data)
{
/*
@@ -213,6 +215,25 @@ static void mgmt_debug(const char *str, void *user_data)
tester_print("%s%s", prefix, str);
}

+static bool hciemu_post_encr_hook(const void *data, uint16_t len,
+ void *user_data)
+{
+ struct test_data *t_data = tester_get_data();
+
+ /*
+ * Expected data: header (4 octets) + conn. handle (2 octets) +
+ * encryption flag (1 octet)
+ */
+ if (len < sizeof(hci_encr_change_hdr) + 3)
+ return true;
+
+ /* Verify header, skip conn. handle and check encryption */
+ if (!memcmp(hci_encr_change_hdr, data, sizeof(hci_encr_change_hdr)))
+ t_data->is_encrypted = ((uint8_t *)data)[6] ? true : false;
+
+ return true;
+}
+
static void read_info_callback(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -250,6 +271,10 @@ static void read_info_callback(uint8_t status, uint16_t length,
return;
}

+ /* set hook for encryption change */
+ hciemu_add_hook(data->hciemu, HCIEMU_HOOK_POST_EVT, 0x08,
+ hciemu_post_encr_hook, NULL);
+
tester_pre_setup_complete();
}

@@ -1804,6 +1829,19 @@ void emu_add_l2cap_server_action(void)
schedule_action_verification(step);
}

+void bt_verify_encryption_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->is_encrypted ? BT_STATUS_SUCCESS :
+ BT_STATUS_FAIL;
+
+ data->is_encrypted = false;
+
+ schedule_action_verification(step);
+}
+
static void rfcomm_connect_cb(uint16_t handle, uint16_t cid, void *user_data,
bool status)
{
diff --git a/android/tester-main.h b/android/tester-main.h
index 46aacce..cb8300d 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -331,6 +331,7 @@ struct test_data {
pid_t bluetoothd_pid;

struct queue *pdus;
+ bool is_encrypted;
};

/*
@@ -477,3 +478,4 @@ void bt_ssp_reply_accept_action(void);
void bt_cancel_bond_action(void);
void bt_remove_bond_action(void);
void set_default_ssp_request_handler(void);
+void bt_verify_encryption_action(void);
--
1.9.1


2014-09-04 12:55:01

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 6/6] android/tester: Add Hidhost rejecting connection case

This test case checks if hidhost rejects connections from
unknown devices.
---
android/tester-hidhost.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 100 insertions(+)

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index 143b5a6..915c9a0 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -42,6 +42,9 @@
#define HID_MODE_BREDR 0x01
#define HID_MODE_LE 0x02

+#define HID_MSG_CONTROL 0x10
+#define HID_VIRTUAL_CABLE_UNPLUG 0x05
+
#define HID_EXPECTED_REPORT_SIZE 0x02

static struct queue *list; /* List of hidhost test cases */
@@ -209,6 +212,15 @@ static struct raw_dataset hid_keyboard_rsp_data = {
.len = sizeof(hid_keyboard_rsp_pdu),
};

+static bt_scan_mode_t setprop_scan_mode_conn_val =
+ BT_SCAN_MODE_CONNECTABLE;
+
+static bt_property_t prop_test_scan_mode_conn = {
+ .type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .val = &setprop_scan_mode_conn_val,
+ .len = sizeof(setprop_scan_mode_conn_val),
+};
+
static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
struct test_data *t_data = tester_get_data();
@@ -280,6 +292,7 @@ static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
void *user_data)
{
struct emu_cid_data *cid_data = user_data;
+ struct test_data *t_data = tester_get_data();
uint8_t header = ((uint8_t *) data)[0];
struct step *step;

@@ -310,6 +323,14 @@ static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,

schedule_action_verification(step);
break;
+ case HID_MSG_CONTROL | HID_VIRTUAL_CABLE_UNPLUG:
+ if (t_data->expect_rejection) {
+ step = g_new0(struct step, 1);
+
+ step->action_status = BT_STATUS_SUCCESS;
+ schedule_action_verification(step);
+ }
+ break;
}
}
static void hid_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
@@ -508,6 +529,68 @@ static void hidhost_send_data_action(void)
}
}

+static void client_l2cap_rsp(uint8_t code, const void *data, uint16_t len,
+ void *user_data)
+{
+ static const uint8_t con_req[] = { 0x13, 0x00, /* PSM */
+ 0x41, 0x00 }; /* Source CID */
+ const uint16_t *psm = data;
+ struct test_data *t_data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+
+ if (len < sizeof(*psm)) {
+ tester_warn("Invalid l2cap response.");
+ return;
+ }
+
+ switch (*psm) {
+ case 0x40:
+ tester_print("Connected ctrl channel");
+
+ bthost_add_cid_hook(bthost, cid_data.ctrl_handle, 0x40,
+ hid_ctrl_cid_hook_cb, &cid_data);
+
+ cid_data.intr_handle = cid_data.ctrl_handle;
+
+ bthost_l2cap_req(bthost, cid_data.intr_handle, 0x02,
+ con_req, sizeof(con_req),
+ client_l2cap_rsp, &cid_data);
+ break;
+ case 0x41:
+ tester_print("Connected intr channel");
+
+ bthost_add_cid_hook(bthost, cid_data.intr_handle, 0x41,
+ hid_intr_cid_hook_cb, &cid_data);
+
+ break;
+ default:
+ break;
+ }
+}
+
+static void hidhost_conn_cb(uint16_t handle, void *user_data)
+{
+ static const uint8_t con_req[] = { 0x11, 0x00, /* PSM */
+ 0x40, 0x00 }; /* Source CID */
+
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+ if (data->hciemu_type == HCIEMU_TYPE_BREDR) {
+ tester_warn("Not handled device type.");
+ return;
+ }
+
+ cid_data.ctrl_cid = 0x40;
+ cid_data.ctrl_handle = handle;
+
+ tester_print("Sending L2CAP Request from remote");
+
+ bthost_l2cap_req(bthost, handle, 0x02,
+ con_req, sizeof(con_req),
+ client_l2cap_rsp, &cid_data);
+}
+
static struct test_case test_cases[] = {
TEST_CASE_BREDRLE("HidHost Init",
ACTION_SUCCESS(dummy_action, NULL),
@@ -653,6 +736,23 @@ static struct test_case test_cases[] = {
BTHH_CONN_STATE_CONNECTED),
ACTION_SUCCESS(hidhost_send_data_action, NULL),
),
+ TEST_CASE_BREDRLE("HidHost Reject Unknown Remote Connection",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(bt_set_property_action,
+ &prop_test_scan_mode_conn),
+ CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_add_l2cap_server_action,
+ &l2cap_setup_keyboard_sdp_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action,
+ &l2cap_setup_cc_data),
+ ACTION_SUCCESS(emu_add_l2cap_server_action,
+ &l2cap_setup_ic_data),
+ /* Trigger incoming connection */
+ ACTION_SUCCESS(emu_set_connect_cb_action, hidhost_conn_cb),
+ ACTION_SUCCESS(emu_remote_connect_hci_rejected_action, NULL),
+ ),
TEST_CASE_BREDRLE("HidHost Encrypted Out. Conn. Success",
ACTION_SUCCESS(bluetooth_enable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
--
1.9.1


2014-09-04 12:54:59

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 4/6] android/tester: Fix HIDHost cases sending fixed tid sdp responses

Multiple cases were affected because of hardcoded transaction id for
emulated remote's SDP responses.

This resulted in the following error in the daemon:
bluetoothd[13486]: sdp_process: Protocol error.

To solve this, sdp response counter was added.
---
android/tester-hidhost.c | 10 +++++++++-
android/tester-main.h | 2 ++
2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index 479be1e..143b5a6 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -21,6 +21,7 @@
#include "tester-main.h"

#include "android/utils.h"
+#include "src/shared/util.h"

#define HID_GET_REPORT_PROTOCOL 0x60
#define HID_GET_BOOT_PROTOCOL 0x61
@@ -214,6 +215,7 @@ static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
struct emu_cid_data *cid_data = user_data;
struct raw_dataset *sdp_data = cid_data->user_data;
+ uint8_t *sdp_buf;

if (!memcmp(did_req_pdu, data, len)) {
bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
@@ -221,8 +223,14 @@ static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
return;
}

+ /* Increment transaction id for each SDP response */
+ sdp_buf = g_memdup(sdp_data->pdu, sdp_data->len);
+ put_be16(++t_data->sdp_call_cnt, &sdp_buf[1]);
+
bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
- sdp_data->pdu, sdp_data->len);
+ sdp_buf, sdp_data->len);
+
+ g_free(sdp_buf);
}
static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
{
diff --git a/android/tester-main.h b/android/tester-main.h
index cb8300d..5fa4649 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -332,6 +332,8 @@ struct test_data {

struct queue *pdus;
bool is_encrypted;
+
+ uint16_t sdp_call_cnt;
};

/*
--
1.9.1


2014-09-04 12:55:00

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 5/6] android/tester: Add support for rejected connections

If we want the connection to be rejected, this can be notified to
remote in various ways. HIDHost expects virtual cable unplug.
This patch adds tester action for triggering connection, which requires
custom verification on remotes side. Hid host will verify it by
listenning on the ctrl channel for virtual cable unplug.
---
android/tester-main.c | 26 +++++++++++++++++++++++---
android/tester-main.h | 2 ++
2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/android/tester-main.c b/android/tester-main.c
index 50aa12b..8ee472b 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -1744,13 +1744,12 @@ void emu_set_connect_cb_action(void)
schedule_action_verification(step);
}

-void emu_remote_connect_hci_action(void)
+static void emu_remote_connect_hci_no_verify_action(void)
{
struct test_data *data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
struct step *current_data_step = queue_peek_head(data->steps);
struct bt_action_data *action_data = current_data_step->set_data;
- struct step *step = g_new0(struct step, 1);
const uint8_t *master_addr;

master_addr = hciemu_get_master_bdaddr(data->hciemu);
@@ -1763,8 +1762,29 @@ void emu_remote_connect_hci_action(void)
else
bthost_hci_connect(bthost, master_addr, BDADDR_BREDR);

- step->action_status = BT_STATUS_SUCCESS;
+ /* This needs custom action verification */
+}
+
+void emu_remote_connect_hci_rejected_action(void)
+{
+ struct test_data *data = tester_get_data();
+
+ data->expect_rejection = true;
+ emu_remote_connect_hci_no_verify_action();
+
+ /*
+ * To verify that remote's connection was rejected is to
+ * check it on remotes side.
+ */
+}

+void emu_remote_connect_hci_action(void)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ emu_remote_connect_hci_no_verify_action();
+
+ step->action_status = BT_STATUS_SUCCESS;
schedule_action_verification(step);
}

diff --git a/android/tester-main.h b/android/tester-main.h
index 5fa4649..885f08c 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -332,6 +332,7 @@ struct test_data {

struct queue *pdus;
bool is_encrypted;
+ bool expect_rejection;

uint16_t sdp_call_cnt;
};
@@ -457,6 +458,7 @@ void emu_setup_powered_remote_action(void);
void emu_set_pin_code_action(void);
void emu_set_ssp_mode_action(void);
void emu_set_connect_cb_action(void);
+void emu_remote_connect_hci_rejected_action(void);
void emu_remote_connect_hci_action(void);
void emu_remote_disconnect_hci_action(void);
void emu_set_io_cap(void);
--
1.9.1