blob: c233b0b6962d793562fba615e5d8be3bdd72d92a [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <unittest/unittest.h>
#include "../../../system/dev/input/hid/hid-parser.h"
// See //system/utest/hid-parser/hid-report-data.cpp for the definitions of the test data.
extern "C" const uint8_t boot_mouse_r_desc[50];
extern "C" const uint8_t trinket_r_desc[173];
extern "C" const uint8_t ps3_ds_r_desc[148];
extern "C" const uint8_t acer12_touch_r_desc[660];
extern "C" const uint8_t eve_tablet_r_desc[28];
extern "C" const uint8_t asus_touch_desc[945];
// All sizes below are in bits. They also include the 8 bits for the report
// ID if the report ID is not 0.
hid_report_size_t boot_mouse_golden_sizes[] = {
{
.id = 0,
.in_size = 24,
.out_size = 0,
.feat_size = 0,
},
};
hid_reports_t boot_mouse_golden = {
.sizes = boot_mouse_golden_sizes,
.sizes_len = 1,
.num_reports = 1,
.has_rpt_id = 0,
};
hid_report_size_t trinket_golden_sizes[] = {
{
.id = 1,
.in_size = 32,
.out_size = 0,
.feat_size = 0,
},
{
.id = 2,
.in_size = 64,
.out_size = 16,
.feat_size = 0,
},
{
.id = 3,
.in_size = 24,
.out_size = 0,
.feat_size = 0,
},
{
.id = 4,
.in_size = 16,
.out_size = 0,
.feat_size = 0,
},
};
hid_reports_t trinket_golden = {
.sizes = trinket_golden_sizes,
.sizes_len = 4,
.num_reports = 4,
.has_rpt_id = 1,
};
hid_report_size_t eve_tablet_golden_sizes[] = {
{
.id = 0,
.in_size = 8,
.out_size = 0,
.feat_size = 0,
},
};
hid_reports_t eve_tablet_golden = {
.sizes = eve_tablet_golden_sizes,
.sizes_len = 1,
.num_reports = 1,
.has_rpt_id = 0,
};
hid_report_size_t ps3_golden_sizes[] = {
{
.id = 1,
.in_size = 392,
.out_size = 392,
.feat_size = 392,
},
{
.id = 2,
.in_size = 0,
.out_size = 0,
.feat_size = 392,
},
{
.id = 238,
.in_size = 0,
.out_size = 0,
.feat_size = 392,
},
{
.id = 239,
.in_size = 0,
.out_size = 0,
.feat_size = 392,
},
};
hid_reports_t ps3_golden = {
.sizes = ps3_golden_sizes,
.sizes_len = 4,
.num_reports = 4,
.has_rpt_id = 1,
};
hid_report_size_t acer12_golden_sizes[] = {
{
.id = 1,
.in_size = 488,
.out_size = 0,
.feat_size = 0,
},
{
.id = 10,
.in_size = 0,
.out_size = 0,
.feat_size = 16,
},
{
.id = 14,
.in_size = 0,
.out_size = 0,
.feat_size = 2056,
},
{
.id = 2,
.in_size = 520,
.out_size = 0,
.feat_size = 0,
},
{
.id = 3,
.in_size = 0,
.out_size = 264,
.feat_size = 0,
},
{
.id = 6,
.in_size = 0,
.out_size = 152,
.feat_size = 32,
},
{
.id = 4,
.in_size = 160,
.out_size = 0,
.feat_size = 0,
},
{
.id = 7,
.in_size = 64,
.out_size = 0,
.feat_size = 0,
},
{
.id = 23,
.in_size = 256,
.out_size = 0,
.feat_size = 0,
},
};
hid_reports_t acer12_golden = {
.sizes = acer12_golden_sizes,
.sizes_len = 9,
.num_reports = 9,
.has_rpt_id = 1,
};
hid_report_size_t asus_golden_sizes[] = {
{
.id = 1,
.in_size = 928,
.out_size = 0,
.feat_size = 0,
},
{
.id = 10,
.in_size = 0,
.out_size = 0,
.feat_size = 16,
},
{
.id = 68,
.in_size = 0,
.out_size = 0,
.feat_size = 2056,
},
{
.id = 2,
.in_size = 520,
.out_size = 0,
.feat_size = 0,
},
{
.id = 3,
.in_size = 0,
.out_size = 512,
.feat_size = 0,
},
{
.id = 4,
.in_size = 160,
.out_size = 0,
.feat_size = 0,
},
};
hid_reports_t asus_golden = {
.sizes = asus_golden_sizes,
.sizes_len = 6,
.num_reports = 6,
.has_rpt_id = 1,
};
static void print_hid_device_reports_compare(hid_reports_t* reps_a, hid_reports_t* reps_b) {
printf("\n");
for (int i = 0; i < (int)reps_a->num_reports; i++) {
hid_report_size_t rep_a = reps_a->sizes[i];
hid_report_size_t rep_b = reps_b->sizes[i];
printf("Report # %d\n", i);
printf("Report id %d %d\n", rep_a.id, rep_b.id);
printf("Report IN %d %d\n", rep_a.in_size, rep_b.in_size);
printf("Report OUT %d %d\n", rep_a.out_size, rep_b.out_size);
printf("Report FEAT %d %d\n", rep_a.feat_size, rep_b.feat_size);
}
}
#define NUM_REPORTS 100
hid_reports_t* allocate_hid_reports() {
hid_reports_t* reports = (hid_reports_t*)calloc(1, sizeof(hid_reports_t));
if (reports == nullptr) {
return nullptr;
}
reports->sizes = (hid_report_size_t*)calloc(NUM_REPORTS, sizeof(hid_report_size_t));
if (reports->sizes == nullptr) {
return nullptr;
}
reports->sizes_len = NUM_REPORTS;
return reports;
}
static bool parse_device(const uint8_t* dev_desc, int size, hid_reports_t *golden_reports) {
BEGIN_TEST;
hid_reports_t* hid_reports = allocate_hid_reports();
ASSERT_NONNULL(hid_reports);
auto status = hid_lib_parse_reports(dev_desc, size, hid_reports);
ASSERT_EQ(status, ZX_OK);
ASSERT_EQ(hid_reports->num_reports, golden_reports->num_reports);
for (int i = 0; i < (int)golden_reports->num_reports; i++) {
ASSERT_EQ(hid_reports->sizes[i].id,
golden_reports->sizes[i].id);
ASSERT_EQ(hid_reports->sizes[i].in_size,
golden_reports->sizes[i].in_size);
ASSERT_EQ(hid_reports->sizes[i].out_size,
golden_reports->sizes[i].out_size);
ASSERT_EQ(hid_reports->sizes[i].feat_size,
golden_reports->sizes[i].feat_size);
}
END_TEST;
}
static bool parse_trinket() {
return parse_device(trinket_r_desc, sizeof(trinket_r_desc), &trinket_golden);
}
static bool parse_boot_mouse() {
return parse_device(boot_mouse_r_desc, sizeof(boot_mouse_r_desc), &boot_mouse_golden);
}
static bool parse_eve_tablet() {
return parse_device(eve_tablet_r_desc, sizeof(eve_tablet_r_desc), &eve_tablet_golden);
}
static bool parse_ps3() {
return parse_device(ps3_ds_r_desc, sizeof(ps3_ds_r_desc), &ps3_golden);
}
static bool parse_acer12() {
return parse_device(acer12_touch_r_desc, sizeof(acer12_touch_r_desc), &acer12_golden);
}
static bool parse_asus() {
return parse_device(asus_touch_desc, sizeof(asus_touch_desc), &asus_golden);
}
BEGIN_TEST_CASE(hid_tests)
RUN_TEST(parse_boot_mouse)
RUN_TEST(parse_trinket)
RUN_TEST(parse_eve_tablet)
RUN_TEST(parse_ps3)
RUN_TEST(parse_acer12)
RUN_TEST(parse_asus)
END_TEST_CASE(hid_tests)