blob: 33a5ca44bf6b4f3c23827c6eb1406a9e8f410355 [file]
/* Copyright 2024 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "common.h"
#include "console.h"
#include "system.h"
#include <stdio.h>
#include <zephyr/fff.h>
#include <zephyr/sys/util.h>
#include <zephyr/ztest.h>
#include <algorithm>
#include <array>
#include <ec_commands.h>
#include <fingerprint/v4l2_types.h>
#include <fpsensor/fpsensor_state_driver.h>
#include <fpsensor/fpsensor_utils.h>
#include <fpsensor_driver.h>
#include <mkbp_event.h>
#include <rollback.h>
static const struct device *const fp_sensor_dev =
DEVICE_DT_GET(DT_CHOSEN(cros_fp_fingerprint_sensor));
static_assert(sizeof(struct fp_image_frame_params_v2) ==
sizeof(struct fingerprint_image_frame_params),
"Frame param structures must be the same size");
int get_image_frame_params(struct fp_image_frame_params_v2 &image_frame_params,
enum fp_capture_type capture_type);
static int is_locked;
int system_is_locked(void)
{
return is_locked;
}
DEFINE_FFF_GLOBALS;
FAKE_VALUE_FUNC(int, mkbp_send_event, uint8_t);
ZTEST_SUITE(fpsensor_debug, NULL, NULL, NULL, NULL, NULL);
ZTEST(fpsensor_debug, test_console_fpinfo)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpinfo";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_SUCCESS);
}
/* TODO(b/371647536): Add other tests of commands in fpsensor_debug to verify
* entire handlers.
*/
ZTEST(fpsensor_debug, test_command_fpupload_success)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpupload 52 image";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_SUCCESS);
}
ZTEST(fpsensor_debug, test_command_fpupload_system_is_locked)
{
/* System is locked. */
is_locked = 1;
/* Test for the case when access is denied. */
char console_input[] = "fpupload 52 image";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_ACCESS_DENIED);
}
ZTEST(fpsensor_debug, test_command_fpupload_one_argument)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpupload 52";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_PARAM_COUNT);
}
ZTEST(fpsensor_debug, test_command_fpupload_three_arguments)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpupload 52 image 78";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_PARAM_COUNT);
}
ZTEST(fpsensor_debug, test_command_fpupload_negative_offset)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpupload -1 image";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_PARAM1);
}
ZTEST(fpsensor_debug,
test_command_fpupload_offset_equal_image_size_minus_image_offset)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpupload " STRINGIFY(UINT32_MAX) " image";
snprintf(console_input, sizeof(console_input),
"fpupload %" PRIu32 " image",
FP_SENSOR_IMAGE_SIZE - FP_SENSOR_IMAGE_OFFSET);
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_PARAM1);
}
ZTEST(fpsensor_debug, test_command_fpupload_correct_uploaded_values)
{
/* System is unlocked. */
is_locked = 0;
std::ranges::fill(fp_buffer, fp_buffer + FP_SENSOR_IMAGE_SIZE, 0);
char console_input[] = "fpupload 0 f16e38";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_SUCCESS);
zassert_equal(fp_buffer[FP_SENSOR_IMAGE_OFFSET], 241);
zassert_equal(fp_buffer[FP_SENSOR_IMAGE_OFFSET + 1], 110);
zassert_equal(fp_buffer[FP_SENSOR_IMAGE_OFFSET + 2], 56);
}
/* TODO(b/371647536): Add other tests of commands in fpsensor_debug to verify
* entire handlers.
*/
ZTEST(fpsensor_debug, test_command_fpcapture_system_is_locked)
{
/* System is locked. */
is_locked = 1;
char console_input[] = "fpcapture";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_ACCESS_DENIED);
}
ZTEST(fpsensor_debug, test_command_fpcapture_mode_is_negative)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpcapture -1";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_PARAM1);
}
ZTEST(fpsensor_debug, test_command_fpcapture_mode_is_too_large)
{
/* System is unlocked. */
is_locked = 0;
char console_input[] = "fpcapture 56";
snprintf(console_input, sizeof(console_input), "fpcapture %d",
FP_CAPTURE_TYPE_MAX);
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_PARAM1);
}
/* TODO(b/371647536): Add other tests of commands in fpsensor_debug to verify
* entire handlers.
*/
ZTEST(fpsensor_debug, test_command_fpenroll)
{
/* System is locked. */
is_locked = 1;
char console_input[] = "fpenroll";
int rv = shell_execute_cmd(get_ec_shell(), console_input);
zassert_equal(rv, EC_ERROR_ACCESS_DENIED);
}
enum ec_error_list
upload_pgm_image(uint8_t *frame,
const struct fp_image_frame_params_v2 &image_frame_params);
ZTEST(fpsensor_debug, test_upload_pgm_image_wrong_bpp)
{
std::array<uint8_t, 100> frame{};
zassert_equal(upload_pgm_image(frame.data(), { .bpp = 0 }),
EC_ERROR_UNKNOWN);
zassert_equal(upload_pgm_image(frame.data(), { .bpp = 17 }),
EC_ERROR_UNKNOWN);
zassert_equal(upload_pgm_image(frame.data(), { .bpp = 23 }),
EC_ERROR_UNKNOWN);
}
ZTEST(fpsensor_debug, test_get_image_frame_params)
{
struct fingerprint_sensor_info sensor_info{};
struct fingerprint_image_frame_params
image_frame_params_arr[NUM_IMAGE_CAPTURE_TYPES] = {};
uint8_t num_params = NUM_IMAGE_CAPTURE_TYPES;
zassert_ok(fingerprint_get_info(fp_sensor_dev, &sensor_info,
image_frame_params_arr, &num_params));
zassert_true(
num_params == NUM_IMAGE_CAPTURE_TYPES,
"fingerprint_get_info returned different params than expected");
constexpr auto kCaptureTypesArray = std::to_array(
{ FP_CAPTURE_VENDOR_FORMAT, FP_CAPTURE_DEFECT_PXL_TEST,
FP_CAPTURE_ABNORMAL_TEST, FP_CAPTURE_NOISE_TEST,
FP_CAPTURE_SIMPLE_IMAGE, FP_CAPTURE_PATTERN0,
FP_CAPTURE_PATTERN1, FP_CAPTURE_QUALITY_TEST,
FP_CAPTURE_RESET_TEST, FP_CAPTURE_TYPE_MAX });
constexpr struct fp_image_frame_params_v2 zero_params{};
for (enum fp_capture_type current_capture_type : kCaptureTypesArray) {
const struct fingerprint_image_frame_params *expected_params =
nullptr;
for (size_t j = 0; j < num_params; ++j) {
if (image_frame_params_arr[j].fp_capture_type ==
current_capture_type) {
expected_params = &image_frame_params_arr[j];
break;
}
}
struct fp_image_frame_params_v2 image_frame_params{};
int rv = get_image_frame_params(image_frame_params,
current_capture_type);
if (expected_params) {
zassert_equal(
rv, EC_RES_SUCCESS,
"get_image_frame_params failed with error %d for capture type %d",
rv, current_capture_type);
zassert_mem_equal(
&image_frame_params, expected_params,
sizeof(struct fp_image_frame_params_v2),
"Struct comparison failed for type %d",
current_capture_type);
} else {
zassert_equal(
rv, EC_ERROR_INVAL,
"Expected EC_ERROR_INVAL (%d), but got %d for invalid type",
EC_ERROR_INVAL, rv);
zassert_mem_equal(
&image_frame_params, &zero_params,
sizeof(struct fp_image_frame_params_v2),
"Struct contents should not change on failure");
}
}
}