Compare commits

..

26 Commits

Author SHA1 Message Date
Benjamin Berg
afa37cbcbf device: Add API for perstistent data storage
API consumers should fetch the persistent data when they are done and
store it to disk. It is undefined when this data is updated by the
driver, but in general, it should only be updated once the first time
a device is used.
2022-07-12 22:39:01 +02:00
hermanlin
24e7e1f100 elanmoc: Make sure sensor in the right mode at identity
Signed-off-by: hermanlin <herman.lin@emc.com.tw>
2022-07-11 15:39:11 +00:00
Sam James
61f0f86904 nbis: fix build on musl
Drop re-definition of stderr. There's no need for this anywhere
(including glibc). This breaks in particular on musl because
stderr (and stdin) are both const, and macros unlike in glibc.

Bug: https://bugs.gentoo.org/853811
2022-07-03 02:36:55 +01:00
Benjamin Berg
08da0eb1e1 goodix: Make fingerlist parse error non-fatal
Otherwise we cannot recover from the error by doing a device reset.
2022-06-22 15:40:12 +00:00
Benjamin Berg
8552290bec goodix: Reset device if storage listing fails
When opening the device, query the stored prints. This should usually
always succeed (and it should be fast). If it fails, then we are very
likely dealing with a corrupted template storage on the device. In that
case, emit the command to clear the storage in order to reset the device
and get it back into a usable state.
2022-06-22 15:40:12 +00:00
Benjamin Berg
42c9003f49 goodix: Lower poor capture warnings to debug message
It is completely fine for a capture to have a low quality or fail. No
need to warn about this. Main reason to remove it though is so that
recordings that contain such a message do not trigger a failure.
2022-06-22 15:40:12 +00:00
ArronYen
7899bf4240 elanmoc: add PID 0x0c88 2022-06-20 14:03:05 +08:00
Benjamin Berg
d1fbf34fdf scripts: Update uncrustify configuration
The mod_full_brace_if_chain option needs an integer (we want method 1)
rather than a boolean.
2022-06-09 15:36:10 +02:00
Benjamin Berg
9c12b762a7 print: Fix indentation 2022-06-09 15:36:10 +02:00
Benjamin Berg
f20b8bc311 Release 1.94.4 2022-05-24 14:53:52 +02:00
Benjamin Berg
8b8dc0fec2 hwdb: Sync with wiki to add more unknown devices 2022-05-24 14:38:10 +02:00
Aris Lin
82d0f4288a synaptics: Add new PID 0x015F 2022-05-23 21:06:23 +08:00
Benjamin Berg
e86c45c988 device: Add missing errno.h include
This made the flatpak build fail.
2022-05-18 09:09:48 +02:00
Benjamin Berg
56ae75d2b2 device: Fully re-evaluate suspend/resume logic when delayed
If we delayed the suspend(/resume) call, then the circumstances may have
changed. In particular, an active action may have completed already
which means that the driver handler should not be called anymore.
2022-05-17 20:29:00 +02:00
Benjamin Berg
54a98bb286 device: Run critical section flushing with a high priority
These delayed calls are pushed into the mainloop for consistency.
However, they should run immediately and not be delayed, as such, it
makes sense to run them at a higher priority.

This actually solves an issue inside the CI where an URB reply is played
back even though it should be cancelled by the client.
2022-05-17 20:29:00 +02:00
Benjamin Berg
bfbe24b172 synaptics: Correctly handle critical section during interrupt resubmit
We re-aquire the critical section at the start of the callback, however,
it needs to be dropped again (or not taken) if the interrupt transfer is
resubmitted.
2022-05-17 20:29:00 +02:00
Benjamin Berg
1f925fef7c tests: Test suspend/resume and sysfs attributes in synaptics 2022-05-17 20:29:00 +02:00
Benjamin Berg
7b0093b4c6 tests: Reset the USB device before testing
The kernel caches URBs to get descriptor values. Doing a reset before
starting the record ensures that we will see any descriptor reads in the
usbmon trace and can therefore correctly replay them (possibly not true
if they happen multiple times).
2022-05-17 20:29:00 +02:00
Benjamin Berg
0fd5a617ab device: Do not update sysfs attributes if value is correct
This avoids spurious warnings on e.g. SELinux enabled systems.
2022-05-17 20:29:00 +02:00
Matthew Mirvish
e7d041d258 elanspi: add 04f3:241f
Reported as working with this config in
https://github.com/mincrmatt12/elan-spi-fingerprint/issues/11.
2022-05-08 18:32:29 -04:00
Josh Chen
eda8d13927 elan: add PID 0x0c4b 2022-04-14 17:21:52 +08:00
Aris Lin
5ba7ff8be9 synaptics: Add new PID 0x0168 2022-04-11 12:01:17 +00:00
Benjamin Berg
da1a56a600 context: Log version number at startup
Having this should at least give us a slightly better idea about the
version that the user has installed. Obviously it is still not very
accurate (maybe a git hash would be good if available?), but it should
still be helpful overall.
2022-04-10 13:58:58 +02:00
ArronYen
2b760dfa38 elanmoc: add PID 0x0c82 2022-03-02 10:43:20 +08:00
Benjamin Berg
f1a61c060f device: Clear the critical section source on destruction 2022-02-17 10:20:55 +01:00
Benjamin Berg
5fb3b8b43a tests: Avoid -Wdangling-pointer warning
The code is correct, but gcc thinks the pointer is still NULL after the
call. As obvious workaround don't seem to work, just disable the warning
for now.
2022-02-14 17:57:59 +01:00
48 changed files with 839 additions and 3148 deletions

View File

@@ -63,7 +63,7 @@ test:
variables: variables:
- $CI_PIPELINE_SOURCE == "schedule" - $CI_PIPELINE_SOURCE == "schedule"
script: script:
- meson --werror -Ddrivers=all -Db_coverage=true -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build - meson --werror -Ddrivers=all -Db_coverage=true . _build
- ninja -C _build - ninja -C _build
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3 - meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
- ninja -C _build coverage - ninja -C _build coverage
@@ -83,7 +83,7 @@ test_valgrind:
variables: variables:
- $CI_PIPELINE_SOURCE == "schedule" - $CI_PIPELINE_SOURCE == "schedule"
script: script:
- meson -Ddrivers=all -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build - meson -Ddrivers=all . _build
- ninja -C _build - ninja -C _build
- meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind - meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind
artifacts: artifacts:
@@ -167,20 +167,8 @@ container_fedora_build:
vala vala
libpcap-devel libpcap-devel
libudev-devel libudev-devel
mbedtls-devel
FDO_DISTRIBUTION_EXEC: | FDO_DISTRIBUTION_EXEC: |
git clone https://github.com/martinpitt/umockdev.git && \ git clone https://github.com/martinpitt/umockdev.git && \
cd umockdev && \ cd umockdev && \
meson _build --prefix=/usr && \ meson _build --prefix=/usr && \
ninja -C _build && ninja -C _build install ninja -C _build && ninja -C _build install
cd /tmp
mkdir -p /usr/local/bin
git clone https://github.com/benzea/SecureDeviceConnectionProtocol.git
# Don't bother with cmake
gcc -l mbedcrypto -I SecureDeviceConnectionProtocol/src/include \
SecureDeviceConnectionProtocol/src/test/virt_device.c \
SecureDeviceConnectionProtocol/src/client/client.c \
SecureDeviceConnectionProtocol/src/test/helpers.c \
SecureDeviceConnectionProtocol/src/test/testkeys.c \
-o /usr/local/bin/sdcp_virt_device
rm -rf SecureDeviceConnectionProtocol

11
NEWS
View File

@@ -1,6 +1,17 @@
This file lists notable changes in each release. For the full history of all This file lists notable changes in each release. For the full history of all
changes, see ChangeLog. changes, see ChangeLog.
2022-05-24: v1.94.4 release
Highlights:
* synaptics: New PIDs 0x0168, 0x015f
* elan: New PID 0x0c4b
* elanspi: New PID 0x241f
* synaptics: Minor fix to interrupt transfer resubmission
* Avoid sysfs writes if value is already expected
* Improvements to the testing setup
* Fixes to the internal critical section API
2021-11-02: v1.94.3 release 2021-11-02: v1.94.3 release
Highlights: Highlights:

View File

@@ -133,6 +133,7 @@ usb:v04F3p0C32*
usb:v04F3p0C33* usb:v04F3p0C33*
usb:v04F3p0C3D* usb:v04F3p0C3D*
usb:v04F3p0C42* usb:v04F3p0C42*
usb:v04F3p0C4B*
usb:v04F3p0C4D* usb:v04F3p0C4D*
usb:v04F3p0C4F* usb:v04F3p0C4F*
usb:v04F3p0C63* usb:v04F3p0C63*
@@ -144,6 +145,8 @@ usb:v04F3p0C58*
# Supported by libfprint driver elanmoc # Supported by libfprint driver elanmoc
usb:v04F3p0C7D* usb:v04F3p0C7D*
usb:v04F3p0C7E* usb:v04F3p0C7E*
usb:v04F3p0C82*
usb:v04F3p0C88*
ID_AUTOSUSPEND=1 ID_AUTOSUSPEND=1
ID_PERSIST=0 ID_PERSIST=0
@@ -187,6 +190,8 @@ usb:v06CBp0103*
usb:v06CBp0123* usb:v06CBp0123*
usb:v06CBp0126* usb:v06CBp0126*
usb:v06CBp0129* usb:v06CBp0129*
usb:v06CBp0168*
usb:v06CBp015F*
ID_AUTOSUSPEND=1 ID_AUTOSUSPEND=1
ID_PERSIST=0 ID_PERSIST=0
@@ -254,9 +259,9 @@ usb:v138Ap0091*
ID_PERSIST=0 ID_PERSIST=0
# Known unsupported devices # Known unsupported devices
usb:v04E8p730B*
usb:v04F3p036B* usb:v04F3p036B*
usb:v04F3p0C00* usb:v04F3p0C00*
usb:v04F3p0C4B*
usb:v04F3p0C4C* usb:v04F3p0C4C*
usb:v04F3p0C57* usb:v04F3p0C57*
usb:v04F3p0C5E* usb:v04F3p0C5E*
@@ -277,6 +282,7 @@ usb:v06CBp00C9*
usb:v06CBp00D8* usb:v06CBp00D8*
usb:v06CBp00DA* usb:v06CBp00DA*
usb:v06CBp00DC* usb:v06CBp00DC*
usb:v06CBp00E4*
usb:v06CBp00E7* usb:v06CBp00E7*
usb:v06CBp00E9* usb:v06CBp00E9*
usb:v06CBp00FD* usb:v06CBp00FD*
@@ -292,6 +298,7 @@ usb:v0A5Cp5845*
usb:v0BDAp5812* usb:v0BDAp5812*
usb:v10A5p0007* usb:v10A5p0007*
usb:v10A5p9200* usb:v10A5p9200*
usb:v10A5p9800*
usb:v1188p9545* usb:v1188p9545*
usb:v138Ap0007* usb:v138Ap0007*
usb:v138Ap003A* usb:v138Ap003A*
@@ -313,6 +320,7 @@ usb:v1C7Ap0576*
usb:v27C6p5042* usb:v27C6p5042*
usb:v27C6p5110* usb:v27C6p5110*
usb:v27C6p5117* usb:v27C6p5117*
usb:v27C6p5125*
usb:v27C6p5201* usb:v27C6p5201*
usb:v27C6p521D* usb:v27C6p521D*
usb:v27C6p5301* usb:v27C6p5301*
@@ -324,6 +332,7 @@ usb:v27C6p5385*
usb:v27C6p538C* usb:v27C6p538C*
usb:v27C6p538D* usb:v27C6p538D*
usb:v27C6p5395* usb:v27C6p5395*
usb:v27C6p5503*
usb:v27C6p5584* usb:v27C6p5584*
usb:v27C6p55A2* usb:v27C6p55A2*
usb:v27C6p55A4* usb:v27C6p55A4*

View File

@@ -40,6 +40,8 @@ fp_device_has_feature
fp_device_has_storage fp_device_has_storage
fp_device_supports_identify fp_device_supports_identify
fp_device_supports_capture fp_device_supports_capture
fp_device_get_persistent_data
fp_device_set_persistent_data
fp_device_is_open fp_device_is_open
fp_device_open fp_device_open
fp_device_close fp_device_close
@@ -100,12 +102,6 @@ FP_TYPE_IMAGE_DEVICE
FpImageDevice FpImageDevice
</SECTION> </SECTION>
<SECTION>
<FILE>fp-sdcp-device</FILE>
FP_TYPE_SDCP_DEVICE
FpSdcpDevice
</SECTION>
<SECTION> <SECTION>
<FILE>fp-print</FILE> <FILE>fp-print</FILE>
FP_TYPE_PRINT FP_TYPE_PRINT
@@ -221,26 +217,6 @@ fpi_image_device_retry_scan
fpi_image_device_set_bz3_threshold fpi_image_device_set_bz3_threshold
</SECTION> </SECTION>
<SECTION>
<FILE>fpi-sdcp-device</FILE>
<TITLE>Internal FpSdcpDevice</TITLE>
FpiSdcpClaim
FpSdcpDeviceClass
fpi_sdcp_claim_copy
fpi_sdcp_claim_free
fpi_sdcp_claim_get_type
fpi_sdcp_claim_new
fpi_sdcp_device_connect_complete
fpi_sdcp_device_get_connect_data
fpi_sdcp_device_get_reconnect_data
fpi_sdcp_device_reconnect_complete
fpi_sdcp_device_enroll_commit_complete
fpi_sdcp_device_enroll_ready
fpi_sdcp_device_enroll_set_nonce
fpi_sdcp_device_identify_retry
fpi_sdcp_device_identify_complete
</SECTION>
<SECTION> <SECTION>
<FILE>fpi-log</FILE> <FILE>fpi-log</FILE>
fp_dbg fp_dbg

View File

@@ -28,7 +28,6 @@
<xi:include href="xml/fp-context.xml"/> <xi:include href="xml/fp-context.xml"/>
<xi:include href="xml/fp-device.xml"/> <xi:include href="xml/fp-device.xml"/>
<xi:include href="xml/fp-image-device.xml"/> <xi:include href="xml/fp-image-device.xml"/>
<xi:include href="xml/fp-sdcp-device.xml"/>
<xi:include href="xml/fp-print.xml"/> <xi:include href="xml/fp-print.xml"/>
<xi:include href="xml/fp-image.xml"/> <xi:include href="xml/fp-image.xml"/>
</part> </part>
@@ -39,7 +38,6 @@
<title>Device methods for drivers</title> <title>Device methods for drivers</title>
<xi:include href="xml/fpi-device.xml"/> <xi:include href="xml/fpi-device.xml"/>
<xi:include href="xml/fpi-image-device.xml"/> <xi:include href="xml/fpi-image-device.xml"/>
<xi:include href="xml/fpi-sdcp-device.xml"/>
</chapter> </chapter>
<chapter id="driver-helpers"> <chapter id="driver-helpers">

View File

