fpsensor: introduce fp_info_v3 Revert the previous format of the FP_INFO V2 host command. Introduce a new V3 version to support the updated format. This change is needed for backward compatibility, to support firmwares that use an old version of the v2 format. BUG=b:498133007 TEST="ectool.py fpinfo" for both version && ectool --name=cros_fp fpinfo Change-Id: I9014cf51c5da5800e5b064590a3f7799ad833ce1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/7716618 Tested-by: Dawid Niedźwiecki <dawidn@google.com> Reviewed-by: Patryk Duda <patrykd@google.com> Commit-Queue: Firas Sammoura <fsammoura@google.com>
diff --git a/common/fpsensor/fpsensor.cc b/common/fpsensor/fpsensor.cc index 27d33b0..0f8ce80 100644 --- a/common/fpsensor/fpsensor.cc +++ b/common/fpsensor/fpsensor.cc
@@ -442,11 +442,11 @@ static enum ec_status fp_command_info(struct host_cmd_handler_args *args) { - struct ec_response_fp_info_v2 *r = - static_cast<ec_response_fp_info_v2 *>(args->response); - const size_t response_size = - sizeof(struct ec_response_fp_info_v2) + - FP_MAX_CAPTURE_TYPES * sizeof(struct fp_image_frame_params); + struct ec_response_fp_info_v3 *r = + static_cast<ec_response_fp_info_v3 *>(args->response); + size_t response_size = + sizeof(struct ec_response_fp_info_v3) + + FP_MAX_CAPTURE_TYPES * sizeof(struct fp_image_frame_params_v2); if (response_size > args->response_max) { return EC_RES_OVERFLOW; @@ -470,11 +470,44 @@ r->template_info.template_dirty = global_context.templ_dirty; r->template_info.template_version = FP_TEMPLATE_FORMAT_VERSION; + if (args->version == 2) { + struct ec_response_fp_info_v2 *r_v2 = + static_cast<ec_response_fp_info_v2 *>(args->response); + /* Convert to v2 format. The formats differ only in the frame + * array, which is located at the end of the structures + * + * SAFETY: 'r->image_frame_params' and r_v2->image_frame_params + * overlap inexactly, but copying data is safe because we copy + * data forward (from the first field of the structure to the + * last). + */ + for (int i = 0; i < FP_MAX_CAPTURE_TYPES; i++) { + r_v2->image_frame_params[i].frame_size = + r->image_frame_params[i].frame_size; + r_v2->image_frame_params[i].pixel_format = + r->image_frame_params[i].pixel_format; + r_v2->image_frame_params[i].width = + r->image_frame_params[i].width; + r_v2->image_frame_params[i].height = + r->image_frame_params[i].height; + r_v2->image_frame_params[i].bpp = + r->image_frame_params[i].bpp; + r_v2->image_frame_params[i].fp_capture_type = + r->image_frame_params[i].fp_capture_type; + r_v2->image_frame_params[i].reserved = + r->image_frame_params[i].reserved; + } + response_size = sizeof(struct ec_response_fp_info_v2) + + FP_MAX_CAPTURE_TYPES * + sizeof(struct fp_image_frame_params); + } + args->response_size = response_size; return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_FP_INFO, fp_command_info, EC_VER_MASK(2)); +DECLARE_HOST_COMMAND(EC_CMD_FP_INFO, fp_command_info, + EC_VER_MASK(2) | EC_VER_MASK(3)); BUILD_ASSERT(FP_CONTEXT_NONCE_BYTES == 12);
diff --git a/common/fpsensor/fpsensor_debug.cc b/common/fpsensor/fpsensor_debug.cc index 19029cf..305a561 100644 --- a/common/fpsensor/fpsensor_debug.cc +++ b/common/fpsensor/fpsensor_debug.cc
@@ -66,7 +66,7 @@ */ test_export_static enum ec_error_list upload_pgm_image(uint8_t *frame, - const struct fp_image_frame_params &image_frame_params) + const struct fp_image_frame_params_v2 &image_frame_params) { uint8_t *ptr = frame; uint8_t bytes_per_pixel = DIV_ROUND_UP(image_frame_params.bpp, 8); @@ -129,15 +129,15 @@ } test_export_static int -get_image_frame_params(struct fp_image_frame_params &image_frame_params, +get_image_frame_params(struct fp_image_frame_params_v2 &image_frame_params, const enum fp_capture_type capture_type) { #if defined(HAVE_FP_PRIVATE_DRIVER) || defined(BOARD_HOST) size_t fp_sensor_get_info_v2_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * FP_MAX_CAPTURE_TYPES; + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; std::vector<uint8_t> buffer(fp_sensor_get_info_v2_size); - auto *info = reinterpret_cast<ec_response_fp_info_v2 *>(buffer.data()); + auto *info = reinterpret_cast<ec_response_fp_info_v3 *>(buffer.data()); if (fp_sensor_get_info(info, buffer.size()) < 0) { return EC_ERROR_UNKNOWN; @@ -177,7 +177,7 @@ const enum ec_error_list rc = fp_console_action(mode); if (rc == EC_SUCCESS) { - struct fp_image_frame_params image_frame_params{}; + struct fp_image_frame_params_v2 image_frame_params{}; int ret = get_image_frame_params( image_frame_params, global_context.current_capture_type); @@ -243,7 +243,7 @@ if (system_is_locked()) return EC_ERROR_ACCESS_DENIED; - struct fp_image_frame_params image_frame_params{}; + struct fp_image_frame_params_v2 image_frame_params{}; int ret = get_image_frame_params(image_frame_params, global_context.current_capture_type); if (ret != EC_RES_SUCCESS) { @@ -300,10 +300,10 @@ { #if defined(HAVE_FP_PRIVATE_DRIVER) || defined(BOARD_HOST) size_t fp_sensor_get_info_v2_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * FP_MAX_CAPTURE_TYPES; + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; std::vector<uint8_t> buffer(fp_sensor_get_info_v2_size); - auto *info = reinterpret_cast<ec_response_fp_info_v2 *>(buffer.data()); + auto *info = reinterpret_cast<ec_response_fp_info_v3 *>(buffer.data()); if (fp_sensor_get_info(info, buffer.size()) < 0) { ccprintf("Failed to get fp_info_v2\n");
diff --git a/common/fpsensor/fpsensor_frame_size.cc b/common/fpsensor/fpsensor_frame_size.cc index e6cb59d..c695872 100644 --- a/common/fpsensor/fpsensor_frame_size.cc +++ b/common/fpsensor/fpsensor_frame_size.cc
@@ -14,11 +14,11 @@ void FpFrameSizeCache::populate_cache(uint32_t max_frame_size_bytes) { const size_t buffer_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * frame_sizes_.size(); + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * frame_sizes_.size(); std::vector<uint8_t> buffer(buffer_size); - auto *info = reinterpret_cast<struct ec_response_fp_info_v2 *>( + auto *info = reinterpret_cast<struct ec_response_fp_info_v3 *>( buffer.data()); if (fp_sensor_get_info(info, buffer.size()) < 0) {
diff --git a/common/mock/fpsensor_mock.c b/common/mock/fpsensor_mock.c index 8f80514..bbac025 100644 --- a/common/mock/fpsensor_mock.c +++ b/common/mock/fpsensor_mock.c
@@ -32,7 +32,7 @@ return mock_ctrl_fp_sensor.fp_sensor_deinit_return; } -int fp_sensor_get_info(struct ec_response_fp_info_v2 *resp, size_t resp_size) +int fp_sensor_get_info(struct ec_response_fp_info_v3 *resp, size_t resp_size) { memset(resp, 0, sizeof(*resp));
diff --git a/driver/fingerprint/egis/egis_private.c b/driver/fingerprint/egis/egis_private.c index 341dc07..0688727 100644 --- a/driver/fingerprint/egis/egis_private.c +++ b/driver/fingerprint/egis/egis_private.c
@@ -44,7 +44,7 @@ .pixel_format = V4L2_PIX_FMT_GREY, .width = FP_SENSOR_RES_X_EGIS, \ .height = FP_SENSOR_RES_Y_EGIS, .bpp = FP_SENSOR_TEST_BPP_EGIS -static const struct fp_image_frame_params egis_image_frame_params[] = { +static const struct fp_image_frame_params_v2 egis_image_frame_params[] = { [EGIS_CAPTURE_NORMAL_FORMAT] = { EGIS_DEFAULT_IMAGE_PARAMS, @@ -163,9 +163,9 @@ return egis_sensor_deinit(); } -int fp_sensor_get_info(struct ec_response_fp_info_v2 *resp, size_t resp_size) +int fp_sensor_get_info(struct ec_response_fp_info_v3 *resp, size_t resp_size) { - if (sizeof(struct ec_response_fp_info_v2) + + if (sizeof(struct ec_response_fp_info_v3) + sizeof(egis_image_frame_params) > resp_size) { return EC_RES_OVERFLOW;
diff --git a/driver/fingerprint/elan/elan_private.c b/driver/fingerprint/elan/elan_private.c index e260645..05a0db6 100644 --- a/driver/fingerprint/elan/elan_private.c +++ b/driver/fingerprint/elan/elan_private.c
@@ -41,7 +41,7 @@ .pixel_format = V4L2_PIX_FMT_GREY, .width = FP_SENSOR_RES_X_ELAN, \ .height = FP_SENSOR_RES_Y_ELAN, .bpp = FP_SENSOR_RES_BPP_ELAN -static const struct fp_image_frame_params elan_image_frame_params[] = { +static const struct fp_image_frame_params_v2 elan_image_frame_params[] = { [ELAN_CAPTURE_VENDOR_FORMAT] = { ELAN_DEFAULT_IMAGE_PARAMS, @@ -177,18 +177,18 @@ } /** - * Fill the 'ec_response_fp_info_v2' buffer with the sensor information + * Fill the 'ec_response_fp_info_v3' buffer with the sensor information * * @param[out] resp retrieve the version, sensor and template information * * @return EC_SUCCESS on success. * @return EC_RES_ERROR on error. */ -int fp_sensor_get_info(struct ec_response_fp_info_v2 *resp, size_t resp_size) +int fp_sensor_get_info(struct ec_response_fp_info_v3 *resp, size_t resp_size) { CPRINTF("========%s=======\n", __func__); - if (sizeof(struct ec_response_fp_info_v2) + + if (sizeof(struct ec_response_fp_info_v3) + sizeof(elan_image_frame_params) > resp_size) { return EC_RES_OVERFLOW;
diff --git a/driver/fingerprint/fpc/bep/fpc_private.c b/driver/fingerprint/fpc/bep/fpc_private.c index f3605ed..1926e85 100644 --- a/driver/fingerprint/fpc/bep/fpc_private.c +++ b/driver/fingerprint/fpc/bep/fpc_private.c
@@ -62,7 +62,7 @@ .pixel_format = V4L2_PIX_FMT_GREY, .width = FP_SENSOR_RES_X_FPC, \ .height = FP_SENSOR_RES_Y_FPC, .bpp = FP_SENSOR_RES_BPP_FPC -static const struct fp_image_frame_params fpc1025_image_frame_params[] = { +static const struct fp_image_frame_params_v2 fpc1025_image_frame_params[] = { [FPC_CAPTURE_VENDOR_FORMAT] = { FPC1025_DEFAULT_RAW_IMAGE_PARAMS, @@ -292,9 +292,9 @@ return rc; } -int fp_sensor_get_info(struct ec_response_fp_info_v2 *resp, size_t resp_size) +int fp_sensor_get_info(struct ec_response_fp_info_v3 *resp, size_t resp_size) { - if (sizeof(struct ec_response_fp_info_v2) + + if (sizeof(struct ec_response_fp_info_v3) + sizeof(fpc1025_image_frame_params) > resp_size) { return EC_RES_OVERFLOW;
diff --git a/driver/fingerprint/fpc/libfp/fpc_private.c b/driver/fingerprint/fpc/libfp/fpc_private.c index d0d6e3b..130784b 100644 --- a/driver/fingerprint/fpc/libfp/fpc_private.c +++ b/driver/fingerprint/fpc/libfp/fpc_private.c
@@ -72,7 +72,7 @@ .pixel_format = V4L2_PIX_FMT_GREY, .width = FP_SENSOR_RES_X_FPC, \ .height = FP_SENSOR_RES_Y_FPC, .bpp = FP_SENSOR_RES_BPP_FPC -static const struct fp_image_frame_params fpc1145_image_frame_params[] = { +static const struct fp_image_frame_params_v2 fpc1145_image_frame_params[] = { [FPC_CAPTURE_VENDOR_FORMAT] = { FPC1145_DEFAULT_RAW_IMAGE_PARAMS, @@ -345,9 +345,9 @@ return EC_SUCCESS; } -int fp_sensor_get_info(struct ec_response_fp_info_v2 *resp, size_t resp_size) +int fp_sensor_get_info(struct ec_response_fp_info_v3 *resp, size_t resp_size) { - if (sizeof(struct ec_response_fp_info_v2) + + if (sizeof(struct ec_response_fp_info_v3) + sizeof(fpc1145_image_frame_params) > resp_size) { return EC_RES_OVERFLOW;
diff --git a/include/ec_cmd_api.h b/include/ec_cmd_api.h index 00b30f2..b374661 100644 --- a/include/ec_cmd_api.h +++ b/include/ec_cmd_api.h
@@ -144,6 +144,13 @@ return CROS_EC_COMMAND(h, EC_CMD_FP_INFO, 2, NULL, 0, r, resp_size); } +static inline int ec_cmd_fp_info_v3(CROS_EC_COMMAND_INFO *h, + struct ec_response_fp_info_v3 *r, + size_t resp_size) +{ + return CROS_EC_COMMAND(h, EC_CMD_FP_INFO, 3, NULL, 0, r, resp_size); +} + /* * Section 2: EC interface functions that can be generated with the help * of template macros.
diff --git a/include/ec_commands.h b/include/ec_commands.h index 0273820..c8cab3f 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h
@@ -8612,7 +8612,6 @@ struct fp_image_frame_params { /* Image frame characteristics */ uint32_t frame_size; - uint32_t image_data_offset_bytes; /**< Byte offset of image buffer */ uint32_t pixel_format; /* using V4L2_PIX_FMT_ */ uint16_t width; uint16_t height; @@ -8621,7 +8620,7 @@ uint8_t fp_capture_type; uint8_t reserved; /**< padding for alignment */ } __ec_align4; -BUILD_ASSERT(sizeof(struct fp_image_frame_params) == 20); +BUILD_ASSERT(sizeof(struct fp_image_frame_params) == 16); struct ec_response_fp_info_v2 { /* Sensor identification */ @@ -8634,6 +8633,31 @@ } __ec_align4; BUILD_ASSERT(sizeof(struct ec_response_fp_info_v2) == 36); +struct fp_image_frame_params_v2 { + /* Image frame characteristics */ + uint32_t frame_size; + uint32_t image_data_offset_bytes; /**< Byte offset of image buffer */ + uint32_t pixel_format; /* using V4L2_PIX_FMT_ */ + uint16_t width; + uint16_t height; + uint16_t bpp; + /** Type of image capture from enum fp_capture_type. */ + uint8_t fp_capture_type; + uint8_t reserved; /**< padding for alignment */ +} __ec_align4; +BUILD_ASSERT(sizeof(struct fp_image_frame_params_v2) == 20); + +struct ec_response_fp_info_v3 { + /* Sensor identification */ + struct fp_sensor_info sensor_info; + /* Template/finger current information */ + struct fp_template_info template_info; + /* fingerprint image frame parameters */ + struct fp_image_frame_params_v2 + image_frame_params[FLEXIBLE_ARRAY_MEMBER_SIZE]; +} __ec_align4; +BUILD_ASSERT(sizeof(struct ec_response_fp_info_v3) == 36); + /* Get the last captured finger frame or a template content */ #define EC_CMD_FP_FRAME 0x0404
diff --git a/include/fpsensor/fpsensor.h b/include/fpsensor/fpsensor.h index 70e2190..7428f75 100644 --- a/include/fpsensor/fpsensor.h +++ b/include/fpsensor/fpsensor.h
@@ -84,7 +84,7 @@ int fp_sensor_deinit(void); /** - * Fill the @p ec_response_fp_info_v2 buffer with the sensor information + * Fill the @p ec_response_fp_info_v3 buffer with the sensor information * as required by the EC_CMD_FP_INFO host command. * * Fills both the static information and information read from the sensor at @@ -96,7 +96,7 @@ * @return EC_SUCCESS on success * @return EC_RES_ERROR on error */ -int fp_sensor_get_info(struct ec_response_fp_info_v2 *resp, size_t resp_size); +int fp_sensor_get_info(struct ec_response_fp_info_v3 *resp, size_t resp_size); /** * Put the sensor in its lowest power state.
diff --git a/util/ectool_usb/ec_commands.py b/util/ectool_usb/ec_commands.py index 9886ccf..a55213c 100644 --- a/util/ectool_usb/ec_commands.py +++ b/util/ectool_usb/ec_commands.py
@@ -351,6 +351,63 @@ ) +class FpInfoCmd3(ECCommand): + """Gets FP information (version 3).""" + + def __init__(self): + # 4 bytes of vendor id + # 4 bytes of product id + # 4 bytes of model id + # 4 bytes of version + # 2 bytes of num of capture types + # 2 bytes of errors + # 4 bytes of template size + # 2 bytes of template max + # 2 bytes of template valid + # 4 bytes of template dirty + # 4 bytes of template version + # unknown number of image_frame + response_msg = [ + ("vendor_id", "I"), + ("product_id", "I"), + ("model_id", "I"), + ("version", "I"), + ("num_capture_types", "H"), + ("errors", "H"), + ("template_size", "I"), + ("template_max", "H"), + ("template_valid", "H"), + ("template_dirty", "I"), + ("template_version", "I"), + ("image_frame_params", ""), + ] + # fp_image_frame_params + # 4 bytes of frame_size; + # 4 bytes of image offset; + # 4 bytes of pixel_format; + # 2 bytes of width; + # 2 bytes of height; + # 2 bytes of bpp; + # 1 byte of fp_capture_type; + # 1 byte of reserved; + image_frame = [ + ("frame_size", "I"), + ("image_data_offset_bytes", "I"), + ("pixel_format", "I"), + ("width", "H"), + ("height", "H"), + ("bpp", "H"), + ("fp_capture_type", "B"), + ("reserved", "B"), + ] + super().__init__( + ECCommandsIds.FP_INFO, + 3, + response_msg=response_msg, + variable_payload_msg=image_frame, + ) + + class FpFrameCmd0(ECCommand): """Gets FP frame (version 0).""" @@ -561,7 +618,7 @@ ECCommandsIds.REBOOT_EC: {0: RebootECCmd0}, ECCommandsIds.ENTER_BOOTLOADER: {0: EnterBootloaderCmd0}, ECCommandsIds.FP_MODE: {0: FpModeCmd0}, - ECCommandsIds.FP_INFO: {1: FpInfoCmd1, 2: FpInfoCmd2}, + ECCommandsIds.FP_INFO: {1: FpInfoCmd1, 2: FpInfoCmd2, 3: FpInfoCmd3}, ECCommandsIds.FP_FRAME: {0: FpFrameCmd0, 1: FpFrameCmd1}, ECCommandsIds.FP_VENDOR: {0: FpVendorCmd0}, ECCommandsIds.RWSIG_ACTION: {0: RwSigActionCmd0},
diff --git a/util/ectool_usb/ectool.py b/util/ectool_usb/ectool.py index c61ba7b..9d4dbc4 100644 --- a/util/ectool_usb/ectool.py +++ b/util/ectool_usb/ectool.py
@@ -176,7 +176,7 @@ print("Template valid: " + str(fp_info.response.template_valid)) print("Template dirty: " + hex(fp_info.response.template_dirty)) print("Template version: " + hex(fp_info.response.template_version)) - elif fp_info.cmd_version == 2: + elif fp_info.cmd_version in (2, 3): print("Vendor ID: " + hex(fp_info.response.vendor_id)) print("Product ID: " + hex(fp_info.response.product_id)) print("Model ID: " + hex(fp_info.response.model_id)) @@ -196,6 +196,11 @@ ): print("Image frame params nr: " + str(i)) print("\tFrame size: " + str(image_frame_params.frame_size)) + if fp_info.cmd_version == 3: + print( + "\tImage offset: " + + str(image_frame_params.image_data_offset_bytes) + ) print("\tPixel format: " + hex(image_frame_params.pixel_format)) print("\tWidth: " + str(image_frame_params.width)) print("\tHeight: " + str(image_frame_params.height))
diff --git a/zephyr/shim/src/fpsensor.c b/zephyr/shim/src/fpsensor.c index 05ec62a..a79237c 100644 --- a/zephyr/shim/src/fpsensor.c +++ b/zephyr/shim/src/fpsensor.c
@@ -110,14 +110,14 @@ return 0; } -int fp_sensor_get_info(struct ec_response_fp_info_v2 *resp, size_t resp_size) +int fp_sensor_get_info(struct ec_response_fp_info_v3 *resp, size_t resp_size) { if (resp == NULL) { return -EINVAL; } const size_t expected_min_size = - sizeof(struct ec_response_fp_info_v2) + + sizeof(struct ec_response_fp_info_v3) + NUM_IMAGE_CAPTURE_TYPES * sizeof(struct fingerprint_image_frame_params);
diff --git a/zephyr/test/fingerprint/task/CMakeLists.txt b/zephyr/test/fingerprint/task/CMakeLists.txt index 83e3c1f..2e3d722 100644 --- a/zephyr/test/fingerprint/task/CMakeLists.txt +++ b/zephyr/test/fingerprint/task/CMakeLists.txt
@@ -31,3 +31,5 @@ src/fpsensor_ascp.cc) target_sources_ifdef(CONFIG_LINK_TEST_SUITE_FINGERPRINT_FRAME_SIZE app PRIVATE src/fpsensor_frame_size.cc) +target_sources_ifdef(CONFIG_LINK_TEST_SUITE_FINGERPRINT_FP_INFO app PRIVATE + src/fpsensor_fp_info.cc)
diff --git a/zephyr/test/fingerprint/task/Kconfig b/zephyr/test/fingerprint/task/Kconfig index b8cb7de..be44168 100644 --- a/zephyr/test/fingerprint/task/Kconfig +++ b/zephyr/test/fingerprint/task/Kconfig
@@ -74,4 +74,10 @@ Link and execute fingerprint subsystem tests that focus on finger frame size. +config LINK_TEST_SUITE_FINGERPRINT_FP_INFO + bool "Link fingerprint FP_INFO tests" + help + Link and execute fingerprint subsystem tests that focus + on FP_INFO host command. + source "Kconfig.zephyr"
diff --git a/zephyr/test/fingerprint/task/src/fpsensor_debug.cc b/zephyr/test/fingerprint/task/src/fpsensor_debug.cc index 872389c..33a5ca4 100644 --- a/zephyr/test/fingerprint/task/src/fpsensor_debug.cc +++ b/zephyr/test/fingerprint/task/src/fpsensor_debug.cc
@@ -25,11 +25,11 @@ 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) == +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 &image_frame_params, +int get_image_frame_params(struct fp_image_frame_params_v2 &image_frame_params, enum fp_capture_type capture_type); static int is_locked; @@ -188,7 +188,7 @@ enum ec_error_list upload_pgm_image(uint8_t *frame, - const struct fp_image_frame_params &image_frame_params); + const struct fp_image_frame_params_v2 &image_frame_params); ZTEST(fpsensor_debug, test_upload_pgm_image_wrong_bpp) { @@ -223,7 +223,7 @@ 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 zero_params{}; + 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 = @@ -236,7 +236,7 @@ } } - struct fp_image_frame_params image_frame_params{}; + struct fp_image_frame_params_v2 image_frame_params{}; int rv = get_image_frame_params(image_frame_params, current_capture_type); @@ -247,7 +247,7 @@ rv, current_capture_type); zassert_mem_equal( &image_frame_params, expected_params, - sizeof(struct fp_image_frame_params), + sizeof(struct fp_image_frame_params_v2), "Struct comparison failed for type %d", current_capture_type); } else { @@ -257,7 +257,7 @@ EC_ERROR_INVAL, rv); zassert_mem_equal( &image_frame_params, &zero_params, - sizeof(struct fp_image_frame_params), + sizeof(struct fp_image_frame_params_v2), "Struct contents should not change on failure"); } }
diff --git a/zephyr/test/fingerprint/task/src/fpsensor_enroll.cc b/zephyr/test/fingerprint/task/src/fpsensor_enroll.cc index fe01800..e612cc6 100644 --- a/zephyr/test/fingerprint/task/src/fpsensor_enroll.cc +++ b/zephyr/test/fingerprint/task/src/fpsensor_enroll.cc
@@ -35,11 +35,11 @@ static uint8_t image_buffer[IMAGE_SIZE]; static const size_t test_info_buffer_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * FP_MAX_CAPTURE_TYPES; + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; static uint8_t buffer[test_info_buffer_size]; -static struct ec_response_fp_info_v2 *test_info_buffer = - (struct ec_response_fp_info_v2 *)buffer; +static struct ec_response_fp_info_v3 *test_info_buffer = + (struct ec_response_fp_info_v3 *)buffer; static int enroll_percent; static int enroll_step_return_val; @@ -454,7 +454,7 @@ zassert_false(response.mode & FP_MODE_ENROLL_SESSION); /* Confirm that there is 1 valid template. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_valid, 1); /* Don't forget that template_dirty is a bitmask. */
diff --git a/zephyr/test/fingerprint/task/src/fpsensor_fp_info.cc b/zephyr/test/fingerprint/task/src/fpsensor_fp_info.cc new file mode 100644 index 0000000..5c56748 --- /dev/null +++ b/zephyr/test/fingerprint/task/src/fpsensor_fp_info.cc
@@ -0,0 +1,96 @@ +/* Copyright 2026 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 <zephyr/drivers/emul.h> +#include <zephyr/fff.h> +#include <zephyr/ztest.h> + +#include <ec_commands.h> +#include <fpsensor/fpsensor.h> +#include <fpsensor/fpsensor_state_driver.h> +#include <fpsensor/fpsensor_utils.h> +#include <fpsensor_driver.h> +#include <host_command.h> +#include <mkbp_event.h> + +DEFINE_FFF_GLOBALS; + +FAKE_VALUE_FUNC(int, mkbp_send_event, uint8_t); + +static const size_t fp_info_v3_buffer_size = + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; +static uint8_t fp_info_v3_buffer[fp_info_v3_buffer_size]; +static struct ec_response_fp_info_v3 *test_fp_info_v3_buffer = + (struct ec_response_fp_info_v3 *)fp_info_v3_buffer; + +/* Use the same response buffer size to store FP info data in v3 format. */ +static const size_t fp_info_v2_buffer_size = fp_info_v3_buffer_size; +static uint8_t fp_info_v2_buffer[fp_info_v2_buffer_size]; +static struct ec_response_fp_info_v2 *test_fp_info_v2_buffer = + (struct ec_response_fp_info_v2 *)fp_info_v2_buffer; + +ZTEST(fp_info, test_v2_v3) +{ + zassert_ok(ec_cmd_fp_info_v2(NULL, test_fp_info_v2_buffer, + fp_info_v2_buffer_size)); + zassert_ok(ec_cmd_fp_info_v3(NULL, test_fp_info_v3_buffer, + fp_info_v3_buffer_size)); + + zassert_equal(test_fp_info_v2_buffer->sensor_info.vendor_id, + test_fp_info_v3_buffer->sensor_info.vendor_id); + zassert_equal(test_fp_info_v2_buffer->sensor_info.product_id, + test_fp_info_v3_buffer->sensor_info.product_id); + zassert_equal(test_fp_info_v2_buffer->sensor_info.model_id, + test_fp_info_v3_buffer->sensor_info.model_id); + zassert_equal(test_fp_info_v2_buffer->sensor_info.version, + test_fp_info_v3_buffer->sensor_info.version); + zassert_equal(test_fp_info_v2_buffer->sensor_info.num_capture_types, + test_fp_info_v3_buffer->sensor_info.num_capture_types); + zassert_equal(test_fp_info_v2_buffer->sensor_info.errors, + test_fp_info_v3_buffer->sensor_info.errors); + + zassert_equal(test_fp_info_v2_buffer->template_info.template_size, + test_fp_info_v3_buffer->template_info.template_size); + zassert_equal(test_fp_info_v2_buffer->template_info.template_max, + test_fp_info_v3_buffer->template_info.template_max); + zassert_equal(test_fp_info_v2_buffer->template_info.template_valid, + test_fp_info_v3_buffer->template_info.template_valid); + zassert_equal(test_fp_info_v2_buffer->template_info.template_dirty, + test_fp_info_v3_buffer->template_info.template_dirty); + zassert_equal(test_fp_info_v2_buffer->template_info.template_version, + test_fp_info_v3_buffer->template_info.template_version); + for (int i = 0; i < FP_MAX_CAPTURE_TYPES; i++) { + zassert_equal( + test_fp_info_v2_buffer->image_frame_params[i].frame_size, + test_fp_info_v3_buffer->image_frame_params[i] + .frame_size); + zassert_equal(test_fp_info_v2_buffer->image_frame_params[i] + .pixel_format, + test_fp_info_v3_buffer->image_frame_params[i] + .pixel_format); + zassert_equal( + test_fp_info_v2_buffer->image_frame_params[i].width, + test_fp_info_v3_buffer->image_frame_params[i].width); + zassert_equal( + test_fp_info_v2_buffer->image_frame_params[i].height, + test_fp_info_v3_buffer->image_frame_params[i].height); + zassert_equal( + test_fp_info_v2_buffer->image_frame_params[i].bpp, + test_fp_info_v3_buffer->image_frame_params[i].bpp); + zassert_equal(test_fp_info_v2_buffer->image_frame_params[i] + .fp_capture_type, + test_fp_info_v3_buffer->image_frame_params[i] + .fp_capture_type); + zassert_equal( + test_fp_info_v2_buffer->image_frame_params[i].reserved, + test_fp_info_v3_buffer->image_frame_params[i].reserved); + } +} +ZTEST_SUITE(fp_info, NULL, NULL, NULL, NULL, NULL);
diff --git a/zephyr/test/fingerprint/task/src/fpsensor_init.cc b/zephyr/test/fingerprint/task/src/fpsensor_init.cc index 47c8fa0..0615300 100644 --- a/zephyr/test/fingerprint/task/src/fpsensor_init.cc +++ b/zephyr/test/fingerprint/task/src/fpsensor_init.cc
@@ -29,11 +29,11 @@ #define fp_sim DEVICE_DT_GET(DT_CHOSEN(cros_fp_fingerprint_sensor)) static const size_t test_info_buffer_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * FP_MAX_CAPTURE_TYPES; + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; static uint8_t buffer[test_info_buffer_size]; -static struct ec_response_fp_info_v2 *test_info_buffer = - (struct ec_response_fp_info_v2 *)buffer; +static struct ec_response_fp_info_v3 *test_info_buffer = + (struct ec_response_fp_info_v3 *)buffer; ZTEST_USER(fpsensor_init, test_tpm_seed_init) { @@ -126,7 +126,7 @@ const int dead_pixels = 3; /* Confirm that number of dead pixels is unknown. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal( FP_ERROR_DEAD_PIXELS(test_info_buffer->sensor_info.errors), @@ -148,7 +148,7 @@ zassert_true(state.maintenance_ran); /* Confirm that number of dead pixels is correct. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal( FP_ERROR_DEAD_PIXELS(test_info_buffer->sensor_info.errors), @@ -187,7 +187,7 @@ zassert_true(state.maintenance_ran); /* Confirm that number of dead pixels is correct. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal( FP_ERROR_DEAD_PIXELS(test_info_buffer->sensor_info.errors), @@ -226,7 +226,7 @@ zassert_true(state.maintenance_ran); /* Confirm that number of dead pixels is correct. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal( FP_ERROR_DEAD_PIXELS(test_info_buffer->sensor_info.errors), @@ -265,7 +265,7 @@ zassert_true(state.maintenance_ran); /* Confirm that number of dead pixels is correct. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal( FP_ERROR_DEAD_PIXELS(test_info_buffer->sensor_info.errors),
diff --git a/zephyr/test/fingerprint/task/src/fpsensor_match.cc b/zephyr/test/fingerprint/task/src/fpsensor_match.cc index 46440be2..e5888a1 100644 --- a/zephyr/test/fingerprint/task/src/fpsensor_match.cc +++ b/zephyr/test/fingerprint/task/src/fpsensor_match.cc
@@ -38,11 +38,11 @@ static const uint8_t fake_rollback_entropy[] = "some_rollback_entropy"; static const size_t test_info_buffer_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * FP_MAX_CAPTURE_TYPES; + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; static uint8_t buffer[test_info_buffer_size]; -static struct ec_response_fp_info_v2 *test_info_buffer = - (struct ec_response_fp_info_v2 *)buffer; +static struct ec_response_fp_info_v3 *test_info_buffer = + (struct ec_response_fp_info_v3 *)buffer; /* The fake TPM seed is "very_secret_32_bytes_of_tpm_seed" */ #define FAKE_TPM_SEED \ @@ -584,7 +584,7 @@ zassert_equal(mock_alg_match_fake.call_count, 1); /* Confirm that dirty templates bitmap is correct. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_dirty, 0x1); } @@ -631,7 +631,7 @@ zassert_equal(mock_alg_match_fake.call_count, 1); /* Confirm that dirty templates bitmap is correct. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_dirty, 0x0); } @@ -677,7 +677,7 @@ zassert_equal(mock_alg_match_fake.call_count, 1); /* Confirm that dirty templates bitmap is correct. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_dirty, 0x0); } @@ -723,7 +723,7 @@ /* Confirm that dirty templates bitmap is correct (no templates dirty). */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_dirty, 0x0); }
diff --git a/zephyr/test/fingerprint/task/src/fpsensor_shim.cc b/zephyr/test/fingerprint/task/src/fpsensor_shim.cc index c4bbb3c..af149eb 100644 --- a/zephyr/test/fingerprint/task/src/fpsensor_shim.cc +++ b/zephyr/test/fingerprint/task/src/fpsensor_shim.cc
@@ -49,11 +49,11 @@ DT_NODELABEL(fpsensor_sim)) }; static const size_t test_info_buffer_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * FP_MAX_CAPTURE_TYPES; + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; static uint8_t buffer[test_info_buffer_size]; -static struct ec_response_fp_info_v2 *test_info_buffer = - (struct ec_response_fp_info_v2 *)buffer; +static struct ec_response_fp_info_v3 *test_info_buffer = + (struct ec_response_fp_info_v3 *)buffer; ZTEST_USER(fpsensor_shim, test_shim_sensor_type_elan) {
diff --git a/zephyr/test/fingerprint/task/src/fpsensor_template.cc b/zephyr/test/fingerprint/task/src/fpsensor_template.cc index a1fc1ab..e42947a 100644 --- a/zephyr/test/fingerprint/task/src/fpsensor_template.cc +++ b/zephyr/test/fingerprint/task/src/fpsensor_template.cc
@@ -155,11 +155,11 @@ static uint8_t encrypted_template[FP_ALGORITHM_ENCRYPTED_TEMPLATE_SIZE]; static const size_t test_info_buffer_size = - sizeof(struct ec_response_fp_info_v2) + - sizeof(struct fp_image_frame_params) * FP_MAX_CAPTURE_TYPES; + sizeof(struct ec_response_fp_info_v3) + + sizeof(struct fp_image_frame_params_v2) * FP_MAX_CAPTURE_TYPES; static uint8_t buffer[test_info_buffer_size]; -static struct ec_response_fp_info_v2 *test_info_buffer = - (struct ec_response_fp_info_v2 *)buffer; +static struct ec_response_fp_info_v3 *test_info_buffer = + (struct ec_response_fp_info_v3 *)buffer; /* * Size of params buffer for FP_TEMPLATE command. Its size must be big enough @@ -226,7 +226,7 @@ } /* Confirm that there is 1 valid template. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_valid, 1); } @@ -295,7 +295,7 @@ zassert_equal(EC_RES_UNAVAILABLE, status); /* Confirm that there is no valid template. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_valid, 0); } @@ -1080,7 +1080,7 @@ } /* Confirm that there is 1 valid template. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_valid, 1); } @@ -1133,7 +1133,7 @@ } /* Confirm that there is no valid template. */ - zassert_ok(ec_cmd_fp_info_v2(NULL, test_info_buffer, + zassert_ok(ec_cmd_fp_info_v3(NULL, test_info_buffer, test_info_buffer_size)); zassert_equal(test_info_buffer->template_info.template_valid, 0); }
diff --git a/zephyr/test/fingerprint/task/testcase.yaml b/zephyr/test/fingerprint/task/testcase.yaml index 9a82af8..990c14a 100644 --- a/zephyr/test/fingerprint/task/testcase.yaml +++ b/zephyr/test/fingerprint/task/testcase.yaml
@@ -80,3 +80,9 @@ - CONFIG_LINK_TEST_SUITE_FINGERPRINT_FRAME_SIZE=y extra_conf_files: - prj.conf + + fingerprint.task.fp_info: + extra_configs: + - CONFIG_LINK_TEST_SUITE_FINGERPRINT_FP_INFO=y + extra_conf_files: + - prj.conf