@@ -215,6 +215,7 @@ static const FpIdEntry elan_id_table[] = {
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV}, {.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c3d, .driver_data = ELAN_ALL_DEV}, {.vid = ELAN_VEND_ID, .pid = 0x0c3d, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42}, {.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
{.vid = ELAN_VEND_ID, .pid = 0x0c4b, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c4d, .driver_data = ELAN_ALL_DEV}, {.vid = ELAN_VEND_ID, .pid = 0x0c4d, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c4f, .driver_data = ELAN_ALL_DEV}, {.vid = ELAN_VEND_ID, .pid = 0x0c4f, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c63, .driver_data = ELAN_ALL_DEV}, {.vid = ELAN_VEND_ID, .pid = 0x0c63, .driver_data = ELAN_ALL_DEV},

View File

@@ -27,6 +27,8 @@ G_DEFINE_TYPE (FpiDeviceElanmoc, fpi_device_elanmoc, FP_TYPE_DEVICE)
static const FpIdEntry id_table[] = { static const FpIdEntry id_table[] = {
{ .vid = 0x04f3, .pid = 0x0c7d, }, { .vid = 0x04f3, .pid = 0x0c7d, },
{ .vid = 0x04f3, .pid = 0x0c7e, }, { .vid = 0x04f3, .pid = 0x0c7e, },
{ .vid = 0x04f3, .pid = 0x0c82, },
{ .vid = 0x04f3, .pid = 0x0c88, },
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
}; };
@@ -757,6 +759,7 @@ identify_status_report (FpiDeviceElanmoc *self, int verify_status_id,
} }
enum identify_states { enum identify_states {
IDENTIFY_SET_MODE,
IDENTIFY_WAIT_FINGER, IDENTIFY_WAIT_FINGER,
IDENTIFY_NUM_STATES, IDENTIFY_NUM_STATES,
}; };
@@ -792,6 +795,13 @@ elan_identify_run_state (FpiSsm *ssm, FpDevice *dev)
fp_info ("elanmoc %s ", __func__); fp_info ("elanmoc %s ", __func__);
switch (fpi_ssm_get_cur_state (ssm)) switch (fpi_ssm_get_cur_state (ssm))
{ {
case IDENTIFY_SET_MODE:
fp_info ("elanmoc %s IDENTIFY_SET_MODE", __func__);
cmd_buf = elanmoc_compose_cmd (&elanmoc_set_mod_cmd);
cmd_buf[3] = 0x03;
elanmoc_get_cmd (dev, cmd_buf, elanmoc_set_mod_cmd.cmd_len, elanmoc_set_mod_cmd.resp_len, 0, elanmoc_cmd_ack_cb);
break;
case IDENTIFY_WAIT_FINGER: case IDENTIFY_WAIT_FINGER:
fp_info ("elanmoc %s VERIFY_WAIT_FINGER", __func__); fp_info ("elanmoc %s VERIFY_WAIT_FINGER", __func__);
cmd_buf = elanmoc_compose_cmd (&elanmoc_verify_cmd); cmd_buf = elanmoc_compose_cmd (&elanmoc_verify_cmd);

View File

@@ -348,6 +348,7 @@ static const FpIdEntry elanspi_id_table[] = {
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x309f}, .driver_data = ELANSPI_180_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x309f}, .driver_data = ELANSPI_180_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x241f}, .driver_data = ELANSPI_NO_ROTATE},
{.udev_types = 0} {.udev_types = 0}
}; };

View File

@@ -661,7 +661,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
/* */ /* */
if (resp->result >= GX_FAILED) if (resp->result >= GX_FAILED)
{ {
fp_warn ("Capture sample failed, result: 0x%x", resp->result); fp_info ("Capture sample failed, result: 0x%x", resp->result);
fpi_device_enroll_progress (FP_DEVICE (self), fpi_device_enroll_progress (FP_DEVICE (self),
self->enroll_stage, self->enroll_stage,
NULL, NULL,
@@ -675,7 +675,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) || if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) ||
(resp->capture_data_resp.img_coverage < self->sensorcfg->config[5])) (resp->capture_data_resp.img_coverage < self->sensorcfg->config[5]))
{ {
fp_warn ("Capture sample poor quality(%d): %d or coverage(%d): %d", fp_info ("Capture sample poor quality(%d): %d or coverage(%d): %d",
self->sensorcfg->config[4], self->sensorcfg->config[4],
resp->capture_data_resp.img_quality, resp->capture_data_resp.img_quality,
self->sensorcfg->config[5], self->sensorcfg->config[5],
@@ -1041,6 +1041,47 @@ fp_init_config_cb (FpiDeviceGoodixMoc *self,
fpi_ssm_next_state (self->task_ssm); fpi_ssm_next_state (self->task_ssm);
} }
static void
fp_init_cb_reset_or_complete (FpiDeviceGoodixMoc *self,
gxfp_cmd_response_t *resp,
GError *error)
{
if (error)
{
fp_warn ("Template storage appears to have been corrupted! Error was: %s", error->message);
fp_warn ("A known reason for this to happen is a firmware bug triggered by another storage area being initialized.");
fpi_ssm_jump_to_state (self->task_ssm, FP_INIT_RESET_DEVICE);
}
else
{
fpi_ssm_mark_completed (self->task_ssm);
}
}
static void
fp_init_reset_device_cb (FpiDeviceGoodixMoc *self,
gxfp_cmd_response_t *resp,
GError *error)
{
if (error)
{
fp_warn ("Reset failed: %s", error->message);
fpi_ssm_mark_failed (self->task_ssm, error);
return;
}
if ((resp->result >= GX_FAILED) && (resp->result != GX_ERROR_FINGER_ID_NOEXIST))
{
fp_warn ("Reset failed, device reported: 0x%x", resp->result);
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Failed clear storage, result: 0x%x",
resp->result));
return;
}
fp_warn ("Reset completed");
fpi_ssm_mark_completed (self->task_ssm);
}
static void static void
fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device) fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
@@ -1065,6 +1106,30 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
sizeof (gxfp_sensor_cfg_t), sizeof (gxfp_sensor_cfg_t),
fp_init_config_cb); fp_init_config_cb);
break; break;
case FP_INIT_TEMPLATE_LIST:
/* List prints to check whether the template DB was corrupted.
* As of 2022-06-13 there is a known firmware issue that can cause the
* stored templates for Linux to be corrupted when the Windows storage
* area is initialized.
* In that case, we'll get a protocol failure trying to retrieve the
* list of prints.
*/
goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT,
FALSE,
(const guint8 *) &dummy,
1,
fp_init_cb_reset_or_complete);
break;
case FP_INIT_RESET_DEVICE:
fp_warn ("Resetting device storage, you will need to enroll all prints again!");
goodix_sensor_cmd (self, MOC_CMD0_DELETETEMPLATE, MOC_CMD1_DELETE_ALL,
FALSE,
NULL,
0,
fp_init_reset_device_cb);
break;
} }

View File

@@ -35,6 +35,8 @@ typedef enum {
typedef enum { typedef enum {
FP_INIT_VERSION = 0, FP_INIT_VERSION = 0,
FP_INIT_CONFIG, FP_INIT_CONFIG,
FP_INIT_TEMPLATE_LIST,
FP_INIT_RESET_DEVICE,
FP_INIT_NUM_STATES, FP_INIT_NUM_STATES,
} FpInitState; } FpInitState;

View File

@@ -393,10 +393,8 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c
fingerid_length, fingerid_length,
&presp->finger_list_resp.finger_list[num]) != 0) &presp->finger_list_resp.finger_list[num]) != 0)
{ {
g_error ("parse fingerlist error"); g_warning ("Failed to parse finger list");
presp->finger_list_resp.finger_num = 0; return -1;
presp->result = GX_FAILED;
break;
} }
offset += fingerid_length; offset += fingerid_length;
} }

View File

@@ -42,6 +42,8 @@ static const FpIdEntry id_table[] = {
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0123, }, { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0123, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, }, { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0129, }, { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0129, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0168, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x015F, },
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
}; };
@@ -224,6 +226,7 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
} }
else else
{ {
fpi_device_critical_leave (device);
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer), fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer),
0, 0,
NULL, NULL,

View File

@@ -1,676 +0,0 @@
/*
* Virtual driver for SDCP device debugging
*
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This is a virtual test driver to test the basic SDCP functionality.
* It uses the test binaries from Microsoft, which were extended to allow
* a simple chat with the device.
* The environment variable contains the to be executed binary including
* arguments. This binary should be compiled from the code in
* https://github.com/Microsoft/SecureDeviceConnectionProtocol
* or, until it is merged upstream
* https://github.com/benzea/SecureDeviceConnectionProtocol
*
* Note that using this as an external executable has the advantage that we
* do not need to link against mbedtls or any other crypto library.
*/
#define FP_COMPONENT "virtual_sdcp"
#include "fpi-log.h"
#include "fpi-ssm.h"
#include "../fpi-sdcp-device.h"
#include <glib/gstdio.h>
#include <gio/gio.h>
struct _FpDeviceVirtualSdcp
{
FpSdcpDevice parent;
GSubprocess *proc;
GOutputStream *proc_stdin;
GInputStream *proc_stdout;
/* Only valid while a read/write is pending */
GByteArray *msg_out;
GByteArray *msg_in;
GByteArray *connect_msg;
};
G_DECLARE_FINAL_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FPI, DEVICE_VIRTUAL_SDCP, FpSdcpDevice)
G_DEFINE_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FP_TYPE_SDCP_DEVICE)
guint8 ca_1[] = {
0x30, 0x82, 0x03, 0xFD, 0x30, 0x82, 0x03, 0x82, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
0x00, 0x00, 0x00, 0x07, 0xE8, 0x9D, 0x61, 0x62, 0x4D, 0x46, 0x0F, 0x95, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81,
0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25,
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65,
0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41,
0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x33, 0x31, 0x31,
0x39, 0x35, 0x34, 0x35, 0x33, 0x5A, 0x17, 0x0D, 0x32, 0x38, 0x30, 0x31, 0x33, 0x31, 0x32, 0x30,
0x30, 0x34, 0x35, 0x33, 0x5A, 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57,
0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55,
0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06,
0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20,
0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x27, 0x30, 0x25, 0x06,
0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65,
0x6C, 0x6C, 0x6F, 0x20, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x20, 0x43, 0x41, 0x20,
0x32, 0x30, 0x31, 0x38, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xBE,
0x4B, 0x90, 0x6E, 0x24, 0xFC, 0xA1, 0x53, 0xC8, 0xA7, 0x3C, 0x70, 0xE8, 0x97, 0xCD, 0x1B, 0x31,
0xE4, 0x95, 0x91, 0x7A, 0x58, 0xA2, 0x86, 0xA8, 0x70, 0xF6, 0x09, 0x30, 0x77, 0x99, 0x3D, 0x10,
0xDF, 0xF7, 0x95, 0x0F, 0x68, 0x83, 0xE6, 0xA4, 0x11, 0x7C, 0xDA, 0x82, 0xE7, 0x0B, 0x8B, 0xF2,
0x9D, 0x6B, 0x5B, 0xF5, 0x3E, 0x77, 0xB4, 0xC1, 0x0E, 0x49, 0x00, 0x83, 0xBA, 0x94, 0xF8, 0xA3,
0x82, 0x01, 0xD7, 0x30, 0x82, 0x01, 0xD3, 0x30, 0x10, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01,
0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E,
0x04, 0x16, 0x04, 0x14, 0x13, 0x93, 0xC8, 0xCD, 0xF2, 0x23, 0x9A, 0x2D, 0xC6, 0x9B, 0x2A, 0xEB,
0x9A, 0xAB, 0x99, 0x0B, 0x56, 0x04, 0x5E, 0x7C, 0x30, 0x65, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04,
0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00, 0x30, 0x52, 0x06, 0x0C, 0x2B,
0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01, 0x30, 0x42, 0x30, 0x40, 0x06,
0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A,
0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E,
0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x44, 0x6F, 0x63, 0x73, 0x2F,
0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E, 0x68, 0x74, 0x6D, 0x00, 0x30,
0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0C, 0x1E, 0x0A,
0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D,
0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01,
0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04,
0x18, 0x30, 0x16, 0x80, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03, 0x27, 0x5F, 0x97, 0xEB,
0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x68, 0x06, 0x03, 0x55, 0x1D, 0x1F,
0x04, 0x61, 0x30, 0x5F, 0x30, 0x5D, 0xA0, 0x5B, 0xA0, 0x59, 0x86, 0x57, 0x68, 0x74, 0x74, 0x70,
0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x72, 0x6C, 0x2F,
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25,
0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63,
0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E,
0x63, 0x72, 0x6C, 0x30, 0x75, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86,
0x59, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32,
0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25,
0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25,
0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86,
0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0x87, 0xB6,
0x82, 0xF3, 0xDA, 0xBE, 0xB1, 0x7B, 0x98, 0x7D, 0x3D, 0x0A, 0x90, 0xA8, 0xF5, 0xBF, 0x15, 0xC3,
0xEE, 0x8A, 0x4E, 0xC0, 0x7B, 0x10, 0x1D, 0xA9, 0xE3, 0x0B, 0xEC, 0x2C, 0x53, 0x4E, 0xA7, 0xBD,
0xF1, 0x6C, 0xAD, 0x18, 0x55, 0xBA, 0x25, 0x73, 0x55, 0xB7, 0x5B, 0x12, 0x24, 0xF4, 0x02, 0x31,
0x00, 0xAF, 0x02, 0x9C, 0x4B, 0x92, 0xD0, 0x72, 0xA5, 0x80, 0xCA, 0x69, 0x2B, 0x38, 0x50, 0x64,
0xD8, 0x58, 0x9E, 0xEA, 0xD6, 0x35, 0xCF, 0x68, 0x98, 0x92, 0x81, 0x09, 0x61, 0xC2, 0xBD, 0xB1,
0x4C, 0x7F, 0xAE, 0x55, 0x7B, 0xFC, 0x22, 0xDD, 0xD6, 0xB7, 0x7C, 0xB5, 0xA8, 0x18, 0x5D, 0x33,
0x04
};
guint8 ca_2[] = {
0x30, 0x82, 0x04, 0x56, 0x30, 0x82, 0x03, 0xDC, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
0x00, 0x00, 0x00, 0x03, 0x6C, 0xCF, 0xED, 0xE2, 0x44, 0x70, 0x19, 0xBF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x30, 0x81,
0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x3E, 0x30, 0x3C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x35,
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x44, 0x65,
0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
0x20, 0x32, 0x30, 0x31, 0x37, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x31,
0x39, 0x34, 0x39, 0x33, 0x38, 0x5A, 0x17, 0x0D, 0x33, 0x33, 0x30, 0x31, 0x32, 0x35, 0x31, 0x39,
0x35, 0x39, 0x33, 0x38, 0x5A, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A,
0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C,
0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C,
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48,
0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69,
0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x76, 0x30, 0x10,
0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22,
0x03, 0x62, 0x00, 0x04, 0x1D, 0xDD, 0x08, 0x02, 0x03, 0x25, 0x75, 0x20, 0xE2, 0x71, 0x8B, 0xAD,
0x28, 0x09, 0x82, 0xE9, 0x06, 0xEE, 0x83, 0xC5, 0x3A, 0x6C, 0x4B, 0x71, 0x92, 0x50, 0x4E, 0x20,
0xE9, 0x72, 0xB4, 0xFC, 0x53, 0x2A, 0xEF, 0x5D, 0xCC, 0x9A, 0xB4, 0xCD, 0x76, 0xB8, 0x94, 0x97,
0x44, 0xB2, 0x71, 0x0E, 0xC9, 0xB1, 0x16, 0x03, 0xA1, 0x65, 0x2B, 0xB9, 0xE8, 0x5D, 0x5F, 0xF2,
0x30, 0x2E, 0xDD, 0xB1, 0x2B, 0x20, 0xFC, 0xBE, 0x00, 0x88, 0xEA, 0x1F, 0xA7, 0x7F, 0x99, 0x84,
0x98, 0x7C, 0x71, 0x3E, 0x4D, 0x34, 0x83, 0x69, 0x9B, 0x08, 0xCB, 0x78, 0xB2, 0x4B, 0xBD, 0xD7,
0x3E, 0xBE, 0x67, 0xA0, 0xA3, 0x82, 0x01, 0xFC, 0x30, 0x82, 0x01, 0xF8, 0x30, 0x10, 0x06, 0x09,
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D,
0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03,
0x27, 0x5F, 0x97, 0xEB, 0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x65, 0x06,
0x03, 0x55, 0x1D, 0x20, 0x04, 0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00,
0x30, 0x52, 0x06, 0x0C, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01,
0x30, 0x42, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34,
0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F,
0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F,
0x44, 0x6F, 0x63, 0x73, 0x2F, 0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E,
0x68, 0x74, 0x6D, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
0x02, 0x04, 0x0C, 0x1E, 0x0A, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30,
0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03,
0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06,
0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x14, 0xDA, 0x5B, 0xF1, 0x0E, 0x66,
0x47, 0xD1, 0x5D, 0x13, 0x5F, 0x5B, 0x7A, 0xEB, 0xEB, 0x5F, 0x01, 0x08, 0xB5, 0x49, 0x30, 0x7A,
0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x73, 0x30, 0x71, 0x30, 0x6F, 0xA0, 0x6D, 0xA0, 0x6B, 0x86,
0x69, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32,
0x30, 0x45, 0x43, 0x43, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32,
0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25,
0x32, 0x30, 0x32, 0x30, 0x31, 0x37, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x81, 0x87, 0x06, 0x08, 0x2B,
0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x7B, 0x30, 0x79, 0x30, 0x77, 0x06, 0x08, 0x2B,
0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x6B, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F,
0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x4D,
0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32, 0x30, 0x45, 0x43, 0x43, 0x25, 0x32,
0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25,
0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30,
0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x37,
0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03,
0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x56, 0x2A, 0xAD, 0x72, 0x4C, 0xB9, 0x8C, 0xB3, 0x23,
0x80, 0xF5, 0x5F, 0xF8, 0x21, 0x94, 0x66, 0x0F, 0x76, 0x77, 0xE2, 0x7B, 0x03, 0xDD, 0x30, 0x5E,
0xCB, 0x90, 0xCA, 0x78, 0xE6, 0x0B, 0x2D, 0x12, 0xE5, 0xF7, 0x67, 0x31, 0x58, 0x71, 0xE6, 0xF3,
0x64, 0xC1, 0x04, 0xB3, 0x8B, 0xE9, 0xE2, 0x02, 0x31, 0x00, 0xB9, 0x20, 0x61, 0xB9, 0xD0, 0x5E,
0x3A, 0xA4, 0xA2, 0x8A, 0xFE, 0x1D, 0xFC, 0x27, 0x61, 0x0B, 0x98, 0x16, 0x8C, 0x02, 0x9C, 0x20,
0x7F, 0xEE, 0xF3, 0xCB, 0x1F, 0x0A, 0x37, 0x62, 0xB1, 0x8E, 0xCE, 0xD9, 0x9A, 0x9E, 0xAC, 0xE6,
0x1A, 0xD4, 0xB8, 0xF1, 0xA8, 0x2B, 0xB1, 0xB4, 0x40, 0x9B
};
static void
msg_written_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GError *error = NULL;
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
FpiSsm *ssm = user_data;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
g_clear_pointer (&self->msg_out, g_byte_array_unref);
g_assert (self->msg_out == NULL);
if (!g_output_stream_write_all_finish (stream, res, NULL, &error))
{
fpi_ssm_mark_failed (ssm, error);
return;
}
fpi_ssm_next_state (ssm);
}
static void
msg_received_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GError *error = NULL;
GInputStream *stream = G_INPUT_STREAM (source_object);
FpiSsm *ssm = user_data;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
gsize read;
g_assert (self->msg_out == NULL);
if (!g_input_stream_read_all_finish (stream, res, &read, &error) ||
read != self->msg_in->len)
{
g_clear_pointer (&self->msg_in, g_byte_array_unref);
if (!error)
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Received EOF while reading from test binary.");
fpi_ssm_mark_failed (ssm, error);
return;
}
fpi_ssm_next_state (ssm);
}
enum {
SEND_MESSAGE,
RECV_MESSAGE,
SEND_RECV_STATES
};
static void
send_recv_ssm (FpiSsm *ssm, FpDevice *dev)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
switch (fpi_ssm_get_cur_state (ssm))
{
case SEND_MESSAGE:
g_output_stream_write_all_async (self->proc_stdin,
self->msg_out->data,
self->msg_out->len,
G_PRIORITY_DEFAULT,
fpi_device_get_cancellable (FP_DEVICE (dev)),
msg_written_cb,
ssm);
break;
case RECV_MESSAGE:
g_input_stream_read_all_async (self->proc_stdout,
self->msg_in->data,
self->msg_in->len,
G_PRIORITY_DEFAULT,
fpi_device_get_cancellable (FP_DEVICE (dev)),
msg_received_cb,
ssm);
break;
}
}
static void
connect_2_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) recv_data = NULL;
g_autoptr(GBytes) r_d = NULL;
g_autoptr(FpiSdcpClaim) claim = NULL;
g_autoptr(GBytes) mac = NULL;
g_autoptr(GBytes) ca_1_bytes = NULL, ca_2_bytes = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
guint16 cert_size;
if (error)
{
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
return;
}
memcpy (&cert_size, self->connect_msg->data + 32, 2);
g_byte_array_append (self->connect_msg, self->msg_in->data, self->msg_in->len);
g_clear_pointer (&self->msg_in, g_byte_array_unref);
/* Double check that the size is correct. */
g_assert (self->connect_msg->len == 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32);
recv_data = g_byte_array_free_to_bytes (g_steal_pointer (&self->connect_msg));
claim = fpi_sdcp_claim_new ();
r_d = g_bytes_new_from_bytes (recv_data, 0, 32);
claim->cert_m = g_bytes_new_from_bytes (recv_data, 34, cert_size);
claim->pk_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size, 65);
claim->pk_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65, 65);
claim->h_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65, 32);
claim->s_m = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32, 64);
claim->s_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64, 64);
mac = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64 + 64, 32);
ca_1_bytes = g_bytes_new_static (ca_1, G_N_ELEMENTS (ca_1));
ca_2_bytes = g_bytes_new_static (ca_2, G_N_ELEMENTS (ca_2));
fpi_sdcp_device_set_intermediat_cas (FP_SDCP_DEVICE (dev),
ca_1_bytes,
ca_2_bytes);
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), r_d, claim, mac, NULL);
}
static void
connect_1_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
guint16 cert_size;
if (error)
{
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
return;
}
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
self->connect_msg = g_steal_pointer (&self->msg_in);
memcpy (&cert_size, self->connect_msg->data + 32, 2);
/* Nothing to send and the rest to receive. */
self->msg_out = g_byte_array_new ();
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32 - self->connect_msg->len);
/* New SSM */
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "connect 2");
fpi_ssm_start (ssm, connect_2_cb);
}
static void
connect (FpSdcpDevice *dev)
{
g_autoptr(GBytes) r_h = NULL;
g_autoptr(GBytes) pk_h = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
g_assert (self->connect_msg == NULL);
fpi_sdcp_device_get_connect_data (dev, &r_h, &pk_h);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "C", 1);
g_byte_array_append (self->msg_out,
g_bytes_get_data (r_h, NULL),
g_bytes_get_size (r_h));
g_byte_array_append (self->msg_out,
g_bytes_get_data (pk_h, NULL),
g_bytes_get_size (pk_h));
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 34);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "connect");
fpi_ssm_start (ssm, connect_1_cb);
}
static void
reconnect_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) mac = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
if (error)
{
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, error);
return;
}
mac = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, NULL);
}
static void
reconnect (FpSdcpDevice *dev)
{
g_autoptr(GBytes) r_h = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "R", 1);
g_byte_array_append (self->msg_out,
g_bytes_get_data (r_h, NULL),
g_bytes_get_size (r_h));
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 32);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "connect 2");
fpi_ssm_start (ssm, reconnect_cb);
}
static void
enroll_begin_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) nonce = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
if (error)
{
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
return;
}
nonce = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
fpi_sdcp_device_enroll_set_nonce (FP_SDCP_DEVICE (dev), nonce);
/* Claim that we completed one enroll step. */
fpi_device_enroll_progress (dev, 1, NULL, NULL);
/* And signal that we are ready to commit. */
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), NULL);
}
static void
enroll_begin (FpSdcpDevice *dev)
{
g_autoptr(GBytes) r_h = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "E", 1);
/* Expect 32 byte nonce */
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 32);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "enroll_begin");
fpi_ssm_start (ssm, enroll_begin_cb);
}
static void
enroll_commit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
g_clear_pointer (&self->msg_in, g_byte_array_unref);
if (error)
{
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
return;
}
/* Signal that we have committed. We don't expect a response
* from the virtual device (even though that is kind of broken).
*/
fpi_sdcp_device_enroll_commit_complete (FP_SDCP_DEVICE (dev), NULL);
}
static void
enroll_commit (FpSdcpDevice *dev, GBytes *id_in)
{
g_autoptr(GBytes) r_h = NULL;
g_autoptr(GBytes) id = id_in;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
self->msg_out = g_byte_array_new ();
self->msg_in = g_byte_array_new ();
if (id)
{
g_byte_array_append (self->msg_out, (const guint8 *) "F", 1);
g_byte_array_append (self->msg_out,
g_bytes_get_data (id, NULL),
g_bytes_get_size (id));
/* NOTE: No response from device, assume commit works. */
}
else
{
/* Cancel enroll (does not receive a reply) */
g_byte_array_append (self->msg_out, (const guint8 *) "G", 1);
/* NOTE: No response from device, assume cancellation works. */
}
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "enroll_commit");
fpi_ssm_start (ssm, enroll_commit_cb);
}
static void
identify_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) reply = NULL;
g_autoptr(GBytes) id = NULL;
g_autoptr(GBytes) mac = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
if (error)
{
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (dev), NULL, NULL, error);
return;
}
reply = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
id = g_bytes_new_from_bytes (reply, 0, 32);
mac = g_bytes_new_from_bytes (reply, 32, 32);
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (self), id, mac, NULL);
}
static void
identify (FpSdcpDevice *dev)
{
g_autoptr(GBytes) nonce = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_identify_data (dev, &nonce);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "I", 1);
g_byte_array_append (self->msg_out, g_bytes_get_data (nonce, NULL), g_bytes_get_size (nonce));
/* Expect 64 byte nonce */
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 64);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "identify");
fpi_ssm_start (ssm, identify_cb);
}
static void
probe (FpDevice *dev)
{
g_auto(GStrv) argv = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
GError *error = NULL;
const char *env;
/* We launch the test binary alread at probe time and quit only when
* the object is finalized. This allows testing reconnect properly.
*
* Also, we'll fail probe if something goes wrong executing it.
*/
env = fpi_device_get_virtual_env (FP_DEVICE (self));
if (!g_shell_parse_argv (env, NULL, &argv, &error))
goto out;
self->proc = g_subprocess_newv ((const char * const *) argv,
G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
&error);
if (!self->proc)
goto out;
self->proc_stdin = g_object_ref (g_subprocess_get_stdin_pipe (self->proc));
self->proc_stdout = g_object_ref (g_subprocess_get_stdout_pipe (self->proc));
out:
fpi_device_probe_complete (dev, "virtual-sdcp", NULL, error);
}
static void
dev_close (FpDevice *dev)
{
/* No-op, needs to be defined. */
fpi_device_close_complete (dev, NULL);
}
static void
fpi_device_virtual_sdcp_init (FpDeviceVirtualSdcp *self)
{
}
static void
fpi_device_virtual_sdcp_finalize (GObject *obj)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (obj);
/* Just kill the subprocess, no need to be graceful here. */
if (self->proc)
g_subprocess_force_exit (self->proc);
g_clear_object (&self->proc);
g_clear_object (&self->proc_stdin);
g_clear_object (&self->proc_stdout);
G_OBJECT_CLASS (fpi_device_virtual_sdcp_parent_class)->finalize (obj);
}
static const FpIdEntry driver_ids[] = {
{ .virtual_envvar = "FP_VIRTUAL_SDCP" },
{ .virtual_envvar = NULL }
};
static void
fpi_device_virtual_sdcp_class_init (FpDeviceVirtualSdcpClass *klass)
{
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpSdcpDeviceClass *sdcp_class = FP_SDCP_DEVICE_CLASS (klass);
obj_class->finalize = fpi_device_virtual_sdcp_finalize;
dev_class->id = FP_COMPONENT;
dev_class->full_name = "Virtual SDCP device talking to MS test code";
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
dev_class->id_table = driver_ids;
dev_class->nr_enroll_stages = 1;
/* The SDCP base class may need to override this in the long run */
dev_class->probe = probe;
dev_class->close = dev_close;
sdcp_class->connect = connect;
sdcp_class->reconnect = reconnect;
sdcp_class->enroll_begin = enroll_begin;
sdcp_class->enroll_commit = enroll_commit;
sdcp_class->identify = identify;
}

View File

@@ -361,6 +361,8 @@ fp_context_init (FpContext *self)
FpContextPrivate *priv = fp_context_get_instance_private (self); FpContextPrivate *priv = fp_context_get_instance_private (self);
guint i; guint i;
g_debug ("Initializing FpContext (libfprint version " LIBFPRINT_VERSION ")");
priv->drivers = fpi_get_driver_types (); priv->drivers = fpi_get_driver_types ();
if (get_drivers_whitelist_env ()) if (get_drivers_whitelist_env ())

View File

@@ -61,6 +61,7 @@ typedef struct
FpDeviceFeature features; FpDeviceFeature features;
guint64 driver_data; guint64 driver_data;
GVariant *persistent_data;
gint nr_enroll_stages; gint nr_enroll_stages;
GSList *sources; GSList *sources;
@@ -130,6 +131,9 @@ typedef struct
void match_data_free (FpMatchData *match_data); void match_data_free (FpMatchData *match_data);
void fpi_device_suspend (FpDevice *device);
void fpi_device_resume (FpDevice *device);
void fpi_device_configure_wakeup (FpDevice *device, void fpi_device_configure_wakeup (FpDevice *device,
gboolean enabled); gboolean enabled);
void fpi_device_update_temp (FpDevice *device, void fpi_device_update_temp (FpDevice *device,

View File

@@ -54,6 +54,7 @@ enum {
PROP_FPI_UDEV_DATA_SPIDEV, PROP_FPI_UDEV_DATA_SPIDEV,
PROP_FPI_UDEV_DATA_HIDRAW, PROP_FPI_UDEV_DATA_HIDRAW,
PROP_FPI_DRIVER_DATA, PROP_FPI_DRIVER_DATA,
PROP_FPI_PERSISTENT_DATA,
N_PROPS N_PROPS
}; };
@@ -225,6 +226,7 @@ fp_device_finalize (GObject *object)
g_clear_pointer (&priv->current_idle_cancel_source, g_source_destroy); g_clear_pointer (&priv->current_idle_cancel_source, g_source_destroy);
g_clear_pointer (&priv->current_task_idle_return_source, g_source_destroy); g_clear_pointer (&priv->current_task_idle_return_source, g_source_destroy);
g_clear_pointer (&priv->critical_section_flush_source, g_source_destroy);
g_clear_pointer (&priv->device_id, g_free); g_clear_pointer (&priv->device_id, g_free);
g_clear_pointer (&priv->device_name, g_free); g_clear_pointer (&priv->device_name, g_free);
@@ -234,6 +236,8 @@ fp_device_finalize (GObject *object)
g_clear_pointer (&priv->udev_data.spidev_path, g_free); g_clear_pointer (&priv->udev_data.spidev_path, g_free);
g_clear_pointer (&priv->udev_data.hidraw_path, g_free); g_clear_pointer (&priv->udev_data.hidraw_path, g_free);
g_clear_pointer (&priv->persistent_data, g_variant_unref);
G_OBJECT_CLASS (fp_device_parent_class)->finalize (object); G_OBJECT_CLASS (fp_device_parent_class)->finalize (object);
} }
@@ -303,6 +307,10 @@ fp_device_get_property (GObject *object,
g_value_set_string (value, NULL); g_value_set_string (value, NULL);
break; break;
case PROP_FPI_PERSISTENT_DATA:
g_value_set_variant (value, priv->persistent_data);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@@ -353,6 +361,11 @@ fp_device_set_property (GObject *object,
priv->driver_data = g_value_get_uint64 (value); priv->driver_data = g_value_get_uint64 (value);
break; break;
case PROP_FPI_PERSISTENT_DATA:
g_clear_pointer (&priv->persistent_data, g_variant_unref);
priv->persistent_data = g_value_dup_variant (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@@ -593,6 +606,21 @@ fp_device_class_init (FpDeviceClass *klass)
0, 0,
G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
/**
* FpDevice::fpi-persistent-data: (skip)
*
* This property is only for internal purposes.
*
* Stability: private
*/
properties[PROP_FPI_PERSISTENT_DATA] =
g_param_spec_variant ("fpi-persistent-data",
"Persistent Driver Data",
"Private: Previously stored data for the device",
G_VARIANT_TYPE_ANY,
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_properties (object_class, N_PROPS, properties); g_object_class_install_properties (object_class, N_PROPS, properties);
} }
@@ -738,6 +766,139 @@ fp_device_get_temperature (FpDevice *device)
return priv->temp_current; return priv->temp_current;
} }
/**
* fp_device_get_persistent_data:
* @device: A #FpDevice
* @data: (array length=length) (transfer full) (out): Return location for data pointer
* @length: (transfer full) (out): Length of @data
* @error: Return location for error
*
* Retrieves persistent data that should be stored for this device. Storage
* needs to be device specific, i.e. device ID and driver must match when
* restored.
*
* Returns: (type void): %TRUE on success
*/
gboolean
fp_device_get_persistent_data (FpDevice *device,
guchar **data,
gsize *length,
GError **error)
{
g_autoptr(GVariant) res = NULL;
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_assert (data);
g_assert (length);
if (priv->persistent_data == NULL)
{
*data = NULL;
*length = 0;
return TRUE;
}
/* Version + variant from driver */
res = g_variant_new ("(issv)",
1,
fp_device_get_driver (device),
priv->device_id,
priv->persistent_data);
*length = g_variant_get_size (res);
*data = g_malloc (*length);
g_variant_store (res, *data);
return TRUE;
}
/**
* fp_device_get_persistent_data:
* @device: A #FpDevice
* @data: (array length=length) (transfer none): Persistent Data
* @length: (transfer none): Length of @data
* @error: Return location for error
*
* Load persistent data from storage. This function should be called after
* a device was discovered and before it is opened for the first time. It is
* an error to call it if data has already been set (or generated by the
* driver).
*
* Note that the driver may update the data. The API user should retrieve the
* value when done with the device and store it in a persistent location.
*
* Returns: (type void): %TRUE on success
*/
gboolean
fp_device_set_persistent_data (FpDevice *device,
guchar *data,
gsize length,
GError **error)
{
g_autoptr(GVariant) stored = NULL;
g_autoptr(GVariant) loaded = NULL;
FpDevicePrivate *priv = fp_device_get_instance_private (device);
guchar *copy;
gint version;
const gchar *device_id;
const gchar *driver;
if (priv->is_open)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Data can only be set right after device creation");
return FALSE;
}
if (priv->persistent_data)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
"Data has already been set");
return FALSE;
}
if (length == 0)
{
g_clear_pointer (&priv->persistent_data, g_variant_unref);
g_object_notify_by_pspec (G_OBJECT (device), properties[PROP_FPI_PERSISTENT_DATA]);
return TRUE;
}
g_assert (data);
copy = g_memdup (data, length);
stored = g_variant_new_from_data (G_VARIANT_TYPE ("(issv)"), copy, length, FALSE, g_free, copy);
if (!stored)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
"Data could not be parsed");
return FALSE;
}
g_variant_get (stored, "(issv)", &version, &driver, &device_id, &loaded);
if (version != 1)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
"Unknown data storage version");
return FALSE;
}
if (g_strcmp0 (device_id, priv->device_id) != 0 ||
g_strcmp0 (driver, fp_device_get_driver (device)) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
"Driver or device ID mismatch!");
return FALSE;
}
g_clear_pointer (&priv->persistent_data, g_variant_unref);
priv->persistent_data = g_steal_pointer (&loaded);
g_object_notify_by_pspec (G_OBJECT (device), properties[PROP_FPI_PERSISTENT_DATA]);
return TRUE;
}
/** /**
* fp_device_supports_identify: * fp_device_supports_identify:
* @device: A #FpDevice * @device: A #FpDevice
@@ -948,16 +1109,6 @@ fp_device_close_finish (FpDevice *device,
return g_task_propagate_boolean (G_TASK (result), error); return g_task_propagate_boolean (G_TASK (result), error);
} }
static void
complete_suspend_resume_task (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_assert (priv->suspend_resume_task);
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
}
/** /**
* fp_device_suspend: * fp_device_suspend:
* @device: a #FpDevice * @device: a #FpDevice
@@ -1008,48 +1159,7 @@ fp_device_suspend (FpDevice *device,
priv->suspend_resume_task = g_steal_pointer (&task); priv->suspend_resume_task = g_steal_pointer (&task);
/* If the device is currently idle, just complete immediately. fpi_device_suspend (device);
* For long running tasks, call the driver handler right away, for short
* tasks, wait for completion and then return the task.
*/
switch (priv->current_action)
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_suspend_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->suspend)
{
if (priv->critical_section)
priv->suspend_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->suspend (device);
}
else
{
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
g_signal_connect_object (priv->current_task,
"notify::completed",
G_CALLBACK (complete_suspend_resume_task),
device,
G_CONNECT_SWAPPED);
break;
}
} }
/** /**
@@ -1114,41 +1224,7 @@ fp_device_resume (FpDevice *device,
priv->suspend_resume_task = g_steal_pointer (&task); priv->suspend_resume_task = g_steal_pointer (&task);
switch (priv->current_action) fpi_device_resume (device);
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_resume_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->resume)
{
if (priv->critical_section)
priv->resume_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->resume (device);
}
else
{
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
/* cannot happen as we make sure these tasks complete before suspend */
g_assert_not_reached ();
complete_suspend_resume_task (device);
break;
}
} }
/** /**

View File

@@ -140,7 +140,6 @@ typedef enum {
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates * @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
* @FP_DEVICE_ERROR_REMOVED: The device has been removed. * @FP_DEVICE_ERROR_REMOVED: The device has been removed.
* @FP_DEVICE_ERROR_TOO_HOT: The device might be getting too hot * @FP_DEVICE_ERROR_TOO_HOT: The device might be getting too hot
* @FP_DEVICE_ERROR_UNTRUSTED: Device cannot be trusted
* *
* Error codes for device operations. More specific errors from other domains * Error codes for device operations. More specific errors from other domains
* such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported. * such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported.
@@ -159,7 +158,6 @@ typedef enum {
/* Leave some room to add more DATA related errors */ /* Leave some room to add more DATA related errors */
FP_DEVICE_ERROR_REMOVED = 0x100, FP_DEVICE_ERROR_REMOVED = 0x100,
FP_DEVICE_ERROR_TOO_HOT, FP_DEVICE_ERROR_TOO_HOT,
FP_DEVICE_ERROR_UNTRUSTED,
} FpDeviceError; } FpDeviceError;
GQuark fp_device_retry_quark (void); GQuark fp_device_retry_quark (void);
@@ -232,6 +230,15 @@ FpDeviceFeature fp_device_get_features (FpDevice *device);
gboolean fp_device_has_feature (FpDevice *device, gboolean fp_device_has_feature (FpDevice *device,
FpDeviceFeature feature); FpDeviceFeature feature);
gboolean fp_device_get_persistent_data (FpDevice *device,
guchar **data,
gsize *length,
GError **error);
gboolean fp_device_set_persistent_data (FpDevice *device,
guchar *data,
gsize length,
GError **error);
/* Opening the device */ /* Opening the device */
void fp_device_open (FpDevice *device, void fp_device_open (FpDevice *device,
GCancellable *cancellable, GCancellable *cancellable,

View File

@@ -605,7 +605,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
if (g_strcmp0 (self->device_id, other->device_id)) if (g_strcmp0 (self->device_id, other->device_id))
return FALSE; return FALSE;
if (self->type == FPI_PRINT_RAW || self->type == FPI_PRINT_SDCP) if (self->type == FPI_PRINT_RAW)
{ {
return g_variant_equal (self->data, other->data); return g_variant_equal (self->data, other->data);
} }
@@ -870,7 +870,7 @@ fp_print_deserialize (const guchar *data,
g_ptr_array_add (result->prints, g_steal_pointer (&xyt)); g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
} }
} }
else if (type == FPI_PRINT_RAW || type == FPI_PRINT_SDCP) else if (type == FPI_PRINT_RAW)
{ {
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0); g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);

View File

@@ -1,58 +0,0 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "fpi-sdcp-device.h"
#include <nss.h>
#include <keyhi.h>
#include <keythi.h>
#include <pk11pub.h>
typedef struct
{
GError *enroll_pre_commit_error;
/* XXX: Do we want a separate SDCP session object?
*/
GPtrArray *intermediate_cas;
/* Host random for the connection */
guint8 host_random[32];
NSSInitContext *nss_init_context;
PK11SlotInfo *slot;
SECKEYPrivateKey *host_key_private;
SECKEYPublicKey *host_key_public;
/* Master secret is required for reconnects.
* TODO: We probably want to serialize this to disk so it can survive
* fprintd idle shutdown. */
PK11SymKey *master_secret;
PK11SymKey *mac_secret;
} FpSdcpDevicePrivate;
void fpi_sdcp_device_connect (FpSdcpDevice *self);
void fpi_sdcp_device_reconnect (FpSdcpDevice *self);
void fpi_sdcp_device_enroll (FpSdcpDevice *self);
void fpi_sdcp_device_identify (FpSdcpDevice *self);

View File

@@ -1,141 +0,0 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "sdcp_device"
#include "fpi-log.h"
#include "fp-sdcp-device-private.h"
/**
* SECTION: fp-sdcp-device
* @title: FpSdcpDevice
* @short_description: SDCP device subclass
*
* This is a base class for devices implementing the SDCP security protocol.
*/
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpSdcpDevice, fp_sdcp_device, FP_TYPE_DEVICE)
#if 0
/* XXX: We'll very likely want/need some properties on this class. */
enum {
PROP_0,
N_PROPS
};
static GParamSpec *properties[N_PROPS];
#endif
/*******************************************************/
/* Callbacks/vfuncs */
static void
fp_sdcp_device_open (FpDevice *device)
{
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
/* Try a reconnect if we still have the mac secret. */
if (priv->mac_secret)
fpi_sdcp_device_reconnect (self);
else
fpi_sdcp_device_connect (self);
}
static void
fp_sdcp_device_enroll (FpDevice *device)
{
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
fpi_sdcp_device_enroll (self);
}
static void
fp_sdcp_device_identify (FpDevice *device)
{
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
fpi_sdcp_device_identify (self);
}
/*********************************************************/
static void
fp_sdcp_device_finalize (GObject *object)
{
FpSdcpDevice *self = (FpSdcpDevice *) object;
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
g_clear_pointer (&priv->intermediate_cas, g_ptr_array_unref);
g_clear_pointer (&priv->slot, PK11_FreeSlot);
g_clear_pointer (&priv->host_key_private, SECKEY_DestroyPrivateKey);
g_clear_pointer (&priv->host_key_public, SECKEY_DestroyPublicKey);
g_clear_pointer (&priv->master_secret, PK11_FreeSymKey);
g_clear_pointer (&priv->mac_secret, PK11_FreeSymKey);
g_clear_pointer (&priv->nss_init_context, NSS_ShutdownContext);
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->finalize (object);
}
static void
fp_sdcp_device_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
fp_sdcp_device_constructed (GObject *obj)
{
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->constructed (obj);
}
static void
fp_sdcp_device_class_init (FpSdcpDeviceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
FpDeviceClass *fp_device_class = FP_DEVICE_CLASS (klass);
object_class->finalize = fp_sdcp_device_finalize;
object_class->get_property = fp_sdcp_device_get_property;
object_class->constructed = fp_sdcp_device_constructed;
fp_device_class->open = fp_sdcp_device_open;
fp_device_class->enroll = fp_sdcp_device_enroll;
fp_device_class->verify = fp_sdcp_device_identify;
fp_device_class->identify = fp_sdcp_device_identify;
#if 0
g_object_class_install_properties (object_class, N_PROPS, properties);
#endif
}
static void
fp_sdcp_device_init (FpSdcpDevice *self)
{
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
priv->intermediate_cas = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
}

View File

@@ -1,29 +0,0 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <fp-device.h>
G_BEGIN_DECLS
#define FP_TYPE_SDCP_DEVICE (fp_sdcp_device_get_type ())
G_DECLARE_DERIVABLE_TYPE (FpSdcpDevice, fp_sdcp_device, FP, SDCP_DEVICE, FpDevice)
G_END_DECLS

View File

@@ -21,6 +21,7 @@
#define FP_COMPONENT "device" #define FP_COMPONENT "device"
#include <math.h> #include <math.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h>
#include "fpi-log.h" #include "fpi-log.h"
@@ -185,9 +186,6 @@ fpi_device_error_new (FpDeviceError error)
case FP_DEVICE_ERROR_TOO_HOT: case FP_DEVICE_ERROR_TOO_HOT:
msg = "Device disabled to prevent overheating."; msg = "Device disabled to prevent overheating.";
case FP_DEVICE_ERROR_UNTRUSTED:
msg = "Could not verify integrity of the device, it cannot be trusted!";
break; break;
default: default:
@@ -869,16 +867,16 @@ fpi_device_critical_section_flush_idle_cb (FpDevice *device)
if (priv->suspend_queued) if (priv->suspend_queued)
{ {
cls->suspend (device);
priv->suspend_queued = FALSE; priv->suspend_queued = FALSE;
fpi_device_suspend (device);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
if (priv->resume_queued) if (priv->resume_queued)
{ {
cls->resume (device);
priv->resume_queued = FALSE; priv->resume_queued = FALSE;
fpi_device_resume (device);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
@@ -915,6 +913,7 @@ fpi_device_critical_leave (FpDevice *device)
return; return;
priv->critical_section_flush_source = g_idle_source_new (); priv->critical_section_flush_source = g_idle_source_new ();
g_source_set_priority (priv->critical_section_flush_source, G_PRIORITY_HIGH);
g_source_set_callback (priv->critical_section_flush_source, g_source_set_callback (priv->critical_section_flush_source,
(GSourceFunc) fpi_device_critical_section_flush_idle_cb, (GSourceFunc) fpi_device_critical_section_flush_idle_cb,
device, device,
@@ -1553,6 +1552,148 @@ fpi_device_list_complete (FpDevice *device,
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error); fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
} }
static int
update_attr (const char *attr, const char *value)
{
int fd, err;
gssize r;
char buf[50] = { 0 };
fd = open (attr, O_RDONLY);
err = -errno;
if (fd < 0)
return -err;
r = read (fd, buf, sizeof (buf) - 1);
err = errno;
close (fd);
if (r < 0)
return -err;
g_strchomp (buf);
if (g_strcmp0 (buf, value) == 0)
return 0;
/* O_TRUNC makes things work in the umockdev environment */
fd = open (attr, O_WRONLY | O_TRUNC);
err = errno;
if (fd < 0)
return -err;
r = write (fd, value, strlen (value));
err = -errno;
close (fd);
if (r < 0)
{
/* Write failures are weird, and are worth a warning */
g_warning ("Could not write %s to %s", value, attr);
return -err;
}
return 0;
}
static void
complete_suspend_resume_task (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_assert (priv->suspend_resume_task);
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
}
void
fpi_device_suspend (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
/* If the device is currently idle, just complete immediately.
* For long running tasks, call the driver handler right away, for short
* tasks, wait for completion and then return the task.
*/
switch (priv->current_action)
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_suspend_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->suspend)
{
if (priv->critical_section)
priv->suspend_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->suspend (device);
}
else
{
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
g_signal_connect_object (priv->current_task,
"notify::completed",
G_CALLBACK (complete_suspend_resume_task),
device,
G_CONNECT_SWAPPED);
break;
}
}
void
fpi_device_resume (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
switch (priv->current_action)
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_resume_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->resume)
{
if (priv->critical_section)
priv->resume_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->resume (device);
}
else
{
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
/* cannot happen as we make sure these tasks complete before suspend */
g_assert_not_reached ();
complete_suspend_resume_task (device);
break;
}
}
void void
fpi_device_configure_wakeup (FpDevice *device, gboolean enabled) fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
{ {
@@ -1568,8 +1709,7 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
guint8 bus, port; guint8 bus, port;
g_autofree gchar *sysfs_wakeup = NULL; g_autofree gchar *sysfs_wakeup = NULL;
g_autofree gchar *sysfs_persist = NULL; g_autofree gchar *sysfs_persist = NULL;
gssize r; int res;
int fd;
ports = g_string_new (NULL); ports = g_string_new (NULL);
bus = g_usb_device_get_bus (priv->usb_device); bus = g_usb_device_get_bus (priv->usb_device);
@@ -1585,20 +1725,9 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
g_string_set_size (ports, ports->len - 1); g_string_set_size (ports, ports->len - 1);
sysfs_wakeup = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/wakeup", bus, ports->str); sysfs_wakeup = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/wakeup", bus, ports->str);
fd = open (sysfs_wakeup, O_WRONLY); res = update_attr (sysfs_wakeup, wakeup_command);
if (res < 0)
if (fd < 0) g_debug ("Failed to set %s to %s", sysfs_wakeup, wakeup_command);
{
/* Wakeup not existing appears to be relatively normal. */
g_debug ("Failed to open %s", sysfs_wakeup);
}
else
{
r = write (fd, wakeup_command, strlen (wakeup_command));
if (r < 0)
g_warning ("Could not configure wakeup to %s by writing %s", wakeup_command, sysfs_wakeup);
close (fd);
}
/* Persist means that the kernel tries to keep the USB device open /* Persist means that the kernel tries to keep the USB device open
* in case it is "replugged" due to suspend. * in case it is "replugged" due to suspend.
@@ -1606,20 +1735,9 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
* state. Instead, seeing an unplug and a new device makes more sense. * state. Instead, seeing an unplug and a new device makes more sense.
*/ */
sysfs_persist = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/persist", bus, ports->str); sysfs_persist = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/persist", bus, ports->str);
fd = open (sysfs_persist, O_WRONLY); res = update_attr (sysfs_persist, "0");
if (res < 0)
if (fd < 0) g_warning ("Failed to disable USB persist by writing to %s", sysfs_persist);
{
g_warning ("Failed to open %s", sysfs_persist);
return;
}
else
{
r = write (fd, "0", 1);
if (r < 0)
g_message ("Could not disable USB persist by writing to %s", sysfs_persist);
close (fd);
}
break; break;
} }

View File

@@ -11,13 +11,11 @@ G_BEGIN_DECLS
* @FPI_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment * @FPI_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment
* @FPI_PRINT_RAW: A raw print where the data is directly compared * @FPI_PRINT_RAW: A raw print where the data is directly compared
* @FPI_PRINT_NBIS: NBIS minutiae comparison * @FPI_PRINT_NBIS: NBIS minutiae comparison
* @FPI_PRINT_SDCP: Print from an SDCP conforming device
*/ */
typedef enum { typedef enum {
FPI_PRINT_UNDEFINED = 0, FPI_PRINT_UNDEFINED = 0,
FPI_PRINT_RAW, FPI_PRINT_RAW,
FPI_PRINT_NBIS, FPI_PRINT_NBIS,
FPI_PRINT_SDCP,
} FpiPrintType; } FpiPrintType;
/** /**
@@ -44,9 +42,9 @@ gboolean fpi_print_add_from_image (FpPrint *print,
FpImage *image, FpImage *image,
GError **error); GError **error);
FpiMatchResult fpi_print_bz3_match (FpPrint * template, FpiMatchResult fpi_print_bz3_match (FpPrint *temp,
FpPrint * print, FpPrint *print,
gint bz3_threshold, gint bz3_threshold,
GError **error); GError **error);
/* Helpers to encode metadata into user ID strings. */ /* Helpers to encode metadata into user ID strings. */

File diff suppressed because it is too large Load Diff

View File

@@ -1,142 +0,0 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <glib-2.0/glib.h>
#include "fpi-device.h"
#include "fp-sdcp-device.h"
/**
* FpiSdcpClaim:
* @cert_m: The per-model ECDSA certificate (x509 ASN.1 DER encoded)
* @pk_d: The device public key (65 bytes)
* @pk_f: The firmware public key (65 bytes)
* @h_f: The firmware hash
* @s_m: Signature over @pk_d using the per-model private key (64 bytes)
* @s_d: Signature over h_f and pk_f using the device private key (64 bytes)
*
* Structure to hold the claim as produced by the device during a secure
* connect. See the SDCP specification for more details.
*
* Note all of these may simply be memory views into a larger #GBytes created
* using g_bytes_new_from_bytes().
*/
struct _FpiSdcpClaim
{
/*< public >*/
GBytes *cert_m;
GBytes *pk_d;
GBytes *pk_f;
GBytes *h_f;
GBytes *s_m;
GBytes *s_d;
};
typedef struct _FpiSdcpClaim FpiSdcpClaim;
GType fpi_sdcp_claim_get_type (void) G_GNUC_CONST;
FpiSdcpClaim *fpi_sdcp_claim_new (void);
FpiSdcpClaim *fpi_sdcp_claim_copy (FpiSdcpClaim *other);
void fpi_sdcp_claim_free (FpiSdcpClaim *claim);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiSdcpClaim, fpi_sdcp_claim_free)
/**
* FpSdcpDeviceClass:
* @connect: Establish SDCP connection. Similar to open in #FpDeviceClass
* but called connect to mirror the SDCP specification.
* @reconnect: Perform a faster reconnect. Drivers do not need to provide this
* function. If reconnect fails, then a normal connect will be tried.
* @enroll_begin: Start the enrollment procedure. In the absence of an error,
* the driver must call fpi_sdcp_device_enroll_set_nonce() at any point. It
* also must report enrollment progress using fpi_device_enroll_progress().
* It should also store available metadata about the print in device memory.
* The operation is completed with fpi_sdcp_device_enroll_ready().
* @enroll_commit: Complete the enrollment procedure. This commits the newly
* enrolled print to the device memory. Will only be called if enroll_begin
* succeeded. The passed id may be %NULL, in that case the driver must
* abort the enrollment process. id is owned by the base class and remains
* valid throughout the operation.
* @identify: Start identification process. On completion, the driver must call
* fpi_sdcp_device_identify_complete(). To request the user to retry the
* fpi_sdcp_device_identify_retry() function is used.
*
*
* These are the main entry points for drivers implementing SDCP.
*
* Drivers *must* eventually call the corresponding function to finish the
* operation.
*
* XXX: Is the use of fpi_device_action_error() acceptable?
*
* Drivers *must* also handle cancellation properly for any long running
* operation (i.e. any operation that requires capturing). It is entirely fine
* to ignore cancellation requests for short operations (e.g. open/close).
*
* This API is solely intended for drivers. It is purely internal and neither
* API nor ABI stable.
*/
struct _FpSdcpDeviceClass
{
FpDeviceClass parent_class;
void (*connect) (FpSdcpDevice *dev);
void (*reconnect) (FpSdcpDevice *dev);
void (*close) (FpSdcpDevice *dev);
void (*enroll_begin) (FpSdcpDevice *dev);
void (*enroll_commit) (FpSdcpDevice *dev,
GBytes *id);
void (*identify) (FpSdcpDevice *dev);
};
void fpi_sdcp_device_set_intermediat_cas (FpSdcpDevice *self,
GBytes *ca_1,
GBytes *ca_2);
void fpi_sdcp_device_get_connect_data (FpSdcpDevice *self,
GBytes **r_h,
GBytes **pk_h);
void fpi_sdcp_device_connect_complete (FpSdcpDevice *self,
GBytes *r_d,
FpiSdcpClaim *claim,
GBytes *mac,
GError *error);
void fpi_sdcp_device_get_reconnect_data (FpSdcpDevice *self,
GBytes **r_h);
void fpi_sdcp_device_reconnect_complete (FpSdcpDevice *self,
GBytes *mac,
GError *error);
void fpi_sdcp_device_enroll_set_nonce (FpSdcpDevice *self,
GBytes *nonce);
void fpi_sdcp_device_enroll_ready (FpSdcpDevice *self,
GError *error);
void fpi_sdcp_device_enroll_commit_complete (FpSdcpDevice *self,
GError *error);
void fpi_sdcp_device_get_identify_data (FpSdcpDevice *self,
GBytes **nonce);
void fpi_sdcp_device_identify_retry (FpSdcpDevice *self,
GError *error);
void fpi_sdcp_device_identify_complete (FpSdcpDevice *self,
GBytes *id,
GBytes *mac,
GError *error);

View File

@@ -29,9 +29,9 @@ static const FpIdEntry whitelist_id_table[] = {
* You can generate this list from the wiki page using e.g.: * You can generate this list from the wiki page using e.g.:
* gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p' * gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p'
*/ */
{ .vid = 0x04e8, .pid = 0x730b },
{ .vid = 0x04f3, .pid = 0x036b }, { .vid = 0x04f3, .pid = 0x036b },
{ .vid = 0x04f3, .pid = 0x0c00 }, { .vid = 0x04f3, .pid = 0x0c00 },
{ .vid = 0x04f3, .pid = 0x0c4b },
{ .vid = 0x04f3, .pid = 0x0c4c }, { .vid = 0x04f3, .pid = 0x0c4c },
{ .vid = 0x04f3, .pid = 0x0c57 }, { .vid = 0x04f3, .pid = 0x0c57 },
{ .vid = 0x04f3, .pid = 0x0c5e }, { .vid = 0x04f3, .pid = 0x0c5e },
@@ -52,6 +52,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x06cb, .pid = 0x00d8 }, { .vid = 0x06cb, .pid = 0x00d8 },
{ .vid = 0x06cb, .pid = 0x00da }, { .vid = 0x06cb, .pid = 0x00da },
{ .vid = 0x06cb, .pid = 0x00dc }, { .vid = 0x06cb, .pid = 0x00dc },
{ .vid = 0x06cb, .pid = 0x00e4 },
{ .vid = 0x06cb, .pid = 0x00e7 }, { .vid = 0x06cb, .pid = 0x00e7 },
{ .vid = 0x06cb, .pid = 0x00e9 }, { .vid = 0x06cb, .pid = 0x00e9 },
{ .vid = 0x06cb, .pid = 0x00fd }, { .vid = 0x06cb, .pid = 0x00fd },
@@ -67,6 +68,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x0bda, .pid = 0x5812 }, { .vid = 0x0bda, .pid = 0x5812 },
{ .vid = 0x10a5, .pid = 0x0007 }, { .vid = 0x10a5, .pid = 0x0007 },
{ .vid = 0x10a5, .pid = 0x9200 }, { .vid = 0x10a5, .pid = 0x9200 },
{ .vid = 0x10a5, .pid = 0x9800 },
{ .vid = 0x1188, .pid = 0x9545 }, { .vid = 0x1188, .pid = 0x9545 },
{ .vid = 0x138a, .pid = 0x0007 }, { .vid = 0x138a, .pid = 0x0007 },
{ .vid = 0x138a, .pid = 0x003a }, { .vid = 0x138a, .pid = 0x003a },
@@ -88,6 +90,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x27c6, .pid = 0x5042 }, { .vid = 0x27c6, .pid = 0x5042 },
{ .vid = 0x27c6, .pid = 0x5110 }, { .vid = 0x27c6, .pid = 0x5110 },
{ .vid = 0x27c6, .pid = 0x5117 }, { .vid = 0x27c6, .pid = 0x5117 },
{ .vid = 0x27c6, .pid = 0x5125 },
{ .vid = 0x27c6, .pid = 0x5201 }, { .vid = 0x27c6, .pid = 0x5201 },
{ .vid = 0x27c6, .pid = 0x521d }, { .vid = 0x27c6, .pid = 0x521d },
{ .vid = 0x27c6, .pid = 0x5301 }, { .vid = 0x27c6, .pid = 0x5301 },
@@ -99,6 +102,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x27c6, .pid = 0x538c }, { .vid = 0x27c6, .pid = 0x538c },
{ .vid = 0x27c6, .pid = 0x538d }, { .vid = 0x27c6, .pid = 0x538d },
{ .vid = 0x27c6, .pid = 0x5395 }, { .vid = 0x27c6, .pid = 0x5395 },
{ .vid = 0x27c6, .pid = 0x5503 },
{ .vid = 0x27c6, .pid = 0x5584 }, { .vid = 0x27c6, .pid = 0x5584 },
{ .vid = 0x27c6, .pid = 0x55a2 }, { .vid = 0x27c6, .pid = 0x55a2 },
{ .vid = 0x27c6, .pid = 0x55a4 }, { .vid = 0x27c6, .pid = 0x55a4 },

View File

@@ -135,8 +135,6 @@ driver_sources = {
[ 'drivers/virtual-device.c' ], [ 'drivers/virtual-device.c' ],
'virtual_device_storage' : 'virtual_device_storage' :
[ 'drivers/virtual-device-storage.c' ], [ 'drivers/virtual-device-storage.c' ],
'virtual_sdcp' :
[ 'drivers/virtual-sdcp.c' ],
'synaptics' : 'synaptics' :
[ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ], [ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ],
'goodixmoc' : 'goodixmoc' :
@@ -144,8 +142,6 @@ driver_sources = {
} }
helper_sources = { helper_sources = {
'sdcp' :
[ 'fp-sdcp-device.c', 'fpi-sdcp-device.c' ],
'aeslib' : 'aeslib' :
[ 'drivers/aeslib.c' ], [ 'drivers/aeslib.c' ],
'aesx660' : 'aesx660' :

View File

@@ -0,0 +1,31 @@
From 2584d440afc87d463cb8dc809d48c660e091c2c4 Mon Sep 17 00:00:00 2001
From: Sam James <sam@gentoo.org>
Date: Thu, 23 Jun 2022 05:57:46 +0100
Subject: [PATCH] nbis: fix build on musl
Drop re-definition of stderr. There's no need for this anywhere
(including glibc). This breaks in particular on musl because
stderr (and stdin) are both const, and macros unlike in glibc.
Bug: https://bugs.gentoo.org/853811
---
nbis/include/bozorth.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/nbis/include/bozorth.h b/nbis/include/bozorth.h
index a705da98..fd8975bf 100644
--- a/nbis/include/bozorth.h
+++ b/nbis/include/bozorth.h
@@ -217,8 +217,6 @@ struct xytq_struct {
/**************************************************************************/
/* Globals supporting command line options */
extern int verbose_threshold;
-/* Global supporting error reporting */
-extern FILE *stderr;
/**************************************************************************/
/* In: BZ_GBLS.C */
--
GitLab

View File

@@ -217,8 +217,6 @@ struct xytq_struct {
/**************************************************************************/ /**************************************************************************/
/* Globals supporting command line options */ /* Globals supporting command line options */
extern int verbose_threshold; extern int verbose_threshold;
/* Global supporting error reporting */
extern FILE *stderr;
/**************************************************************************/ /**************************************************************************/
/* In: BZ_GBLS.C */ /* In: BZ_GBLS.C */

View File

@@ -198,3 +198,6 @@ patch -p0 < fix-scan-build-reports.patch
# Add pass to remove perimeter points # Add pass to remove perimeter points
patch -p0 < remove-perimeter-pts.patch patch -p0 < remove-perimeter-pts.patch
# Fix build on musl by dropping unnecessary redeclaration of stderr
patch -p0 < fix-musl-build.patch

View File

@@ -1,5 +1,5 @@
project('libfprint', [ 'c', 'cpp' ], project('libfprint', [ 'c', 'cpp' ],
version: '1.94.3', version: '1.94.4',
license: 'LGPLv2.1+', license: 'LGPLv2.1+',
default_options: [ default_options: [
'buildtype=debugoptimized', 'buildtype=debugoptimized',
@@ -11,6 +11,7 @@ project('libfprint', [ 'c', 'cpp' ],
gnome = import('gnome') gnome = import('gnome')
libfprint_conf = configuration_data() libfprint_conf = configuration_data()
libfprint_conf.set_quoted('LIBFPRINT_VERSION', meson.project_version())
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp') cpp = meson.get_compiler('cpp')
@@ -96,8 +97,8 @@ virtual_drivers = [
'virtual_image', 'virtual_image',
'virtual_device', 'virtual_device',
'virtual_device_storage', 'virtual_device_storage',
'virtual_sdcp',
] ]
default_drivers = [ default_drivers = [
'upektc_img', 'upektc_img',
'vfs5011', 'vfs5011',
@@ -159,7 +160,6 @@ driver_helper_mapping = {
'virtual_image' : [ 'virtual' ], 'virtual_image' : [ 'virtual' ],
'virtual_device' : [ 'virtual' ], 'virtual_device' : [ 'virtual' ],
'virtual_device_storage' : [ 'virtual' ], 'virtual_device_storage' : [ 'virtual' ],
'virtual_sdcp' : [ 'sdcp' ],
} }
driver_helpers = [] driver_helpers = []
@@ -218,13 +218,6 @@ foreach i : driver_helpers
error('nss is required for @0@ and possibly others'.format(driver)) error('nss is required for @0@ and possibly others'.format(driver))
endif endif
optional_deps += nss_dep
elif i == 'sdcp'
nss_dep = dependency('nss', version: '>=3.55', required: false)
if not nss_dep.found()
error('nss >=3.55 is required for SDCP support (@0@ and possibly others)'.format(driver))
endif
optional_deps += nss_dep optional_deps += nss_dep
elif i == 'udev' elif i == 'udev'
install_udev_rules = true install_udev_rules = true

View File

@@ -30,8 +30,3 @@ option('doc',
description: 'Whether to build the API documentation', description: 'Whether to build the API documentation',
type: 'boolean', type: 'boolean',
value: true) value: true)
option('sdcp_virt_binary',
description: 'Path to virtual SDCP test binary, please refer to CI for more details.',
type: 'string',
value: '')

View File

@@ -120,7 +120,7 @@ nl_multi_line_cond true
# Not clear what to do about that... # Not clear what to do about that...
mod_full_brace_for Remove mod_full_brace_for Remove
mod_full_brace_if Remove mod_full_brace_if Remove
mod_full_brace_if_chain True mod_full_brace_if_chain 1
mod_full_brace_while Remove mod_full_brace_while Remove
mod_full_brace_do Remove mod_full_brace_do Remove
mod_full_brace_nl 3 mod_full_brace_nl 3

View File

@@ -105,6 +105,11 @@ process.wait()
# Run capture # Run capture
# https://osqa-ask.wireshark.org/questions/53919/how-can-i-precisely-specify-a-usb-device-to-capture-with-tshark/ # https://osqa-ask.wireshark.org/questions/53919/how-can-i-precisely-specify-a-usb-device-to-capture-with-tshark/
print(f'### Reseting USB port (as descriptors could be missing in the dump otherwise)')
usb_device.open()
usb_device.reset()
usb_device.close()
print(f'### Starting USB capture on usbmon{bus_num}') print(f'### Starting USB capture on usbmon{bus_num}')
capture_pid = os.fork() capture_pid = os.fork()
assert(capture_pid >= 0) assert(capture_pid >= 0)

Binary file not shown.

View File

@@ -1,63 +1,67 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-1 P: /devices/pci0000:00/0000:00:14.0/usb1/1-9
N: bus/usb/001/010=1201000200000040F3047E0C05030102000109025300010103A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001 N: bus/usb/001/003=1201000200000008F304880C04800102000109025300010100A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001
E: DEVNAME=/dev/bus/usb/001/010 E: DEVNAME=/dev/bus/usb/001/003
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=4f3/c7e/305 E: PRODUCT=4f3/c88/8004
E: TYPE=0/0/0 E: TYPE=0/0/0
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=010 E: DEVNUM=003
E: MAJOR=189 E: MAJOR=189
E: MINOR=9 E: MINOR=2
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=ELAN E: ID_VENDOR=ELAN
E: ID_VENDOR_ENC=ELAN E: ID_VENDOR_ENC=ELAN
E: ID_VENDOR_ID=04f3 E: ID_VENDOR_ID=04f3
E: ID_MODEL=ELAN:ARM-M4 E: ID_MODEL=ELAN:ARM-M4
E: ID_MODEL_ENC=ELAN:ARM-M4 E: ID_MODEL_ENC=ELAN:ARM-M4
E: ID_MODEL_ID=0c7e E: ID_MODEL_ID=0c88
E: ID_REVISION=0305 E: ID_REVISION=8004
E: ID_SERIAL=ELAN_ELAN:ARM-M4 E: ID_SERIAL=ELAN_ELAN:ARM-M4
E: ID_BUS=usb E: ID_BUS=usb
E: ID_USB_INTERFACES=:ff0000: E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp. E: ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp.
E: ID_PATH=pci-0000:00:14.0-usb-0:1 E: ID_PATH=pci-0000:00:14.0-usb-0:9
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_1 E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9
E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_9
E: TAGS=:seat:
E: CURRENT_TAGS=:seat:
A: authorized=1\n A: authorized=1\n
A: avoid_reset_quirk=0\n A: avoid_reset_quirk=0\n
A: bConfigurationValue=1\n A: bConfigurationValue=1\n
A: bDeviceClass=00\n A: bDeviceClass=00\n
A: bDeviceProtocol=00\n A: bDeviceProtocol=00\n
A: bDeviceSubClass=00\n A: bDeviceSubClass=00\n
A: bMaxPacketSize0=64\n A: bMaxPacketSize0=8\n
A: bMaxPower=100mA\n A: bMaxPower=100mA\n
A: bNumConfigurations=1\n A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n A: bNumInterfaces= 1\n
A: bcdDevice=0305\n A: bcdDevice=8004\n
A: bmAttributes=a0\n A: bmAttributes=a0\n
A: busnum=1\n A: busnum=1\n
A: configuration=add909c9-e67e-4126-a6f7-1e31179e27d9\n A: configuration=
H: descriptors=1201000200000040F3047E0C05030102000109025300010103A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001 H: descriptors=1201000200000008F304880C04800102000109025300010100A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001
A: dev=189:9\n A: dev=189:2\n
A: devnum=10\n A: devnum=3\n
A: devpath=1\n A: devpath=9\n
L: driver=../../../../../bus/usb/drivers/usb L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=0c7e\n L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:3d/device:3e/device:47
A: idProduct=0c88\n
A: idVendor=04f3\n A: idVendor=04f3\n
A: ltm_capable=no\n A: ltm_capable=no\n
A: manufacturer=ELAN\n A: manufacturer=ELAN\n
A: maxchild=0\n A: maxchild=0\n
L: port=../1-0:1.0/usb1-port1 L: port=../1-0:1.0/usb1-port9
A: power/active_duration=94712\n A: power/active_duration=35269124\n
A: power/async=enabled\n A: power/async=enabled\n
A: power/autosuspend=2\n A: power/autosuspend=2\n
A: power/autosuspend_delay_ms=2000\n A: power/autosuspend_delay_ms=2000\n
A: power/connected_duration=94712\n A: power/connected_duration=35283788\n
A: power/control=on\n A: power/control=on\n
A: power/level=on\n A: power/level=on\n
A: power/persist=1\n A: power/persist=0\n
A: power/runtime_active_kids=0\n A: power/runtime_active_kids=0\n
A: power/runtime_active_time=94436\n A: power/runtime_active_time=35276624\n
A: power/runtime_enabled=forbidden\n A: power/runtime_enabled=forbidden\n
A: power/runtime_status=active\n A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n A: power/runtime_suspended_time=0\n
@@ -77,38 +81,40 @@ A: removable=removable\n
A: rx_lanes=1\n A: rx_lanes=1\n
A: speed=12\n A: speed=12\n
A: tx_lanes=1\n A: tx_lanes=1\n
A: urbnum=12\n A: urbnum=2773\n
A: version= 2.00\n A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0/usb1 P: /devices/pci0000:00/0000:00:14.0/usb1
N: bus/usb/001/001=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C N: bus/usb/001/001=12010002090001406B1D020015050302010109021900010100E0000904000001090000000705810304000C
E: DEVNAME=/dev/bus/usb/001/001 E: DEVNAME=/dev/bus/usb/001/001
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=1d6b/2/504 E: PRODUCT=1d6b/2/515
E: TYPE=9/0/1 E: TYPE=9/0/1
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=001 E: DEVNUM=001
E: MAJOR=189 E: MAJOR=189
E: MINOR=0 E: MINOR=0
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.4.0-42-generic_xhci-hcd E: ID_VENDOR=Linux_5.15.0-39-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.4.0-42-generic\x20xhci-hcd E: ID_VENDOR_ENC=Linux\x205.15.0-39-generic\x20xhci-hcd
E: ID_VENDOR_ID=1d6b E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002 E: ID_MODEL_ID=0002
E: ID_REVISION=0504 E: ID_REVISION=0515
E: ID_SERIAL=Linux_5.4.0-42-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 E: ID_SERIAL=Linux_5.15.0-39-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_SERIAL_SHORT=0000:00:14.0 E: ID_SERIAL_SHORT=0000:00:14.0
E: ID_BUS=usb E: ID_BUS=usb
E: ID_USB_INTERFACES=:090000: E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR_FROM_DATABASE=Linux Foundation E: ID_VENDOR_FROM_DATABASE=Linux Foundation
E: ID_AUTOSUSPEND=1
E: ID_MODEL_FROM_DATABASE=2.0 root hub E: ID_MODEL_FROM_DATABASE=2.0 root hub
E: ID_PATH=pci-0000:00:14.0 E: ID_PATH=pci-0000:00:14.0
E: ID_PATH_TAG=pci-0000_00_14_0 E: ID_PATH_TAG=pci-0000_00_14_0
E: ID_FOR_SEAT=usb-pci-0000_00_14_0 E: ID_FOR_SEAT=usb-pci-0000_00_14_0
E: TAGS=:seat: E: TAGS=:seat:
E: CURRENT_TAGS=:seat:
A: authorized=1\n A: authorized=1\n
A: authorized_default=1\n A: authorized_default=1\n
A: avoid_reset_quirk=0\n A: avoid_reset_quirk=0\n
@@ -120,30 +126,31 @@ A: bMaxPacketSize0=64\n
A: bMaxPower=0mA\n A: bMaxPower=0mA\n
A: bNumConfigurations=1\n A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n A: bNumInterfaces= 1\n
A: bcdDevice=0504\n A: bcdDevice=0515\n
A: bmAttributes=e0\n A: bmAttributes=e0\n
A: busnum=1\n A: busnum=1\n
A: configuration=\n A: configuration=
H: descriptors=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C H: descriptors=12010002090001406B1D020015050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0\n A: dev=189:0\n
A: devnum=1\n A: devnum=1\n
A: devpath=0\n A: devpath=0\n
L: driver=../../../../bus/usb/drivers/usb L: driver=../../../../bus/usb/drivers/usb
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:3d/device:3e
A: idProduct=0002\n A: idProduct=0002\n
A: idVendor=1d6b\n A: idVendor=1d6b\n
A: interface_authorized_default=1\n A: interface_authorized_default=1\n
A: ltm_capable=no\n A: ltm_capable=no\n
A: manufacturer=Linux 5.4.0-42-generic xhci-hcd\n A: manufacturer=Linux 5.15.0-39-generic xhci-hcd\n
A: maxchild=12\n A: maxchild=14\n
A: power/active_duration=74604360\n A: power/active_duration=35270364\n
A: power/async=enabled\n A: power/async=enabled\n
A: power/autosuspend=0\n A: power/autosuspend=0\n
A: power/autosuspend_delay_ms=0\n A: power/autosuspend_delay_ms=0\n
A: power/connected_duration=74606456\n A: power/connected_duration=35284300\n
A: power/control=auto\n A: power/control=auto\n
A: power/level=auto\n A: power/level=auto\n
A: power/runtime_active_kids=4\n A: power/runtime_active_kids=2\n
A: power/runtime_active_time=74605838\n A: power/runtime_active_time=35277420\n
A: power/runtime_enabled=enabled\n A: power/runtime_enabled=enabled\n
A: power/runtime_status=active\n A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n A: power/runtime_suspended_time=0\n
@@ -164,62 +171,63 @@ A: rx_lanes=1\n
A: serial=0000:00:14.0\n A: serial=0000:00:14.0\n
A: speed=480\n A: speed=480\n
A: tx_lanes=1\n A: tx_lanes=1\n
A: urbnum=490\n A: urbnum=549\n
A: version= 2.00\n A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0 P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd E: DRIVER=xhci_hcd
E: PCI_CLASS=C0330 E: PCI_CLASS=C0330
E: PCI_ID=8086:9DED E: PCI_ID=8086:8C31
E: PCI_SUBSYS_ID=103C:85EF E: PCI_SUBSYS_ID=1043:201F
E: PCI_SLOT_NAME=0000:00:14.0 E: PCI_SLOT_NAME=0000:00:14.0
E: MODALIAS=pci:v00008086d00009DEDsv0000103Csd000085EFbc0Csc03i30 E: MODALIAS=pci:v00008086d00008C31sv00001043sd0000201Fbc0Csc03i30
E: SUBSYSTEM=pci E: SUBSYSTEM=pci
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
E: ID_VENDOR_FROM_DATABASE=Intel Corporation E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller E: ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI
A: ari_enabled=0\n A: ari_enabled=0\n
A: broken_parity_status=0\n A: broken_parity_status=0\n
A: class=0x0c0330\n A: class=0x0c0330\n
H: config=8680ED9D060490023030030C00008000040030A10000000000000000000000000000000000000000000000003C10EF85000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F00000000181C030400000000316000000000000000000000000000000180C2C1080000000000000000000000059087007802E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000B50F300112000000 H: config=8680318C060490020530030C000000000400A0F700000000000000000000000000000000000000000000000043101F200000000070000000000000000B010000FD01368089C60F8000000000000000009F6E8807000000000000000000000000302000000000000000000000000000000180C2C1080000000000000000000000050087000410E0FE000000002F00000000000000000000000000000000000000400100000000000000000000000000000F000100000000000000000000000000030420C0030C3000030C300000000000FF1A0000FF1A00003F0000003F000000A00000000000000000000000D8D8D8080000000000000000B10F060800000000
A: consistent_dma_mask_bits=64\n A: consistent_dma_mask_bits=64\n
A: d3cold_allowed=1\n A: d3cold_allowed=1\n
A: dbc=disabled\n A: device=0x8c31\n
A: device=0x9ded\n
A: dma_mask_bits=64\n A: dma_mask_bits=64\n
L: driver=../../../bus/pci/drivers/xhci_hcd L: driver=../../../bus/pci/drivers/xhci_hcd
A: driver_override=(null)\n A: driver_override=(null)\n
A: enable=1\n A: enable=1\n
A: irq=124\n L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:3d
A: irq=31\n
A: local_cpulist=0-3\n A: local_cpulist=0-3\n
A: local_cpus=f\n A: local_cpus=f\n
A: modalias=pci:v00008086d00009DEDsv0000103Csd000085EFbc0Csc03i30\n A: modalias=pci:v00008086d00008C31sv00001043sd0000201Fbc0Csc03i30\n
A: msi_bus=1\n A: msi_bus=1\n
A: msi_irqs/124=msi\n A: msi_irqs/31=msi\n
A: numa_node=-1\n A: numa_node=-1\n
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 32 128 1\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 11 12 2112 12\nxHCI ring segments 54 54 4096 54\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 9 32 128 1\nbuffer-32 0 0 32 0\n A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 5 6 2112 6\nxHCI ring segments 24 24 4096 24\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 3 32 128 1\nbuffer-32 0 0 32 0\n
A: power/async=enabled\n A: power/async=enabled\n
A: power/control=auto\n A: power/control=on\n
A: power/runtime_active_kids=1\n A: power/runtime_active_kids=1\n
A: power/runtime_active_time=74606194\n A: power/runtime_active_time=35278060\n
A: power/runtime_enabled=enabled\n A: power/runtime_enabled=forbidden\n
A: power/runtime_status=active\n A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n A: power/runtime_suspended_time=0\n
A: power/runtime_usage=0\n A: power/runtime_usage=1\n
A: power/wakeup=enabled\n A: power/wakeup=enabled\n
A: power/wakeup_abort_count=0\n A: power/wakeup_abort_count=0\n
A: power/wakeup_active=0\n A: power/wakeup_active=0\n
A: power/wakeup_active_count=0\n A: power/wakeup_active_count=5\n
A: power/wakeup_count=0\n A: power/wakeup_count=0\n
A: power/wakeup_expire_count=0\n A: power/wakeup_expire_count=5\n
A: power/wakeup_last_time_ms=0\n A: power/wakeup_last_time_ms=12694896\n
A: power/wakeup_max_time_ms=0\n A: power/wakeup_max_time_ms=103\n
A: power/wakeup_total_time_ms=0\n A: power/wakeup_total_time_ms=518\n
A: resource=0x00000000a1300000 0x00000000a130ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n A: power_state=D0\n
A: revision=0x30\n A: resource=0x00000000f7a00000 0x00000000f7a0ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n
A: subsystem_device=0x85ef\n A: revision=0x05\n
A: subsystem_vendor=0x103c\n A: subsystem_device=0x201f\n
A: subsystem_vendor=0x1043\n
A: vendor=0x8086\n A: vendor=0x8086\n

Binary file not shown.

View File

@@ -25,6 +25,9 @@ assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)
d.open_sync() d.open_sync()
# 1. verify clear storage command, 2. make sure later asserts are good
d.clear_storage_sync()
template = FPrint.Print.new(d) template = FPrint.Print.new(d)
def enroll_progress(*args): def enroll_progress(*args):

View File

@@ -1,14 +1,14 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-3 P: /devices/pci0000:00/0000:00:14.0/usb1/1-3
N: bus/usb/001/053=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000 N: bus/usb/001/023=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000
E: DEVNAME=/dev/bus/usb/001/053 E: DEVNAME=/dev/bus/usb/001/023
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=27c6/6496/100 E: PRODUCT=27c6/6496/100
E: TYPE=239/0/0 E: TYPE=239/0/0
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=053 E: DEVNUM=023
E: MAJOR=189 E: MAJOR=189
E: MINOR=52 E: MINOR=22
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=Goodix_Technology_Co.__Ltd. E: ID_VENDOR=Goodix_Technology_Co.__Ltd.
E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd. E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd.
@@ -23,6 +23,7 @@ E: ID_BUS=usb
E: ID_USB_INTERFACES=:ff0000: E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd. E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd.
E: ID_AUTOSUSPEND=1 E: ID_AUTOSUSPEND=1
E: ID_PERSIST=0
E: ID_PATH=pci-0000:00:14.0-usb-0:3 E: ID_PATH=pci-0000:00:14.0-usb-0:3
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_3 E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_3
A: authorized=1\n A: authorized=1\n
@@ -40,8 +41,8 @@ A: bmAttributes=a0\n
A: busnum=1\n A: busnum=1\n
A: configuration=XXXX_MOC_B0\n A: configuration=XXXX_MOC_B0\n
H: descriptors=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000 H: descriptors=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000
A: dev=189:52\n A: dev=189:22\n
A: devnum=53\n A: devnum=23\n
A: devpath=3\n A: devpath=3\n
L: driver=../../../../../bus/usb/drivers/usb L: driver=../../../../../bus/usb/drivers/usb
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:20 L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:20
@@ -51,16 +52,16 @@ A: ltm_capable=no\n
A: manufacturer=Goodix Technology Co., Ltd.\n A: manufacturer=Goodix Technology Co., Ltd.\n
A: maxchild=0\n A: maxchild=0\n
L: port=../1-0:1.0/usb1-port3 L: port=../1-0:1.0/usb1-port3
A: power/active_duration=29262\n A: power/active_duration=22667\n
A: power/autosuspend=2\n A: power/autosuspend=2\n
A: power/autosuspend_delay_ms=2000\n A: power/autosuspend_delay_ms=2000\n
A: power/connected_duration=57399\n A: power/connected_duration=917616\n
A: power/control=auto\n A: power/control=auto\n
A: power/level=auto\n A: power/level=auto\n
A: power/persist=1\n A: power/persist=1\n
A: power/runtime_active_time=29308\n A: power/runtime_active_time=22809\n
A: power/runtime_status=active\n A: power/runtime_status=active\n
A: power/runtime_suspended_time=27850\n A: power/runtime_suspended_time=894564\n
A: power/wakeup=disabled\n A: power/wakeup=disabled\n
A: power/wakeup_abort_count=\n A: power/wakeup_abort_count=\n
A: power/wakeup_active=\n A: power/wakeup_active=\n
@@ -77,29 +78,29 @@ A: rx_lanes=1\n
A: serial=XXXX_MOC_B0\n A: serial=XXXX_MOC_B0\n
A: speed=12\n A: speed=12\n
A: tx_lanes=1\n A: tx_lanes=1\n
A: urbnum=394\n A: urbnum=298\n
A: version= 2.00\n A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0/usb1 P: /devices/pci0000:00/0000:00:14.0/usb1
N: bus/usb/001/001=12010002090001406B1D020013050302010109021900010100E0000904000001090000000705810304000C N: bus/usb/001/001=12010002090001406B1D020017050302010109021900010100E0000904000001090000000705810304000C
E: DEVNAME=/dev/bus/usb/001/001 E: DEVNAME=/dev/bus/usb/001/001
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=1d6b/2/513 E: PRODUCT=1d6b/2/517
E: TYPE=9/0/1 E: TYPE=9/0/1
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=001 E: DEVNUM=001
E: MAJOR=189 E: MAJOR=189
E: MINOR=0 E: MINOR=0
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.13.15-200.fc34.x86_64_xhci-hcd E: ID_VENDOR=Linux_5.17.12-300.fc36.x86_64_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.13.15-200.fc34.x86_64\x20xhci-hcd E: ID_VENDOR_ENC=Linux\x205.17.12-300.fc36.x86_64\x20xhci-hcd
E: ID_VENDOR_ID=1d6b E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002 E: ID_MODEL_ID=0002
E: ID_REVISION=0513 E: ID_REVISION=0517
E: ID_SERIAL=Linux_5.13.15-200.fc34.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 E: ID_SERIAL=Linux_5.17.12-300.fc36.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_SERIAL_SHORT=0000:00:14.0 E: ID_SERIAL_SHORT=0000:00:14.0
E: ID_BUS=usb E: ID_BUS=usb
E: ID_USB_INTERFACES=:090000: E: ID_USB_INTERFACES=:090000:
@@ -122,11 +123,11 @@ A: bMaxPacketSize0=64\n
A: bMaxPower=0mA\n A: bMaxPower=0mA\n
A: bNumConfigurations=1\n A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n A: bNumInterfaces= 1\n
A: bcdDevice=0513\n A: bcdDevice=0517\n
A: bmAttributes=e0\n A: bmAttributes=e0\n
A: busnum=1\n A: busnum=1\n
A: configuration=\n A: configuration=\n
H: descriptors=12010002090001406B1D020013050302010109021900010100E0000904000001090000000705810304000C H: descriptors=12010002090001406B1D020017050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0\n A: dev=189:0\n
A: devnum=1\n A: devnum=1\n
A: devpath=0\n A: devpath=0\n
@@ -136,15 +137,15 @@ A: idProduct=0002\n
A: idVendor=1d6b\n A: idVendor=1d6b\n
A: interface_authorized_default=1\n A: interface_authorized_default=1\n
A: ltm_capable=no\n A: ltm_capable=no\n
A: manufacturer=Linux 5.13.15-200.fc34.x86_64 xhci-hcd\n A: manufacturer=Linux 5.17.12-300.fc36.x86_64 xhci-hcd\n
A: maxchild=12\n A: maxchild=12\n
A: power/active_duration=219578717\n A: power/active_duration=164289796\n
A: power/autosuspend=0\n A: power/autosuspend=0\n
A: power/autosuspend_delay_ms=0\n A: power/autosuspend_delay_ms=0\n
A: power/connected_duration=219649620\n A: power/connected_duration=164360220\n
A: power/control=auto\n A: power/control=auto\n
A: power/level=auto\n A: power/level=auto\n
A: power/runtime_active_time=219589127\n A: power/runtime_active_time=164331876\n
A: power/runtime_status=active\n A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n A: power/runtime_suspended_time=0\n
A: power/wakeup=disabled\n A: power/wakeup=disabled\n
@@ -163,14 +164,14 @@ A: rx_lanes=1\n
A: serial=0000:00:14.0\n A: serial=0000:00:14.0\n
A: speed=480\n A: speed=480\n
A: tx_lanes=1\n A: tx_lanes=1\n
A: urbnum=4325\n A: urbnum=2097\n
A: version= 2.00\n A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0 P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd E: DRIVER=xhci_hcd
E: PCI_CLASS=C0330 E: PCI_CLASS=C0330
E: PCI_ID=8086:9DED E: PCI_ID=8086:9DED
E: PCI_SUBSYS_ID=17AA:2292\n E: PCI_SUBSYS_ID=17AA:2292
E: PCI_SLOT_NAME=0000:00:14.0 E: PCI_SLOT_NAME=0000:00:14.0
E: MODALIAS=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30 E: MODALIAS=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30
E: SUBSYSTEM=pci E: SUBSYSTEM=pci
@@ -183,7 +184,7 @@ E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller
A: ari_enabled=0\n A: ari_enabled=0\n
A: broken_parity_status=0\n A: broken_parity_status=0\n
A: class=0x0c0330\n A: class=0x0c0330\n
H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F000000004C084B0100000000316000000000000000000000000000000180C2C1080000000000000000000000059087001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000 H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F00000000F507312600000000316000000000000000000000000000000180C2C1080000000000000000000000059087001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000
A: consistent_dma_mask_bits=64\n A: consistent_dma_mask_bits=64\n
A: d3cold_allowed=1\n A: d3cold_allowed=1\n
A: dbc=disabled\n A: dbc=disabled\n
@@ -201,8 +202,8 @@ A: msi_bus=1\n
A: msi_irqs/128=msi\n A: msi_irqs/128=msi\n
A: numa_node=-1\n A: numa_node=-1\n
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 11 12 2112 12\nxHCI ring segments 46 50 4096 50\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 6 32 128 1\nbuffer-32 0 0 32 0\n A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 11 12 2112 12\nxHCI ring segments 46 50 4096 50\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 6 32 128 1\nbuffer-32 0 0 32 0\n
A: power/control=on\n A: power/control=auto\n
A: power/runtime_active_time=219589302\n A: power/runtime_active_time=164332777\n
A: power/runtime_status=active\n A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n A: power/runtime_suspended_time=0\n
A: power/wakeup=enabled\n A: power/wakeup=enabled\n

View File

@@ -12,9 +12,6 @@ envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint'))
# random numbers rather than proper ones) # random numbers rather than proper ones)
envs.set('FP_DEVICE_EMULATION', '1') envs.set('FP_DEVICE_EMULATION', '1')
# Path to SDCP virtual device binary, only used for virtual-sdcp test
envs.set('SDCP_VIRT_BINARY', get_option('sdcp_virt_binary'))
# Set a colon-separated list of native drivers we enable in tests # Set a colon-separated list of native drivers we enable in tests
envs.set('FP_DRIVERS_WHITELIST', ':'.join([ envs.set('FP_DRIVERS_WHITELIST', ':'.join([
'virtual_image', 'virtual_image',
@@ -91,7 +88,6 @@ if get_option('introspection')
suite: ut_suite, suite: ut_suite,
depends: libfprint_typelib, depends: libfprint_typelib,
env: envs, env: envs,
workdir: meson.current_source_dir(),
) )
endforeach endforeach
else else
@@ -102,46 +98,6 @@ if get_option('introspection')
endif endif
endforeach endforeach
if 'virtual_sdcp' in drivers and get_option('sdcp_virt_binary') != ''
python3 = find_program('python3')
unittest_inspector = find_program('unittest_inspector.py')
base_args = files('virtual-sdcp.py')
suite = []
r = run_command(unittest_inspector, files('virtual-sdcp.py'))
unit_tests = r.stdout().strip().split('\n')
if r.returncode() == 0 and unit_tests.length() > 0
suite += 'virtual-sdcp'
else
unit_tests = ['virtual-sdcp']
endif
sdcp_envs = envs
sdcp_envs.set('FP_DEVICE_EMULATION', '0')
foreach ut: unit_tests
ut_suite = suite
ut_args = base_args
if unit_tests.length() > 1
ut_args += ut
ut_suite += ut.split('.')[0]
endif
test(ut,
python3,
args: ut_args,
suite: ut_suite,
depends: libfprint_typelib,
env: sdcp_envs,
workdir: meson.current_source_dir(),
)
endforeach
else
test('virtual-sdcp',
find_program('sh'),
args: ['-c', 'exit 77']
)
endif
foreach driver_test: drivers_tests foreach driver_test: drivers_tests
driver_name = driver_test.split('-')[0] driver_name = driver_test.split('-')[0]
driver_envs = envs driver_envs = envs
@@ -153,7 +109,6 @@ if get_option('introspection')
find_program('umockdev-test.py'), find_program('umockdev-test.py'),
args: join_paths(meson.current_source_dir(), driver_test), args: join_paths(meson.current_source_dir(), driver_test),
env: driver_envs, env: driver_envs,
workdir: meson.current_source_dir(),
suite: ['drivers'], suite: ['drivers'],
timeout: 15, timeout: 15,
depends: libfprint_typelib, depends: libfprint_typelib,

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,10 +1,14 @@
#!/usr/bin/python3 #!/usr/bin/python3
import os
import gi import gi
gi.require_version('FPrint', '2.0') gi.require_version('FPrint', '2.0')
from gi.repository import FPrint, GLib from gi.repository import FPrint, GLib
ctx = GLib.main_context_default() import sys
import traceback
sys.excepthook = lambda *args : (traceback.print_exception(*args), sys.exit(1))
c = FPrint.Context() c = FPrint.Context()
c.enumerate() c.enumerate()
@@ -13,6 +17,24 @@ devices = c.get_devices()
d = devices[0] d = devices[0]
del devices del devices
usb_device = d.get_property('fpi-usb-device')
bus_num = usb_device.get_bus()
port = []
while True:
parent = usb_device.get_parent()
if parent is None:
break
port.append(str(usb_device.get_port_number()))
usb_device = parent
port = '.'.join(port)
persist = f'/sys/bus/usb/devices/{bus_num}-{port}/power/persist'
wakeup = f'/sys/bus/usb/devices/{bus_num}-{port}/power/wakeup'
# may not have written anything
assert open(persist).read().strip() == "0"
assert open(wakeup).read().strip() == "disabled"
assert d.get_driver() == "synaptics" assert d.get_driver() == "synaptics"
assert not d.has_feature(FPrint.DeviceFeature.CAPTURE) assert not d.has_feature(FPrint.DeviceFeature.CAPTURE)
assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) assert d.has_feature(FPrint.DeviceFeature.IDENTIFY)
@@ -29,7 +51,7 @@ d.clear_storage_sync()
template = FPrint.Print.new(d) template = FPrint.Print.new(d)
def enroll_progress(*args): def enroll_progress(*args):
assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED #assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED
print('enroll progress: ' + str(args)) print('enroll progress: ' + str(args))
# List, enroll, list, verify, delete, list # List, enroll, list, verify, delete, list
@@ -41,6 +63,21 @@ print("enroll done")
print("verifying") print("verifying")
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
# Inject a suspend/resume cycle into the verify
def suspend_resume():
d.suspend_sync()
assert open(persist).read().strip() == "0"
assert open(wakeup).read().strip() == "enabled"
assert open(persist, 'w').write('0\n')
d.resume_sync()
# This tests that libfprint doesn't write if the value is correct
# (i.e. the trailing \ would be lost inside umockdev if written)
assert open(persist).read() == "0\n"
assert open(wakeup).read().strip() == "disabled"
GLib.idle_add(suspend_resume, priority=GLib.PRIORITY_HIGH)
verify_res, verify_print = d.verify_sync(p) verify_res, verify_print = d.verify_sync(p)
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
print("verify done") print("verify done")

View File

@@ -1,14 +1,14 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-9 P: /devices/pci0000:00/0000:00:14.0/usb1/1-9
N: bus/usb/001/005 N: bus/usb/001/004=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004
E: DEVNAME=/dev/bus/usb/001/005 E: DEVNAME=/dev/bus/usb/001/004
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=6cb/bd/0 E: PRODUCT=6cb/bd/0
E: TYPE=255/16/255 E: TYPE=255/16/255
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=005 E: DEVNUM=004
E: MAJOR=189 E: MAJOR=189
E: MINOR=4 E: MINOR=3
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=06cb E: ID_VENDOR=06cb
E: ID_VENDOR_ENC=06cb E: ID_VENDOR_ENC=06cb
@@ -24,82 +24,82 @@ E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Synaptics, Inc. E: ID_VENDOR_FROM_DATABASE=Synaptics, Inc.
E: ID_AUTOSUSPEND=1 E: ID_AUTOSUSPEND=1
E: ID_MODEL_FROM_DATABASE=Prometheus MIS Touch Fingerprint Reader E: ID_MODEL_FROM_DATABASE=Prometheus MIS Touch Fingerprint Reader
E: ID_PERSIST=0
E: ID_PATH=pci-0000:00:14.0-usb-0:9 E: ID_PATH=pci-0000:00:14.0-usb-0:9
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9 E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9
E: LIBFPRINT_DRIVER=Synaptics Sensors A: authorized=1
A: authorized=1\n A: avoid_reset_quirk=0
A: avoid_reset_quirk=0\n A: bConfigurationValue=1
A: bConfigurationValue=1\n A: bDeviceClass=ff
A: bDeviceClass=ff\n A: bDeviceProtocol=ff
A: bDeviceProtocol=ff\n A: bDeviceSubClass=10
A: bDeviceSubClass=10\n A: bMaxPacketSize0=8
A: bMaxPacketSize0=8\n A: bMaxPower=100mA
A: bMaxPower=100mA\n A: bNumConfigurations=1
A: bNumConfigurations=1\n A: bNumInterfaces= 1
A: bNumInterfaces= 1\n A: bcdDevice=0000
A: bcdDevice=0000\n A: bmAttributes=a0
A: bmAttributes=a0\n A: busnum=1
A: busnum=1\n
A: configuration= A: configuration=
H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004 H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004
A: dev=189:4\n A: dev=189:3
A: devnum=5\n A: devnum=4
A: devpath=9\n A: devpath=9
L: driver=../../../../../bus/usb/drivers/usb L: driver=../../../../../bus/usb/drivers/usb
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:28 L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:28
A: idProduct=00bd\n A: idProduct=00bd
A: idVendor=06cb\n A: idVendor=06cb
A: ltm_capable=no\n A: ltm_capable=no
A: maxchild=0\n A: maxchild=0
L: port=../1-0:1.0/usb1-port9 L: port=../1-0:1.0/usb1-port9
A: power/active_duration=82065\n A: power/active_duration=9424964
A: power/autosuspend=2\n A: power/autosuspend=2
A: power/autosuspend_delay_ms=2000\n A: power/autosuspend_delay_ms=2000
A: power/connected_duration=4271349\n A: power/connected_duration=866169213
A: power/control=auto\n A: power/control=auto
A: power/level=auto\n A: power/level=auto
A: power/persist=1\n A: power/persist=0
A: power/runtime_active_time=82975\n A: power/runtime_active_time=9431408
A: power/runtime_status=suspended\n A: power/runtime_status=active
A: power/runtime_suspended_time=4186597\n A: power/runtime_suspended_time=856661633
A: power/wakeup=disabled\n A: power/wakeup=disabled
A: power/wakeup_abort_count=\n A: power/wakeup_abort_count=
A: power/wakeup_active=\n A: power/wakeup_active=
A: power/wakeup_active_count=\n A: power/wakeup_active_count=
A: power/wakeup_count=\n A: power/wakeup_count=
A: power/wakeup_expire_count=\n A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=\n A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=\n A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=\n A: power/wakeup_total_time_ms=
A: quirks=0x0\n A: quirks=0x0
A: removable=fixed\n A: removable=fixed
A: rx_lanes=1\n A: rx_lanes=1
A: serial=c087f7d72126\n A: serial=c087f7d72126
A: speed=12\n A: speed=12
A: tx_lanes=1\n A: tx_lanes=1
A: urbnum=618\n A: urbnum=8945
A: version= 2.00\n A: version= 2.00
P: /devices/pci0000:00/0000:00:14.0/usb1 P: /devices/pci0000:00/0000:00:14.0/usb1
N: bus/usb/001/001=12010002090001406B1D020012050302010109021900010100E0000904000001090000000705810304000C N: bus/usb/001/001=12010002090001406B1D020016050302010109021900010100E0000904000001090000000705810304000C
E: DEVNAME=/dev/bus/usb/001/001 E: DEVNAME=/dev/bus/usb/001/001
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=1d6b/2/512 E: PRODUCT=1d6b/2/516
E: TYPE=9/0/1 E: TYPE=9/0/1
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=001 E: DEVNUM=001
E: MAJOR=189 E: MAJOR=189
E: MINOR=0 E: MINOR=0
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.12.9-300.fc34.x86_64_xhci-hcd E: ID_VENDOR=Linux_5.16.8-200.fc35.x86_64_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.12.9-300.fc34.x86_64\x20xhci-hcd E: ID_VENDOR_ENC=Linux\x205.16.8-200.fc35.x86_64\x20xhci-hcd
E: ID_VENDOR_ID=1d6b E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002 E: ID_MODEL_ID=0002
E: ID_REVISION=0512 E: ID_REVISION=0516
E: ID_SERIAL=Linux_5.12.9-300.fc34.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 E: ID_SERIAL=Linux_5.16.8-200.fc35.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_SERIAL_SHORT=0000:00:14.0 E: ID_SERIAL_SHORT=0000:00:14.0
E: ID_BUS=usb E: ID_BUS=usb
E: ID_USB_INTERFACES=:090000: E: ID_USB_INTERFACES=:090000:
@@ -111,60 +111,60 @@ E: ID_PATH_TAG=pci-0000_00_14_0
E: ID_FOR_SEAT=usb-pci-0000_00_14_0 E: ID_FOR_SEAT=usb-pci-0000_00_14_0
E: TAGS=:seat: E: TAGS=:seat:
E: CURRENT_TAGS=:seat: E: CURRENT_TAGS=:seat:
A: authorized=1\n A: authorized=1
A: authorized_default=1\n A: authorized_default=1
A: avoid_reset_quirk=0\n A: avoid_reset_quirk=0
A: bConfigurationValue=1\n A: bConfigurationValue=1
A: bDeviceClass=09\n A: bDeviceClass=09
A: bDeviceProtocol=01\n A: bDeviceProtocol=01
A: bDeviceSubClass=00\n A: bDeviceSubClass=00
A: bMaxPacketSize0=64\n A: bMaxPacketSize0=64
A: bMaxPower=0mA\n A: bMaxPower=0mA
A: bNumConfigurations=1\n A: bNumConfigurations=1
A: bNumInterfaces= 1\n A: bNumInterfaces= 1
A: bcdDevice=0512\n A: bcdDevice=0516
A: bmAttributes=e0\n A: bmAttributes=e0
A: busnum=1\n A: busnum=1
A: configuration= A: configuration=
H: descriptors=12010002090001406B1D020012050302010109021900010100E0000904000001090000000705810304000C H: descriptors=12010002090001406B1D020016050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0\n A: dev=189:0
A: devnum=1\n A: devnum=1
A: devpath=0\n A: devpath=0
L: driver=../../../../bus/usb/drivers/usb L: driver=../../../../bus/usb/drivers/usb
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d
A: idProduct=0002\n A: idProduct=0002
A: idVendor=1d6b\n A: idVendor=1d6b
A: interface_authorized_default=1\n A: interface_authorized_default=1
A: ltm_capable=no\n A: ltm_capable=no
A: manufacturer=Linux 5.12.9-300.fc34.x86_64 xhci-hcd\n A: manufacturer=Linux 5.16.8-200.fc35.x86_64 xhci-hcd
A: maxchild=12\n A: maxchild=12
A: power/active_duration=4270585\n A: power/active_duration=865968060
A: power/autosuspend=0\n A: power/autosuspend=0
A: power/autosuspend_delay_ms=0\n A: power/autosuspend_delay_ms=0
A: power/connected_duration=4272308\n A: power/connected_duration=866169920
A: power/control=auto\n A: power/control=auto
A: power/level=auto\n A: power/level=auto
A: power/runtime_active_time=4270770\n A: power/runtime_active_time=866093998
A: power/runtime_status=active\n A: power/runtime_status=active
A: power/runtime_suspended_time=0\n A: power/runtime_suspended_time=0
A: power/wakeup=disabled\n A: power/wakeup=disabled
A: power/wakeup_abort_count=\n A: power/wakeup_abort_count=
A: power/wakeup_active=\n A: power/wakeup_active=
A: power/wakeup_active_count=\n A: power/wakeup_active_count=
A: power/wakeup_count=\n A: power/wakeup_count=
A: power/wakeup_expire_count=\n A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=\n A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=\n A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=\n A: power/wakeup_total_time_ms=
A: product=xHCI Host Controller\n A: product=xHCI Host Controller
A: quirks=0x0\n A: quirks=0x0
A: removable=unknown\n A: removable=unknown
A: rx_lanes=1\n A: rx_lanes=1
A: serial=0000:00:14.0\n A: serial=0000:00:14.0
A: speed=480\n A: speed=480
A: tx_lanes=1\n A: tx_lanes=1
A: urbnum=463\n A: urbnum=9372
A: version= 2.00\n A: version= 2.00
P: /devices/pci0000:00/0000:00:14.0 P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd E: DRIVER=xhci_hcd
@@ -180,44 +180,44 @@ E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
E: ID_VENDOR_FROM_DATABASE=Intel Corporation E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: ID_AUTOSUSPEND=1 E: ID_AUTOSUSPEND=1
E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller
A: ari_enabled=0\n A: ari_enabled=0
A: broken_parity_status=0\n A: broken_parity_status=0
A: class=0x0c0330\n A: class=0x0c0330
H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000 H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F0000000060069A2400000000316000000000000000000000000000000180C2C108000000000000000000000005908700D802E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000
A: consistent_dma_mask_bits=64\n A: consistent_dma_mask_bits=64
A: d3cold_allowed=1\n A: d3cold_allowed=1
A: dbc=disabled\n A: dbc=disabled
A: device=0x9ded\n A: device=0x9ded
A: dma_mask_bits=64\n A: dma_mask_bits=64
L: driver=../../../bus/pci/drivers/xhci_hcd L: driver=../../../bus/pci/drivers/xhci_hcd
A: driver_override=(null)\n A: driver_override=(null)
A: enable=1\n A: enable=1
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c
A: irq=128\n A: irq=126
A: local_cpulist=0-7\n A: local_cpulist=0-7
A: local_cpus=ff\n A: local_cpus=ff
A: modalias=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30\n A: modalias=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30
A: msi_bus=1\n A: msi_bus=1
A: msi_irqs/128=msi\n A: msi_irqs/126=msi
A: numa_node=-1\n A: numa_node=-1
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 9 12 2112 12\nxHCI ring segments 40 50 4096 50\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 6 32 128 1\nbuffer-32 0 0 32 0\n A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 21 24 2112 24\nxHCI ring segments 68 80 4096 80\nbuffer-2048 0 38 2048 19\nbuffer-512 0 0 512 0\nbuffer-128 18 32 128 1\nbuffer-32 0 128 32 1
A: power/control=auto\n A: power/control=auto
A: power/runtime_active_time=4271635\n A: power/runtime_active_time=866094158
A: power/runtime_status=active\n A: power/runtime_status=active
A: power/runtime_suspended_time=0\n A: power/runtime_suspended_time=0
A: power/wakeup=enabled\n A: power/wakeup=enabled
A: power/wakeup_abort_count=0\n A: power/wakeup_abort_count=0
A: power/wakeup_active=0\n A: power/wakeup_active=0
A: power/wakeup_active_count=0\n A: power/wakeup_active_count=2
A: power/wakeup_count=0\n A: power/wakeup_count=0
A: power/wakeup_expire_count=0\n A: power/wakeup_expire_count=2
A: power/wakeup_last_time_ms=0\n A: power/wakeup_last_time_ms=476219021
A: power/wakeup_max_time_ms=0\n A: power/wakeup_max_time_ms=103
A: power/wakeup_total_time_ms=0\n A: power/wakeup_total_time_ms=207
A: power_state=D0\n A: power_state=D0
A: resource=0x00000000ea220000 0x00000000ea22ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n A: resource=0x00000000ea220000 0x00000000ea22ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
A: revision=0x11\n A: revision=0x11
A: subsystem_device=0x2292\n A: subsystem_device=0x2292
A: subsystem_vendor=0x17aa\n A: subsystem_vendor=0x17aa
A: vendor=0x8086\n A: vendor=0x8086

View File

@@ -232,6 +232,53 @@ test_device_has_storage (void)
G_GNUC_END_IGNORE_DEPRECATIONS G_GNUC_END_IGNORE_DEPRECATIONS
} }
static void
test_device_persistent_data (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
g_autoptr(GVariant) initial = NULL;
g_autoptr(GVariant) loaded = NULL;
g_autoptr(GError) error = NULL;
guint8 *data = (guint8 *) 0xdeadbeef;
gsize length = 1;
initial = g_variant_ref_sink (g_variant_new ("(s)", "stored data"));
g_assert_true (fp_device_get_persistent_data (tctx->device, &data, &length, &error));
g_assert_cmpint (length, ==, 0);
g_assert_null (data);
g_assert_no_error (error);
/* Use the fact that this is a property that we can poke from the outside. */
g_object_set (tctx->device, "fpi-persistent-data", initial, NULL);
/* Works now */
g_assert_true (fp_device_get_persistent_data (tctx->device, &data, &length, &error));
g_assert_cmpint (length, !=, 0);
g_assert_nonnull (data);
g_assert_no_error (error);
/* We can't load the data, as data has been set already. */
g_assert_false (fp_device_set_persistent_data (tctx->device, data, length, &error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
g_clear_pointer (&error, g_error_free);
/* Abuse that we can "load" again if the data is set to NULL.
* This is an implementation detail and just a lack of error checking. */
g_object_set (tctx->device, "fpi-persistent-data", NULL, NULL);
/* Incomplete data, causes parsing error */
g_assert_false (fp_device_set_persistent_data (tctx->device, data, 5, &error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
g_clear_pointer (&error, g_error_free);
g_assert_true (fp_device_set_persistent_data (tctx->device, data, length, &error));
g_assert_no_error (error);
g_object_get (tctx->device, "fpi-persistent-data", &loaded, NULL);
g_assert_cmpvariant (initial, loaded);
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@@ -252,6 +299,7 @@ main (int argc, char *argv[])
g_test_add_func ("/device/sync/supports_identify", test_device_supports_identify); g_test_add_func ("/device/sync/supports_identify", test_device_supports_identify);
g_test_add_func ("/device/sync/supports_capture", test_device_supports_capture); g_test_add_func ("/device/sync/supports_capture", test_device_supports_capture);
g_test_add_func ("/device/sync/has_storage", test_device_has_storage); g_test_add_func ("/device/sync/has_storage", test_device_has_storage);
g_test_add_func ("/device/persistent_data", test_device_persistent_data);
return g_test_run (); return g_test_run ();
} }

View File

@@ -29,6 +29,10 @@
#include "test-device-fake.h" #include "test-device-fake.h"
#include "fp-print-private.h" #include "fp-print-private.h"
/* gcc 12.0.1 is complaining about dangling pointers in the auto_close* functions */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-pointer"
/* Utility functions */ /* Utility functions */
typedef FpDevice FpAutoCloseDevice; typedef FpDevice FpAutoCloseDevice;
@@ -65,6 +69,8 @@ auto_close_fake_device_free (FpAutoCloseDevice *device)
} }
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpAutoCloseDevice, auto_close_fake_device_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpAutoCloseDevice, auto_close_fake_device_free)
#pragma GCC diagnostic pop
typedef FpDeviceClass FpAutoResetClass; typedef FpDeviceClass FpAutoResetClass;
static FpAutoResetClass default_fake_dev_class = {0}; static FpAutoResetClass default_fake_dev_class = {0};

View File

@@ -1,144 +0,0 @@
#!/usr/bin/env python3
import sys
try:
import gi
import os
from gi.repository import GLib, Gio
import unittest
import subprocess
import shutil
import tempfile
except Exception as e:
print("Missing dependencies: %s" % str(e))
sys.exit(77)
FPrint = None
# Re-run the test with the passed wrapper if set
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
if wrapper:
wrap_cmd = wrapper.split(' ') + [sys.executable, os.path.abspath(__file__)] + \
sys.argv[1:]
os.unsetenv('LIBFPRINT_TEST_WRAPPER')
sys.exit(subprocess.check_call(wrap_cmd))
# Only permit loading virtual_sdcp driver for tests in this file
os.environ['FP_DRIVERS_WHITELIST'] = 'virtual_sdcp'
if hasattr(os.environ, 'MESON_SOURCE_ROOT'):
root = os.environ['MESON_SOURCE_ROOT']
else:
root = os.path.join(os.path.dirname(__file__), '..')
ctx = GLib.main_context_default()
class VirtualSDCP(unittest.TestCase):
@classmethod
def setUpClass(cls):
os.environ['FP_VIRTUAL_SDCP'] = os.environ['SDCP_VIRT_BINARY']
cls.ctx = FPrint.Context()
cls.dev = None
for dev in cls.ctx.get_devices():
cls.dev = dev
break
assert cls.dev is not None, "You need to compile with virtual_sdcp for testing"
@classmethod
def tearDownClass(cls):
del cls.dev
del cls.ctx
def setUp(self):
pass
def tearDown(self):
pass
def enroll(self, progress_cb=None):
# Enroll another print
template = FPrint.Print.new(self.dev)
template.props.finger = FPrint.Finger.LEFT_THUMB
template.props.username = "testuser"
template.props.description = "test print"
datetime = GLib.DateTime.new_now_local()
date = GLib.Date()
date.set_dmy(*datetime.get_ymd()[::-1])
template.props.enroll_date = date
return self.dev.enroll_sync(template, None, progress_cb, None)
def test_connect(self):
self.dev.open_sync()
self.dev.close_sync()
def test_reconnect(self):
# Ensure device was opened once before, this may be a reconnect if
# it is the same process as another test.
self.dev.open_sync()
self.dev.close_sync()
# Check that a reconnect happens on next open. To know about this, we
# need to parse check log messages for that.
success = [False]
def log_func(domain, level, msg):
print("log: '%s', '%s', '%s'" % (str(domain), str(level), msg))
if msg == 'Reconnect succeeded':
success[0] = True
# Call default handler
GLib.log_default_handler(domain, level, msg)
handler_id = GLib.log_set_handler('libfprint-sdcp_device', GLib.LogLevelFlags.LEVEL_DEBUG, log_func)
self.dev.open_sync()
self.dev.close_sync()
GLib.log_remove_handler('libfprint-sdcp_device', handler_id)
assert success[0]
def test_enroll(self):
self.dev.open_sync()
# Must return a print
assert isinstance(self.enroll(), FPrint.Print)
self.dev.close_sync()
def test_verify(self):
self.dev.open_sync()
# Enroll a new print (will be the last), check that it verifies
p = self.enroll()
match, dev_print = self.dev.verify_sync(p)
assert match
# The returned "device" print is identical
assert p.equal(dev_print)
# We can do the same with it
match, dev_print2 = self.dev.verify_sync(dev_print)
assert match
# Now, enroll a new print, causing the old one to not match anymore
# (the device always claims to see the last enrolled print).
self.enroll()
match, dev_print = self.dev.verify_sync(p)
assert match is False
self.dev.close_sync()
if __name__ == '__main__':
try:
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint
except Exception as e:
print("Missing dependencies: %s" % str(e))
sys.exit(77)
# avoid writing to stderr
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))